1+ package github .nighter .smartspawner .spawner .gui .layout ;
2+
3+ import github .nighter .smartspawner .SmartSpawner ;
4+ import org .bukkit .Material ;
5+ import org .bukkit .configuration .file .FileConfiguration ;
6+ import org .bukkit .configuration .file .YamlConfiguration ;
7+
8+ import java .io .File ;
9+ import java .util .logging .Level ;
10+
11+ public class GuiLayoutConfig {
12+ private static final String GUI_LAYOUTS_DIR = "gui_layouts" ;
13+ private static final String STORAGE_GUI_FILE = "storage_gui.yml" ;
14+ private static final String DEFAULT_LAYOUT = "default" ;
15+ private static final int MIN_SLOT = 1 ;
16+ private static final int MAX_SLOT = 9 ;
17+ private static final int SLOT_OFFSET = 44 ;
18+
19+ private final SmartSpawner plugin ;
20+ private final File layoutsDir ;
21+ private String currentLayout ;
22+ private GuiLayout currentGuiLayout ;
23+
24+ public GuiLayoutConfig (SmartSpawner plugin ) {
25+ this .plugin = plugin ;
26+ this .layoutsDir = new File (plugin .getDataFolder (), GUI_LAYOUTS_DIR );
27+ loadLayout ();
28+ }
29+
30+ public void loadLayout () {
31+ this .currentLayout = plugin .getConfig ().getString ("gui_layout" , DEFAULT_LAYOUT );
32+ initializeLayoutsDirectory ();
33+ this .currentGuiLayout = loadCurrentLayout ();
34+ }
35+
36+ private void initializeLayoutsDirectory () {
37+ if (!layoutsDir .exists ()) {
38+ layoutsDir .mkdirs ();
39+ }
40+ autoSaveLayoutFiles ();
41+ }
42+
43+ private void autoSaveLayoutFiles () {
44+ try {
45+ String [] layoutNames = new String []{DEFAULT_LAYOUT , "DonutSMP" };
46+
47+ for (String layoutName : layoutNames ) {
48+ File layoutDir = new File (layoutsDir , layoutName );
49+ if (!layoutDir .exists ()) {
50+ layoutDir .mkdirs ();
51+ }
52+
53+ File storageFile = new File (layoutDir , STORAGE_GUI_FILE );
54+ String resourcePath = GUI_LAYOUTS_DIR + "/" + layoutName + "/" + STORAGE_GUI_FILE ;
55+
56+ if (!storageFile .exists ()) {
57+ try {
58+ plugin .saveResource (resourcePath , false );
59+ } catch (Exception e ) {
60+ plugin .getLogger ().log (Level .WARNING ,
61+ "Failed to auto-save layout resource for " + layoutName + ": " + e .getMessage (), e );
62+ }
63+ }
64+ }
65+ } catch (Exception e ) {
66+ plugin .getLogger ().log (Level .SEVERE , "Failed to auto-save layout files" , e );
67+ }
68+ }
69+
70+ private GuiLayout loadCurrentLayout () {
71+ File layoutDir = new File (layoutsDir , currentLayout );
72+ File storageFile = new File (layoutDir , STORAGE_GUI_FILE );
73+
74+ if (storageFile .exists ()) {
75+ GuiLayout layout = loadStorageLayout (storageFile );
76+ if (layout != null ) {
77+ plugin .getLogger ().info ("Loaded GUI layout: " + currentLayout );
78+ return layout ;
79+ }
80+ }
81+
82+ if (!currentLayout .equals (DEFAULT_LAYOUT )) {
83+ plugin .getLogger ().warning ("Layout '" + currentLayout + "' not found. Attempting to use default layout." );
84+ File defaultLayoutDir = new File (layoutsDir , DEFAULT_LAYOUT );
85+ File defaultStorageFile = new File (defaultLayoutDir , STORAGE_GUI_FILE );
86+
87+ if (defaultStorageFile .exists ()) {
88+ GuiLayout defaultLayout = loadStorageLayout (defaultStorageFile );
89+ if (defaultLayout != null ) {
90+ plugin .getLogger ().info ("Loaded default layout as fallback" );
91+ return defaultLayout ;
92+ }
93+ }
94+ }
95+
96+ plugin .getLogger ().severe ("No valid layout found! Creating empty layout as fallback." );
97+ return new GuiLayout ();
98+ }
99+
100+ private GuiLayout loadStorageLayout (File file ) {
101+ try {
102+ FileConfiguration config = YamlConfiguration .loadConfiguration (file );
103+ GuiLayout layout = new GuiLayout ();
104+
105+ if (!config .contains ("buttons" )) {
106+ plugin .getLogger ().warning ("No buttons section found in GUI layout: " + file .getName ());
107+ return layout ;
108+ }
109+
110+ for (String buttonKey : config .getConfigurationSection ("buttons" ).getKeys (false )) {
111+ if (!loadButton (config , layout , buttonKey )) {
112+ continue ;
113+ }
114+ }
115+
116+ return layout ;
117+ } catch (Exception e ) {
118+ plugin .getLogger ().log (Level .WARNING ,
119+ "Failed to load storage layout from " + file .getName () + ": " + e .getMessage (), e );
120+ return null ;
121+ }
122+ }
123+
124+ private boolean loadButton (FileConfiguration config , GuiLayout layout , String buttonKey ) {
125+ String path = "buttons." + buttonKey ;
126+
127+ if (!config .getBoolean (path + ".enabled" , true )) {
128+ return false ;
129+ }
130+
131+ int slot = config .getInt (path + ".slot" , -1 );
132+ String materialName = config .getString (path + ".material" , "STONE" );
133+
134+ if (!isValidSlot (slot )) {
135+ plugin .getLogger ().warning (String .format (
136+ "Invalid slot %d for button %s. Must be between %d and %d." ,
137+ slot , buttonKey , MIN_SLOT , MAX_SLOT ));
138+ return false ;
139+ }
140+
141+ Material material = parseMaterial (materialName , buttonKey );
142+ int actualSlot = SLOT_OFFSET + slot ;
143+
144+ GuiButton button = new GuiButton (buttonKey , actualSlot , material , true );
145+ layout .addButton (buttonKey , button );
146+ return true ;
147+ }
148+
149+ private boolean isValidSlot (int slot ) {
150+ return slot >= MIN_SLOT && slot <= MAX_SLOT ;
151+ }
152+
153+ private Material parseMaterial (String materialName , String buttonKey ) {
154+ try {
155+ return Material .valueOf (materialName .toUpperCase ());
156+ } catch (IllegalArgumentException e ) {
157+ plugin .getLogger ().warning (String .format (
158+ "Invalid material %s for button %s. Using STONE instead." ,
159+ materialName , buttonKey ));
160+ return Material .STONE ;
161+ }
162+ }
163+
164+ public GuiLayout getCurrentLayout () {
165+ return currentGuiLayout ;
166+ }
167+
168+ public void reloadLayouts () {
169+ loadLayout ();
170+ }
171+ }
0 commit comments