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);