diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3ecddfa9..4c6656a7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,7 +4,7 @@ stages: variables: name: "SongodaCore" path: "/builds/$CI_PROJECT_PATH" - version: "2.0.5" + version: "2.0.6" build: stage: build diff --git a/src/main/java/com/songoda/core/commands/CommandManager.java b/src/main/java/com/songoda/core/commands/CommandManager.java index c13edcd0..cc7e538d 100644 --- a/src/main/java/com/songoda/core/commands/CommandManager.java +++ b/src/main/java/com/songoda/core/commands/CommandManager.java @@ -253,7 +253,7 @@ public class CommandManager implements CommandExecutor, TabCompleter { // If we're on Paper 1.8, we need to register timings (spigot creates timings on init, paper creates it on register) // later versions of paper create timings if needed when the command is executed - if(ServerProject.isServer(ServerProject.PAPER) && ServerVersion.isServerVersionBelow(ServerVersion.V1_9)) { + if(ServerProject.isServer(ServerProject.PAPER, ServerProject.TACO) && ServerVersion.isServerVersionBelow(ServerVersion.V1_9)) { commandObject.timings = co.aikar.timings.TimingsManager.getCommandTiming(plugin.getName().toLowerCase(), commandObject); } diff --git a/src/main/java/com/songoda/core/compatibility/LegacyMaterials.java b/src/main/java/com/songoda/core/compatibility/LegacyMaterials.java index 7ecfe5a3..e74dbc4e 100644 --- a/src/main/java/com/songoda/core/compatibility/LegacyMaterials.java +++ b/src/main/java/com/songoda/core/compatibility/LegacyMaterials.java @@ -1966,6 +1966,23 @@ public enum LegacyMaterials { case WITHER_SKELETON_WALL_SKULL: return false; } + if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_12)) { + switch (this) { + case ACACIA_WOOD: + case BIRCH_WOOD: + case DARK_OAK_WOOD: + case JUNGLE_WOOD: + case OAK_WOOD: + case SPRUCE_WOOD: + case STRIPPED_ACACIA_WOOD: + case STRIPPED_BIRCH_WOOD: + case STRIPPED_DARK_OAK_WOOD: + case STRIPPED_JUNGLE_WOOD: + case STRIPPED_OAK_WOOD: + case STRIPPED_SPRUCE_WOOD: + return false; + } + } return true; } diff --git a/src/main/java/com/songoda/core/compatibility/ServerProject.java b/src/main/java/com/songoda/core/compatibility/ServerProject.java index 248f45f0..82f20df0 100644 --- a/src/main/java/com/songoda/core/compatibility/ServerProject.java +++ b/src/main/java/com/songoda/core/compatibility/ServerProject.java @@ -5,7 +5,7 @@ import org.bukkit.Bukkit; public enum ServerProject { - UNKNOWN, CRAFTBUKKIT, SPIGOT, PAPER, GLOWSTONE; + UNKNOWN, CRAFTBUKKIT, SPIGOT, PAPER, TACO, GLOWSTONE; private static ServerProject serverProject = checkProject(); private static ServerProject checkProject() { @@ -13,6 +13,12 @@ public enum ServerProject { if (serverPath.contains("glowstone")) { return GLOWSTONE; } + // taco is pretty easy to check. it uses paper stuff, though, so should be checked first + try { + Class.forName("net.techcable.tacospigot.TacoSpigotConfig"); + return TACO; + } catch (ClassNotFoundException ex) { + } // paper used to be called "paperclip" try { Class.forName("com.destroystokyo.paperclip.Paperclip"); @@ -24,6 +30,7 @@ public enum ServerProject { return PAPER; } catch (ClassNotFoundException ex) { } + // spigot is the fork that pretty much all builds are based on anymore try { Class.forName("org.spigotmc.SpigotConfig"); return SPIGOT; diff --git a/src/main/java/com/songoda/core/configuration/Config.java b/src/main/java/com/songoda/core/configuration/Config.java index c17a56f8..0f929ebb 100644 --- a/src/main/java/com/songoda/core/configuration/Config.java +++ b/src/main/java/com/songoda/core/configuration/Config.java @@ -372,6 +372,7 @@ public class Config extends ConfigSection { } protected void convertMapsToSections(@NotNull Map input, @NotNull ConfigSection section) { + // TODO: make this non-recursive for (Map.Entry entry : input.entrySet()) { String key = entry.getKey().toString(); Object value = entry.getValue(); diff --git a/src/main/java/com/songoda/core/configuration/ConfigSection.java b/src/main/java/com/songoda/core/configuration/ConfigSection.java index 84086d86..f6e2a320 100644 --- a/src/main/java/com/songoda/core/configuration/ConfigSection.java +++ b/src/main/java/com/songoda/core/configuration/ConfigSection.java @@ -107,8 +107,34 @@ public class ConfigSection extends MemoryConfiguration { return nodeKey; } + /** + * Create the path required for this node to exist.
+ * DO NOT USE THIS IN A SYNCHRONIZED LOCK + * + * @param path full path of the node required. Eg, for foo.bar.node, this will create sections for foo and foo.bar + * @param useDefault set to true if this is a default value + */ + protected void createNodePath(@NotNull String path, boolean useDefault) { + if (path.indexOf(root.pathChar) != -1) { + // if any intermediate nodes don't exist, create them + String[] pathParts = path.split(Pattern.quote(String.valueOf(root.pathChar))); + StringBuilder nodePath = new StringBuilder(fullPath); + LinkedHashMap writeTo = useDefault ? root.defaults : root.values; + ConfigSection travelNode = this; + synchronized (root.lock) { + for (int i = 0; i < pathParts.length - 1; ++i) { + final String node = (i != 0 ? nodePath.append(root.pathChar) : nodePath).append(pathParts[i]).toString(); + if (!(writeTo.get(node) instanceof ConfigSection)) { + writeTo.put(node, travelNode = new ConfigSection(root, travelNode, pathParts[i], useDefault)); + } + } + } + } + } + @NotNull public ConfigSection createDefaultSection(@NotNull String path) { + createNodePath(path, true); ConfigSection section = new ConfigSection(root, this, path, true); synchronized (root.lock) { root.defaults.put(fullPath + path, section); @@ -118,6 +144,7 @@ public class ConfigSection extends MemoryConfiguration { @NotNull public ConfigSection createDefaultSection(@NotNull String path, String... comment) { + createNodePath(path, true); ConfigSection section = new ConfigSection(root, this, path, true); synchronized (root.lock) { root.defaults.put(fullPath + path, section); @@ -128,6 +155,7 @@ public class ConfigSection extends MemoryConfiguration { @NotNull public ConfigSection createDefaultSection(@NotNull String path, ConfigFormattingRules.CommentStyle commentStyle, String... comment) { + createNodePath(path, true); ConfigSection section = new ConfigSection(root, this, path, true); synchronized (root.lock) { root.defaults.put(fullPath + path, section); @@ -199,16 +227,8 @@ public class ConfigSection extends MemoryConfiguration { @Override public void addDefault(@NotNull String path, @Nullable Object value) { + createNodePath(path, true); synchronized (root.lock) { - // if any intermediate nodes don't exist, create them - String[] pathParts = path.split(Pattern.quote(String.valueOf(root.pathChar))); - String nodePath = ""; - for (int i = 0; i < pathParts.length - 1; ++i) { - nodePath += (nodePath.isEmpty() ? pathParts[i] : root.pathChar + pathParts[i]); - if (!(root.defaults.get(nodePath) instanceof ConfigSection)) { - root.defaults.put(nodePath, new ConfigSection(root, this, nodePath, true)); - } - } root.defaults.put(fullPath + path, value); } } @@ -262,7 +282,7 @@ public class ConfigSection extends MemoryConfiguration { .collect(Collectors.toCollection(LinkedHashSet::new))); } else { result.addAll(root.defaults.keySet().stream() - .filter(k -> k.startsWith(fullPath) && k.lastIndexOf(root.pathChar) == pathIndex + 1) + .filter(k -> k.startsWith(fullPath) && k.lastIndexOf(root.pathChar) == pathIndex) .map(k -> !k.endsWith(String.valueOf(root.pathChar)) ? k.substring(pathIndex + 1) : k.substring(pathIndex + 1, k.length() - 1)) .collect(Collectors.toCollection(LinkedHashSet::new))); result.addAll(root.values.keySet().stream() @@ -384,8 +404,9 @@ public class ConfigSection extends MemoryConfiguration { @Override public void set(@NotNull String path, @Nullable Object value) { if (isDefault) { - root.defaults.put(fullPath + path, value); + addDefault(path, value); } else { + createNodePath(path, false); synchronized (root.lock) { if (value != null) { root.changed |= root.values.put(fullPath + path, value) != value; @@ -454,6 +475,7 @@ public class ConfigSection extends MemoryConfiguration { @NotNull @Override public ConfigSection createSection(@NotNull String path) { + createNodePath(path, false); ConfigSection section = new ConfigSection(root, this, path, false); synchronized(root.lock) { root.values.put(fullPath + path, section); @@ -480,6 +502,7 @@ public class ConfigSection extends MemoryConfiguration { @NotNull public ConfigSection createSection(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, @Nullable List comment) { + createNodePath(path, false); ConfigSection section = new ConfigSection(root, this, path, false); synchronized (root.lock) { root.values.put(fullPath + path, section); @@ -493,6 +516,7 @@ public class ConfigSection extends MemoryConfiguration { @NotNull @Override public ConfigSection createSection(@NotNull String path, Map map) { + createNodePath(path, false); ConfigSection section = new ConfigSection(root, this, path, false); synchronized (root.lock) { root.values.put(fullPath + path, section);