Skip to content

Commit 50ff7d6

Browse files
authored
Merge pull request #8 from NighterDevelopment/copilot/fix-9884094d-89ef-45c6-8df0-3d1e03cc4e26
Enhance GuiLayoutConfig system with conditional action handling and shop integration
2 parents 90a98d0 + 1c3273a commit 50ff7d6

13 files changed

Lines changed: 632 additions & 61 deletions

File tree

core/src/main/java/github/nighter/smartspawner/SmartSpawner.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,10 @@ public SpawnerStorageUI getSpawnerStorageUI() {
367367
return spawnerStorageUI;
368368
}
369369

370+
public GuiLayoutConfig getGuiLayoutConfig() {
371+
return guiLayoutConfig;
372+
}
373+
370374
public SpawnerManager getSpawnerManager() {
371375
return spawnerManager;
372376
}

core/src/main/java/github/nighter/smartspawner/spawner/gui/layout/GuiButton.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,36 @@
33
import lombok.Getter;
44
import org.bukkit.Material;
55

6+
import java.util.Map;
7+
68
@Getter
79
public class GuiButton {
810
private final String buttonType;
911
private final int slot;
1012
private final Material material;
1113
private final boolean enabled;
14+
private final String condition;
15+
private final Map<String, String> actions;
1216

1317
public GuiButton(String buttonType, int slot, Material material, boolean enabled) {
18+
this(buttonType, slot, material, enabled, null, null);
19+
}
20+
21+
public GuiButton(String buttonType, int slot, Material material, boolean enabled, String condition, Map<String, String> actions) {
1422
this.buttonType = buttonType;
1523
this.slot = slot;
1624
this.material = material;
1725
this.enabled = enabled;
26+
this.condition = condition;
27+
this.actions = actions;
28+
}
29+
30+
public String getAction(String clickType) {
31+
return actions != null ? actions.get(clickType) : null;
32+
}
33+
34+
public boolean hasCondition() {
35+
return condition != null && !condition.isEmpty();
1836
}
1937

2038
@Override
@@ -24,6 +42,8 @@ public String toString() {
2442
", slot=" + slot +
2543
", material=" + material +
2644
", enabled=" + enabled +
45+
", condition='" + condition + '\'' +
46+
", actions=" + actions +
2747
'}';
2848
}
2949
}

core/src/main/java/github/nighter/smartspawner/spawner/gui/layout/GuiLayout.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ public Optional<String> getButtonTypeAtSlot(int slot) {
2828
return Optional.ofNullable(slotToButtonType.get(slot));
2929
}
3030

31+
public Optional<GuiButton> getButtonAtSlot(int slot) {
32+
String buttonType = slotToButtonType.get(slot);
33+
return buttonType != null ? Optional.ofNullable(buttons.get(buttonType)) : Optional.empty();
34+
}
35+
3136
public boolean hasButton(String buttonType) {
3237
return buttons.containsKey(buttonType) && buttons.get(buttonType).isEnabled();
3338
}

core/src/main/java/github/nighter/smartspawner/spawner/gui/layout/GuiLayoutConfig.java

Lines changed: 115 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,50 @@
11
package github.nighter.smartspawner.spawner.gui.layout;
22

33
import github.nighter.smartspawner.SmartSpawner;
4+
import github.nighter.smartspawner.updates.GuiLayoutUpdater;
45
import org.bukkit.Material;
6+
import org.bukkit.configuration.ConfigurationSection;
57
import org.bukkit.configuration.file.FileConfiguration;
68
import org.bukkit.configuration.file.YamlConfiguration;
79

810
import java.io.File;
11+
import java.util.HashMap;
12+
import java.util.Map;
913
import java.util.logging.Level;
1014

1115
public class GuiLayoutConfig {
1216
private static final String GUI_LAYOUTS_DIR = "gui_layouts";
1317
private static final String STORAGE_GUI_FILE = "storage_gui.yml";
18+
private static final String MAIN_GUI_FILE = "main_gui.yml";
1419
private static final String DEFAULT_LAYOUT = "default";
1520
private static final int MIN_SLOT = 1;
1621
private static final int MAX_SLOT = 9;
1722
private static final int SLOT_OFFSET = 44;
23+
private static final int MAIN_GUI_SIZE = 27;
1824

1925
private final SmartSpawner plugin;
2026
private final File layoutsDir;
27+
private final GuiLayoutUpdater layoutUpdater;
2128
private String currentLayout;
22-
private GuiLayout currentGuiLayout;
29+
private GuiLayout currentStorageLayout;
30+
private GuiLayout currentMainLayout;
2331

2432
public GuiLayoutConfig(SmartSpawner plugin) {
2533
this.plugin = plugin;
2634
this.layoutsDir = new File(plugin.getDataFolder(), GUI_LAYOUTS_DIR);
35+
this.layoutUpdater = new GuiLayoutUpdater(plugin);
2736
loadLayout();
2837
}
2938

3039
public void loadLayout() {
3140
this.currentLayout = plugin.getConfig().getString("gui_layout", DEFAULT_LAYOUT);
3241
initializeLayoutsDirectory();
33-
this.currentGuiLayout = loadCurrentLayout();
42+
43+
// Check and update layout files before loading
44+
layoutUpdater.checkAndUpdateLayouts();
45+
46+
this.currentStorageLayout = loadCurrentStorageLayout();
47+
this.currentMainLayout = loadCurrentMainLayout();
3448
}
3549

3650
private void initializeLayoutsDirectory() {
@@ -50,15 +64,29 @@ private void autoSaveLayoutFiles() {
5064
layoutDir.mkdirs();
5165
}
5266

67+
// Save storage GUI layout
5368
File storageFile = new File(layoutDir, STORAGE_GUI_FILE);
54-
String resourcePath = GUI_LAYOUTS_DIR + "/" + layoutName + "/" + STORAGE_GUI_FILE;
69+
String storageResourcePath = GUI_LAYOUTS_DIR + "/" + layoutName + "/" + STORAGE_GUI_FILE;
5570

5671
if (!storageFile.exists()) {
5772
try {
58-
plugin.saveResource(resourcePath, false);
73+
plugin.saveResource(storageResourcePath, false);
5974
} catch (Exception e) {
6075
plugin.getLogger().log(Level.WARNING,
61-
"Failed to auto-save layout resource for " + layoutName + ": " + e.getMessage(), e);
76+
"Failed to auto-save storage layout resource for " + layoutName + ": " + e.getMessage(), e);
77+
}
78+
}
79+
80+
// Save main GUI layout
81+
File mainFile = new File(layoutDir, MAIN_GUI_FILE);
82+
String mainResourcePath = GUI_LAYOUTS_DIR + "/" + layoutName + "/" + MAIN_GUI_FILE;
83+
84+
if (!mainFile.exists()) {
85+
try {
86+
plugin.saveResource(mainResourcePath, false);
87+
} catch (Exception e) {
88+
plugin.getLogger().log(Level.WARNING,
89+
"Failed to auto-save main layout resource for " + layoutName + ": " + e.getMessage(), e);
6290
}
6391
}
6492
}
@@ -67,37 +95,45 @@ private void autoSaveLayoutFiles() {
6795
}
6896
}
6997

70-
private GuiLayout loadCurrentLayout() {
98+
private GuiLayout loadCurrentStorageLayout() {
99+
return loadLayoutFromFile(STORAGE_GUI_FILE, "storage");
100+
}
101+
102+
private GuiLayout loadCurrentMainLayout() {
103+
return loadLayoutFromFile(MAIN_GUI_FILE, "main");
104+
}
105+
106+
private GuiLayout loadLayoutFromFile(String fileName, String layoutType) {
71107
File layoutDir = new File(layoutsDir, currentLayout);
72-
File storageFile = new File(layoutDir, STORAGE_GUI_FILE);
108+
File layoutFile = new File(layoutDir, fileName);
73109

74-
if (storageFile.exists()) {
75-
GuiLayout layout = loadStorageLayout(storageFile);
110+
if (layoutFile.exists()) {
111+
GuiLayout layout = loadLayout(layoutFile, layoutType);
76112
if (layout != null) {
77-
plugin.getLogger().info("Loaded GUI layout: " + currentLayout);
113+
plugin.getLogger().info("Loaded " + layoutType + " GUI layout: " + currentLayout);
78114
return layout;
79115
}
80116
}
81117

82118
if (!currentLayout.equals(DEFAULT_LAYOUT)) {
83119
plugin.getLogger().warning("Layout '" + currentLayout + "' not found. Attempting to use default layout.");
84120
File defaultLayoutDir = new File(layoutsDir, DEFAULT_LAYOUT);
85-
File defaultStorageFile = new File(defaultLayoutDir, STORAGE_GUI_FILE);
121+
File defaultLayoutFile = new File(defaultLayoutDir, fileName);
86122

87-
if (defaultStorageFile.exists()) {
88-
GuiLayout defaultLayout = loadStorageLayout(defaultStorageFile);
123+
if (defaultLayoutFile.exists()) {
124+
GuiLayout defaultLayout = loadLayout(defaultLayoutFile, layoutType);
89125
if (defaultLayout != null) {
90-
plugin.getLogger().info("Loaded default layout as fallback");
126+
plugin.getLogger().info("Loaded default " + layoutType + " layout as fallback");
91127
return defaultLayout;
92128
}
93129
}
94130
}
95131

96-
plugin.getLogger().severe("No valid layout found! Creating empty layout as fallback.");
132+
plugin.getLogger().severe("No valid " + layoutType + " layout found! Creating empty layout as fallback.");
97133
return new GuiLayout();
98134
}
99135

100-
private GuiLayout loadStorageLayout(File file) {
136+
private GuiLayout loadLayout(File file, String layoutType) {
101137
try {
102138
FileConfiguration config = YamlConfiguration.loadConfiguration(file);
103139
GuiLayout layout = new GuiLayout();
@@ -108,20 +144,20 @@ private GuiLayout loadStorageLayout(File file) {
108144
}
109145

110146
for (String buttonKey : config.getConfigurationSection("buttons").getKeys(false)) {
111-
if (!loadButton(config, layout, buttonKey)) {
147+
if (!loadButton(config, layout, buttonKey, layoutType)) {
112148
continue;
113149
}
114150
}
115151

116152
return layout;
117153
} catch (Exception e) {
118154
plugin.getLogger().log(Level.WARNING,
119-
"Failed to load storage layout from " + file.getName() + ": " + e.getMessage(), e);
155+
"Failed to load " + layoutType + " layout from " + file.getName() + ": " + e.getMessage(), e);
120156
return null;
121157
}
122158
}
123159

124-
private boolean loadButton(FileConfiguration config, GuiLayout layout, String buttonKey) {
160+
private boolean loadButton(FileConfiguration config, GuiLayout layout, String buttonKey, String layoutType) {
125161
String path = "buttons." + buttonKey;
126162

127163
if (!config.getBoolean(path + ".enabled", true)) {
@@ -130,24 +166,68 @@ private boolean loadButton(FileConfiguration config, GuiLayout layout, String bu
130166

131167
int slot = config.getInt(path + ".slot", -1);
132168
String materialName = config.getString(path + ".material", "STONE");
169+
String condition = config.getString(path + ".condition", null);
133170

134-
if (!isValidSlot(slot)) {
171+
// Validate slot based on layout type
172+
if (!isValidSlot(slot, layoutType)) {
135173
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));
174+
"Invalid slot %d for button %s in %s layout. Must be between %d and %d.",
175+
slot, buttonKey, layoutType, getMinSlot(layoutType), getMaxSlot(layoutType)));
176+
return false;
177+
}
178+
179+
// Check condition if present
180+
if (condition != null && !evaluateCondition(condition)) {
138181
return false;
139182
}
140183

141184
Material material = parseMaterial(materialName, buttonKey);
142-
int actualSlot = SLOT_OFFSET + slot;
185+
int actualSlot = calculateActualSlot(slot, layoutType);
143186

144-
GuiButton button = new GuiButton(buttonKey, actualSlot, material, true);
187+
// Load actions
188+
Map<String, String> actions = new HashMap<>();
189+
ConfigurationSection actionsSection = config.getConfigurationSection(path + ".actions");
190+
if (actionsSection != null) {
191+
for (String actionKey : actionsSection.getKeys(false)) {
192+
actions.put(actionKey, actionsSection.getString(actionKey));
193+
}
194+
}
195+
196+
GuiButton button = new GuiButton(buttonKey, actualSlot, material, true, condition, actions);
145197
layout.addButton(buttonKey, button);
146198
return true;
147199
}
148200

149-
private boolean isValidSlot(int slot) {
150-
return slot >= MIN_SLOT && slot <= MAX_SLOT;
201+
private boolean isValidSlot(int slot, String layoutType) {
202+
return slot >= getMinSlot(layoutType) && slot <= getMaxSlot(layoutType);
203+
}
204+
205+
private int getMinSlot(String layoutType) {
206+
return "storage".equals(layoutType) ? MIN_SLOT : 1;
207+
}
208+
209+
private int getMaxSlot(String layoutType) {
210+
return "storage".equals(layoutType) ? MAX_SLOT : MAIN_GUI_SIZE;
211+
}
212+
213+
private int calculateActualSlot(int slot, String layoutType) {
214+
if ("storage".equals(layoutType)) {
215+
return SLOT_OFFSET + slot;
216+
} else {
217+
return slot - 1; // Convert 1-based to 0-based indexing for main GUI
218+
}
219+
}
220+
221+
private boolean evaluateCondition(String condition) {
222+
switch (condition) {
223+
case "shop_integration":
224+
return plugin.hasSellIntegration();
225+
case "no_shop_integration":
226+
return !plugin.hasSellIntegration();
227+
default:
228+
plugin.getLogger().warning("Unknown condition: " + condition);
229+
return true;
230+
}
151231
}
152232

153233
private Material parseMaterial(String materialName, String buttonKey) {
@@ -162,7 +242,15 @@ private Material parseMaterial(String materialName, String buttonKey) {
162242
}
163243

164244
public GuiLayout getCurrentLayout() {
165-
return currentGuiLayout;
245+
return getCurrentStorageLayout();
246+
}
247+
248+
public GuiLayout getCurrentStorageLayout() {
249+
return currentStorageLayout;
250+
}
251+
252+
public GuiLayout getCurrentMainLayout() {
253+
return currentMainLayout;
166254
}
167255

168256
public void reloadLayouts() {

0 commit comments

Comments
 (0)