diff --git a/api/build.gradle b/api/build.gradle index a571b2a53..472f70c56 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -5,4 +5,5 @@ plugins { dependencies { compileOnly("com.github.ClubObsidian:FuzzUtil:1.1.0") compileOnly("javax.inject:javax.inject:1") + compileOnly("com.github.clubobsidian:wrappy:$wrappyVersion") } \ No newline at end of file diff --git a/api/src/main/java/com/clubobsidian/dynamicgui/api/parser/macro/MacroParser.java b/api/src/main/java/com/clubobsidian/dynamicgui/api/parser/macro/MacroParser.java index 22e032e18..3c7e716e0 100644 --- a/api/src/main/java/com/clubobsidian/dynamicgui/api/parser/macro/MacroParser.java +++ b/api/src/main/java/com/clubobsidian/dynamicgui/api/parser/macro/MacroParser.java @@ -16,6 +16,8 @@ package com.clubobsidian.dynamicgui.api.parser.macro; +import com.clubobsidian.wrappy.ConfigurationSection; + import java.io.Serializable; import java.util.List; @@ -27,4 +29,5 @@ public interface MacroParser extends Serializable { List parseListMacros(final List replaceIn); + ConfigurationSection parseSectionMacros(ConfigurationSection copyInto); } \ No newline at end of file diff --git a/core/src/main/java/com/clubobsidian/dynamicgui/core/gui/SimpleGui.java b/core/src/main/java/com/clubobsidian/dynamicgui/core/gui/SimpleGui.java index 9443578b3..4e68b3f2a 100644 --- a/core/src/main/java/com/clubobsidian/dynamicgui/core/gui/SimpleGui.java +++ b/core/src/main/java/com/clubobsidian/dynamicgui/core/gui/SimpleGui.java @@ -53,7 +53,7 @@ public class SimpleGui implements Gui { private final List> locations; private final Map> npcIds; private transient InventoryWrapper inventoryWrapper; - private final FunctionTree functions; + private transient FunctionTree functions; private Gui back; private final Map metadata; private final boolean isStatic; @@ -221,6 +221,15 @@ public boolean isStatic() { } public Gui clone() { - return SerializationUtils.clone(this); + SimpleGui cloned = SerializationUtils.clone(this); + cloned.functions = this.functions; + for (Slot slot : this.slots) { + Slot clonedSlot = cloned.slots.get(slot.getIndex()); + if (clonedSlot instanceof SimpleSlot) { + SimpleSlot clonedSimpleSlot = (SimpleSlot) clonedSlot; + clonedSimpleSlot.setFunctions(slot.getFunctions()); + } + } + return cloned; } } \ No newline at end of file diff --git a/core/src/main/java/com/clubobsidian/dynamicgui/core/gui/SimpleSlot.java b/core/src/main/java/com/clubobsidian/dynamicgui/core/gui/SimpleSlot.java index b0c659349..53c9ef52c 100644 --- a/core/src/main/java/com/clubobsidian/dynamicgui/core/gui/SimpleSlot.java +++ b/core/src/main/java/com/clubobsidian/dynamicgui/core/gui/SimpleSlot.java @@ -59,7 +59,7 @@ public class SimpleSlot implements Slot { private final int amount; private transient ItemStackWrapper itemStack; private Gui owner; - private final FunctionTree functions; + private transient FunctionTree functions; private final int updateInterval; private int tick; private int frame; @@ -180,6 +180,10 @@ public FunctionTree getFunctions() { return this.functions; } + public void setFunctions(FunctionTree functions) { + this.functions = functions; + } + @Override @Nullable public ItemStackWrapper buildItemStack(@NotNull PlayerWrapper playerWrapper) { diff --git a/parser/src/main/java/com/clubobsidian/dynamicgui/parser/gui/SimpleGuiToken.java b/parser/src/main/java/com/clubobsidian/dynamicgui/parser/gui/SimpleGuiToken.java index 0e32a7b46..f897f69ef 100644 --- a/parser/src/main/java/com/clubobsidian/dynamicgui/parser/gui/SimpleGuiToken.java +++ b/parser/src/main/java/com/clubobsidian/dynamicgui/parser/gui/SimpleGuiToken.java @@ -69,6 +69,7 @@ public SimpleGuiToken(ConfigurationSection section, List macroTokens copyMacroTokens.add(new SimpleMacroToken(macrosSection)); this.macroParser = new SimpleMacroParser(copyMacroTokens); + this.macroParser.parseSectionMacros(section); this.title = this.macroParser.parseStringMacros(section.getString("title")); this.type = this.parseType(section.getString("type")); diff --git a/parser/src/main/java/com/clubobsidian/dynamicgui/parser/macro/SimpleMacroParser.java b/parser/src/main/java/com/clubobsidian/dynamicgui/parser/macro/SimpleMacroParser.java index 709b70550..1c413f0fd 100644 --- a/parser/src/main/java/com/clubobsidian/dynamicgui/parser/macro/SimpleMacroParser.java +++ b/parser/src/main/java/com/clubobsidian/dynamicgui/parser/macro/SimpleMacroParser.java @@ -18,6 +18,7 @@ import com.clubobsidian.dynamicgui.api.parser.macro.MacroParser; import com.clubobsidian.dynamicgui.api.parser.macro.MacroToken; +import com.clubobsidian.wrappy.ConfigurationSection; import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; @@ -50,10 +51,12 @@ public String parseStringMacros(final String replaceIn) { } String replace = replaceIn; for (MacroToken token : this.tokens) { - for (Map.Entry next : token.getMacros().entrySet()) { - String key = next.getKey(); - Object value = next.getValue(); - + for (Map.Entry entry : token.getMacros().entrySet()) { + if (entry.getValue() instanceof ConfigurationSection) { + continue; + } + String key = entry.getKey(); + Object value = entry.getValue(); if (replace.contains(key)) { replace = StringUtils.replace(replace, key, value.toString()); } @@ -62,6 +65,9 @@ public String parseStringMacros(final String replaceIn) { for (MacroToken token : this.tokens) { for (Map.Entry entry : token.getMacros().entrySet()) { + if (entry.getValue() instanceof ConfigurationSection) { + continue; + } String key = entry.getKey(); if (replace.contains(key)) { return this.parseStringMacros(replace); @@ -78,7 +84,9 @@ public List parseListMacros(final List replaceIn) { for (MacroToken token : this.tokens) { for (Map.Entry next : token.getMacros().entrySet()) { String key = next.getKey(); - + if (next.getValue() instanceof ConfigurationSection) { + continue; + } for (int i = 0; i < newList.size(); i++) { String line = newList.get(i); if (line.contains(key)) { @@ -137,4 +145,38 @@ public List parseListMacros(final List replaceIn) { return newList; } + + @Override + public ConfigurationSection parseSectionMacros(ConfigurationSection copyInto) { + for (MacroToken token : this.tokens) { + for (Map.Entry entry : token.getMacros().entrySet()) { + if (entry.getValue() instanceof ConfigurationSection) { + String macroName = entry.getKey(); + ConfigurationSection tokenSection = (ConfigurationSection) entry.getValue(); + this.recurReplaceSection(macroName, tokenSection, copyInto); + } + } + } + return copyInto; + } + + private void recurReplaceSection(String macroName, + ConfigurationSection tokenSection, + ConfigurationSection copyInto) { + for (Object key : copyInto.getKeys()) { + Object value = copyInto.get(key); + if (value instanceof String) { + String strValue = (String) value; + if (strValue.equals(macroName)) { + copyInto.set(key, null); + ConfigurationSection valueSection = copyInto.getConfigurationSection(key); + valueSection.combine(tokenSection); + } + } + ConfigurationSection childSection = copyInto.getConfigurationSection(key); + if (!childSection.getKeys().isEmpty()) { + this.recurReplaceSection(macroName, tokenSection, childSection); + } + } + } } diff --git a/parser/src/main/java/com/clubobsidian/dynamicgui/parser/macro/SimpleMacroToken.java b/parser/src/main/java/com/clubobsidian/dynamicgui/parser/macro/SimpleMacroToken.java index 7288e7624..3e795d39e 100644 --- a/parser/src/main/java/com/clubobsidian/dynamicgui/parser/macro/SimpleMacroToken.java +++ b/parser/src/main/java/com/clubobsidian/dynamicgui/parser/macro/SimpleMacroToken.java @@ -41,7 +41,12 @@ private void parse(ConfigurationSection section) { for (Object key : section.getKeys()) { if (key instanceof String) { String keyStr = (String) key; - this.macros.put(keyStr, section.get(key)); + ConfigurationSection keySection = section.getConfigurationSection(key); + if (!keySection.getKeys().isEmpty()) { + this.macros.put(keyStr, keySection); + } else { + this.macros.put(keyStr, section.get(key)); + } } else { DynamicGui.get().getLogger().error("Macros do not support non-string keys: " + key); } diff --git a/parser/src/main/java/com/clubobsidian/dynamicgui/parser/slot/SimpleSlotToken.java b/parser/src/main/java/com/clubobsidian/dynamicgui/parser/slot/SimpleSlotToken.java index 0332744a9..f6c15fcdb 100644 --- a/parser/src/main/java/com/clubobsidian/dynamicgui/parser/slot/SimpleSlotToken.java +++ b/parser/src/main/java/com/clubobsidian/dynamicgui/parser/slot/SimpleSlotToken.java @@ -64,6 +64,7 @@ public SimpleSlotToken(int index, ConfigurationSection section, List ConfigurationSection macrosSection = section.getConfigurationSection("macros"); copyMacroTokens.add(new SimpleMacroToken(macrosSection)); this.macroParser = new SimpleMacroParser(copyMacroTokens); + this.macroParser.parseSectionMacros(section); this.index = index; this.amount = this.parseAmount(section.getInteger("amount")); this.icon = this.macroParser.parseStringMacros(section.getString("icon")); diff --git a/parser/src/test/java/com/clubobsidian/dynamicgui/parser/test/macro/MacroParserTest.java b/parser/src/test/java/com/clubobsidian/dynamicgui/parser/test/macro/MacroParserTest.java index f05e88850..3a231bd4d 100644 --- a/parser/src/test/java/com/clubobsidian/dynamicgui/parser/test/macro/MacroParserTest.java +++ b/parser/src/test/java/com/clubobsidian/dynamicgui/parser/test/macro/MacroParserTest.java @@ -27,8 +27,9 @@ import java.io.File; import java.util.ArrayList; import java.util.List; +import java.util.Map; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; public class MacroParserTest { @@ -168,4 +169,20 @@ public void testMacroChaining() { assertEquals("with some other text", parsedLore.get(3)); assertEquals("still-not-a-macro", parsedLore.get(4)); } + + @Test + public void testSectionMacroToken() { + File file = new File("test.yml"); + Configuration config = Configuration.load(file); + ConfigurationSection macroSection = config.getConfigurationSection("macros"); + + MacroToken token = new SimpleMacroToken(macroSection); + MacroParser parser = new SimpleMacroParser(List.of(token)); + ConfigurationSection parentFunctionSection = config.getConfigurationSection("functions"); + parser.parseSectionMacros(parentFunctionSection); + ConfigurationSection childFunctionSection = parentFunctionSection.getConfigurationSection("function"); + assertEquals(2, childFunctionSection.getKeys().size()); + assertEquals("load", childFunctionSection.getString("type")); + assertEquals("function-2", childFunctionSection.getStringList("functions").get(0)); + } } \ No newline at end of file diff --git a/parser/src/test/java/com/clubobsidian/dynamicgui/parser/test/macro/MacrosTokenTest.java b/parser/src/test/java/com/clubobsidian/dynamicgui/parser/test/macro/MacrosTokenTest.java index 9888ff8d2..e9361369b 100644 --- a/parser/src/test/java/com/clubobsidian/dynamicgui/parser/test/macro/MacrosTokenTest.java +++ b/parser/src/test/java/com/clubobsidian/dynamicgui/parser/test/macro/MacrosTokenTest.java @@ -34,12 +34,10 @@ public class MacrosTokenTest { public void testGuiMacroToken() { File file = new File("test.yml"); Configuration config = Configuration.load(file); - ConfigurationSection section = config - .getConfigurationSection("macros"); + ConfigurationSection section = config.getConfigurationSection("macros"); MacroToken token = new SimpleMacroToken(section); Map macros = token.getMacros(); - - assertEquals(2, macros.size()); + assertEquals(3, macros.size()); } @Test diff --git a/parser/test.yml b/parser/test.yml index ccba12384..0b41e6491 100644 --- a/parser/test.yml +++ b/parser/test.yml @@ -13,12 +13,13 @@ macros: - "not-a-macro" - "%multiline-test%" - "still-not-a-macro" - -functions: - function: + '%function-macro%': type: "load" functions: - - "function-2" + - "function-2" + +functions: + function: "%function-macro%" '0': name: "Some name"