From eb81ed6852ab44b1ce3cfb8c3b590c00b2f46ad1 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Thu, 18 Mar 2021 00:36:47 -0400 Subject: [PATCH 01/61] Gradle setup for configurate --- Essentials/build.gradle | 10 ++++++++ .../config/EssentialsConfiguration.java | 23 +++++++++++++++++++ build.gradle | 4 +++- 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java diff --git a/Essentials/build.gradle b/Essentials/build.gradle index 559b8fbe30c..79129e27942 100644 --- a/Essentials/build.gradle +++ b/Essentials/build.gradle @@ -8,6 +8,9 @@ dependencies { api 'org.bstats:bstats-bukkit:1.8' + api 'org.spongepowered:configurate-yaml:4.0.0' + implementation 'org.yaml:snakeyaml:1.+' + // Providers api project(':providers:BaseProviders') api project(':providers:PaperProvider') @@ -23,6 +26,10 @@ shadowJar { dependencies { include (dependency('io.papermc:paperlib')) include (dependency('org.bstats:bstats-bukkit')) + include (dependency('org.spongepowered:configurate-yaml')) + include (dependency('org.spongepowered:configurate-core')) + include (dependency('org.yaml:snakeyaml')) + include (dependency('io.leangen.geantyref:geantyref')) include (project(':providers:BaseProviders')) include (project(':providers:PaperProvider')) include (project(':providers:NMSReflectionProvider')) @@ -30,4 +37,7 @@ shadowJar { } relocate 'io.papermc.lib', 'com.earth2me.essentials.paperlib' relocate 'org.bstats.bukkit', 'com.earth2me.essentials.metrics' + relocate 'org.spongepowered.configurate', 'com.earth2me.essentials.configurate' + relocate 'org.yaml.snakeyaml', 'com.earth2me.essentials.snakeyaml' + relocate 'io.leangen.geantyref', 'com.earth2me.essentials.geantyref' } diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java new file mode 100644 index 00000000000..0c82acfec7b --- /dev/null +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -0,0 +1,23 @@ +package com.earth2me.essentials.config; + +import org.spongepowered.configurate.yaml.YamlConfigurationLoader; + +import java.io.File; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class EssentialsConfiguration { + private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor(); + private final File configFile; + private final YamlConfigurationLoader loader; + + public EssentialsConfiguration(final File configFile) { + this.configFile = configFile; + loader = YamlConfigurationLoader.builder().file(configFile).build(); + + } + + public synchronized void load() { + + } +} diff --git a/build.gradle b/build.gradle index f2795558775..ce992aa6f46 100644 --- a/build.gradle +++ b/build.gradle @@ -82,7 +82,9 @@ subprojects { testImplementation "org.mockito:mockito-core:${mockitoVersion}" if (project.name != "1_8Provider" && project.name != "PaperProvider" && project.name != "NMSReflectionProvider") { // These providers use their own bukkit versions - api "org.spigotmc:spigot-api:${spigotVersion}" + api("org.spigotmc:spigot-api:${spigotVersion}") { + exclude group: "org.yaml", module: "snakeyaml" + } } } From 11f763c66ebe5c8d375588f66de76da9c94e524b Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Thu, 18 Mar 2021 11:43:56 -0400 Subject: [PATCH 02/61] Add loading logic --- .../config/EssentialsConfiguration.java | 60 ++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index 0c82acfec7b..6cfe9802a93 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -1,23 +1,79 @@ package com.earth2me.essentials.config; +import org.spongepowered.configurate.CommentedConfigurationNode; +import org.spongepowered.configurate.ConfigurateException; +import org.spongepowered.configurate.loader.ParsingException; import org.spongepowered.configurate.yaml.YamlConfigurationLoader; import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Level; +import java.util.logging.Logger; + +import static com.earth2me.essentials.I18n.tl; public class EssentialsConfiguration { + protected static final Logger LOGGER = Logger.getLogger("Essentials"); private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor(); + private final AtomicInteger pendingWrites = new AtomicInteger(0); + private Class resourceClass = EssentialsConfiguration.class; private final File configFile; private final YamlConfigurationLoader loader; + private final String templateName; + private CommentedConfigurationNode configurationNode; public EssentialsConfiguration(final File configFile) { - this.configFile = configFile; - loader = YamlConfigurationLoader.builder().file(configFile).build(); + this(configFile, null); + } + public EssentialsConfiguration(final File configFile, final String templateName) { + this.configFile = configFile; + this.loader = YamlConfigurationLoader.builder().file(configFile).build(); + this.templateName = templateName; } public synchronized void load() { + if (pendingWrites.get() != 0) { + LOGGER.log(Level.INFO, "Parsing config file {0} has been aborted due to {1} current pending write(s).", new Object[]{configFile, pendingWrites.get()}); + return; + } + + if (!configFile.getParentFile().exists()) { + if (!configFile.getParentFile().mkdirs()) { + LOGGER.log(Level.SEVERE, tl("failedToCreateConfig", configFile.toString())); + return; + } + } + + if (!configFile.exists() && templateName != null) { + try (final InputStream is = resourceClass.getResourceAsStream(templateName)) { + Files.copy(is, configFile.toPath()); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, tl("failedToWriteConfig", configFile.toString()), e); + } + } + try { + configurationNode = loader.load(); + } catch (final ParsingException e) { + final File broken = new File(configFile.getAbsolutePath() + ".broken." + System.currentTimeMillis()); + if (configFile.renameTo(broken)) { + LOGGER.log(Level.SEVERE, "The file " + configFile.toString() + " is broken, it has been renamed to " + broken.toString(), e.getCause()); + return; + } + LOGGER.log(Level.SEVERE, "The file " + configFile.toString() + " is broken. A backup file has failed to be created", e.getCause()); + } catch (final ConfigurateException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + } finally { + // Something is wrong! We need a node! I hope the backup worked! + if (configurationNode == null) { + configurationNode = loader.createNode(); + } + } } } From a2186f9d93ecb4369860f0c94bace5a147b3b781 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Thu, 18 Mar 2021 13:44:51 -0400 Subject: [PATCH 03/61] Add save logic --- .../config/ConfigurationSaveTask.java | 41 ++++++++++++++ .../config/EssentialsConfiguration.java | 53 +++++++++++++++++-- 2 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 Essentials/src/main/java/com/earth2me/essentials/config/ConfigurationSaveTask.java diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/ConfigurationSaveTask.java b/Essentials/src/main/java/com/earth2me/essentials/config/ConfigurationSaveTask.java new file mode 100644 index 00000000000..6c9ebc51ca7 --- /dev/null +++ b/Essentials/src/main/java/com/earth2me/essentials/config/ConfigurationSaveTask.java @@ -0,0 +1,41 @@ +package com.earth2me.essentials.config; + +import org.spongepowered.configurate.CommentedConfigurationNode; +import org.spongepowered.configurate.ConfigurateException; +import org.spongepowered.configurate.yaml.YamlConfigurationLoader; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Level; + +import static com.earth2me.essentials.config.EssentialsConfiguration.LOGGER; + +public class ConfigurationSaveTask implements Runnable { + private final YamlConfigurationLoader loader; + private final CommentedConfigurationNode node; + private final AtomicInteger pendingWrites; + + public ConfigurationSaveTask(final YamlConfigurationLoader loader, final CommentedConfigurationNode node, final AtomicInteger pendingWrites) { + this.loader = loader; + this.node = node; + this.pendingWrites = pendingWrites; + } + + @Override + public void run() { + synchronized (loader) { + // Check if there are more writes in queue. + // If that's the case, we shouldn't bother writing data which is already out-of-date. + if (pendingWrites.get() > 1) { + pendingWrites.decrementAndGet(); + } + + try { + loader.save(node); + } catch (ConfigurateException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + } finally { + pendingWrites.decrementAndGet(); + } + } + } +} diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index 6cfe9802a93..036755cf730 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -3,14 +3,19 @@ import org.spongepowered.configurate.CommentedConfigurationNode; import org.spongepowered.configurate.ConfigurateException; import org.spongepowered.configurate.loader.ParsingException; +import org.spongepowered.configurate.serialize.SerializationException; +import org.spongepowered.configurate.yaml.NodeStyle; import org.spongepowered.configurate.yaml.YamlConfigurationLoader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; import java.util.logging.Logger; @@ -21,7 +26,8 @@ public class EssentialsConfiguration { protected static final Logger LOGGER = Logger.getLogger("Essentials"); private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor(); private final AtomicInteger pendingWrites = new AtomicInteger(0); - private Class resourceClass = EssentialsConfiguration.class; + private final AtomicBoolean transaction = new AtomicBoolean(false); + protected Class resourceClass = EssentialsConfiguration.class; private final File configFile; private final YamlConfigurationLoader loader; private final String templateName; @@ -33,7 +39,7 @@ public EssentialsConfiguration(final File configFile) { public EssentialsConfiguration(final File configFile, final String templateName) { this.configFile = configFile; - this.loader = YamlConfigurationLoader.builder().file(configFile).build(); + this.loader = YamlConfigurationLoader.builder().nodeStyle(NodeStyle.BLOCK).indent(2).file(configFile).build(); this.templateName = templateName; } @@ -43,7 +49,7 @@ public synchronized void load() { return; } - if (!configFile.getParentFile().exists()) { + if (configFile.getParentFile() != null && !configFile.getParentFile().exists()) { if (!configFile.getParentFile().mkdirs()) { LOGGER.log(Level.SEVERE, tl("failedToCreateConfig", configFile.toString())); return; @@ -76,4 +82,45 @@ public synchronized void load() { } } } + + /** + * Begins a transaction. + * + * A transaction informs Essentials to pause the saving of data. This is should be used when + * bulk operations are being done and data shouldn't be saved until after the transaction has + * been completed. + */ + public void startTransaction() { + transaction.set(true); + } + + public void stopTransaction() { + transaction.set(false); + save(); + } + + public synchronized void save() { + if (!transaction.get()) { + delaySave(); + } + } + + public synchronized void blockingSave() { + try { + final Future future = delaySave(); + if (future != null) { + future.get(); + } + } catch (final InterruptedException | ExecutionException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + } + } + + private Future delaySave() { + final CommentedConfigurationNode node = configurationNode.copy(); + + pendingWrites.incrementAndGet(); + + return EXECUTOR_SERVICE.submit(new ConfigurationSaveTask(loader, node, pendingWrites)); + } } From 8e315ce466c579d1c5b35ce2dff0c96f2bb0aea7 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Thu, 18 Mar 2021 23:50:24 -0400 Subject: [PATCH 04/61] Add helper methods for fetching data --- .../essentials/config/ConfigurateUtil.java | 76 +++++++ .../config/EssentialsConfiguration.java | 202 +++++++++++++++++- 2 files changed, 274 insertions(+), 4 deletions(-) create mode 100644 Essentials/src/main/java/com/earth2me/essentials/config/ConfigurateUtil.java diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/ConfigurateUtil.java b/Essentials/src/main/java/com/earth2me/essentials/config/ConfigurateUtil.java new file mode 100644 index 00000000000..aef1231dbc9 --- /dev/null +++ b/Essentials/src/main/java/com/earth2me/essentials/config/ConfigurateUtil.java @@ -0,0 +1,76 @@ +package com.earth2me.essentials.config; + +import org.spongepowered.configurate.CommentedConfigurationNode; + +import java.math.BigDecimal; +import java.math.MathContext; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +public final class ConfigurateUtil { + private ConfigurateUtil() { + } + + public static Set getKeys(final CommentedConfigurationNode node) { + if (node == null || !node.isMap()) { + return Collections.emptySet(); + } + + final Set keys = new LinkedHashSet<>(); + for (Object obj : node.childrenMap().keySet()) { + keys.add(String.valueOf(obj)); + } + return keys; + } + + public static Map getMap(final CommentedConfigurationNode node) { + if (node == null || !node.isMap()) { + return Collections.emptyMap(); + } + + final Map map = new LinkedHashMap<>(); + for (Map.Entry entry : node.childrenMap().entrySet()) { + map.put(String.valueOf(entry.getKey()), entry.getValue()); + } + return map; + } + + public static Map getRawMap(final CommentedConfigurationNode node) { + if (node == null || !node.isMap()) { + return Collections.emptyMap(); + } + + final Map map = new LinkedHashMap<>(); + for (Map.Entry entry : node.childrenMap().entrySet()) { + map.put(String.valueOf(entry.getKey()), entry.getValue().raw()); + } + return map; + } + + public static BigDecimal toBigDecimal(final String input, final BigDecimal def) { + if (input == null || input.isEmpty()) { + return def; + } + + try { + return new BigDecimal(input, MathContext.DECIMAL128); + } catch (final NumberFormatException | ArithmeticException e) { + return def; + } + } + + public static boolean isDouble(final CommentedConfigurationNode node) { + return node != null && node.raw() instanceof Double; + } + + public static boolean isInt(final CommentedConfigurationNode node) { + return node != null && node.raw() instanceof Integer; + } + + public static boolean isString(final CommentedConfigurationNode node) { + return node != null && node.raw() instanceof String; + } +} diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index 036755cf730..3cc0ba286fd 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -1,5 +1,9 @@ package com.earth2me.essentials.config; +import net.ess3.api.InvalidWorldException; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; import org.spongepowered.configurate.CommentedConfigurationNode; import org.spongepowered.configurate.ConfigurateException; import org.spongepowered.configurate.loader.ParsingException; @@ -10,7 +14,11 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.math.BigDecimal; import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -43,6 +51,195 @@ public EssentialsConfiguration(final File configFile, final String templateName) this.templateName = templateName; } + public void setProperty(final String path, final Location location) { + //noinspection ConstantConditions + setInternal(path + ".world", location.getWorld().getName()); + setInternal(path + ".x", location.getX()); + setInternal(path + ".y", location.getY()); + setInternal(path + ".z", location.getZ()); + setInternal(path + ".yaw", location.getYaw()); + setInternal(path + ".pitch", location.getPitch()); + } + + public Location getLocation(final String path) throws InvalidWorldException { + final String worldName = getString(path + ".world", null); + if (worldName == null || worldName.isEmpty()) { + return null; + } + + final World world = Bukkit.getWorld(worldName); + if (world == null) { + throw new InvalidWorldException(worldName); + } + return new Location(world, getDouble(path + ".x", 0), getDouble(path + ".y", 0), + getDouble(path + ".z", 0), getFloat(path + ".yaw", 0), getFloat(path + ".pitch", 0)); + } + + public void setProperty(final String path, final List list) { + setInternal(path, list); + } + + public List getList(final String path, Class type) { + final CommentedConfigurationNode node = getInternal(path); + if (node == null) { + return new ArrayList<>(); + } + try { + final List list = node.getList(type); + if (list == null) { + return new ArrayList<>(); + } + return list; + } catch (SerializationException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + return new ArrayList<>(); + } + } + + public boolean isList(String path) { + final CommentedConfigurationNode node = getInternal(path); + return node != null && node.isList(); + } + + public void setProperty(final String path, final String value) { + setInternal(path, value); + } + + public String getString(final String path, final String def) { + final CommentedConfigurationNode node = getInternal(path); + if (node == null) { + return def; + } + return node.getString(); + } + + public void setProperty(final String path, final boolean value) { + setInternal(path, value); + } + + public boolean getBoolean(final String path, final boolean def) { + final CommentedConfigurationNode node = getInternal(path); + if (node == null) { + return def; + } + return node.getBoolean(); + } + + public boolean isBoolean(final String path) { + final CommentedConfigurationNode node = getInternal(path); + return node != null && node.raw() instanceof Boolean; + } + + public void setProperty(final String path, final long value) { + setInternal(path, value); + } + + public long getLong(final String path, final long def) { + final CommentedConfigurationNode node = getInternal(path); + if (node == null) { + return def; + } + return node.getLong(); + } + + public void setProperty(final String path, final int value) { + setInternal(path, value); + } + + public int getInt(final String path, final int def) { + final CommentedConfigurationNode node = getInternal(path); + if (node == null) { + return def; + } + return node.getInt(); + } + + public void setProperty(final String path, final double value) { + setInternal(path, value); + } + + public double getDouble(final String path, final double def) { + final CommentedConfigurationNode node = getInternal(path); + if (node == null) { + return def; + } + return node.getDouble(); + } + + public boolean isDouble(final String path) { + final CommentedConfigurationNode node = getInternal(path); + return node != null && node.raw() instanceof Double; + } + + public void setProperty(final String path, final float value) { + setInternal(path, value); + } + + public float getFloat(final String path, final float def) { + final CommentedConfigurationNode node = getInternal(path); + if (node == null) { + return def; + } + return node.getFloat(); + } + + public void setProperty(final String path, final BigDecimal value) { + setProperty(path, value.toString()); + } + + public BigDecimal getBigDecimal(final String path, final BigDecimal def) { + final CommentedConfigurationNode node = getInternal(path); + if (node == null) { + return def; + } + return ConfigurateUtil.toBigDecimal(node.getString(), def); + } + + public Object get(final String path) { + final CommentedConfigurationNode node = getInternal(path); + return node == null ? null : node.raw(); + } + + public CommentedConfigurationNode getSection(final String path) { + final CommentedConfigurationNode node = configurationNode.node(toSplitRoot(path)); + if (node.virtual()) { + return null; + } + return node; + } + + public CommentedConfigurationNode newSection() { + return loader.createNode(); + } + + public Set getKeys() { + return ConfigurateUtil.getKeys(configurationNode); + } + + private void setInternal(final String path, final Object value) { + try { + configurationNode.node(toSplitRoot(path)).set(value); + } catch (SerializationException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + } + } + + private CommentedConfigurationNode getInternal(final String path) { + final CommentedConfigurationNode node = configurationNode.node(toSplitRoot(path)); + if (node.virtual()) { + return null; + } + return node; + } + + public boolean hasProperty(final String path) { + return !configurationNode.node(toSplitRoot(path)).virtual(); + } + + public Object[] toSplitRoot(String node) { + return node.split("\\."); + } + public synchronized void load() { if (pendingWrites.get() != 0) { LOGGER.log(Level.INFO, "Parsing config file {0} has been aborted due to {1} current pending write(s).", new Object[]{configFile, pendingWrites.get()}); @@ -107,10 +304,7 @@ public synchronized void save() { public synchronized void blockingSave() { try { - final Future future = delaySave(); - if (future != null) { - future.get(); - } + delaySave().get(); } catch (final InterruptedException | ExecutionException e) { LOGGER.log(Level.SEVERE, e.getMessage(), e); } From 3f368b93bd1c9d8c7f38413f17b139de44bac07c Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Thu, 18 Mar 2021 23:53:07 -0400 Subject: [PATCH 05/61] Migrate Settings to Configurate --- .../essentials/EssentialsUpgrade.java | 7 +- .../com/earth2me/essentials/ISettings.java | 22 +-- .../com/earth2me/essentials/Settings.java | 127 ++++++++---------- 3 files changed, 64 insertions(+), 92 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java index d8d66008744..ce81ce65287 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java @@ -1,5 +1,6 @@ package com.earth2me.essentials; +import com.earth2me.essentials.config.ConfigurateUtil; import com.earth2me.essentials.craftbukkit.BanLookup; import com.earth2me.essentials.settings.Spawns; import com.earth2me.essentials.storage.YamlStorageWriter; @@ -11,7 +12,7 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; -import org.bukkit.configuration.ConfigurationSection; +import org.spongepowered.configurate.CommentedConfigurationNode; import java.io.BufferedInputStream; import java.io.BufferedReader; @@ -204,13 +205,13 @@ public void convertKits() { LOGGER.info("Attempting to convert old kits in config.yml to new kits.yml"); - final ConfigurationSection section = ess.getSettings().getKitSection(); + final CommentedConfigurationNode section = ess.getSettings().getKitSection(); if (section == null) { LOGGER.info("No kits found to migrate."); return; } - final Map legacyKits = ess.getSettings().getKitSection().getValues(true); + final Map legacyKits = ConfigurateUtil.getRawMap(section); for (final Map.Entry entry : legacyKits.entrySet()) { LOGGER.info("Converting " + entry.getKey()); diff --git a/Essentials/src/main/java/com/earth2me/essentials/ISettings.java b/Essentials/src/main/java/com/earth2me/essentials/ISettings.java index 97c61b5aab5..14b3805ba6e 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/ISettings.java +++ b/Essentials/src/main/java/com/earth2me/essentials/ISettings.java @@ -4,8 +4,8 @@ import com.earth2me.essentials.signs.EssentialsSign; import com.earth2me.essentials.textreader.IText; import org.bukkit.Material; -import org.bukkit.configuration.ConfigurationSection; import org.bukkit.event.EventPriority; +import org.spongepowered.configurate.CommentedConfigurationNode; import java.math.BigDecimal; import java.text.NumberFormat; @@ -65,26 +65,8 @@ public interface ISettings extends IConf { Set getMuteCommands(); - /** - * @Deprecated in favor of {@link Kits#getKits()} - */ @Deprecated - ConfigurationSection getKits(); - - /** - * @Deprecated in favor of {@link Kits#getKit(String)} - */ - @Deprecated - Map getKit(String kit); - - /** - * @Deprecated in favor of {@link Kits#addKit(String, List, long)}} - */ - @Deprecated - void addKit(String name, List lines, long delay); - - @Deprecated - ConfigurationSection getKitSection(); + CommentedConfigurationNode getKitSection(); boolean isSkippingUsedOneTimeKitsFromKitList(); diff --git a/Essentials/src/main/java/com/earth2me/essentials/Settings.java b/Essentials/src/main/java/com/earth2me/essentials/Settings.java index 3aff06af8df..8b4a30a1428 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Settings.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Settings.java @@ -2,6 +2,8 @@ import com.earth2me.essentials.api.IItemDb; import com.earth2me.essentials.commands.IEssentialsCommand; +import com.earth2me.essentials.config.ConfigurateUtil; +import com.earth2me.essentials.config.EssentialsConfiguration; import com.earth2me.essentials.signs.EssentialsSign; import com.earth2me.essentials.signs.Signs; import com.earth2me.essentials.textreader.IText; @@ -13,10 +15,9 @@ import net.ess3.api.IEssentials; import org.bukkit.ChatColor; import org.bukkit.Material; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.MemoryConfiguration; import org.bukkit.event.EventPriority; import org.bukkit.inventory.ItemStack; +import org.spongepowered.configurate.CommentedConfigurationNode; import java.io.File; import java.math.BigDecimal; @@ -47,7 +48,7 @@ public class Settings implements net.ess3.api.ISettings { private static final Logger logger = Logger.getLogger("Essentials"); private static final BigDecimal MAXMONEY = new BigDecimal("10000000000000"); private static final BigDecimal MINMONEY = new BigDecimal("-10000000000000"); - private final transient EssentialsConf config; + private final transient EssentialsConfiguration config; private final transient IEssentials ess; private final Map chatFormats = Collections.synchronizedMap(new HashMap<>()); private int chatRadius = 0; @@ -58,7 +59,7 @@ public class Settings implements net.ess3.api.ISettings { private boolean teleportSafety; private boolean forceDisableTeleportSafety; private Set disabledCommands = new HashSet<>(); - private ConfigurationSection commandCosts; + private CommentedConfigurationNode commandCosts; private Set socialSpyCommands = new HashSet<>(); private Set muteCommands = new HashSet<>(); private String nicknamePrefix = "~"; @@ -121,7 +122,6 @@ public class Settings implements net.ess3.api.ISettings { private boolean isCompassTowardsHomePerm; private boolean isAllowWorldInBroadcastworld; private String itemDbType; // #EasterEgg - admins can manually switch items provider if they want - private boolean forceEnableRecipe; // https://github.com/EssentialsX/Essentials/issues/1397 private boolean allowOldIdSigns; private boolean isWaterSafe; private boolean isSafeUsermap; @@ -133,8 +133,7 @@ public class Settings implements net.ess3.api.ISettings { public Settings(final IEssentials ess) { this.ess = ess; - config = new EssentialsConf(new File(ess.getDataFolder(), "config.yml")); - config.setTemplateName("/config.yml"); + config = new EssentialsConfiguration(new File(ess.getDataFolder(), "config.yml"), "/config.yml"); reloadConfig(); } @@ -155,8 +154,8 @@ public boolean getUpdateBedAtDaytime() { @Override public Set getMultipleHomes() { - final ConfigurationSection section = config.getConfigurationSection("sethome-multiple"); - return section == null ? null : section.getKeys(false); + final CommentedConfigurationNode section = config.getSection("sethome-multiple"); + return section == null ? null : ConfigurateUtil.getKeys(section); } @Override @@ -279,10 +278,10 @@ public boolean isCommandDisabled(final String label) { private Set getDisabledCommands() { final Set disCommands = new HashSet<>(); - for (final String c : config.getStringList("disabled-commands")) { + for (final String c : config.getList("disabled-commands", String.class)) { disCommands.add(c.toLowerCase(Locale.ENGLISH)); } - for (final String c : config.getKeys(false)) { + for (final String c : config.getKeys()) { if (c.startsWith("disable-")) { disCommands.add(c.substring(8).toLowerCase(Locale.ENGLISH)); } @@ -292,7 +291,7 @@ private Set getDisabledCommands() { @Override public boolean isPlayerCommand(final String label) { - for (final String c : config.getStringList("player-commands")) { + for (final String c : config.getList("player-commands", String.class)) { if (!c.equalsIgnoreCase(label)) { continue; } @@ -303,7 +302,7 @@ public boolean isPlayerCommand(final String label) { @Override public boolean isCommandOverridden(final String name) { - for (final String c : config.getStringList("overridden-commands")) { + for (final String c : config.getList("overridden-commands", String.class)) { if (!c.equalsIgnoreCase(name)) { continue; } @@ -317,28 +316,30 @@ public BigDecimal getCommandCost(final IEssentialsCommand cmd) { return getCommandCost(cmd.getName()); } - private ConfigurationSection _getCommandCosts() { - if (config.isConfigurationSection("command-costs")) { - final ConfigurationSection section = config.getConfigurationSection("command-costs"); - final ConfigurationSection newSection = new MemoryConfiguration(); - for (final String command : section.getKeys(false)) { + private CommentedConfigurationNode _getCommandCosts() { + final Map section = ConfigurateUtil.getMap(config.getSection("command-costs")); + if (!section.isEmpty()) { + final CommentedConfigurationNode newSection = config.newSection(); + for (Map.Entry entry : section.entrySet()) { + final String command = entry.getKey(); + final CommentedConfigurationNode node = entry.getValue(); if (command.charAt(0) == '/') { ess.getLogger().warning("Invalid command cost. '" + command + "' should not start with '/'."); } - if (section.isDouble(command)) { - newSection.set(command.toLowerCase(Locale.ENGLISH), section.getDouble(command)); - } else if (section.isInt(command)) { - newSection.set(command.toLowerCase(Locale.ENGLISH), (double) section.getInt(command)); - } else if (section.isString(command)) { - final String costString = section.getString(command); - try { + try { + if (ConfigurateUtil.isDouble(node)) { + newSection.node(command.toLowerCase(Locale.ENGLISH)).set(node.getDouble()); + } else if (ConfigurateUtil.isInt(node)) { + newSection.node(command.toLowerCase(Locale.ENGLISH)).set((double) node.getInt()); + } else if (ConfigurateUtil.isString(node)) { + final String costString = node.getString(); + //noinspection ConstantConditions final double cost = Double.parseDouble(costString.trim().replace("$", "").replace(getCurrencySymbol(), "").replaceAll("\\W", "")); - newSection.set(command.toLowerCase(Locale.ENGLISH), cost); - } catch (final NumberFormatException ex) { - ess.getLogger().warning("Invalid command cost for: " + command + " (" + costString + ")"); + newSection.node(command.toLowerCase(Locale.ENGLISH)).set(cost); + } else { + ess.getLogger().warning("Invalid command cost for: " + command); } - - } else { + } catch (final Exception ex) { ess.getLogger().warning("Invalid command cost for: " + command); } } @@ -360,7 +361,7 @@ private Set _getSocialSpyCommands() { final Set socialspyCommands = new HashSet<>(); if (config.isList("socialspy-commands")) { - for (final String c : config.getStringList("socialspy-commands")) { + for (final String c : config.getList("socialspy-commands", String.class)) { socialspyCommands.add(c.toLowerCase(Locale.ENGLISH)); } } else { @@ -388,7 +389,7 @@ public boolean isSocialSpyMessages() { private Set _getMuteCommands() { final Set muteCommands = new HashSet<>(); if (config.isList("mute-commands")) { - for (final String s : config.getStringList("mute-commands")) { + for (final String s : config.getList("mute-commands", String.class)) { muteCommands.add(s.toLowerCase(Locale.ENGLISH)); } } @@ -421,23 +422,8 @@ public double getHealCooldown() { } @Override - public ConfigurationSection getKits() { - return ess.getKits().getKits(); - } - - @Override - public Map getKit(final String name) { - return ess.getKits().getKit(name); - } - - @Override - public void addKit(final String name, final List lines, final long delay) { - ess.getKits().addKit(name, lines, delay); - } - - @Override - public ConfigurationSection getKitSection() { - return config.getConfigurationSection("kits"); + public CommentedConfigurationNode getKitSection() { + return config.getSection("kits"); } @Override @@ -550,13 +536,13 @@ public String getWorldAlias(String world) { private Map _getWorldAliases() { final Map map = new HashMap<>(); - final ConfigurationSection section = config.getConfigurationSection("chat.world-aliases"); + final CommentedConfigurationNode section = config.getSection("chat.world-aliases"); if (section == null) { return map; } - for (String world : section.getKeys(false)) { - map.put(world.toLowerCase(), FormatUtil.replaceFormat(section.getString(world))); + for (Map.Entry entry : ConfigurateUtil.getMap(section).entrySet()) { + map.put(entry.getKey().toLowerCase(), FormatUtil.replaceFormat(entry.getValue().getString())); } return map; } @@ -588,8 +574,9 @@ public boolean getPerWarpPermission() { @Override public Map getListGroupConfig() { - if (config.isConfigurationSection("list")) { - final Map values = config.getConfigurationSection("list").getValues(false); + final CommentedConfigurationNode node = config.getSection("list"); + if (node.isMap()) { + final Map values = ConfigurateUtil.getRawMap(node); if (!values.isEmpty()) { return values; } @@ -606,7 +593,7 @@ public Map getListGroupConfig() { @Override public void reloadConfig() { config.load(); - noGodWorlds = new HashSet<>(config.getStringList("no-god-in-worlds")); + noGodWorlds = new HashSet<>(config.getList("no-god-in-worlds", String.class)); enabledSigns = _getEnabledSigns(); teleportSafety = _isTeleportSafetyEnabled(); forceDisableTeleportSafety = _isForceDisableTeleportSafety(); @@ -689,6 +676,7 @@ public List itemSpawnBlacklist() { private List _getItemSpawnBlacklist() { final List epItemSpwn = new ArrayList<>(); + //noinspection deprecation final IItemDb itemDb = ess.getItemDb(); if (itemDb == null || !itemDb.isReady()) { logger.log(Level.FINE, "Skipping item spawn blacklist read; item DB not yet loaded."); @@ -719,7 +707,7 @@ private List _getEnabledSigns() { final List newSigns = new ArrayList<>(); - for (String signName : config.getStringList("enabledSigns")) { + for (String signName : config.getList("enabledSigns", String.class)) { signName = signName.trim().toUpperCase(Locale.ENGLISH); if (signName.isEmpty()) { continue; @@ -1380,12 +1368,12 @@ public boolean isSpawnOnJoin() { public List _getSpawnOnJoinGroups() { final List def = Collections.emptyList(); - if (config.isSet("spawn-on-join")) { + if (config.hasProperty("spawn-on-join")) { if (config.isList("spawn-on-join")) { - return new ArrayList<>(config.getStringList("spawn-on-join")); + return new ArrayList<>(config.getList("spawn-on-join", String.class)); } else if (config.isBoolean("spawn-on-join")) { // List of [*] to make all groups go to spawn on join. // This also maintains backwards compatibility with initial impl of single boolean value. - return config.getBoolean("spawn-on-join") ? Collections.singletonList("*") : def; + return config.getBoolean("spawn-on-join", true) ? Collections.singletonList("*") : def; } // Take whatever the value is, convert to string and add it to a list as a single value. final String val = config.get("spawn-on-join").toString(); @@ -1401,7 +1389,7 @@ public List getSpawnOnJoinGroups() { } @Override - public boolean isUserInSpawnOnJoinGroup(final IUser user) { + public boolean isUserInSpawnOnJoinGroup(@SuppressWarnings("deprecation") final IUser user) { for (final String group : this.spawnOnJoinGroups) { if (group.equals("*") || user.inGroup(group)) { return true; @@ -1416,12 +1404,14 @@ public boolean isTeleportToCenterLocation() { } private Map _getCommandCooldowns() { - if (!config.isConfigurationSection("command-cooldowns")) { + final CommentedConfigurationNode section = config.getSection("command-cooldowns"); + if (section == null) { return null; } - final ConfigurationSection section = config.getConfigurationSection("command-cooldowns"); final Map result = new LinkedHashMap<>(); - for (String cmdEntry : section.getKeys(false)) { + for (Map.Entry entry : ConfigurateUtil.getRawMap(section).entrySet()) { + String cmdEntry = entry.getKey(); + Object value = entry.getValue(); Pattern pattern = null; /* ================================ @@ -1439,14 +1429,13 @@ private Map _getCommandCooldowns() { cmdEntry = cmdEntry.substring(1); } final String cmd = cmdEntry - .replaceAll("\\*", ".*"); // Wildcards are accepted as asterisk * as known universally. + .replaceAll("\\*", ".*"); // Wildcards are accepted as asterisk * as known universally. pattern = Pattern.compile(cmd + "( .*)?"); // This matches arguments, if present, to "ignore" them from the feature. } /* ================================ * >> Process cooldown value * ================================ */ - Object value = section.get(cmdEntry); if (value instanceof String) { try { value = Double.parseDouble(value.toString()); @@ -1514,7 +1503,7 @@ public boolean isNpcsInBalanceRanking() { private NumberFormat _getCurrencyFormat() { final String currencyFormatString = config.getString("currency-format", "#,##0.00"); - final String symbolLocaleString = config.getString("currency-symbol-format-locale"); + final String symbolLocaleString = config.getString("currency-symbol-format-locale", null); final DecimalFormatSymbols decimalFormatSymbols; if (symbolLocaleString != null) { decimalFormatSymbols = DecimalFormatSymbols.getInstance(Locale.forLanguageTag(symbolLocaleString)); @@ -1544,7 +1533,7 @@ public List getUnprotectedSignNames() { private List _getUnprotectedSign() { final List newSigns = new ArrayList<>(); - for (String signName : config.getStringList("unprotected-sign-names")) { + for (String signName : config.getList("unprotected-sign-names", String.class)) { signName = signName.trim().toUpperCase(Locale.ENGLISH); if (signName.isEmpty()) { continue; @@ -1614,7 +1603,7 @@ public boolean isWorldChangeSpeedResetEnabled() { } private List _getDefaultEnabledConfirmCommands() { - final List commands = config.getStringList("default-enabled-confirm-commands"); + final List commands = config.getList("default-enabled-confirm-commands", String.class); for (int i = 0; i < commands.size(); i++) { commands.set(i, commands.get(i).toLowerCase()); } @@ -1714,7 +1703,7 @@ public boolean logCommandBlockCommands() { private Set> _getNickBlacklist() { final Set> blacklist = new HashSet<>(); - config.getStringList("nick-blacklist").forEach(entry -> { + config.getList("nick-blacklist", String.class).forEach(entry -> { try { blacklist.add(Pattern.compile(entry).asPredicate()); } catch (final PatternSyntaxException e) { From fd8d83740aff7f5bec734d16633a3575330ba58d Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Thu, 18 Mar 2021 23:59:54 -0400 Subject: [PATCH 06/61] Removed unused method --- .../earth2me/essentials/config/EssentialsConfiguration.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index 3cc0ba286fd..a7512ad163a 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -166,11 +166,6 @@ public double getDouble(final String path, final double def) { return node.getDouble(); } - public boolean isDouble(final String path) { - final CommentedConfigurationNode node = getInternal(path); - return node != null && node.raw() instanceof Double; - } - public void setProperty(final String path, final float value) { setInternal(path, value); } From 59c9fccfa824dcc8aa185d606ab7f8efb6d01150 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Fri, 19 Mar 2021 00:16:39 -0400 Subject: [PATCH 07/61] Migrate EssentialsUpgrade to Configurate --- .../main/java/com/earth2me/essentials/EssentialsUpgrade.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java index ce81ce65287..cc63e54994d 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java @@ -1,6 +1,7 @@ package com.earth2me.essentials; import com.earth2me.essentials.config.ConfigurateUtil; +import com.earth2me.essentials.config.EssentialsConfiguration; import com.earth2me.essentials.craftbukkit.BanLookup; import com.earth2me.essentials.settings.Spawns; import com.earth2me.essentials.storage.YamlStorageWriter; @@ -52,14 +53,14 @@ public class EssentialsUpgrade { private static final String PATTERN_CONFIG_NAME_REGEX = "(?mi)^lastAccountName:\\s*[\"\']?(\\w+)[\"\']?\\s*$"; private static final Pattern PATTERN_CONFIG_NAME = Pattern.compile(PATTERN_CONFIG_NAME_REGEX); private final transient IEssentials ess; - private final transient EssentialsConf doneFile; + private final transient EssentialsConfiguration doneFile; EssentialsUpgrade(final IEssentials essentials) { ess = essentials; if (!ess.getDataFolder().exists()) { ess.getDataFolder().mkdirs(); } - doneFile = new EssentialsConf(new File(ess.getDataFolder(), "upgrades-done.yml")); + doneFile = new EssentialsConfiguration(new File(ess.getDataFolder(), "upgrades-done.yml")); doneFile.load(); } From bceeca5f1a8435a959d0a1e6e6b3c0ffac3b3f5d Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Fri, 19 Mar 2021 00:25:27 -0400 Subject: [PATCH 08/61] Add helper method to remove a property --- .../essentials/config/EssentialsConfiguration.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index a7512ad163a..d9554a21c1f 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -211,6 +211,17 @@ public Set getKeys() { return ConfigurateUtil.getKeys(configurationNode); } + public void removeProperty(String path) { + final CommentedConfigurationNode node = getInternal(path); + if (node != null) { + try { + node.set(null); + } catch (SerializationException e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + } + } + } + private void setInternal(final String path, final Object value) { try { configurationNode.node(toSplitRoot(path)).set(value); From 0d97492215c56ffcc52b4c25d380b2ecee1f752c Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 20 Mar 2021 01:57:10 -0400 Subject: [PATCH 09/61] Convert over Jails, Spawns, and Kits --- .../com/earth2me/essentials/Essentials.java | 223 ++++++++------- .../java/com/earth2me/essentials/Jails.java | 176 ++++++------ .../java/com/earth2me/essentials/Kits.java | 66 ++--- .../com/earth2me/essentials/api/IJails.java | 13 +- .../com/earth2me/essentials/api/IReload.java | 15 -- .../essentials/commands/Commandcreatekit.java | 48 ++-- .../essentials/commands/Commanddelkit.java | 3 +- .../essentials/commands/Commandkit.java | 5 +- .../essentials/commands/Commandkitreset.java | 3 +- .../essentials/commands/Commandshowkit.java | 3 +- .../config/EssentialsConfiguration.java | 46 +++- .../earth2me/essentials/settings/Jails.java | 39 --- .../earth2me/essentials/settings/Spawns.java | 39 --- .../AbstractDelayedYamlFileReader.java | 56 ---- .../AbstractDelayedYamlFileWriter.java | 44 --- .../storage/AsyncStorageObjectHolder.java | 128 --------- .../essentials/storage/BukkitConstructor.java | 214 --------------- .../earth2me/essentials/storage/Comment.java | 14 - .../essentials/storage/EnchantmentLevel.java | 66 ----- .../storage/IStorageObjectHolder.java | 13 - .../essentials/storage/IStorageReader.java | 5 - .../essentials/storage/IStorageWriter.java | 5 - .../earth2me/essentials/storage/ListType.java | 12 - .../essentials/storage/MapKeyType.java | 12 - .../essentials/storage/MapValueType.java | 12 - .../storage/ObjectLoadException.java | 7 - .../essentials/storage/StorageObject.java | 4 - .../essentials/storage/YamlStorageReader.java | 97 ------- .../essentials/storage/YamlStorageWriter.java | 254 ------------------ .../src/main/java/net/ess3/api/IReload.java | 12 - .../main/java/net/ess3/api/ISpawnStorage.java | 9 + .../essentials/spawn/SpawnStorage.java | 70 ++--- 32 files changed, 368 insertions(+), 1345 deletions(-) delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/api/IReload.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/settings/Jails.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/settings/Spawns.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/storage/AbstractDelayedYamlFileReader.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/storage/AbstractDelayedYamlFileWriter.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/storage/AsyncStorageObjectHolder.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/storage/BukkitConstructor.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/storage/Comment.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/storage/EnchantmentLevel.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/storage/IStorageObjectHolder.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/storage/IStorageReader.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/storage/IStorageWriter.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/storage/ListType.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/storage/MapKeyType.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/storage/MapValueType.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/storage/ObjectLoadException.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/storage/StorageObject.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/storage/YamlStorageReader.java delete mode 100644 Essentials/src/main/java/com/earth2me/essentials/storage/YamlStorageWriter.java delete mode 100644 Essentials/src/main/java/net/ess3/api/IReload.java create mode 100644 Essentials/src/main/java/net/ess3/api/ISpawnStorage.java diff --git a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java index e21c5744a9b..88710ee6c47 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java @@ -99,7 +99,6 @@ import org.bukkit.plugin.java.JavaPluginLoader; import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitTask; -import org.yaml.snakeyaml.error.YAMLException; import java.io.File; import java.io.IOException; @@ -240,142 +239,132 @@ public void onEnable() { } } - try { - final EssentialsUpgrade upgrade = new EssentialsUpgrade(this); - upgrade.beforeSettings(); - execTimer.mark("Upgrade"); - - confList = new ArrayList<>(); - settings = new Settings(this); - confList.add(settings); - execTimer.mark("Settings"); + final EssentialsUpgrade upgrade = new EssentialsUpgrade(this); + upgrade.beforeSettings(); + execTimer.mark("Upgrade"); - userMap = new UserMap(this); - confList.add(userMap); - execTimer.mark("Init(Usermap)"); + confList = new ArrayList<>(); + settings = new Settings(this); + confList.add(settings); + execTimer.mark("Settings"); - balanceTop = new BalanceTopImpl(this); - execTimer.mark("Init(BalanceTop)"); + userMap = new UserMap(this); + confList.add(userMap); + execTimer.mark("Init(Usermap)"); - kits = new Kits(this); - confList.add(kits); - upgrade.convertKits(); - execTimer.mark("Kits"); + balanceTop = new BalanceTopImpl(this); + execTimer.mark("Init(BalanceTop)"); - upgrade.afterSettings(); - execTimer.mark("Upgrade2"); + kits = new Kits(this); + confList.add(kits); + upgrade.convertKits(); + execTimer.mark("Kits"); - warps = new Warps(getServer(), this.getDataFolder()); - confList.add(warps); - execTimer.mark("Init(Warp)"); + upgrade.afterSettings(); + execTimer.mark("Upgrade2"); - worth = new Worth(this.getDataFolder()); - confList.add(worth); - execTimer.mark("Init(Worth)"); + warps = new Warps(getServer(), this.getDataFolder()); + confList.add(warps); + execTimer.mark("Init(Warp)"); - itemDb = getItemDbFromConfig(); - confList.add(itemDb); - execTimer.mark("Init(ItemDB)"); + worth = new Worth(this.getDataFolder()); + confList.add(worth); + execTimer.mark("Init(Worth)"); - randomTeleport = new RandomTeleport(this); - if (randomTeleport.getPreCache()) { - randomTeleport.cacheRandomLocations(randomTeleport.getCenter(), randomTeleport.getMinRange(), randomTeleport.getMaxRange()); - } - confList.add(randomTeleport); - execTimer.mark("Init(RandomTeleport)"); + itemDb = getItemDbFromConfig(); + confList.add(itemDb); + execTimer.mark("Init(ItemDB)"); - customItemResolver = new CustomItemResolver(this); - try { - itemDb.registerResolver(this, "custom_items", customItemResolver); - confList.add(customItemResolver); - } catch (final Exception e) { - e.printStackTrace(); - customItemResolver = null; - } - execTimer.mark("Init(CustomItemResolver)"); + randomTeleport = new RandomTeleport(this); + if (randomTeleport.getPreCache()) { + randomTeleport.cacheRandomLocations(randomTeleport.getCenter(), randomTeleport.getMinRange(), randomTeleport.getMaxRange()); + } + confList.add(randomTeleport); + execTimer.mark("Init(RandomTeleport)"); - jails = new Jails(this); - confList.add(jails); - execTimer.mark("Init(Jails)"); + customItemResolver = new CustomItemResolver(this); + try { + itemDb.registerResolver(this, "custom_items", customItemResolver); + confList.add(customItemResolver); + } catch (final Exception e) { + e.printStackTrace(); + customItemResolver = null; + } + execTimer.mark("Init(CustomItemResolver)"); - //Spawner item provider only uses one but it's here for legacy... - spawnerItemProvider = new BlockMetaSpawnerItemProvider(); + jails = new Jails(this); + confList.add(jails); + execTimer.mark("Init(Jails)"); - //Spawner block providers - if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_12_0_R01)) { - spawnerBlockProvider = new ReflSpawnerBlockProvider(); - } else { - spawnerBlockProvider = new BukkitSpawnerBlockProvider(); - } + //Spawner item provider only uses one but it's here for legacy... + spawnerItemProvider = new BlockMetaSpawnerItemProvider(); - //Spawn Egg Providers - if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_9_R01)) { - spawnEggProvider = new LegacySpawnEggProvider(); - } else if (VersionUtil.getServerBukkitVersion().isLowerThanOrEqualTo(VersionUtil.v1_12_2_R01)) { - spawnEggProvider = new ReflSpawnEggProvider(); - } else { - spawnEggProvider = new FlatSpawnEggProvider(); - } + //Spawner block providers + if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_12_0_R01)) { + spawnerBlockProvider = new ReflSpawnerBlockProvider(); + } else { + spawnerBlockProvider = new BukkitSpawnerBlockProvider(); + } - //Potion Meta Provider - if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_9_R01)) { - potionMetaProvider = new LegacyPotionMetaProvider(); - } else { - potionMetaProvider = new BasePotionDataProvider(); - } + //Spawn Egg Providers + if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_9_R01)) { + spawnEggProvider = new LegacySpawnEggProvider(); + } else if (VersionUtil.getServerBukkitVersion().isLowerThanOrEqualTo(VersionUtil.v1_12_2_R01)) { + spawnEggProvider = new ReflSpawnEggProvider(); + } else { + spawnEggProvider = new FlatSpawnEggProvider(); + } - //Server State Provider - //Container Provider - if (PaperLib.isPaper() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_15_2_R01)) { - serverStateProvider = new PaperServerStateProvider(); - containerProvider = new PaperContainerProvider(); - } else { - serverStateProvider = new ReflServerStateProvider(getLogger()); - } + //Potion Meta Provider + if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_9_R01)) { + potionMetaProvider = new LegacyPotionMetaProvider(); + } else { + potionMetaProvider = new BasePotionDataProvider(); + } - //Event Providers - if (PaperLib.isPaper()) { - try { - Class.forName("com.destroystokyo.paper.event.player.PlayerRecipeBookClickEvent"); - recipeBookEventProvider = new PaperRecipeBookListener(event -> { - if (this.getUser(((PlayerEvent) event).getPlayer()).isRecipeSee()) { - ((Cancellable) event).setCancelled(true); - } - }); - } catch (final ClassNotFoundException ignored) { - } - } + //Server State Provider + //Container Provider + if (PaperLib.isPaper() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_15_2_R01)) { + serverStateProvider = new PaperServerStateProvider(); + containerProvider = new PaperContainerProvider(); + } else { + serverStateProvider = new ReflServerStateProvider(getLogger()); + } - //Known Commands Provider - if (PaperLib.isPaper() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_11_2_R01)) { - knownCommandsProvider = new PaperKnownCommandsProvider(); - } else { - knownCommandsProvider = new ReflKnownCommandsProvider(); + //Event Providers + if (PaperLib.isPaper()) { + try { + Class.forName("com.destroystokyo.paper.event.player.PlayerRecipeBookClickEvent"); + recipeBookEventProvider = new PaperRecipeBookListener(event -> { + if (this.getUser(((PlayerEvent) event).getPlayer()).isRecipeSee()) { + ((Cancellable) event).setCancelled(true); + } + }); + } catch (final ClassNotFoundException ignored) { } + } - // Command aliases provider - formattedCommandAliasProvider = new ReflFormattedCommandAliasProvider(PaperLib.isPaper()); - - //Material Tag Providers - if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_13_0_R01)) { - materialTagProvider = PaperLib.isPaper() ? new PaperMaterialTagProvider() : new BukkitMaterialTagProvider(); - } + //Known Commands Provider + if (PaperLib.isPaper() && VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_11_2_R01)) { + knownCommandsProvider = new PaperKnownCommandsProvider(); + } else { + knownCommandsProvider = new ReflKnownCommandsProvider(); + } - execTimer.mark("Init(Providers)"); - reload(); + // Command aliases provider + formattedCommandAliasProvider = new ReflFormattedCommandAliasProvider(PaperLib.isPaper()); - // The item spawn blacklist is loaded with all other settings, before the item - // DB, but it depends on the item DB, so we need to reload it again here: - ((Settings) settings)._lateLoadItemSpawnBlacklist(); - } catch (final YAMLException exception) { - if (pm.getPlugin("EssentialsUpdate") != null) { - LOGGER.log(Level.SEVERE, tl("essentialsHelp2")); - } else { - LOGGER.log(Level.SEVERE, tl("essentialsHelp1")); - } - handleCrash(exception); - return; + //Material Tag Providers + if (VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_13_0_R01)) { + materialTagProvider = PaperLib.isPaper() ? new PaperMaterialTagProvider() : new BukkitMaterialTagProvider(); } + + execTimer.mark("Init(Providers)"); + reload(); + + // The item spawn blacklist is loaded with all other settings, before the item + // DB, but it depends on the item DB, so we need to reload it again here: + ((Settings) settings)._lateLoadItemSpawnBlacklist(); backup = new Backup(this); permissionsHandler = new PermissionsHandler(this, settings.useBukkitPermissions()); alternativeCommandsHandler = new AlternativeCommandsHandler(this); @@ -1114,7 +1103,7 @@ private static class EssentialsWorldListener implements Listener, Runnable { public void onWorldLoad(final WorldLoadEvent event) { PermissionsDefaults.registerBackDefaultFor(event.getWorld()); - ess.getJails().onReload(); + ess.getJails().reloadConfig(); ess.getWarps().reloadConfig(); for (final IConf iConf : ((Essentials) ess).confList) { if (iConf instanceof IEssentialsModule) { @@ -1125,7 +1114,7 @@ public void onWorldLoad(final WorldLoadEvent event) { @EventHandler(priority = EventPriority.LOW) public void onWorldUnload(final WorldUnloadEvent event) { - ess.getJails().onReload(); + ess.getJails().reloadConfig(); ess.getWarps().reloadConfig(); for (final IConf iConf : ((Essentials) ess).confList) { if (iConf instanceof IEssentialsModule) { diff --git a/Essentials/src/main/java/com/earth2me/essentials/Jails.java b/Essentials/src/main/java/com/earth2me/essentials/Jails.java index b78ff03450e..65293be19e3 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Jails.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Jails.java @@ -1,10 +1,12 @@ package com.earth2me.essentials; -import com.earth2me.essentials.storage.AsyncStorageObjectHolder; +import com.earth2me.essentials.config.ConfigurateUtil; +import com.earth2me.essentials.config.EssentialsConfiguration; import net.ess3.api.IEssentials; import net.ess3.api.IUser; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; @@ -23,28 +25,57 @@ import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.plugin.PluginManager; +import org.spongepowered.configurate.CommentedConfigurationNode; import java.io.File; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.Locale; +import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.logging.Level; import java.util.logging.Logger; import static com.earth2me.essentials.I18n.tl; -public class Jails extends AsyncStorageObjectHolder implements net.ess3.api.IJails { - private static final transient Logger LOGGER = Bukkit.getLogger(); +public class Jails implements net.ess3.api.IJails { + private static final transient Logger LOGGER = Logger.getLogger("Essentials"); private static transient boolean enabled = false; + private final IEssentials ess; + private final EssentialsConfiguration config; + private final Map jails = new HashMap<>(); public Jails(final IEssentials ess) { - super(ess, com.earth2me.essentials.settings.Jails.class); + this.ess = ess; + this.config = new EssentialsConfiguration(new File(ess.getDataFolder(), "jail.yml")); reloadConfig(); } + @Override + public void reloadConfig() { + synchronized (jails) { + config.load(); + final CommentedConfigurationNode jailsNode = config.getSection("jails"); + for (final Map.Entry entry : ConfigurateUtil.getMap(jailsNode).entrySet()) { + final CommentedConfigurationNode jailNode = entry.getValue(); + final String worldName = jailNode.node("world").getString(); + if (worldName == null || worldName.isEmpty()) { + continue; + } + + final World world = Bukkit.getWorld(worldName); + if (world == null) { + LOGGER.log(Level.WARNING, "Invalid world name, " + worldName + ", for jail name " + entry.getKey()); + continue; + } + jails.put(entry.getKey().toLowerCase(Locale.ENGLISH), new Location(world, jailNode.node("x").getDouble(), jailNode.node("y").getDouble(), + jailNode.node("z").getDouble(), jailNode.node("yaw").getFloat(), jailNode.node("pitch").getFloat())); + } + checkRegister(); + } + } + private void registerListeners() { enabled = true; final PluginManager pluginManager = ess.getServer().getPluginManager(); @@ -55,21 +86,6 @@ private void registerListeners() { } } - @Override - public File getStorageFile() { - return new File(ess.getDataFolder(), "jail.yml"); - } - - @Override - public void finishRead() { - checkRegister(); - } - - @Override - public void finishWrite() { - checkRegister(); - } - public void resetListener() { enabled = false; checkRegister(); @@ -82,92 +98,100 @@ private void checkRegister() { } @Override - public Location getJail(final String jailName) throws Exception { - acquireReadLock(); - try { - if (getData().getJails() == null || jailName == null || !getData().getJails().containsKey(jailName.toLowerCase(Locale.ENGLISH))) { - throw new Exception(tl("jailNotExist")); - } - final Location loc = getData().getJails().get(jailName.toLowerCase(Locale.ENGLISH)); - if (loc == null || loc.getWorld() == null) { + public void startTransaction() { + config.startTransaction(); + } + + @Override + public void stopTransaction(final boolean blocking) { + config.stopTransaction(blocking); + } + + @Override + public Location getJail(String jailName) throws Exception { + if (jailName == null) { + throw new Exception(tl("jailNotExist")); + } + + jailName = jailName.toLowerCase(Locale.ENGLISH); + synchronized (jails) { + if (!jails.containsKey(jailName)) { throw new Exception(tl("jailNotExist")); } - return loc; - } finally { - unlock(); + return jails.get(jailName); } } @Override public Collection getList() throws Exception { - acquireReadLock(); - try { - if (getData().getJails() == null) { - return Collections.emptyList(); - } - return new ArrayList<>(getData().getJails().keySet()); - } finally { - unlock(); + synchronized (jails) { + return new ArrayList<>(jails.keySet()); } } @Override - public void removeJail(final String jail) throws Exception { - acquireWriteLock(); - try { - if (getData().getJails() == null) { - return; + public void removeJail(String jail) throws Exception { + if (jail == null) { + return; + } + + jail = jail.toLowerCase(Locale.ENGLISH); + synchronized (jails) { + if (jails.remove(jail) != null) { + config.getSection("jails").node(jail).set(null); + config.save(); } - getData().getJails().remove(jail.toLowerCase(Locale.ENGLISH)); - } finally { - unlock(); } } /** * @deprecated This method does not use asynchronous teleportation. Use {@link Jails#sendToJail(IUser, String, CompletableFuture)} */ + @SuppressWarnings("deprecation") @Override @Deprecated - public void sendToJail(final IUser user, final String jail) throws Exception { - acquireReadLock(); - try { - if (user.getBase().isOnline()) { - final Location loc = getJail(jail); - user.getTeleport().now(loc, false, TeleportCause.COMMAND); + public void sendToJail(final IUser user, String jail) throws Exception { + if (jail == null || jail.isEmpty()) { + return; + } + + jail = jail.toLowerCase(Locale.ENGLISH); + synchronized (jails) { + if (jails.containsKey(jail)) { + if (user.getBase().isOnline()) { + user.getTeleport().now(jails.get(jail), false, TeleportCause.COMMAND); + } + user.setJail(jail); } - user.setJail(jail); - } finally { - unlock(); } } @Override - public void sendToJail(final IUser user, final String jail, final CompletableFuture future) throws Exception { - acquireReadLock(); - try { - if (user.getBase().isOnline()) { - final Location loc = getJail(jail); - user.getAsyncTeleport().now(loc, false, TeleportCause.COMMAND, future); - future.thenAccept(success -> user.setJail(jail)); - return; + public void sendToJail(final IUser user, final String jailName, final CompletableFuture future) throws Exception { + if (jailName == null || jailName.isEmpty()) { + return; + } + + final String jail = jailName.toLowerCase(Locale.ENGLISH); + synchronized (jails) { + if (jails.containsKey(jail)) { + if (user.getBase().isOnline()) { + user.getAsyncTeleport().now(jails.get(jail), false, TeleportCause.COMMAND, future); + future.thenAccept(success -> user.setJail(jail)); + return; + } + user.setJail(jail); } - user.setJail(jail); - } finally { - unlock(); } } @Override - public void setJail(final String jailName, final Location loc) throws Exception { - acquireWriteLock(); - try { - if (getData().getJails() == null) { - getData().setJails(new HashMap<>()); - } - getData().getJails().put(jailName.toLowerCase(Locale.ENGLISH), loc); - } finally { - unlock(); + public void setJail(String jailName, final Location loc) throws Exception { + jailName = jailName.toLowerCase(Locale.ENGLISH); + synchronized (jails) { + jails.put(jailName, loc); + config.setProperty("jails." + jailName, loc); + config.save(); } } diff --git a/Essentials/src/main/java/com/earth2me/essentials/Kits.java b/Essentials/src/main/java/com/earth2me/essentials/Kits.java index 19c0c7b9526..c5a7896e494 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Kits.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Kits.java @@ -1,8 +1,10 @@ package com.earth2me.essentials; +import com.earth2me.essentials.config.ConfigurateUtil; +import com.earth2me.essentials.config.EssentialsConfiguration; import com.earth2me.essentials.utils.NumberUtil; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.MemoryConfiguration; +import org.spongepowered.configurate.CommentedConfigurationNode; +import org.spongepowered.configurate.serialize.SerializationException; import java.io.File; import java.math.BigDecimal; @@ -14,13 +16,11 @@ import static com.earth2me.essentials.I18n.tl; public class Kits implements IConf { - - private final EssentialsConf config; - private ConfigurationSection kits; + private final EssentialsConfiguration config; + private CommentedConfigurationNode kits; public Kits(final IEssentials essentials) { - config = new EssentialsConf(new File(essentials.getDataFolder(), "kits.yml")); - config.setTemplateName("/kits.yml"); + config = new EssentialsConfiguration(new File(essentials.getDataFolder(), "kits.yml"), "/kits.yml"); reloadConfig(); } @@ -31,13 +31,18 @@ public void reloadConfig() { kits = _getKits(); } - private ConfigurationSection _getKits() { - if (config.isConfigurationSection("kits")) { - final ConfigurationSection section = config.getConfigurationSection("kits"); - final ConfigurationSection newSection = new MemoryConfiguration(); - for (final String kitItem : section.getKeys(false)) { - if (section.isConfigurationSection(kitItem)) { - newSection.set(kitItem.toLowerCase(Locale.ENGLISH), section.getConfigurationSection(kitItem)); + private CommentedConfigurationNode _getKits() { + final CommentedConfigurationNode section = config.getSection("kits"); + if (section != null) { + final CommentedConfigurationNode newSection = config.newSection(); + for (final String kitItem : ConfigurateUtil.getKeys(section)) { + final CommentedConfigurationNode kitSection = section.node(kitItem); + if (kitSection.isMap()) { + try { + newSection.node(kitItem.toLowerCase(Locale.ENGLISH)).set(kitSection); + } catch (SerializationException e) { + e.printStackTrace(); + } } } return newSection; @@ -45,25 +50,26 @@ private ConfigurationSection _getKits() { return null; } - public EssentialsConf getConfig() { + public EssentialsConfiguration getConfig() { return config; } - public ConfigurationSection getKits() { + public CommentedConfigurationNode getKits() { return kits; } public Map getKit(String name) { name = name.replace('.', '_').replace('/', '_'); if (getKits() != null) { - final ConfigurationSection kits = getKits(); + final CommentedConfigurationNode kits = getKits(); // For some reason, YAML doesn't sees keys as always lowercase even if they aren't defined like that. // Workaround is to toLowercase when getting from the config, but showing normally elsewhere. // ODDLY ENOUGH when you get the configuration section for ALL kits, it will return the proper // case of each kit. But when you check for each kit's configuration section, it won't return the kit // you just found if you don't toLowercase it. - if (kits.isConfigurationSection(name.toLowerCase())) { - return kits.getConfigurationSection(name.toLowerCase()).getValues(true); + final CommentedConfigurationNode kitSection = kits.node(name.toLowerCase()); + if (!kitSection.virtual() && kitSection.isMap()) { + return ConfigurateUtil.getRawMap(kitSection); } } @@ -72,13 +78,11 @@ public Map getKit(String name) { // Tries to find an existing kit name that matches the given name, ignoring case. Returns null if no match. public String matchKit(final String name) { - if (config.isConfigurationSection("kits")) { - final ConfigurationSection section = config.getConfigurationSection("kits"); - if (section != null) { - for (final String kitName : section.getKeys(false)) { - if (kitName.equalsIgnoreCase(name)) { - return kitName; - } + final CommentedConfigurationNode section = config.getSection("kits"); + if (section != null) { + for (final String kitName : ConfigurateUtil.getKeys(section)) { + if (kitName.equalsIgnoreCase(name)) { + return kitName; } } } @@ -87,23 +91,23 @@ public String matchKit(final String name) { public void addKit(final String name, final List lines, final long delay) { // Will overwrite but w/e - config.set("kits." + name + ".delay", delay); - config.set("kits." + name + ".items", lines); + config.setProperty("kits." + name + ".delay", delay); + config.setProperty("kits." + name + ".items", lines); kits = _getKits(); config.save(); } public void removeKit(final String name) { - config.set("kits." + name, null); + config.removeProperty("kits." + name); kits = _getKits(); config.save(); } public String listKits(final net.ess3.api.IEssentials ess, final User user) throws Exception { try { - final ConfigurationSection kits = config.getConfigurationSection("kits"); + final CommentedConfigurationNode kits = config.getSection("kits"); final StringBuilder list = new StringBuilder(); - for (final String kitItem : kits.getKeys(false)) { + for (final String kitItem : ConfigurateUtil.getKeys(kits)) { if (user == null) { list.append(" ").append(capitalCase(kitItem)); } else if (user.isAuthorized("essentials.kits." + kitItem.toLowerCase(Locale.ENGLISH))) { diff --git a/Essentials/src/main/java/com/earth2me/essentials/api/IJails.java b/Essentials/src/main/java/com/earth2me/essentials/api/IJails.java index 9a779e98002..89370f0682a 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/api/IJails.java +++ b/Essentials/src/main/java/com/earth2me/essentials/api/IJails.java @@ -1,5 +1,6 @@ package com.earth2me.essentials.api; +import com.earth2me.essentials.IConf; import net.ess3.api.IUser; import org.bukkit.Location; @@ -12,7 +13,7 @@ * @deprecated External plugins should use {@link net.ess3.api.IJails} instead of this interface in case future APIs are added. */ @Deprecated -public interface IJails extends IReload { +public interface IJails extends IConf { /** * Gets the location of the jail with the given name * @@ -74,4 +75,14 @@ public interface IJails extends IReload { * @throws Exception */ void setJail(String jailName, Location loc) throws Exception; + + /** + * Beings a transaction + */ + void startTransaction(); + + /** + * Ends the current transaction and saves the state + */ + void stopTransaction(boolean blocking); } diff --git a/Essentials/src/main/java/com/earth2me/essentials/api/IReload.java b/Essentials/src/main/java/com/earth2me/essentials/api/IReload.java deleted file mode 100644 index 1cacf8f795f..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/api/IReload.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.earth2me.essentials.api; - -/** - * Represents a storage object that is reloadable. - * - * @deprecated This is a remnant of the abandoned 3.x storage system. Neither future 2.x code nor external plugins - * should use this interface. - */ -@Deprecated -public interface IReload { - /** - * Reloads the given storage object. - */ - void onReload(); -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandcreatekit.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandcreatekit.java index 5147be0d221..9a362f0e62e 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandcreatekit.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandcreatekit.java @@ -10,18 +10,16 @@ import com.google.gson.JsonObject; import org.bukkit.Material; import org.bukkit.Server; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.MemoryConfiguration; -import org.bukkit.configuration.file.YamlConstructor; -import org.bukkit.configuration.file.YamlRepresenter; import org.bukkit.inventory.ItemStack; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.DumperOptions.FlowStyle; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.representer.Representer; +import org.spongepowered.configurate.BasicConfigurationNode; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.yaml.NodeStyle; +import org.spongepowered.configurate.yaml.YamlConfigurationLoader; +import java.io.BufferedWriter; import java.io.InputStreamReader; import java.io.OutputStream; +import java.io.StringWriter; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; @@ -32,20 +30,14 @@ import static com.earth2me.essentials.I18n.tl; public class Commandcreatekit extends EssentialsCommand { - private static final String PASTE_URL = "https://paste.gg/"; private static final String PASTE_UPLOAD_URL = "https://api.paste.gg/v1/pastes"; private static final Gson GSON = new Gson(); private final ExecutorService executorService = Executors.newSingleThreadExecutor(); - private final DumperOptions yamlOptions = new DumperOptions(); - private final Representer yamlRepresenter = new YamlRepresenter(); - private final YamlConstructor yamlConstructor = new YamlConstructor(); public Commandcreatekit() { super("createkit"); - yamlOptions.setDefaultFlowStyle(FlowStyle.BLOCK); - yamlRepresenter.setDefaultFlowStyle(FlowStyle.BLOCK); } // /createkit @@ -71,21 +63,27 @@ public void run(final Server server, final User user, final String commandLabel, ess.getKits().addKit(kitname, list, delay); user.sendMessage(tl("createdKit", kitname, list.size(), delay)); } else { - final ConfigurationSection config = new MemoryConfiguration(); - config.set("kits." + kitname + ".delay", delay); - config.set("kits." + kitname + ".items", list); - - final Yaml yaml = new Yaml(yamlConstructor, yamlRepresenter, yamlOptions); - String fileContents = "# Copy the kit code below into the kits section in your config.yml file\n"; - fileContents += yaml.dump(config.getValues(false)); - - uploadPaste(user.getSource(), kitname, delay, fileContents); + uploadPaste(user.getSource(), kitname, delay, list); } } - private void uploadPaste(final CommandSource sender, final String kitName, final long delay, final String contents) { + private void uploadPaste(final CommandSource sender, final String kitName, final long delay, final List list) { executorService.submit(() -> { try { + final ConfigurationNode config = BasicConfigurationNode.root(); + config.node("kits", kitName, "delay").set(delay); + config.node("kits", kitName, "items").set(list); + + final StringWriter sw = new StringWriter(); + + final YamlConfigurationLoader loader = YamlConfigurationLoader.builder().sink(() -> new BufferedWriter(sw)).indent(2).nodeStyle(NodeStyle.BLOCK).build(); + loader.save(config); + + String fileContents = "# Copy the kit code below into the kits section in your config.yml file\n"; + fileContents += sw.toString(); + sw.flush(); + sw.close(); + final HttpURLConnection connection = (HttpURLConnection) new URL(PASTE_UPLOAD_URL).openConnection(); connection.setRequestMethod("POST"); connection.setDoInput(true); @@ -97,7 +95,7 @@ private void uploadPaste(final CommandSource sender, final String kitName, final final JsonObject file = new JsonObject(); final JsonObject content = new JsonObject(); content.addProperty("format", "text"); - content.addProperty("value", contents); + content.addProperty("value", fileContents); file.add("content", content); files.add(file); body.add("files", files); diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commanddelkit.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commanddelkit.java index d14280e87b0..777fd29b20f 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commanddelkit.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commanddelkit.java @@ -2,6 +2,7 @@ import com.earth2me.essentials.CommandSource; import com.earth2me.essentials.Kit; +import com.earth2me.essentials.config.ConfigurateUtil; import com.google.common.collect.Lists; import org.bukkit.Server; @@ -37,7 +38,7 @@ public void run(final Server server, final CommandSource sender, final String co @Override protected List getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) { if (args.length == 1) { - return Lists.newArrayList(ess.getKits().getKits().getKeys(false)); + return Lists.newArrayList(ConfigurateUtil.getKeys(ess.getKits().getKits())); } return Collections.emptyList(); } diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandkit.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandkit.java index 445e4064d0d..10f2eacb0bf 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandkit.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandkit.java @@ -3,6 +3,7 @@ import com.earth2me.essentials.CommandSource; import com.earth2me.essentials.Kit; import com.earth2me.essentials.User; +import com.earth2me.essentials.config.ConfigurateUtil; import com.earth2me.essentials.utils.StringUtil; import org.bukkit.Server; @@ -100,7 +101,7 @@ protected List getTabCompleteOptions(final Server server, final User use if (args.length == 1) { final List options = new ArrayList<>(); // TODO: Move all of this to its own method - for (final String kitName : ess.getKits().getKits().getKeys(false)) { + for (final String kitName : ConfigurateUtil.getKeys(ess.getKits().getKits())) { if (!user.isAuthorized("essentials.kits." + kitName)) { // Only check perm, not time or money continue; } @@ -117,7 +118,7 @@ protected List getTabCompleteOptions(final Server server, final User use @Override protected List getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) { if (args.length == 1) { - return new ArrayList<>(ess.getKits().getKits().getKeys(false)); // TODO: Move this to its own method + return new ArrayList<>(ConfigurateUtil.getKeys(ess.getKits().getKits())); // TODO: Move this to its own method } else if (args.length == 2) { return getPlayers(server, sender); } else { diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandkitreset.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandkitreset.java index 2129c347c97..82dc5492138 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandkitreset.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandkitreset.java @@ -2,6 +2,7 @@ import com.earth2me.essentials.CommandSource; import com.earth2me.essentials.User; +import com.earth2me.essentials.config.ConfigurateUtil; import org.bukkit.Server; import java.util.ArrayList; @@ -58,7 +59,7 @@ protected void run(Server server, CommandSource sender, String commandLabel, Str @Override protected List getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) { if (args.length == 1) { - return new ArrayList<>(ess.getKits().getKits().getKeys(false)); + return new ArrayList<>(ConfigurateUtil.getKeys(ess.getKits().getKits())); } else if (args.length == 2 && sender.isAuthorized("essentials.kitreset.others", ess)) { return getPlayers(server, sender); } else { diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandshowkit.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandshowkit.java index 142b2ec9073..1da50851a0d 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandshowkit.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandshowkit.java @@ -2,6 +2,7 @@ import com.earth2me.essentials.Kit; import com.earth2me.essentials.User; +import com.earth2me.essentials.config.ConfigurateUtil; import org.bukkit.Server; import java.util.ArrayList; @@ -33,7 +34,7 @@ public void run(final Server server, final User user, final String commandLabel, @Override protected List getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) { if (args.length == 1) { - return new ArrayList<>(ess.getKits().getKits().getKeys(false)); // TODO: Move this to its own method + return new ArrayList<>(ConfigurateUtil.getKeys(ess.getKits().getKits())); // TODO: Move this to its own method } else { return Collections.emptyList(); } diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index d9554a21c1f..293b4b78b03 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -17,7 +17,10 @@ import java.math.BigDecimal; import java.nio.file.Files; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Locale; +import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -51,6 +54,10 @@ public EssentialsConfiguration(final File configFile, final String templateName) this.templateName = templateName; } + public CommentedConfigurationNode getRootNode() { + return configurationNode; + } + public void setProperty(final String path, final Location location) { //noinspection ConstantConditions setInternal(path + ".world", location.getWorld().getName()); @@ -75,6 +82,27 @@ public Location getLocation(final String path) throws InvalidWorldException { getDouble(path + ".z", 0), getFloat(path + ".yaw", 0), getFloat(path + ".pitch", 0)); } + public Map getLocationSectionMap(final String path) { + final CommentedConfigurationNode node = getSection(path); + final Map result = new HashMap<>(); + for (final Map.Entry entry : ConfigurateUtil.getMap(node).entrySet()) { + final CommentedConfigurationNode jailNode = entry.getValue(); + final String worldName = jailNode.node("world").getString(); + if (worldName == null || worldName.isEmpty()) { + continue; + } + + final World world = Bukkit.getWorld(worldName); + if (world == null) { + LOGGER.log(Level.WARNING, "Invalid world name, " + worldName + ", for key " + entry.getKey()); + continue; + } + result.put(entry.getKey().toLowerCase(Locale.ENGLISH), new Location(world, jailNode.node("x").getDouble(), jailNode.node("y").getDouble(), + jailNode.node("z").getDouble(), jailNode.node("yaw").getFloat(), jailNode.node("pitch").getFloat())); + } + return result; + } + public void setProperty(final String path, final List list) { setInternal(path, list); } @@ -190,6 +218,10 @@ public BigDecimal getBigDecimal(final String path, final BigDecimal def) { return ConfigurateUtil.toBigDecimal(node.getString(), def); } + public void setRaw(final String path, final Object value) { + setInternal(path, value); + } + public Object get(final String path) { final CommentedConfigurationNode node = getInternal(path); return node == null ? null : node.raw(); @@ -211,6 +243,10 @@ public Set getKeys() { return ConfigurateUtil.getKeys(configurationNode); } + public Map getMap() { + return ConfigurateUtil.getMap(configurationNode); + } + public void removeProperty(String path) { final CommentedConfigurationNode node = getInternal(path); if (node != null) { @@ -298,8 +334,16 @@ public void startTransaction() { } public void stopTransaction() { + stopTransaction(false); + } + + public void stopTransaction(final boolean blocking) { transaction.set(false); - save(); + if (blocking) { + blockingSave(); + } else { + save(); + } } public synchronized void save() { diff --git a/Essentials/src/main/java/com/earth2me/essentials/settings/Jails.java b/Essentials/src/main/java/com/earth2me/essentials/settings/Jails.java deleted file mode 100644 index 1c867cfa82a..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/settings/Jails.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.earth2me.essentials.settings; - -import com.earth2me.essentials.storage.MapValueType; -import com.earth2me.essentials.storage.StorageObject; -import org.bukkit.Location; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -public class Jails implements StorageObject { - @MapValueType(Location.class) - private Map jails = new HashMap<>(); - - public Map getJails() { - return jails; - } - - public void setJails(final Map jails) { - this.jails = jails; - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - final Jails jails1 = (Jails) o; - return Objects.equals(jails, jails1.jails); - } - - @Override - public int hashCode() { - return Objects.hash(jails); - } -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/settings/Spawns.java b/Essentials/src/main/java/com/earth2me/essentials/settings/Spawns.java deleted file mode 100644 index 5f0c3b5e039..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/settings/Spawns.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.earth2me.essentials.settings; - -import com.earth2me.essentials.storage.MapValueType; -import com.earth2me.essentials.storage.StorageObject; -import org.bukkit.Location; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -public class Spawns implements StorageObject { - @MapValueType(Location.class) - private Map spawns = new HashMap<>(); - - public Map getSpawns() { - return spawns; - } - - public void setSpawns(final Map spawns) { - this.spawns = spawns; - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - final Spawns spawns1 = (Spawns) o; - return Objects.equals(spawns, spawns1.spawns); - } - - @Override - public int hashCode() { - return Objects.hash(spawns); - } -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/storage/AbstractDelayedYamlFileReader.java b/Essentials/src/main/java/com/earth2me/essentials/storage/AbstractDelayedYamlFileReader.java deleted file mode 100644 index 1903a20f644..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/storage/AbstractDelayedYamlFileReader.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.earth2me.essentials.storage; - -import net.ess3.api.IEssentials; -import org.bukkit.Bukkit; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.util.logging.Level; - -public abstract class AbstractDelayedYamlFileReader implements Runnable { - protected final transient IEssentials plugin; - private final transient File file; - private final transient Class clazz; - - public AbstractDelayedYamlFileReader(final IEssentials ess, final File file, final Class clazz) { - this.file = file; - this.clazz = clazz; - this.plugin = ess; - ess.runTaskAsynchronously(this); - } - - public abstract void onStart(); - - @Override - public void run() { - onStart(); - try { - final FileReader reader = new FileReader(file); - try { - final T object = new YamlStorageReader(reader, plugin).load(clazz); - onSuccess(object); - } finally { - try { - reader.close(); - } catch (final IOException ex) { - Bukkit.getLogger().log(Level.SEVERE, "File can't be closed: " + file.toString(), ex); - } - } - - } catch (final FileNotFoundException ex) { - onException(); - if (plugin.getSettings() == null || plugin.getSettings().isDebug()) { - Bukkit.getLogger().log(Level.INFO, "File not found: " + file.toString()); - } - } catch (final ObjectLoadException ex) { - onException(); - Bukkit.getLogger().log(Level.SEVERE, "File broken: " + file.toString(), ex.getCause()); - } - } - - public abstract void onSuccess(T object); - - public abstract void onException(); -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/storage/AbstractDelayedYamlFileWriter.java b/Essentials/src/main/java/com/earth2me/essentials/storage/AbstractDelayedYamlFileWriter.java deleted file mode 100644 index 0b75a53dda0..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/storage/AbstractDelayedYamlFileWriter.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.earth2me.essentials.storage; - -import net.ess3.api.IEssentials; -import org.bukkit.Bukkit; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.PrintWriter; -import java.util.logging.Level; - -public abstract class AbstractDelayedYamlFileWriter implements Runnable { - private final transient File file; - - public AbstractDelayedYamlFileWriter(final IEssentials ess, final File file) { - this.file = file; - ess.runTaskAsynchronously(this); - } - - public abstract StorageObject getObject(); - - @Override - public void run() { - PrintWriter pw = null; - try { - final StorageObject object = getObject(); - final File folder = file.getParentFile(); - if (!folder.exists()) { - folder.mkdirs(); - } - pw = new PrintWriter(file); - new YamlStorageWriter(pw).save(object); - } catch (final FileNotFoundException ex) { - Bukkit.getLogger().log(Level.SEVERE, file.toString(), ex); - } finally { - onFinish(); - if (pw != null) { - pw.close(); - } - } - - } - - public abstract void onFinish(); -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/storage/AsyncStorageObjectHolder.java b/Essentials/src/main/java/com/earth2me/essentials/storage/AsyncStorageObjectHolder.java deleted file mode 100644 index 6788bd4af1c..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/storage/AsyncStorageObjectHolder.java +++ /dev/null @@ -1,128 +0,0 @@ -package com.earth2me.essentials.storage; - -import com.earth2me.essentials.IConf; -import net.ess3.api.IEssentials; -import net.ess3.api.IReload; -import org.bukkit.Bukkit; - -import java.io.File; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.logging.Level; - -public abstract class AsyncStorageObjectHolder implements IConf, IStorageObjectHolder, IReload { - protected final transient IEssentials ess; - private final transient ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); - private final transient Class clazz; - private transient T data; - - public AsyncStorageObjectHolder(final IEssentials ess, final Class clazz) { - this.ess = ess; - this.clazz = clazz; - try { - this.data = clazz.newInstance(); - } catch (final IllegalAccessException | InstantiationException ex) { - Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex); - } - } - - @Override - public T getData() { - return data; - } - - @Override - public void acquireReadLock() { - rwl.readLock().lock(); - } - - @Override - public void acquireWriteLock() { - while (rwl.getReadHoldCount() > 0) { - rwl.readLock().unlock(); - } - rwl.writeLock().lock(); - rwl.readLock().lock(); - } - - @Override - public void close() { - unlock(); - } - - @Override - public void unlock() { - if (rwl.isWriteLockedByCurrentThread()) { - rwl.writeLock().unlock(); - new StorageObjectDataWriter(); - } - while (rwl.getReadHoldCount() > 0) { - rwl.readLock().unlock(); - } - } - - @Override - public void reloadConfig() { - new StorageObjectDataReader(); - } - - @Override - public void onReload() { - new StorageObjectDataReader(); - } - - public abstract void finishRead(); - - public abstract void finishWrite(); - - public abstract File getStorageFile(); - - private class StorageObjectDataWriter extends AbstractDelayedYamlFileWriter { - StorageObjectDataWriter() { - super(ess, getStorageFile()); - } - - @Override - public StorageObject getObject() { - acquireReadLock(); - return getData(); - } - - @Override - public void onFinish() { - unlock(); - finishWrite(); - } - } - - private class StorageObjectDataReader extends AbstractDelayedYamlFileReader { - StorageObjectDataReader() { - super(ess, getStorageFile(), clazz); - } - - @Override - public void onStart() { - rwl.writeLock().lock(); - } - - @Override - public void onSuccess(final T object) { - if (object != null) { - data = object; - } - rwl.writeLock().unlock(); - finishRead(); - } - - @Override - public void onException() { - if (data == null) { - try { - data = clazz.newInstance(); - } catch (final IllegalAccessException | InstantiationException ex) { - Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex); - } - } - rwl.writeLock().unlock(); - } - } -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/storage/BukkitConstructor.java b/Essentials/src/main/java/com/earth2me/essentials/storage/BukkitConstructor.java deleted file mode 100644 index d4aa1d3b4e4..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/storage/BukkitConstructor.java +++ /dev/null @@ -1,214 +0,0 @@ -package com.earth2me.essentials.storage; - -import com.earth2me.essentials.Enchantments; -import com.earth2me.essentials.utils.NumberUtil; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.inventory.ItemStack; -import org.bukkit.material.MaterialData; -import org.bukkit.plugin.Plugin; -import org.yaml.snakeyaml.constructor.BaseConstructor; -import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor; -import org.yaml.snakeyaml.introspector.PropertyUtils; -import org.yaml.snakeyaml.nodes.MappingNode; -import org.yaml.snakeyaml.nodes.Node; -import org.yaml.snakeyaml.nodes.NodeId; -import org.yaml.snakeyaml.nodes.NodeTuple; -import org.yaml.snakeyaml.nodes.ScalarNode; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -public class BukkitConstructor extends CustomClassLoaderConstructor { - private Method constructScalarMethod = null; - - public BukkitConstructor(final Class clazz, final Plugin plugin) { - super(clazz, plugin.getClass().getClassLoader()); - yamlClassConstructors.put(NodeId.scalar, new ConstructBukkitScalar()); - yamlClassConstructors.put(NodeId.mapping, new ConstructBukkitMapping()); - - final PropertyUtils propertyUtils = getPropertyUtils(); - propertyUtils.setSkipMissingProperties(true); - setPropertyUtils(propertyUtils); - } - - protected String constructScalarRefl(final ScalarNode scalarNode) { - try { - if (constructScalarMethod == null) { - constructScalarMethod = BaseConstructor.class.getDeclaredMethod("constructScalar", ScalarNode.class); - } - return (String) constructScalarMethod.invoke(this, scalarNode); - } catch (final NoSuchMethodException - | SecurityException - | IllegalAccessException - | IllegalArgumentException - | InvocationTargetException e) { - e.printStackTrace(); - } - - return null; - } - - private class ConstructBukkitScalar extends ConstructScalar { - - @Override - public Object construct(final Node node) { - if (node.getType().equals(Material.class)) { - final String val = constructScalarRefl((ScalarNode) node); - return Material.matchMaterial(val); - } - - if (node.getType().equals(MaterialData.class)) { - final String val = constructScalarRefl((ScalarNode) node); - if (val.isEmpty()) { - return null; - } - final String[] split = val.split("[:+',;.]", 2); - if (split.length == 0) { - return null; - } - - final Material mat = Material.matchMaterial(split[0]); - - if (mat == null) { - return null; - } - byte data = 0; - if (split.length == 2 && NumberUtil.isInt(split[1])) { - data = Byte.parseByte(split[1]); - } - return new MaterialData(mat, data); - } - if (node.getType().equals(ItemStack.class)) { - final String val = constructScalarRefl((ScalarNode) node); - if (val.isEmpty()) { - return null; - } - final String[] split1 = val.split("\\W"); - if (split1.length == 0) { - return null; - } - final String[] split2 = split1[0].split("[:+',;.]", 2); - if (split2.length == 0) { - return null; - } - - final Material mat = Material.matchMaterial(split2[0]); - - if (mat == null) { - return null; - } - short data = 0; - if (split2.length == 2 && NumberUtil.isInt(split2[1])) { - data = Short.parseShort(split2[1]); - } - int size = mat.getMaxStackSize(); - if (split1.length > 1 && NumberUtil.isInt(split1[1])) { - size = Integer.parseInt(split1[1]); - } - final ItemStack stack = new ItemStack(mat, size, data); - if (split1.length > 2) { - for (int i = 2; i < split1.length; i++) { - final String[] split3 = split1[0].split("[:+',;.]", 2); - if (split3.length < 1) { - continue; - } - final Enchantment enchantment = Enchantments.getByName(split3[0]); - if (enchantment == null) { - continue; - } - int level = enchantment.getStartLevel(); - if (split3.length == 2 && NumberUtil.isInt(split3[1])) { - level = Integer.parseInt(split3[1]); - } - if (level < enchantment.getStartLevel()) { - level = enchantment.getStartLevel(); - } - if (level > enchantment.getMaxLevel()) { - level = enchantment.getMaxLevel(); - } - stack.addUnsafeEnchantment(enchantment, level); - } - } - return stack; - } - if (node.getType().equals(EnchantmentLevel.class)) { - final String val = constructScalarRefl((ScalarNode) node); - if (val.isEmpty()) { - return null; - } - final String[] split = val.split("[:+',;.]", 2); - if (split.length == 0) { - return null; - } - final Enchantment enchant = Enchantments.getByName(split[0]); - if (enchant == null) { - return null; - } - int level = enchant.getStartLevel(); - if (split.length == 2 && NumberUtil.isInt(split[1])) { - level = Integer.parseInt(split[1]); - } - if (level < enchant.getStartLevel()) { - level = enchant.getStartLevel(); - } - if (level > enchant.getMaxLevel()) { - level = enchant.getMaxLevel(); - } - return new EnchantmentLevel(enchant, level); - } - return super.construct(node); - } - } - - private class ConstructBukkitMapping extends ConstructMapping { - - @Override - public Object construct(final Node node) { - if (node.getType().equals(Location.class)) { - //TODO: NPE checks - final MappingNode mnode = (MappingNode) node; - String worldName = ""; - double x = 0, y = 0, z = 0; - float yaw = 0, pitch = 0; - if (mnode.getValue().size() < 4) { - return null; - } - for (final NodeTuple nodeTuple : mnode.getValue()) { - final String key = constructScalarRefl((ScalarNode) nodeTuple.getKeyNode()); - final ScalarNode snode = (ScalarNode) nodeTuple.getValueNode(); - if (key.equalsIgnoreCase("world")) { - worldName = constructScalarRefl(snode); - } - if (key.equalsIgnoreCase("x")) { - x = Double.parseDouble(constructScalarRefl(snode)); - } - if (key.equalsIgnoreCase("y")) { - y = Double.parseDouble(constructScalarRefl(snode)); - } - if (key.equalsIgnoreCase("z")) { - z = Double.parseDouble(constructScalarRefl(snode)); - } - if (key.equalsIgnoreCase("yaw")) { - yaw = Float.parseFloat(constructScalarRefl(snode)); - } - if (key.equalsIgnoreCase("pitch")) { - pitch = Float.parseFloat(constructScalarRefl(snode)); - } - } - if (worldName == null || worldName.isEmpty()) { - return null; - } - final World world = Bukkit.getWorld(worldName); - if (world == null) { - return null; - } - return new Location(world, x, y, z, yaw, pitch); - } - return super.construct(node); - } - } -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/storage/Comment.java b/Essentials/src/main/java/com/earth2me/essentials/storage/Comment.java deleted file mode 100644 index 0a4514a67c3..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/storage/Comment.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.earth2me.essentials.storage; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.FIELD) -@Documented -@Retention(RetentionPolicy.RUNTIME) -public @interface Comment { - String[] value() default ""; -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/storage/EnchantmentLevel.java b/Essentials/src/main/java/com/earth2me/essentials/storage/EnchantmentLevel.java deleted file mode 100644 index b9290a7617c..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/storage/EnchantmentLevel.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.earth2me.essentials.storage; - -import org.bukkit.enchantments.Enchantment; - -import java.util.Map.Entry; - -public class EnchantmentLevel implements Entry { - private Enchantment enchantment; - private int level; - - public EnchantmentLevel(final Enchantment enchantment, final int level) { - this.enchantment = enchantment; - this.level = level; - } - - public Enchantment getEnchantment() { - return enchantment; - } - - public void setEnchantment(final Enchantment enchantment) { - this.enchantment = enchantment; - } - - public int getLevel() { - return level; - } - - public void setLevel(final int level) { - this.level = level; - } - - @Override - public Enchantment getKey() { - return enchantment; - } - - @Override - public Integer getValue() { - return level; - } - - @Override - public Integer setValue(final Integer v) { - final int t = level; - level = v; - return t; - } - - @Override - public int hashCode() { - return enchantment.hashCode() ^ level; - } - - @Override - public boolean equals(final Object obj) { - if (obj instanceof Entry) { - final Entry entry = (Entry) obj; - if (entry.getKey() instanceof Enchantment && entry.getValue() instanceof Integer) { - final Enchantment enchant = (Enchantment) entry.getKey(); - final Integer lvl = (Integer) entry.getValue(); - return this.enchantment.equals(enchant) && this.level == lvl; - } - } - return false; - } -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/storage/IStorageObjectHolder.java b/Essentials/src/main/java/com/earth2me/essentials/storage/IStorageObjectHolder.java deleted file mode 100644 index b7ef42d7e36..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/storage/IStorageObjectHolder.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.earth2me.essentials.storage; - -public interface IStorageObjectHolder { - T getData(); - - void acquireReadLock(); - - void acquireWriteLock(); - - void close(); - - void unlock(); -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/storage/IStorageReader.java b/Essentials/src/main/java/com/earth2me/essentials/storage/IStorageReader.java deleted file mode 100644 index b21d9aa310c..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/storage/IStorageReader.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.earth2me.essentials.storage; - -public interface IStorageReader { - T load(final Class clazz) throws ObjectLoadException; -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/storage/IStorageWriter.java b/Essentials/src/main/java/com/earth2me/essentials/storage/IStorageWriter.java deleted file mode 100644 index 698ee9ec1ae..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/storage/IStorageWriter.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.earth2me.essentials.storage; - -public interface IStorageWriter { - void save(final StorageObject object); -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/storage/ListType.java b/Essentials/src/main/java/com/earth2me/essentials/storage/ListType.java deleted file mode 100644 index d58af79308e..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/storage/ListType.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.earth2me.essentials.storage; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -public @interface ListType { - Class value() default String.class; -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/storage/MapKeyType.java b/Essentials/src/main/java/com/earth2me/essentials/storage/MapKeyType.java deleted file mode 100644 index 2a2374d5587..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/storage/MapKeyType.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.earth2me.essentials.storage; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -public @interface MapKeyType { - Class value() default String.class; -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/storage/MapValueType.java b/Essentials/src/main/java/com/earth2me/essentials/storage/MapValueType.java deleted file mode 100644 index ef6d72e7bce..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/storage/MapValueType.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.earth2me.essentials.storage; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -public @interface MapValueType { - Class value() default String.class; -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/storage/ObjectLoadException.java b/Essentials/src/main/java/com/earth2me/essentials/storage/ObjectLoadException.java deleted file mode 100644 index 97a1de67daf..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/storage/ObjectLoadException.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.earth2me.essentials.storage; - -public class ObjectLoadException extends Exception { - public ObjectLoadException(final Throwable thrwbl) { - super(thrwbl); - } -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/storage/StorageObject.java b/Essentials/src/main/java/com/earth2me/essentials/storage/StorageObject.java deleted file mode 100644 index 7e01ce46382..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/storage/StorageObject.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.earth2me.essentials.storage; - -public interface StorageObject { -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/storage/YamlStorageReader.java b/Essentials/src/main/java/com/earth2me/essentials/storage/YamlStorageReader.java deleted file mode 100644 index f3038fb6a3b..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/storage/YamlStorageReader.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.earth2me.essentials.storage; - -import org.bukkit.plugin.Plugin; -import org.yaml.snakeyaml.TypeDescription; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.Constructor; - -import java.io.Reader; -import java.lang.reflect.Field; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.locks.ReentrantLock; - -public class YamlStorageReader implements IStorageReader { - private transient static final Map PREPARED_YAMLS = Collections.synchronizedMap(new HashMap<>()); - private transient static final Map LOCKS = new HashMap<>(); - private transient final Reader reader; - private transient final Plugin plugin; - - public YamlStorageReader(final Reader reader, final Plugin plugin) { - this.reader = reader; - this.plugin = plugin; - } - - @Override - public T load(final Class clazz) throws ObjectLoadException { - Yaml yaml = PREPARED_YAMLS.get(clazz); - if (yaml == null) { - yaml = new Yaml(prepareConstructor(clazz)); - PREPARED_YAMLS.put(clazz, yaml); - } - ReentrantLock lock; - synchronized (LOCKS) { - lock = LOCKS.get(clazz); - if (lock == null) { - lock = new ReentrantLock(); - } - } - lock.lock(); - try { - T object = yaml.load(reader); - if (object == null) { - object = clazz.newInstance(); - } - return object; - } catch (final IllegalAccessException | InstantiationException ex) { - throw new ObjectLoadException(ex); - } finally { - lock.unlock(); - } - } - - private Constructor prepareConstructor(final Class clazz) { - final Constructor constructor = new BukkitConstructor(clazz, plugin); - final Set classes = new HashSet<>(); - - prepareConstructor(constructor, classes, clazz); - return constructor; - } - - private void prepareConstructor(final Constructor constructor, final Set classes, final Class clazz) { - classes.add(clazz); - final TypeDescription description = new TypeDescription(clazz); - for (final Field field : clazz.getDeclaredFields()) { - prepareList(field, description, classes, constructor); - prepareMap(field, description, classes, constructor); - if (StorageObject.class.isAssignableFrom(field.getType()) && !classes.contains(field.getType())) { - prepareConstructor(constructor, classes, field.getType()); - } - } - constructor.addTypeDescription(description); - } - - private void prepareList(final Field field, final TypeDescription description, final Set classes, final Constructor constructor) { - final ListType listType = field.getAnnotation(ListType.class); - if (listType != null) { - description.putListPropertyType(field.getName(), listType.value()); - if (StorageObject.class.isAssignableFrom(listType.value()) && !classes.contains(listType.value())) { - prepareConstructor(constructor, classes, listType.value()); - } - } - } - - private void prepareMap(final Field field, final TypeDescription description, final Set classes, final Constructor constructor) { - final MapValueType mapType = field.getAnnotation(MapValueType.class); - if (mapType != null) { - final MapKeyType mapKeyType = field.getAnnotation(MapKeyType.class); - description.putMapPropertyType(field.getName(), mapKeyType == null ? String.class : mapKeyType.value(), mapType.value()); - if (StorageObject.class.isAssignableFrom(mapType.value()) && !classes.contains(mapType.value())) { - prepareConstructor(constructor, classes, mapType.value()); - } - } - } -} diff --git a/Essentials/src/main/java/com/earth2me/essentials/storage/YamlStorageWriter.java b/Essentials/src/main/java/com/earth2me/essentials/storage/YamlStorageWriter.java deleted file mode 100644 index c6a8a353261..00000000000 --- a/Essentials/src/main/java/com/earth2me/essentials/storage/YamlStorageWriter.java +++ /dev/null @@ -1,254 +0,0 @@ -package com.earth2me.essentials.storage; - -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.inventory.ItemStack; -import org.bukkit.material.MaterialData; -import org.yaml.snakeyaml.Yaml; - -import java.io.PrintWriter; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.Collection; -import java.util.Collections; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.regex.Pattern; - -public class YamlStorageWriter implements IStorageWriter { - private transient static final Pattern NON_WORD_PATTERN = Pattern.compile("\\W"); - private transient static final Yaml YAML = new Yaml(); - private transient final PrintWriter writer; - - public YamlStorageWriter(final PrintWriter writer) { - this.writer = writer; - } - - @Override - public void save(final StorageObject object) { - try { - writeToFile(object, 0, object.getClass()); - } catch (final IllegalArgumentException | IllegalAccessException ex) { - Logger.getLogger(YamlStorageWriter.class.getName()).log(Level.SEVERE, null, ex); - } - } - - private void writeToFile(final Object object, final int depth, final Class clazz) throws IllegalAccessException { - for (final Field field : clazz.getDeclaredFields()) { - final int modifier = field.getModifiers(); - if (Modifier.isPrivate(modifier) && !Modifier.isTransient(modifier) && !Modifier.isStatic(modifier)) { - field.setAccessible(true); - - final Object data = field.get(object); - if (writeKey(field, depth, data)) { - continue; - } - if (data instanceof StorageObject) { - writer.println(); - writeToFile(data, depth + 1, data.getClass()); - } else if (data instanceof Map) { - writeMap((Map) data, depth + 1); - } else if (data instanceof Collection) { - writeCollection((Collection) data, depth + 1); - } else if (data instanceof Location) { - writeLocation((Location) data, depth + 1); - } else { - writeScalar(data); - writer.println(); - } - } - } - } - - private boolean writeKey(final Field field, final int depth, final Object data) { - final boolean commentPresent = writeComment(field, depth); - if (data == null && !commentPresent) { - return true; - } - writeIndention(depth); - if (data == null && commentPresent) { - writer.print('#'); - } - final String name = field.getName(); - writer.print(name); - writer.print(": "); - if (data == null && commentPresent) { - writer.println(); - writer.println(); - return true; - } - return false; - } - - private boolean writeComment(final Field field, final int depth) { - final boolean commentPresent = field.isAnnotationPresent(Comment.class); - if (commentPresent) { - final Comment comments = field.getAnnotation(Comment.class); - for (final String comment : comments.value()) { - final String trimmed = comment.trim(); - if (trimmed.isEmpty()) { - continue; - } - writeIndention(depth); - writer.print("# "); - writer.print(trimmed); - writer.println(); - } - } - return commentPresent; - } - - private void writeCollection(final Collection data, final int depth) throws IllegalAccessException { - writer.println(); - if (data.isEmpty()) { - writer.println(); - } - for (final Object entry : data) { - if (entry != null) { - writeIndention(depth); - writer.print("- "); - if (entry instanceof StorageObject) { - writer.println(); - writeToFile(entry, depth + 1, entry.getClass()); - } else if (entry instanceof Location) { - writeLocation((Location) entry, depth + 1); - } else { - writeScalar(entry); - } - } - } - writer.println(); - } - - private void writeMap(final Map data, final int depth) throws IllegalArgumentException, IllegalAccessException { - writer.println(); - if (data.isEmpty()) { - writer.println(); - } - for (final Entry entry : data.entrySet()) { - final Object value = entry.getValue(); - if (value != null) { - writeIndention(depth); - writeKey(entry.getKey()); - writer.print(": "); - if (value instanceof StorageObject) { - writer.println(); - writeToFile(value, depth + 1, value.getClass()); - } else if (value instanceof Collection) { - writeCollection((Collection) value, depth + 1); - } else if (value instanceof Location) { - writeLocation((Location) value, depth + 1); - } else { - writeScalar(value); - writer.println(); - } - } - } - } - - private void writeIndention(final int depth) { - for (int i = 0; i < depth; i++) { - writer.print(" "); - } - } - - private void writeScalar(final Object data) { - if (data instanceof String || data instanceof Boolean || data instanceof Number) { - synchronized (YAML) { - YAML.dumpAll(Collections.singletonList(data).iterator(), writer); - } - } else if (data instanceof Material) { - writeMaterial(data); - writer.println(); - } else if (data instanceof MaterialData) { - writeMaterialData(data); - writer.println(); - } else if (data instanceof ItemStack) { - writeItemStack(data); - writer.println(); - } else if (data instanceof EnchantmentLevel) { - writeEnchantmentLevel(data); - writer.println(); - } else { - throw new UnsupportedOperationException(); - } - } - - private void writeKey(final Object data) { - if (data instanceof String || data instanceof Boolean || data instanceof Number) { - final String output = data.toString(); - if (NON_WORD_PATTERN.matcher(output).find()) { - writer.print('"'); - writer.print(output.replace("\"", "\\\"")); - writer.print('"'); - } else { - writer.print(output); - } - } else if (data instanceof Material) { - writeMaterial(data); - } else if (data instanceof MaterialData) { - writeMaterialData(data); - } else if (data instanceof EnchantmentLevel) { - writeEnchantmentLevel(data); - } else { - throw new UnsupportedOperationException(); - } - } - - private void writeMaterial(final Object data) { - writer.print(data.toString().toLowerCase(Locale.ENGLISH)); - } - - private void writeMaterialData(final Object data) { - final MaterialData matData = (MaterialData) data; - writeMaterial(matData.getItemType()); - if (matData.getData() > 0) { - writer.print(':'); - writer.print(matData.getData()); - } - } - - private void writeItemStack(final Object data) { - final ItemStack itemStack = (ItemStack) data; - writeMaterialData(itemStack.getData()); - writer.print(' '); - writer.print(itemStack.getAmount()); - for (final Entry entry : itemStack.getEnchantments().entrySet()) { - writer.print(' '); - writeEnchantmentLevel(entry); - } - } - - private void writeEnchantmentLevel(final Object data) { - final Entry enchLevel = (Entry) data; - writer.print(enchLevel.getKey().getName().toLowerCase(Locale.ENGLISH)); - writer.print(':'); - writer.print(enchLevel.getValue()); - } - - private void writeLocation(final Location entry, final int depth) { - writer.println(); - writeIndention(depth); - writer.print("world: "); - writeScalar(entry.getWorld().getName()); - writeIndention(depth); - writer.print("x: "); - writeScalar(entry.getX()); - writeIndention(depth); - writer.print("y: "); - writeScalar(entry.getY()); - writeIndention(depth); - writer.print("z: "); - writeScalar(entry.getZ()); - writeIndention(depth); - writer.print("yaw: "); - writeScalar(entry.getYaw()); - writeIndention(depth); - writer.print("pitch: "); - writeScalar(entry.getPitch()); - } -} diff --git a/Essentials/src/main/java/net/ess3/api/IReload.java b/Essentials/src/main/java/net/ess3/api/IReload.java deleted file mode 100644 index 7347089307c..00000000000 --- a/Essentials/src/main/java/net/ess3/api/IReload.java +++ /dev/null @@ -1,12 +0,0 @@ -package net.ess3.api; - -/** - * Represents a storage object that is reloadable. - * - * @deprecated This is a remnant of the abandoned 3.x storage system. Neither future 2.x code nor external plugins - * should use this interface. - */ -@Deprecated -public interface IReload extends com.earth2me.essentials.api.IReload { - -} diff --git a/Essentials/src/main/java/net/ess3/api/ISpawnStorage.java b/Essentials/src/main/java/net/ess3/api/ISpawnStorage.java new file mode 100644 index 00000000000..9a12c740f60 --- /dev/null +++ b/Essentials/src/main/java/net/ess3/api/ISpawnStorage.java @@ -0,0 +1,9 @@ +package net.ess3.api; + +import com.earth2me.essentials.IConf; + +/** + * This interface contains basic API functions for Essentials Spawn. + */ +public interface ISpawnStorage extends IConf { +} diff --git a/EssentialsSpawn/src/main/java/com/earth2me/essentials/spawn/SpawnStorage.java b/EssentialsSpawn/src/main/java/com/earth2me/essentials/spawn/SpawnStorage.java index adab926aec2..b45e70979fd 100644 --- a/EssentialsSpawn/src/main/java/com/earth2me/essentials/spawn/SpawnStorage.java +++ b/EssentialsSpawn/src/main/java/com/earth2me/essentials/spawn/SpawnStorage.java @@ -1,8 +1,8 @@ package com.earth2me.essentials.spawn; +import com.earth2me.essentials.IConf; import com.earth2me.essentials.IEssentialsModule; -import com.earth2me.essentials.settings.Spawns; -import com.earth2me.essentials.storage.AsyncStorageObjectHolder; +import com.earth2me.essentials.config.EssentialsConfiguration; import net.ess3.api.IEssentials; import org.bukkit.Location; import org.bukkit.World; @@ -12,58 +12,46 @@ import java.util.Locale; import java.util.Map; -public class SpawnStorage extends AsyncStorageObjectHolder implements IEssentialsModule { +public class SpawnStorage implements IEssentialsModule, IConf { + private final IEssentials ess; + private final EssentialsConfiguration config; + private final Map spawns = new HashMap<>(); + SpawnStorage(final IEssentials ess) { - super(ess, Spawns.class); + this.ess = ess; + this.config = new EssentialsConfiguration(new File(ess.getDataFolder(), "spawn.yml")); reloadConfig(); } @Override - public File getStorageFile() { - return new File(ess.getDataFolder(), "spawn.yml"); - } - - @Override - public void finishRead() { - } - - @Override - public void finishWrite() { + public void reloadConfig() { + synchronized (spawns) { + config.load(); + // need to outsource this because transitive relocations :) + spawns.putAll(config.getLocationSectionMap("spawns")); + } } - void setSpawn(final Location loc, final String group) { - acquireWriteLock(); - try { - if (getData().getSpawns() == null) { - getData().setSpawns(new HashMap<>()); - } - getData().getSpawns().put(group.toLowerCase(Locale.ENGLISH), loc); - } finally { - unlock(); + void setSpawn(final Location loc, String group) { + group = group.toLowerCase(Locale.ENGLISH); + synchronized (spawns) { + spawns.put(group, loc); + config.setProperty("spawns." + group, loc); + config.save(); } + } - if ("default".equalsIgnoreCase(group)) { - loc.getWorld().setSpawnLocation(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + Location getSpawn(String group) { + if (group == null) { + return getWorldSpawn(); } - } - Location getSpawn(final String group) { - acquireReadLock(); - try { - if (getData().getSpawns() == null || group == null) { - return getWorldSpawn(); - } - final Map spawnMap = getData().getSpawns(); - String groupName = group.toLowerCase(Locale.ENGLISH); - if (!spawnMap.containsKey(groupName)) { - groupName = "default"; - } - if (!spawnMap.containsKey(groupName)) { + group = group.toLowerCase(Locale.ENGLISH); + synchronized (spawns) { + if (!spawns.containsKey(group)) { return getWorldSpawn(); } - return spawnMap.get(groupName); - } finally { - unlock(); + return spawns.get(group); } } From 90dbc634ba5be6130df4c6e86d3fde4dce2cc467 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 20 Mar 2021 01:57:30 -0400 Subject: [PATCH 10/61] Convert over EssentialsUpgrade --- .../essentials/EssentialsUpgrade.java | 96 +++++++++---------- 1 file changed, 43 insertions(+), 53 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java index cc63e54994d..935c2177886 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java @@ -3,8 +3,6 @@ import com.earth2me.essentials.config.ConfigurateUtil; import com.earth2me.essentials.config.EssentialsConfiguration; import com.earth2me.essentials.craftbukkit.BanLookup; -import com.earth2me.essentials.settings.Spawns; -import com.earth2me.essentials.storage.YamlStorageWriter; import com.earth2me.essentials.utils.StringUtil; import com.google.common.base.Charsets; import com.google.common.collect.Maps; @@ -100,7 +98,7 @@ public static void uuidFileConvert(final IEssentials ess, final Boolean ignoreUF uuid = UUID.fromString(name); } catch (final IllegalArgumentException ex) { final File file = new File(userdir, string); - final EssentialsConf conf = new EssentialsConf(file); + final EssentialsConfiguration conf = new EssentialsConfiguration(file); conf.load(); conf.setProperty("lastAccountName", name); conf.save(); @@ -131,7 +129,7 @@ public static void uuidFileConvert(final IEssentials ess, final Boolean ignoreUF } if (uuid != null) { - conf.forceSave(); + conf.blockingSave(); config = new EssentialsUserConf(name, uuid, new File(userdir, uuid + ".yml")); config.convertLegacyFile(); ess.getUserMap().trackUUID(uuid, name, false); @@ -165,12 +163,12 @@ public void convertIgnoreList() { if (!file.isFile() || !file.getName().endsWith(".yml")) { continue; } - final EssentialsConf config = new EssentialsConf(file); + final EssentialsConfiguration config = new EssentialsConfiguration(file); try { config.load(); if (config.hasProperty("ignore")) { final List migratedIgnores = new ArrayList<>(); - for (final String name : Collections.synchronizedList(config.getStringList("ignore"))) { + for (final String name : Collections.synchronizedList(config.getList("ignore", String.class))) { if (name == null) { continue; } @@ -185,7 +183,7 @@ public void convertIgnoreList() { } config.removeProperty("ignore"); config.setProperty("ignore", migratedIgnores); - config.forceSave(); + config.blockingSave(); } } catch (final RuntimeException ex) { LOGGER.log(Level.INFO, "File: " + file.toString()); @@ -199,7 +197,7 @@ public void convertIgnoreList() { public void convertKits() { final Kits kits = ess.getKits(); - final EssentialsConf config = kits.getConfig(); + final EssentialsConfiguration config = kits.getConfig(); if (doneFile.getBoolean("kitsyml", false)) { return; } @@ -216,7 +214,7 @@ public void convertKits() { for (final Map.Entry entry : legacyKits.entrySet()) { LOGGER.info("Converting " + entry.getKey()); - config.set("kits." + entry.getKey(), entry.getValue()); + config.setRaw("kits." + entry.getKey(), entry.getValue()); } config.save(); @@ -238,9 +236,9 @@ private void moveMotdRulesToFile(final String name) { if (!configFile.exists()) { return; } - final EssentialsConf conf = new EssentialsConf(configFile); + final EssentialsConfiguration conf = new EssentialsConfiguration(configFile); conf.load(); - final List lines = conf.getStringList(name); + final List lines = conf.getList(name, String.class); if (lines != null && !lines.isEmpty()) { if (!file.createNewFile()) { throw new IOException("Failed to create file " + file); @@ -314,12 +312,12 @@ private void updateUsersPowerToolsFormat() { if (!file.isFile() || !file.getName().endsWith(".yml")) { continue; } - final EssentialsConf config = new EssentialsConf(file); + final EssentialsConfiguration config = new EssentialsConfiguration(file); try { config.load(); if (config.hasProperty("powertools")) { - final Map powertools = config.getConfigurationSection("powertools").getValues(false); - if (powertools == null) { + final Map powertools = ConfigurateUtil.getRawMap(config.getSection("powertools")); + if (powertools.isEmpty()) { continue; } for (final Map.Entry entry : powertools.entrySet()) { @@ -329,7 +327,8 @@ private void updateUsersPowerToolsFormat() { powertools.put(entry.getKey(), temp); } } - config.forceSave(); + config.setRaw("powertools", powertools); + config.blockingSave(); } } catch (final RuntimeException ex) { LOGGER.log(Level.INFO, "File: " + file.toString()); @@ -354,39 +353,37 @@ private void updateUsersHomesFormat() { if (!file.isFile() || !file.getName().endsWith(".yml")) { continue; } - final EssentialsConf config = new EssentialsConf(file); + final EssentialsConfiguration config = new EssentialsConfiguration(file); try { config.load(); if (config.hasProperty("home") && config.hasProperty("home.default")) { - final String defworld = (String) config.getProperty("home.default"); - final Location defloc = getFakeLocation(config, "home.worlds." + defworld); + final String defworld = config.getString("home.default", null); + final Location defloc = getFakeLocation(config.getRootNode(), "home.worlds." + defworld); if (defloc != null) { config.setProperty("homes.home", defloc); } - final Set worlds = config.getConfigurationSection("home.worlds").getKeys(false); + final Set worlds = ConfigurateUtil.getKeys(config.getSection("home.worlds")); Location loc; String worldName; - if (worlds == null) { + if (worlds.isEmpty()) { continue; } for (final String world : worlds) { if (defworld.equalsIgnoreCase(world)) { continue; } - loc = getFakeLocation(config, "home.worlds." + world); + loc = getFakeLocation(config.getRootNode(), "home.worlds." + world); if (loc == null) { continue; } worldName = loc.getWorld().getName().toLowerCase(Locale.ENGLISH); - if (worldName != null && !worldName.isEmpty()) { - config.setProperty("homes." + worldName, loc); - } + config.setProperty("homes." + worldName, loc); } config.removeProperty("home"); - config.forceSave(); + config.blockingSave(); } } catch (final RuntimeException ex) { @@ -443,7 +440,7 @@ private World getFakeWorld(final String name) { return null; } - public Location getFakeLocation(final EssentialsConf config, final String path) { + public Location getFakeLocation(final CommentedConfigurationNode config, final String path) { final String worldName = config.getString((path != null ? path + "." : "") + "world"); if (worldName == null || worldName.isEmpty()) { return null; @@ -452,7 +449,8 @@ public Location getFakeLocation(final EssentialsConf config, final String path) if (world == null) { return null; } - return new Location(world, config.getDouble((path != null ? path + "." : "") + "x", 0), config.getDouble((path != null ? path + "." : "") + "y", 0), config.getDouble((path != null ? path + "." : "") + "z", 0), (float) config.getDouble((path != null ? path + "." : "") + "yaw", 0), (float) config.getDouble((path != null ? path + "." : "") + "pitch", 0)); + return new Location(world, config.node("x").getDouble(0), config.node("y").getDouble(0), + config.node("z").getDouble(0), config.node("yaw").getFloat(0), config.node("pitch").getFloat(0)); } private void deleteOldItemsCsv() { @@ -495,22 +493,18 @@ private void updateSpawnsToNewSpawnsConfig() { final File configFile = new File(ess.getDataFolder(), "spawn.yml"); if (configFile.exists()) { - final EssentialsConf config = new EssentialsConf(configFile); + final EssentialsConfiguration config = new EssentialsConfiguration(configFile); try { config.load(); if (!config.hasProperty("spawns")) { - final Spawns spawns = new Spawns(); - final Set keys = config.getKeys(false); - for (final String group : keys) { - final Location loc = getFakeLocation(config, group); - spawns.getSpawns().put(group.toLowerCase(Locale.ENGLISH), loc); + for (final Map.Entry entry : config.getMap().entrySet()) { + final Location loc = getFakeLocation(entry.getValue(), entry.getKey()); + config.setProperty(entry.getKey(), loc); } if (!configFile.renameTo(new File(ess.getDataFolder(), "spawn.yml.old"))) { throw new Exception(tl("fileRenameError", "spawn.yml")); } - try (final PrintWriter writer = new PrintWriter(configFile)) { - new YamlStorageWriter(writer).save(spawns); - } + config.blockingSave(); } } catch (final Exception ex) { Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex); @@ -527,22 +521,18 @@ private void updateJailsToNewJailsConfig() { final File configFile = new File(ess.getDataFolder(), "jail.yml"); if (configFile.exists()) { - final EssentialsConf config = new EssentialsConf(configFile); + final EssentialsConfiguration config = new EssentialsConfiguration(configFile); try { config.load(); if (!config.hasProperty("jails")) { - final com.earth2me.essentials.settings.Jails jails = new com.earth2me.essentials.settings.Jails(); - final Set keys = config.getKeys(false); - for (final String jailName : keys) { - final Location loc = getFakeLocation(config, jailName); - jails.getJails().put(jailName.toLowerCase(Locale.ENGLISH), loc); + for (final Map.Entry entry : config.getMap().entrySet()) { + final Location loc = getFakeLocation(entry.getValue(), entry.getKey()); + config.setProperty(entry.getKey(), loc); } if (!configFile.renameTo(new File(ess.getDataFolder(), "jail.yml.old"))) { throw new Exception(tl("fileRenameError", "jail.yml")); } - try (final PrintWriter writer = new PrintWriter(configFile)) { - new YamlStorageWriter(writer).save(jails); - } + config.blockingSave(); } } catch (final Exception ex) { Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex); @@ -643,23 +633,23 @@ public void banFormatChange() { countFiles++; final File pFile = new File(userdir, string); - final EssentialsConf conf = new EssentialsConf(pFile); + final EssentialsConfiguration conf = new EssentialsConfiguration(pFile); conf.load(); - String banReason; + final String banReason; long banTimeout; - try { - banReason = conf.getConfigurationSection("ban").getString("reason"); - } catch (final NullPointerException n) { + if (conf.hasProperty("ban.reason")) { + banReason = conf.getString("ban.reason", null); + } else { banReason = null; } - final String playerName = conf.getString("lastAccountName"); + final String playerName = conf.getString("lastAccountName", null); if (playerName != null && playerName.length() > 1 && banReason != null && banReason.length() > 1) { try { - if (conf.getConfigurationSection("ban").contains("timeout")) { - banTimeout = Long.parseLong(conf.getConfigurationSection("ban").getString("timeout")); + if (conf.hasProperty("ban.timeout")) { + banTimeout = Long.parseLong(conf.getString("ban.timeout", null)); } else { banTimeout = 0L; } From b79f25c131c6933e90ca395df5597f2a67bfffc2 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 20 Mar 2021 10:16:55 -0400 Subject: [PATCH 11/61] Clear jails and spawn cache on reload --- Essentials/src/main/java/com/earth2me/essentials/Jails.java | 1 + .../main/java/com/earth2me/essentials/spawn/SpawnStorage.java | 1 + 2 files changed, 2 insertions(+) diff --git a/Essentials/src/main/java/com/earth2me/essentials/Jails.java b/Essentials/src/main/java/com/earth2me/essentials/Jails.java index 65293be19e3..f91f24ed521 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Jails.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Jails.java @@ -56,6 +56,7 @@ public Jails(final IEssentials ess) { public void reloadConfig() { synchronized (jails) { config.load(); + jails.clear(); final CommentedConfigurationNode jailsNode = config.getSection("jails"); for (final Map.Entry entry : ConfigurateUtil.getMap(jailsNode).entrySet()) { final CommentedConfigurationNode jailNode = entry.getValue(); diff --git a/EssentialsSpawn/src/main/java/com/earth2me/essentials/spawn/SpawnStorage.java b/EssentialsSpawn/src/main/java/com/earth2me/essentials/spawn/SpawnStorage.java index b45e70979fd..1f7bc14a25a 100644 --- a/EssentialsSpawn/src/main/java/com/earth2me/essentials/spawn/SpawnStorage.java +++ b/EssentialsSpawn/src/main/java/com/earth2me/essentials/spawn/SpawnStorage.java @@ -27,6 +27,7 @@ public class SpawnStorage implements IEssentialsModule, IConf { public void reloadConfig() { synchronized (spawns) { config.load(); + spawns.clear(); // need to outsource this because transitive relocations :) spawns.putAll(config.getLocationSectionMap("spawns")); } From d841325d2fe33c31bc7931a70677cabdc8044eea Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 20 Mar 2021 10:22:41 -0400 Subject: [PATCH 12/61] Add copy header option --- .../essentials/config/EssentialsConfiguration.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index 293b4b78b03..761f630ce1f 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -6,6 +6,8 @@ import org.bukkit.World; import org.spongepowered.configurate.CommentedConfigurationNode; import org.spongepowered.configurate.ConfigurateException; +import org.spongepowered.configurate.ConfigurationOptions; +import org.spongepowered.configurate.loader.HeaderMode; import org.spongepowered.configurate.loader.ParsingException; import org.spongepowered.configurate.serialize.SerializationException; import org.spongepowered.configurate.yaml.NodeStyle; @@ -49,8 +51,13 @@ public EssentialsConfiguration(final File configFile) { } public EssentialsConfiguration(final File configFile, final String templateName) { + this(configFile, templateName, null); + } + + public EssentialsConfiguration(final File configFile, final String templateName, final String header) { this.configFile = configFile; - this.loader = YamlConfigurationLoader.builder().nodeStyle(NodeStyle.BLOCK).indent(2).file(configFile).build(); + this.loader = YamlConfigurationLoader.builder().defaultOptions(ConfigurationOptions.defaults().header(header)) + .headerMode(HeaderMode.PRESET).nodeStyle(NodeStyle.BLOCK).indent(2).file(configFile).build(); this.templateName = templateName; } From 4b2eb222fa0601bf31a813624e46db2638bbbfaa Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 20 Mar 2021 10:23:05 -0400 Subject: [PATCH 13/61] Convert over RandomTeleport --- .../com/earth2me/essentials/RandomTeleport.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/RandomTeleport.java b/Essentials/src/main/java/com/earth2me/essentials/RandomTeleport.java index d9e92885896..d830a1bf28f 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/RandomTeleport.java +++ b/Essentials/src/main/java/com/earth2me/essentials/RandomTeleport.java @@ -1,5 +1,6 @@ package com.earth2me.essentials; +import com.earth2me.essentials.config.EssentialsConfiguration; import com.earth2me.essentials.utils.LocationUtil; import com.earth2me.essentials.utils.VersionUtil; import io.papermc.lib.PaperLib; @@ -21,15 +22,13 @@ public class RandomTeleport implements IConf { private static final Random RANDOM = new Random(); private static final int HIGHEST_BLOCK_Y_OFFSET = VersionUtil.getServerBukkitVersion().isHigherThanOrEqualTo(VersionUtil.v1_15_R01) ? 1 : 0; private final IEssentials essentials; - private final EssentialsConf config; + private final EssentialsConfiguration config; private final ConcurrentLinkedQueue cachedLocations = new ConcurrentLinkedQueue<>(); public RandomTeleport(final IEssentials essentials) { this.essentials = essentials; - final File file = new File(essentials.getDataFolder(), "tpr.yml"); - config = new EssentialsConf(file); - config.setTemplateName("/tpr.yml"); - config.options().copyHeader(true); + config = new EssentialsConfiguration(new File(essentials.getDataFolder(), "tpr.yml"), "/tpr.yml", + "Configuration for the random teleport command.\nSome settings may be defaulted, and can be changed via the /settpr command in-game."); reloadConfig(); } @@ -41,7 +40,7 @@ public void reloadConfig() { public Location getCenter() { try { - final Location center = config.getLocation("center", essentials.getServer()); + final Location center = config.getLocation("center"); if (center != null) { return center; } @@ -77,7 +76,7 @@ public void setMaxRange(final double maxRange) { } public Set getExcludedBiomes() { - final List biomeNames = config.getStringList("excluded-biomes"); + final List biomeNames = config.getList("excluded-biomes", String.class); final Set excludedBiomes = new HashSet<>(); for (final String biomeName : biomeNames) { try { From 860cf2f7d804ba5e100ce0ad2c5008124ba781ad Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 20 Mar 2021 11:16:08 -0400 Subject: [PATCH 14/61] Add better support for null (root) paths --- .../config/EssentialsConfiguration.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index 761f630ce1f..c3573d297c7 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -65,7 +65,12 @@ public CommentedConfigurationNode getRootNode() { return configurationNode; } - public void setProperty(final String path, final Location location) { + public File getFile() { + return configFile; + } + + public void setProperty(String path, final Location location) { + path = path == null ? "" : path; //noinspection ConstantConditions setInternal(path + ".world", location.getWorld().getName()); setInternal(path + ".x", location.getX()); @@ -76,7 +81,8 @@ public void setProperty(final String path, final Location location) { } public Location getLocation(final String path) throws InvalidWorldException { - final String worldName = getString(path + ".world", null); + final CommentedConfigurationNode node = path == null ? getRootNode() : getSection(path); + final String worldName = node.node("world").getString(); if (worldName == null || worldName.isEmpty()) { return null; } @@ -85,8 +91,8 @@ public Location getLocation(final String path) throws InvalidWorldException { if (world == null) { throw new InvalidWorldException(worldName); } - return new Location(world, getDouble(path + ".x", 0), getDouble(path + ".y", 0), - getDouble(path + ".z", 0), getFloat(path + ".yaw", 0), getFloat(path + ".pitch", 0)); + return new Location(world, node.node("x").getDouble(0), node.node("y").getDouble(0), + node.node("z").getDouble(0), node.node("yaw").getFloat(0), node.node("pitch").getFloat(0)); } public Map getLocationSectionMap(final String path) { @@ -286,7 +292,8 @@ public boolean hasProperty(final String path) { } public Object[] toSplitRoot(String node) { - return node.split("\\."); + node = node.startsWith(".") ? node.substring(1) : node; + return node.contains(".") ? node.split("\\.") : new Object[]{node}; } public synchronized void load() { @@ -331,7 +338,7 @@ public synchronized void load() { /** * Begins a transaction. - * + *

* A transaction informs Essentials to pause the saving of data. This is should be used when * bulk operations are being done and data shouldn't be saved until after the transaction has * been completed. From 9f0ac9cb0a235c8a63f1f395197e41654b3a9717 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 20 Mar 2021 11:19:55 -0400 Subject: [PATCH 15/61] Convert over Warps --- .../java/com/earth2me/essentials/Warps.java | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/Warps.java b/Essentials/src/main/java/com/earth2me/essentials/Warps.java index 828c3cfaae8..c163d551058 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Warps.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Warps.java @@ -1,6 +1,7 @@ package com.earth2me.essentials; import com.earth2me.essentials.commands.WarpNotFoundException; +import com.earth2me.essentials.config.EssentialsConfiguration; import com.earth2me.essentials.utils.StringUtil; import net.ess3.api.InvalidNameException; import net.ess3.api.InvalidWorldException; @@ -8,7 +9,6 @@ import org.bukkit.Server; import java.io.File; -import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -23,7 +23,7 @@ public class Warps implements IConf, net.ess3.api.IWarps { private static final Logger logger = Logger.getLogger("Essentials"); - private final Map warpPoints = new HashMap<>(); + private final Map warpPoints = new HashMap<>(); private final File warpsFolder; private final Server server; @@ -53,11 +53,11 @@ public Collection getList() { @Override public Location getWarp(final String warp) throws WarpNotFoundException, InvalidWorldException { - final EssentialsConf conf = warpPoints.get(new StringIgnoreCase(warp)); + final EssentialsConfiguration conf = warpPoints.get(new StringIgnoreCase(warp)); if (conf == null) { throw new WarpNotFoundException(); } - return conf.getLocation(null, server); + return conf.getLocation(null); } @Override @@ -68,34 +68,33 @@ public void setWarp(final String name, final Location loc) throws Exception { @Override public void setWarp(final IUser user, final String name, final Location loc) throws Exception { final String filename = StringUtil.sanitizeFileName(name); - EssentialsConf conf = warpPoints.get(new StringIgnoreCase(name)); + EssentialsConfiguration conf = warpPoints.get(new StringIgnoreCase(name)); if (conf == null) { final File confFile = new File(warpsFolder, filename + ".yml"); if (confFile.exists()) { throw new Exception(tl("similarWarpExist")); } - conf = new EssentialsConf(confFile); + conf = new EssentialsConfiguration(confFile); + conf.load(); warpPoints.put(new StringIgnoreCase(name), conf); } conf.setProperty(null, loc); conf.setProperty("name", name); - if (user != null) conf.setProperty("lastowner", user.getBase().getUniqueId().toString()); - try { - conf.saveWithError(); - } catch (final IOException ex) { - throw new IOException(tl("invalidWarpName")); + if (user != null) { + conf.setProperty("lastowner", user.getBase().getUniqueId().toString()); } + conf.save(); } @Override public UUID getLastOwner(final String warp) throws WarpNotFoundException { - final EssentialsConf conf = warpPoints.get(new StringIgnoreCase(warp)); + final EssentialsConfiguration conf = warpPoints.get(new StringIgnoreCase(warp)); if (conf == null) { throw new WarpNotFoundException(); } UUID uuid = null; try { - uuid = UUID.fromString(conf.getString("lastowner")); + uuid = UUID.fromString(conf.getString("lastowner", null)); } catch (final Exception ignored) { } return uuid; @@ -103,7 +102,7 @@ public UUID getLastOwner(final String warp) throws WarpNotFoundException { @Override public void removeWarp(final String name) throws Exception { - final EssentialsConf conf = warpPoints.get(new StringIgnoreCase(name)); + final EssentialsConfiguration conf = warpPoints.get(new StringIgnoreCase(name)); if (conf == null) { throw new Exception(tl("warpNotExist")); } @@ -122,9 +121,9 @@ public final void reloadConfig() { final String filename = listOfFile.getName(); if (listOfFile.isFile() && filename.endsWith(".yml")) { try { - final EssentialsConf conf = new EssentialsConf(listOfFile); + final EssentialsConfiguration conf = new EssentialsConfiguration(listOfFile); conf.load(); - final String name = conf.getString("name"); + final String name = conf.getString("name", null); if (name != null) { warpPoints.put(new StringIgnoreCase(name), conf); } From de7a529588a50989c81aa1206f96af0e3ed09f6c Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 20 Mar 2021 11:21:37 -0400 Subject: [PATCH 16/61] Remove missed use of EssentialsConf in Settings --- Essentials/src/main/java/com/earth2me/essentials/Settings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/Settings.java b/Essentials/src/main/java/com/earth2me/essentials/Settings.java index 8b4a30a1428..b88c6a4e6bf 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Settings.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Settings.java @@ -352,7 +352,7 @@ private CommentedConfigurationNode _getCommandCosts() { public BigDecimal getCommandCost(String name) { name = name.replace('.', '_').replace('/', '_'); if (commandCosts != null) { - return EssentialsConf.toBigDecimal(commandCosts.getString(name), BigDecimal.ZERO); + return ConfigurateUtil.toBigDecimal(commandCosts.getString(name), BigDecimal.ZERO); } return BigDecimal.ZERO; } From 754bc241ca0c3a1ecca310e6775b1df7d9023bc0 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 20 Mar 2021 11:23:21 -0400 Subject: [PATCH 17/61] Convert over Worth --- .../main/java/com/earth2me/essentials/Worth.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/Worth.java b/Essentials/src/main/java/com/earth2me/essentials/Worth.java index 9beea191872..dc9e6405830 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Worth.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Worth.java @@ -1,10 +1,12 @@ package com.earth2me.essentials; import com.earth2me.essentials.commands.NotEnoughArgumentsException; +import com.earth2me.essentials.config.ConfigurateUtil; +import com.earth2me.essentials.config.EssentialsConfiguration; import com.earth2me.essentials.utils.VersionUtil; import org.bukkit.Material; -import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; +import org.spongepowered.configurate.CommentedConfigurationNode; import java.io.File; import java.math.BigDecimal; @@ -13,11 +15,10 @@ import static com.earth2me.essentials.I18n.tl; public class Worth implements IConf { - private final EssentialsConf config; + private final EssentialsConfiguration config; public Worth(final File dataFolder) { - config = new EssentialsConf(new File(dataFolder, "worth.yml")); - config.setTemplateName("/worth.yml"); + config = new EssentialsConfiguration(new File(dataFolder, "worth.yml"), "/worth.yml"); config.load(); } @@ -39,8 +40,8 @@ public BigDecimal getPrice(final IEssentials ess, final ItemStack itemStack) { // Check for matches with data value 0 if (result.signum() < 0) { - final ConfigurationSection itemNameMatch = config.getConfigurationSection("worth." + itemname); - if (itemNameMatch != null && itemNameMatch.getKeys(false).size() == 1) { + final CommentedConfigurationNode itemNameMatch = config.getSection("worth." + itemname); + if (itemNameMatch != null && ConfigurateUtil.getKeys(itemNameMatch).size() == 1) { result = config.getBigDecimal("worth." + itemname + ".0", BigDecimal.ONE.negate()); } } From 9039947cca374d2c822e7d478374998cbb7b5bb4 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 20 Mar 2021 11:33:33 -0400 Subject: [PATCH 18/61] Convert over CustomItemResolver --- .../essentials/items/CustomItemResolver.java | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/items/CustomItemResolver.java b/Essentials/src/main/java/com/earth2me/essentials/items/CustomItemResolver.java index 18fbdfb0545..6e49feb1904 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/items/CustomItemResolver.java +++ b/Essentials/src/main/java/com/earth2me/essentials/items/CustomItemResolver.java @@ -1,10 +1,10 @@ package com.earth2me.essentials.items; import com.earth2me.essentials.Essentials; -import com.earth2me.essentials.EssentialsConf; import com.earth2me.essentials.IConf; +import com.earth2me.essentials.config.ConfigurateUtil; +import com.earth2me.essentials.config.EssentialsConfiguration; import net.ess3.api.IItemDb; -import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; import java.io.File; @@ -15,14 +15,13 @@ import java.util.Map; public class CustomItemResolver implements IItemDb.ItemResolver, IConf { - private final EssentialsConf config; + private final EssentialsConfiguration config; private final Essentials ess; private final HashMap map = new HashMap<>(); public CustomItemResolver(final Essentials ess) { - config = new EssentialsConf(new File(ess.getDataFolder(), "custom_items.yml")); + config = new EssentialsConfiguration(new File(ess.getDataFolder(), "custom_items.yml"), "/custom_items.yml"); this.ess = ess; - config.setTemplateName("/custom_items.yml"); } @Override @@ -57,18 +56,20 @@ public void reloadConfig() { map.clear(); config.load(); - final ConfigurationSection section = config.getConfigurationSection("aliases"); - if (section == null || section.getKeys(false).isEmpty()) { + final Map section = ConfigurateUtil.getRawMap(config.getSection("aliases")); + if (section.isEmpty()) { ess.getLogger().warning("No aliases found in custom_items.yml."); return; } - for (final String alias : section.getKeys(false)) { - if (!section.isString(alias)) continue; - final String target = section.getString(alias); + for (final Map.Entry alias : section.entrySet()) { + if (!(alias.getValue() instanceof String)) { + continue; + } + final String target = (String) alias.getValue(); - if (target != null && !section.contains(target) && existsInItemDb(target)) { - map.put(alias, target); + if (existsInItemDb(target)) { + map.put(alias.getKey(), target); } } } @@ -89,7 +90,7 @@ public void removeAlias(final String alias) { } private void save() { - config.setProperty("aliases", map); + config.setRaw("aliases", map); config.save(); } From ae882ce9c7f3dd8ea0cc68d0cb2f9e226cfc058f Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 20 Mar 2021 11:41:43 -0400 Subject: [PATCH 19/61] Add constructor param for resource class --- .../essentials/config/EssentialsConfiguration.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index c3573d297c7..5d9e0400584 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -40,7 +40,7 @@ public class EssentialsConfiguration { private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor(); private final AtomicInteger pendingWrites = new AtomicInteger(0); private final AtomicBoolean transaction = new AtomicBoolean(false); - protected Class resourceClass = EssentialsConfiguration.class; + private Class resourceClass = EssentialsConfiguration.class; private final File configFile; private final YamlConfigurationLoader loader; private final String templateName; @@ -51,7 +51,12 @@ public EssentialsConfiguration(final File configFile) { } public EssentialsConfiguration(final File configFile, final String templateName) { - this(configFile, templateName, null); + this(configFile, templateName, (String) null); + } + + public EssentialsConfiguration(final File configFile, final String templateName, final Class resourceClass) { + this(configFile, templateName, (String) null); + this.resourceClass = resourceClass; } public EssentialsConfiguration(final File configFile, final String templateName, final String header) { From 3ef22013fd27e1d6808f968c4c054844e91cdaba Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 20 Mar 2021 11:41:48 -0400 Subject: [PATCH 20/61] Convert over EssentialsGeoIPPlayerListener --- .../geoip/EssentialsGeoIPPlayerListener.java | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/EssentialsGeoIP/src/main/java/com/earth2me/essentials/geoip/EssentialsGeoIPPlayerListener.java b/EssentialsGeoIP/src/main/java/com/earth2me/essentials/geoip/EssentialsGeoIPPlayerListener.java index 806b138d505..9bdbc30bdc5 100644 --- a/EssentialsGeoIP/src/main/java/com/earth2me/essentials/geoip/EssentialsGeoIPPlayerListener.java +++ b/EssentialsGeoIP/src/main/java/com/earth2me/essentials/geoip/EssentialsGeoIPPlayerListener.java @@ -1,8 +1,8 @@ package com.earth2me.essentials.geoip; -import com.earth2me.essentials.EssentialsConf; import com.earth2me.essentials.IConf; import com.earth2me.essentials.User; +import com.earth2me.essentials.config.EssentialsConfiguration; import com.ice.tar.TarEntry; import com.ice.tar.TarInputStream; import com.maxmind.geoip2.DatabaseReader; @@ -39,7 +39,7 @@ public class EssentialsGeoIPPlayerListener implements Listener, IConf { private static final Logger logger = Logger.getLogger("EssentialsGeoIP"); private final File dataFolder; - private final EssentialsConf config; + private final EssentialsConfiguration config; private final transient IEssentials ess; private DatabaseReader mmreader = null; // initialize maxmind geoip2 reader private File databaseFile; @@ -47,8 +47,7 @@ public class EssentialsGeoIPPlayerListener implements Listener, IConf { EssentialsGeoIPPlayerListener(final File dataFolder, final IEssentials ess) { this.ess = ess; this.dataFolder = dataFolder; - this.config = new EssentialsConf(new File(dataFolder, "config.yml")); - config.setTemplateName("/config.yml", EssentialsGeoIP.class); + this.config = new EssentialsConfiguration(new File(dataFolder, "config.yml"), "/config.yml", EssentialsGeoIP.class); reloadConfig(); } @@ -130,13 +129,13 @@ public final void reloadConfig() { config.load(); // detect and update the old config.yml. migrate from legacy GeoIP to GeoIP2. - if (!config.isSet("enable-locale")) { - config.set("database.download-url", "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&license_key={LICENSEKEY}&suffix=tar.gz"); - config.set("database.download-url-city", "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key={LICENSEKEY}&suffix=tar.gz"); - config.set("database.license-key", ""); - config.set("database.update.enable", true); - config.set("database.update.by-every-x-days", 30); - config.set("enable-locale", true); + if (!config.hasProperty("enable-locale")) { + config.setProperty("database.download-url", "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&license_key={LICENSEKEY}&suffix=tar.gz"); + config.setProperty("database.download-url-city", "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key={LICENSEKEY}&suffix=tar.gz"); + config.setProperty("database.license-key", ""); + config.setProperty("database.update.enable", true); + config.setProperty("database.update.by-every-x-days", 30); + config.setProperty("enable-locale", true); config.save(); // delete old GeoIP.dat fiiles final File oldDatFile = new File(dataFolder, "GeoIP.dat"); @@ -166,7 +165,7 @@ public final void reloadConfig() { } try { // locale setting - if (config.getBoolean("enable-locale")) { + if (config.getBoolean("enable-locale", false)) { // Get geolocation based on Essentials' locale. If the locale is not avaliable, use "en". String locale = ess.getI18n().getCurrentLocale().toString().replace('_', '-'); // This fixes an inconsistency where Essentials uses "zh" but MaxMind expects "zh-CN". @@ -186,9 +185,9 @@ private void downloadDatabase() { try { String url; if (config.getBoolean("database.show-cities", false)) { - url = config.getString("database.download-url-city"); + url = config.getString("database.download-url-city", null); } else { - url = config.getString("database.download-url"); + url = config.getString("database.download-url", null); } if (url == null || url.isEmpty()) { logger.log(Level.SEVERE, tl("geoIpUrlEmpty")); From d69590365fe9103e7b50e1dbd057fc1f714bd3fe Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 20 Mar 2021 11:44:42 -0400 Subject: [PATCH 21/61] Convert over UserManager --- .../com/earth2me/essentials/xmpp/UserManager.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/EssentialsXMPP/src/main/java/com/earth2me/essentials/xmpp/UserManager.java b/EssentialsXMPP/src/main/java/com/earth2me/essentials/xmpp/UserManager.java index 64d5541db64..73f6ba0f5d9 100644 --- a/EssentialsXMPP/src/main/java/com/earth2me/essentials/xmpp/UserManager.java +++ b/EssentialsXMPP/src/main/java/com/earth2me/essentials/xmpp/UserManager.java @@ -1,7 +1,8 @@ package com.earth2me.essentials.xmpp; -import com.earth2me.essentials.EssentialsConf; import com.earth2me.essentials.IConf; +import com.earth2me.essentials.config.ConfigurateUtil; +import com.earth2me.essentials.config.EssentialsConfiguration; import java.io.File; import java.util.ArrayList; @@ -15,11 +16,11 @@ public class UserManager implements IConf { private static final String ADDRESS = "address"; private static final String SPY = "spy"; - private final transient EssentialsConf users; + private final transient EssentialsConfiguration users; private final transient List spyusers = Collections.synchronizedList(new ArrayList<>()); UserManager(final File folder) { - users = new EssentialsConf(new File(folder, "users.yml")); + users = new EssentialsConfiguration(new File(folder, "users.yml")); reloadConfig(); } @@ -36,7 +37,7 @@ final String getAddress(final String username) { } final String getUserByAddress(final String search) { - final Set usernames = users.getKeys(false); + final Set usernames = ConfigurateUtil.getKeys(users.getRootNode()); for (final String username : usernames) { final String address = users.getString(username + "." + ADDRESS, null); if (search.equalsIgnoreCase(address)) { @@ -58,7 +59,7 @@ private void setUser(final String username, final String address, final boolean final Map userdata = new HashMap<>(); userdata.put(ADDRESS, address); userdata.put(SPY, spy); - users.setProperty(username, userdata); + users.setRaw(username, userdata); users.save(); reloadConfig(); } @@ -67,7 +68,7 @@ private void setUser(final String username, final String address, final boolean public final void reloadConfig() { users.load(); spyusers.clear(); - final Set keys = users.getKeys(false); + final Set keys = ConfigurateUtil.getKeys(users.getRootNode()); for (final String key : keys) { if (isSpy(key)) { final String address = getAddress(key); From fefa826c088fcb7bb39cc2fba57f9230d1c41e9f Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 20 Mar 2021 11:45:56 -0400 Subject: [PATCH 22/61] Convert over XMPPManager --- .../earth2me/essentials/xmpp/XMPPManager.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/EssentialsXMPP/src/main/java/com/earth2me/essentials/xmpp/XMPPManager.java b/EssentialsXMPP/src/main/java/com/earth2me/essentials/xmpp/XMPPManager.java index ae1cb4d1658..d8dc4c03515 100644 --- a/EssentialsXMPP/src/main/java/com/earth2me/essentials/xmpp/XMPPManager.java +++ b/EssentialsXMPP/src/main/java/com/earth2me/essentials/xmpp/XMPPManager.java @@ -1,8 +1,8 @@ package com.earth2me.essentials.xmpp; import com.earth2me.essentials.Console; -import com.earth2me.essentials.EssentialsConf; import com.earth2me.essentials.IConf; +import com.earth2me.essentials.config.EssentialsConfiguration; import com.earth2me.essentials.utils.FormatUtil; import net.ess3.api.IUser; import org.bukkit.entity.Player; @@ -37,7 +37,7 @@ public class XMPPManager extends Handler implements MessageListener, ChatManagerListener, IConf { private static final Logger logger = Logger.getLogger("EssentialsXMPP"); private static final SimpleFormatter formatter = new SimpleFormatter(); - private final transient EssentialsConf config; + private final transient EssentialsConfiguration config; private final transient Map chats = Collections.synchronizedMap(new HashMap<>()); private final transient Set logrecords = Collections.synchronizedSet(new HashSet<>()); private final transient IEssentialsXMPP parent; @@ -52,8 +52,7 @@ public class XMPPManager extends Handler implements MessageListener, ChatManager XMPPManager(final IEssentialsXMPP parent) { super(); this.parent = parent; - config = new EssentialsConf(new File(parent.getDataFolder(), "config.yml")); - config.setTemplateName("/config.yml", EssentialsXMPP.class); + config = new EssentialsConfiguration(new File(parent.getDataFolder(), "config.yml"), "/config.yml", EssentialsXMPP.class); reloadConfig(); } @@ -102,15 +101,15 @@ public void processMessage(final Chat chat, final Message msg) { } private boolean connect() { - final String server = config.getString("xmpp.server"); + final String server = config.getString("xmpp.server", null); if (server == null || server.equals("example.com")) { logger.log(Level.WARNING, tl("xmppNotConfigured")); return false; } final int port = config.getInt("xmpp.port", 5222); final String serviceName = config.getString("xmpp.servicename", server); - final String xmppuser = config.getString("xmpp.user"); - final String password = config.getString("xmpp.password"); + final String xmppuser = config.getString("xmpp.user", null); + final String password = config.getString("xmpp.password", null); final boolean requireTLS = config.getBoolean("xmpp.require-server-tls", false); final ConnectionConfiguration connConf = new ConnectionConfiguration(server, port, serviceName); final String stringBuilder = "Connecting to xmpp server " + server + ":" + port + " as user " + xmppuser + "."; @@ -207,7 +206,7 @@ public final void reloadConfig() { } if (config.getBoolean("log-enabled", false)) { logger.addHandler(this); - logUsers = config.getStringList("log-users"); + logUsers = config.getList("log-users", String.class); final String level = config.getString("log-level", "info"); try { logLevel = Level.parse(level.toUpperCase(Locale.ENGLISH)); @@ -328,7 +327,7 @@ private void sendPrivateMessage(final Chat chat, final String message) { } private void sendCommand(final Chat chat, final String message) { - if (config.getStringList("op-users").contains(StringUtils.parseBareAddress(chat.getParticipant()))) { + if (config.getList("op-users", String.class).contains(StringUtils.parseBareAddress(chat.getParticipant()))) { parent.getServer().getScheduler().runTask(parent, () -> { try { parent.getServer().dispatchCommand(Console.getInstance().getCommandSender(), message.substring(1)); @@ -348,7 +347,7 @@ private void disableChat(final String address) { } public boolean isConfigValid() { - final String server = config.getString("xmpp.server"); + final String server = config.getString("xmpp.server", null); return server != null && !server.equals("example.com"); } } From 7366c30a168e441a87b16493a1baa6d644a4c6d8 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 20 Mar 2021 12:40:38 -0400 Subject: [PATCH 23/61] Convert over UserData --- .../java/com/earth2me/essentials/IUser.java | 1 + .../com/earth2me/essentials/UserData.java | 114 +++++++++--------- .../essentials/config/ConfigurateUtil.java | 23 ++++ .../config/EssentialsConfiguration.java | 35 +++++- .../config/EssentialsUserConfiguration.java | 70 +++++++++++ 5 files changed, 177 insertions(+), 66 deletions(-) create mode 100644 Essentials/src/main/java/com/earth2me/essentials/config/EssentialsUserConfiguration.java diff --git a/Essentials/src/main/java/com/earth2me/essentials/IUser.java b/Essentials/src/main/java/com/earth2me/essentials/IUser.java index 6ae20d3ee7c..1b113229238 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/IUser.java +++ b/Essentials/src/main/java/com/earth2me/essentials/IUser.java @@ -160,6 +160,7 @@ public interface IUser { void setIgnoreMsg(boolean ignoreMsg); + @Deprecated void setConfigProperty(String node, Object object); Set getConfigKeys(); diff --git a/Essentials/src/main/java/com/earth2me/essentials/UserData.java b/Essentials/src/main/java/com/earth2me/essentials/UserData.java index 26b4d5c71d0..4674e2d67c5 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/UserData.java +++ b/Essentials/src/main/java/com/earth2me/essentials/UserData.java @@ -1,5 +1,7 @@ package com.earth2me.essentials; +import com.earth2me.essentials.config.ConfigurateUtil; +import com.earth2me.essentials.config.EssentialsUserConfiguration; import com.earth2me.essentials.utils.NumberUtil; import com.earth2me.essentials.utils.StringUtil; import com.google.common.collect.ImmutableMap; @@ -8,9 +10,9 @@ import net.ess3.api.MaxMoneyException; import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.spongepowered.configurate.CommentedConfigurationNode; import java.io.File; import java.math.BigDecimal; @@ -32,7 +34,7 @@ public abstract class UserData extends PlayerExtension implements IConf { protected final transient IEssentials ess; - private final EssentialsUserConf config; + private final EssentialsUserConfiguration config; private BigDecimal money; private Map homes; private String nickname; @@ -88,20 +90,20 @@ protected UserData(final Player base, final IEssentials ess) { filename = base.getName(); } - config = new EssentialsUserConf(base.getName(), base.getUniqueId(), new File(folder, filename + ".yml")); + config = new EssentialsUserConfiguration(base.getName(), base.getUniqueId(), new File(folder, filename + ".yml")); reloadConfig(); } public final void reset() { - config.forceSave(); + config.blockingSave(); config.getFile().delete(); - if (config.username != null) { - ess.getUserMap().removeUser(config.username); + if (config.getUsername() != null) { + ess.getUserMap().removeUser(config.getUsername()); } } public final void cleanup() { - config.cleanup(); + config.blockingSave(); } @Override @@ -190,8 +192,9 @@ public void setMoney(final BigDecimal value, final boolean throwError) throws Ma } private Map _getHomes() { - if (config.isConfigurationSection("homes")) { - return config.getConfigurationSection("homes").getValues(false); + final CommentedConfigurationNode section = config.getSection("homes"); + if (section != null) { + return ConfigurateUtil.getRawMap(section); } return new HashMap<>(); } @@ -208,7 +211,7 @@ private String getHomeName(String search) { public Location getHome(final String name) throws Exception { final String search = getHomeName(name); - return config.getLocation("homes." + search, this.getBase().getServer()); + return config.getLocation("homes." + search); } public Location getHome(final Location world) { @@ -218,13 +221,13 @@ public Location getHome(final Location world) { } Location loc; for (final String home : getHomes()) { - loc = config.getLocation("homes." + home, this.getBase().getServer()); + loc = config.getLocation("homes." + home); if (world.getWorld() == loc.getWorld()) { return loc; } } - loc = config.getLocation("homes." + getHomes().get(0), this.getBase().getServer()); + loc = config.getLocation("homes." + getHomes().get(0)); return loc; } catch (final InvalidWorldException ex) { return null; @@ -266,7 +269,7 @@ public boolean hasHome(final String name) { } public String _getNickname() { - return config.getString("nickname"); + return config.getString("nickname", null); } public String getNickname() { @@ -281,7 +284,7 @@ public void setNickname(final String nick) { private Set _getUnlimited() { final Set retlist = new HashSet<>(); - final List configList = config.getStringList("unlimited"); + final List configList = config.getList("unlimited", String.class); for (final String s : configList) { final Material mat = Material.matchMaterial(s); if (mat != null) { @@ -319,15 +322,16 @@ private void applyUnlimited() { } private Map _getPowertools() { - if (config.isConfigurationSection("powertools")) { - return config.getConfigurationSection("powertools").getValues(false); + final CommentedConfigurationNode node = config.getSection("powertools"); + if (node != null) { + return ConfigurateUtil.getRawMap(node); } return new HashMap<>(); } public void clearAllPowertools() { powertools.clear(); - config.setProperty("powertools", powertools); + config.setRaw("powertools", powertools); config.save(); } @@ -347,7 +351,7 @@ public void setPowertool(final ItemStack stack, final List commandList) } else { powertools.put(stack.getType().name().toLowerCase(Locale.ENGLISH), commandList); } - config.setProperty("powertools", powertools); + config.setRaw("powertools", powertools); config.save(); } @@ -357,7 +361,7 @@ public boolean hasPowerTools() { private Location _getLastLocation() { try { - return config.getLocation("lastlocation", this.getBase().getServer()); + return config.getLocation("lastlocation"); } catch (final InvalidWorldException e) { return null; } @@ -378,7 +382,7 @@ public void setLastLocation(final Location loc) { private Location _getLogoutLocation() { try { - return config.getLocation("logoutlocation", this.getBase().getServer()); + return config.getLocation("logoutlocation"); } catch (final InvalidWorldException e) { return null; } @@ -426,7 +430,7 @@ public void setLastHealTimestamp(final long time) { } private String _getJail() { - return config.getString("jail"); + return config.getString("jail", null); } public String getJail() { @@ -445,7 +449,7 @@ public void setJail(final String jail) { } private List _getMails() { - return config.getStringList("mail"); + return config.getList("mail", String.class); } public List getMails() { @@ -498,7 +502,7 @@ public void setAutoTeleportEnabled(final boolean set) { public List _getIgnoredPlayers() { final List players = new ArrayList<>(); - for (final String uuid : config.getStringList("ignore")) { + for (final String uuid : config.getList("ignore", String.class)) { try { players.add(UUID.fromString(uuid)); } catch (final IllegalArgumentException ignored) { @@ -593,7 +597,7 @@ public void setMuted(final boolean set) { } public String _getMuteReason() { - return config.getString("muteReason"); + return config.getString("muteReason", null); } public String getMuteReason() { @@ -742,7 +746,7 @@ public void _setAfk(final boolean set) { } private String _getGeoLocation() { - return config.getString("geolocation"); + return config.getString("geolocation", null); } public String getGeoLocation() { @@ -824,15 +828,14 @@ private boolean _arePowerToolsEnabled() { } private Map _getKitTimestamps() { - - if (config.isConfigurationSection("timestamps.kits")) { - final ConfigurationSection section = config.getConfigurationSection("timestamps.kits"); + final Map node = ConfigurateUtil.getRawMap(config.getSection("timestamps.kits")); + if (!node.isEmpty()) { final Map timestamps = new HashMap<>(); - for (final String command : section.getKeys(false)) { - if (section.isLong(command)) { - timestamps.put(command.toLowerCase(Locale.ENGLISH), section.getLong(command)); - } else if (section.isInt(command)) { - timestamps.put(command.toLowerCase(Locale.ENGLISH), (long) section.getInt(command)); + for (final Map.Entry entry : node.entrySet()) { + if (entry.getValue() instanceof Long) { + timestamps.put(entry.getKey().toLowerCase(Locale.ENGLISH), (Long) entry.getValue()); + } else if (entry.getValue() instanceof Integer) { + timestamps.put(entry.getKey().toLowerCase(Locale.ENGLISH), Long.valueOf((Integer) entry.getValue())); } } return timestamps; @@ -851,55 +854,42 @@ public long getKitTimestamp(String name) { public void setKitTimestamp(String name, final long time) { name = name.replace('.', '_').replace('/', '_').toLowerCase(Locale.ENGLISH); kitTimestamps.put(name, time); - config.setProperty("timestamps.kits", kitTimestamps); - config.save(); - } - - public void setConfigProperty(String node, final Object object) { - final String prefix = "info."; - node = prefix + node; - if (object instanceof Map) { - config.setProperty(node, (Map) object); - } else if (object instanceof List) { - config.setProperty(node, (List) object); - } else if (object instanceof Location) { - config.setProperty(node, (Location) object); - } else if (object instanceof ItemStack) { - config.setProperty(node, (ItemStack) object); - } else { - config.setProperty(node, object); - } + config.setRaw("timestamps.kits", kitTimestamps); config.save(); } public Set getConfigKeys() { - if (config.isConfigurationSection("info")) { - return config.getConfigurationSection("info").getKeys(true); + final Set keys = ConfigurateUtil.getKeys(config.getSection("info")); + if (!keys.isEmpty()) { + return keys; } return new HashSet<>(); } public Map getConfigMap() { - if (config.isConfigurationSection("info")) { - return config.getConfigurationSection("info").getValues(true); + final Map node = ConfigurateUtil.getRawMap(config.getSection("info")); + if (!node.isEmpty()) { + return node; } return new HashMap<>(); } public Map getConfigMap(final String node) { - if (config.isConfigurationSection("info." + node)) { - return config.getConfigurationSection("info." + node).getValues(true); + final Map nodeMap = ConfigurateUtil.getRawMap(config.getSection("info." + node)); + if (!nodeMap.isEmpty()) { + return nodeMap; } return new HashMap<>(); } private Map _getCommandCooldowns() { - if (!config.contains("timestamps.command-cooldowns")) { + final CommentedConfigurationNode node = config.getSection("timestamps.command-cooldowns"); + if (node == null) { return null; } // See saveCommandCooldowns() for deserialization explanation - final List> section = config.getMapList("timestamps.command-cooldowns"); + final List> section = ConfigurateUtil.getMapList(node); final HashMap result = new HashMap<>(); for (final Map map : section) { final Pattern pattern = Pattern.compile(map.get("pattern").toString()); @@ -1044,7 +1034,7 @@ public void setBaltopExemptCache(boolean baltopExempt) { } public UUID getConfigUUID() { - return config.uuid; + return config.getUuid(); } public void save() { @@ -1058,4 +1048,8 @@ public void startTransaction() { public void stopTransaction() { config.stopTransaction(); } + + public void setConfigProperty(String node, Object object) { + throw new UnsupportedOperationException("This method is unused in EssentialsX and is scheduled for removal. Please use another method!"); + } } diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/ConfigurateUtil.java b/Essentials/src/main/java/com/earth2me/essentials/config/ConfigurateUtil.java index aef1231dbc9..8daaec77478 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/ConfigurateUtil.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/ConfigurateUtil.java @@ -1,12 +1,15 @@ package com.earth2me.essentials.config; import org.spongepowered.configurate.CommentedConfigurationNode; +import org.spongepowered.configurate.serialize.SerializationException; import java.math.BigDecimal; import java.math.MathContext; +import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; import java.util.Set; @@ -50,6 +53,26 @@ public static Map getRawMap(final CommentedConfigurationNode nod return map; } + public static List> getMapList(final CommentedConfigurationNode node) { + List list = null; + try { + list = node.getList(Object.class); + } catch (SerializationException ignored) { + } + final List> result = new ArrayList<>(); + + if (list == null) { + return result; + } + + for (Object object : list) { + if (object instanceof Map) { + result.add((Map) object); + } + } + return result; + } + public static BigDecimal toBigDecimal(final String input, final BigDecimal def) { if (input == null || input.isEmpty()) { return def; diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index 5d9e0400584..7452ce9cf67 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -41,7 +41,7 @@ public class EssentialsConfiguration { private final AtomicInteger pendingWrites = new AtomicInteger(0); private final AtomicBoolean transaction = new AtomicBoolean(false); private Class resourceClass = EssentialsConfiguration.class; - private final File configFile; + protected final File configFile; private final YamlConfigurationLoader loader; private final String templateName; private CommentedConfigurationNode configurationNode; @@ -314,11 +314,18 @@ public synchronized void load() { } } - if (!configFile.exists() && templateName != null) { - try (final InputStream is = resourceClass.getResourceAsStream(templateName)) { - Files.copy(is, configFile.toPath()); - } catch (IOException e) { - LOGGER.log(Level.SEVERE, tl("failedToWriteConfig", configFile.toString()), e); + if (!configFile.exists()) { + if (legacyFileExists()) { + convertLegacyFile(); + } else if (altFileExists()) { + convertAltFile(); + } else if (templateName != null) { + try (final InputStream is = resourceClass.getResourceAsStream(templateName)) { + LOGGER.log(Level.INFO, tl("creatingConfigFromTemplate", configFile.toString())); + Files.copy(is, configFile.toPath()); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, tl("failedToWriteConfig", configFile.toString()), e); + } } } @@ -341,6 +348,22 @@ public synchronized void load() { } } + public boolean legacyFileExists() { + return false; + } + + public void convertLegacyFile() { + + } + + public boolean altFileExists() { + return false; + } + + public void convertAltFile() { + + } + /** * Begins a transaction. *

diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsUserConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsUserConfiguration.java new file mode 100644 index 00000000000..d3f5a668031 --- /dev/null +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsUserConfiguration.java @@ -0,0 +1,70 @@ +package com.earth2me.essentials.config; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; + +import java.io.File; +import java.io.IOException; +import java.util.Locale; +import java.util.UUID; +import java.util.logging.Level; + +public class EssentialsUserConfiguration extends EssentialsConfiguration { + private final String username; + private final UUID uuid; + + public EssentialsUserConfiguration(final String username, final UUID uuid, final File configFile) { + super(configFile); + this.username = username; + this.uuid = uuid; + } + + public String getUsername() { + return username; + } + + public UUID getUuid() { + return uuid; + } + + @Override + public boolean legacyFileExists() { + return new File(configFile.getParentFile(), username + ".yml").exists(); + } + + @Override + public void convertLegacyFile() { + final File file = new File(configFile.getParentFile(), username + ".yml"); + try { + //noinspection UnstableApiUsage + Files.move(file, new File(configFile.getParentFile(), uuid + ".yml")); + } catch (final IOException ex) { + LOGGER.log(Level.WARNING, "Failed to migrate user: " + username, ex); + } + + setProperty("lastAccountName", username); + } + + private File getAltFile() { + final UUID fn = UUID.nameUUIDFromBytes(("OfflinePlayer:" + username.toLowerCase(Locale.ENGLISH)).getBytes(Charsets.UTF_8)); + return new File(configFile.getParentFile(), fn.toString() + ".yml"); + } + + @Override + public boolean altFileExists() { + if (username.equals(username.toLowerCase())) { + return false; + } + return getAltFile().exists(); + } + + @Override + public void convertAltFile() { + try { + //noinspection UnstableApiUsage + Files.move(getAltFile(), new File(configFile.getParentFile(), uuid + ".yml")); + } catch (final IOException ex) { + LOGGER.log(Level.WARNING, "Failed to migrate user: " + username, ex); + } + } +} From 3e2b7d8936f215545b49067b67d82e0c81b0b8d9 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 20 Mar 2021 12:44:15 -0400 Subject: [PATCH 24/61] Migrate over remaining uses of EssentialsUserConfiguration --- .../java/com/earth2me/essentials/EssentialsUpgrade.java | 5 +++-- .../src/main/java/com/earth2me/essentials/api/Economy.java | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java index 935c2177886..e09d747f9ad 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java @@ -2,6 +2,7 @@ import com.earth2me.essentials.config.ConfigurateUtil; import com.earth2me.essentials.config.EssentialsConfiguration; +import com.earth2me.essentials.config.EssentialsUserConfiguration; import com.earth2me.essentials.craftbukkit.BanLookup; import com.earth2me.essentials.utils.StringUtil; import com.google.common.base.Charsets; @@ -92,7 +93,7 @@ public static void uuidFileConvert(final IEssentials ess, final Boolean ignoreUF countFiles++; final String name = string.substring(0, string.length() - 4); - final EssentialsUserConf config; + final EssentialsUserConfiguration config; UUID uuid = null; try { uuid = UUID.fromString(name); @@ -130,7 +131,7 @@ public static void uuidFileConvert(final IEssentials ess, final Boolean ignoreUF if (uuid != null) { conf.blockingSave(); - config = new EssentialsUserConf(name, uuid, new File(userdir, uuid + ".yml")); + config = new EssentialsUserConfiguration(name, uuid, new File(userdir, uuid + ".yml")); config.convertLegacyFile(); ess.getUserMap().trackUUID(uuid, name, false); continue; diff --git a/Essentials/src/main/java/com/earth2me/essentials/api/Economy.java b/Essentials/src/main/java/com/earth2me/essentials/api/Economy.java index d1ce409017d..46721abca8b 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/api/Economy.java +++ b/Essentials/src/main/java/com/earth2me/essentials/api/Economy.java @@ -1,8 +1,8 @@ package com.earth2me.essentials.api; -import com.earth2me.essentials.EssentialsUserConf; import com.earth2me.essentials.Trade; import com.earth2me.essentials.User; +import com.earth2me.essentials.config.EssentialsUserConfiguration; import com.earth2me.essentials.utils.NumberUtil; import com.earth2me.essentials.utils.StringUtil; import com.google.common.base.Charsets; @@ -57,12 +57,12 @@ private static void createNPCFile(String name) { LOGGER.log(Level.SEVERE, MessageFormat.format(WARN_NPC_RECREATE_1, name, npcUUID.toString()), new RuntimeException()); LOGGER.log(Level.SEVERE, WARN_NPC_RECREATE_2); } - final EssentialsUserConf npcConfig = new EssentialsUserConf(name, npcUUID, npcFile); + final EssentialsUserConfiguration npcConfig = new EssentialsUserConfiguration(name, npcUUID, npcFile); npcConfig.load(); npcConfig.setProperty("npc", true); npcConfig.setProperty("lastAccountName", name); npcConfig.setProperty("money", ess.getSettings().getStartingBalance()); - npcConfig.forceSave(); + npcConfig.blockingSave(); ess.getUserMap().trackUUID(npcUUID, name, false); } From 9753eabf9725d0c3faadc0b4100265d38a6b77a3 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 20 Mar 2021 12:57:11 -0400 Subject: [PATCH 25/61] Fix NPE in EssentialsConfiguration#getLocation when section is null --- .../com/earth2me/essentials/config/EssentialsConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index 7452ce9cf67..f35db713c1e 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -87,7 +87,7 @@ public void setProperty(String path, final Location location) { public Location getLocation(final String path) throws InvalidWorldException { final CommentedConfigurationNode node = path == null ? getRootNode() : getSection(path); - final String worldName = node.node("world").getString(); + final String worldName = node == null ? null : node.node("world").getString(); if (worldName == null || worldName.isEmpty()) { return null; } From 186d4ec9937348d2edd4870c60fa6d0a8e84e71c Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 20 Mar 2021 15:00:38 -0400 Subject: [PATCH 26/61] Move relocated dependencies into common package --- Essentials/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Essentials/build.gradle b/Essentials/build.gradle index 79129e27942..c08f22befba 100644 --- a/Essentials/build.gradle +++ b/Essentials/build.gradle @@ -37,7 +37,7 @@ shadowJar { } relocate 'io.papermc.lib', 'com.earth2me.essentials.paperlib' relocate 'org.bstats.bukkit', 'com.earth2me.essentials.metrics' - relocate 'org.spongepowered.configurate', 'com.earth2me.essentials.configurate' - relocate 'org.yaml.snakeyaml', 'com.earth2me.essentials.snakeyaml' - relocate 'io.leangen.geantyref', 'com.earth2me.essentials.geantyref' + relocate 'org.spongepowered.configurate', 'com.earth2me.essentials.libs.configurate' + relocate 'org.yaml.snakeyaml', 'com.earth2me.essentials.libs.snakeyaml' + relocate 'io.leangen.geantyref', 'com.earth2me.essentials.libs.geantyref' } From 8796f2c66d25059448531511da0130af246560b5 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Tue, 30 Mar 2021 09:27:20 -0400 Subject: [PATCH 27/61] Fix auto teleport never being read from userdata --- Essentials/src/main/java/com/earth2me/essentials/UserData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/UserData.java b/Essentials/src/main/java/com/earth2me/essentials/UserData.java index 4674e2d67c5..acf15bfdf76 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/UserData.java +++ b/Essentials/src/main/java/com/earth2me/essentials/UserData.java @@ -59,7 +59,6 @@ public abstract class UserData extends PlayerExtension implements IConf { private long lastLogout; private String lastLoginAddress; private boolean afk; - private boolean newplayer; private String geolocation; private boolean isSocialSpyEnabled; private boolean isNPC; @@ -119,6 +118,7 @@ public final void reloadConfig() { jail = _getJail(); mails = _getMails(); teleportEnabled = _getTeleportEnabled(); + autoTeleportEnabled = _getAutoTeleportEnabled(); godmode = _getGodModeEnabled(); muted = _getMuted(); muteTimeout = _getMuteTimeout(); From e5fcf988d855035d553bd3758391f772096f919c Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Tue, 30 Mar 2021 09:48:34 -0400 Subject: [PATCH 28/61] Add BigDecimal & Location serializers Co-authored-by: MD <1917406+mdcfe@users.noreply.github.com> --- .../config/EssentialsConfiguration.java | 64 +++++++++--------- .../serializers/BigDecimalTypeSerializer.java | 61 +++++++++++++++++ .../serializers/LocationTypeSerializer.java | 66 +++++++++++++++++++ 3 files changed, 158 insertions(+), 33 deletions(-) create mode 100644 Essentials/src/main/java/com/earth2me/essentials/config/serializers/BigDecimalTypeSerializer.java create mode 100644 Essentials/src/main/java/com/earth2me/essentials/config/serializers/LocationTypeSerializer.java diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index f35db713c1e..831462f2228 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -1,15 +1,16 @@ package com.earth2me.essentials.config; +import com.earth2me.essentials.config.serializers.BigDecimalTypeSerializer; +import com.earth2me.essentials.config.serializers.LocationTypeSerializer; import net.ess3.api.InvalidWorldException; -import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.World; import org.spongepowered.configurate.CommentedConfigurationNode; import org.spongepowered.configurate.ConfigurateException; import org.spongepowered.configurate.ConfigurationOptions; import org.spongepowered.configurate.loader.HeaderMode; import org.spongepowered.configurate.loader.ParsingException; import org.spongepowered.configurate.serialize.SerializationException; +import org.spongepowered.configurate.serialize.TypeSerializerCollection; import org.spongepowered.configurate.yaml.NodeStyle; import org.spongepowered.configurate.yaml.YamlConfigurationLoader; @@ -38,6 +39,11 @@ public class EssentialsConfiguration { protected static final Logger LOGGER = Logger.getLogger("Essentials"); private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor(); + private static final TypeSerializerCollection SERIALIZERS = TypeSerializerCollection.builder() + .register(BigDecimal.class, new BigDecimalTypeSerializer()) + .register(Location.class, new LocationTypeSerializer()) + .build(); + private final AtomicInteger pendingWrites = new AtomicInteger(0); private final AtomicBoolean transaction = new AtomicBoolean(false); private Class resourceClass = EssentialsConfiguration.class; @@ -61,8 +67,15 @@ public EssentialsConfiguration(final File configFile, final String templateName, public EssentialsConfiguration(final File configFile, final String templateName, final String header) { this.configFile = configFile; - this.loader = YamlConfigurationLoader.builder().defaultOptions(ConfigurationOptions.defaults().header(header)) - .headerMode(HeaderMode.PRESET).nodeStyle(NodeStyle.BLOCK).indent(2).file(configFile).build(); + this.loader = YamlConfigurationLoader.builder() + .defaultOptions(ConfigurationOptions.defaults() + .header(header) + .serializers(SERIALIZERS)) + .headerMode(HeaderMode.PRESET) + .nodeStyle(NodeStyle.BLOCK) + .indent(2) + .file(configFile) + .build(); this.templateName = templateName; } @@ -76,28 +89,16 @@ public File getFile() { public void setProperty(String path, final Location location) { path = path == null ? "" : path; - //noinspection ConstantConditions - setInternal(path + ".world", location.getWorld().getName()); - setInternal(path + ".x", location.getX()); - setInternal(path + ".y", location.getY()); - setInternal(path + ".z", location.getZ()); - setInternal(path + ".yaw", location.getYaw()); - setInternal(path + ".pitch", location.getPitch()); + setInternal(path, location); } public Location getLocation(final String path) throws InvalidWorldException { final CommentedConfigurationNode node = path == null ? getRootNode() : getSection(path); - final String worldName = node == null ? null : node.node("world").getString(); - if (worldName == null || worldName.isEmpty()) { + try { + return node.get(Location.class); + } catch (SerializationException e) { return null; } - - final World world = Bukkit.getWorld(worldName); - if (world == null) { - throw new InvalidWorldException(worldName); - } - return new Location(world, node.node("x").getDouble(0), node.node("y").getDouble(0), - node.node("z").getDouble(0), node.node("yaw").getFloat(0), node.node("pitch").getFloat(0)); } public Map getLocationSectionMap(final String path) { @@ -105,18 +106,11 @@ public Map getLocationSectionMap(final String path) { final Map result = new HashMap<>(); for (final Map.Entry entry : ConfigurateUtil.getMap(node).entrySet()) { final CommentedConfigurationNode jailNode = entry.getValue(); - final String worldName = jailNode.node("world").getString(); - if (worldName == null || worldName.isEmpty()) { - continue; - } - - final World world = Bukkit.getWorld(worldName); - if (world == null) { - LOGGER.log(Level.WARNING, "Invalid world name, " + worldName + ", for key " + entry.getKey()); - continue; + try { + result.put(entry.getKey().toLowerCase(Locale.ENGLISH), jailNode.get(Location.class)); + } catch (SerializationException e) { + LOGGER.log(Level.WARNING, "Error serializing key " + entry.getKey(), e); } - result.put(entry.getKey().toLowerCase(Locale.ENGLISH), new Location(world, jailNode.node("x").getDouble(), jailNode.node("y").getDouble(), - jailNode.node("z").getDouble(), jailNode.node("yaw").getFloat(), jailNode.node("pitch").getFloat())); } return result; } @@ -225,7 +219,7 @@ public float getFloat(final String path, final float def) { } public void setProperty(final String path, final BigDecimal value) { - setProperty(path, value.toString()); + setInternal(path, value); } public BigDecimal getBigDecimal(final String path, final BigDecimal def) { @@ -233,7 +227,11 @@ public BigDecimal getBigDecimal(final String path, final BigDecimal def) { if (node == null) { return def; } - return ConfigurateUtil.toBigDecimal(node.getString(), def); + try { + return node.get(BigDecimal.class); + } catch (SerializationException e) { + return null; + } } public void setRaw(final String path, final Object value) { diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/serializers/BigDecimalTypeSerializer.java b/Essentials/src/main/java/com/earth2me/essentials/config/serializers/BigDecimalTypeSerializer.java new file mode 100644 index 00000000000..6e147eba687 --- /dev/null +++ b/Essentials/src/main/java/com/earth2me/essentials/config/serializers/BigDecimalTypeSerializer.java @@ -0,0 +1,61 @@ +package com.earth2me.essentials.config.serializers; + +import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.configurate.ConfigurationOptions; +import org.spongepowered.configurate.serialize.ScalarSerializer; +import org.spongepowered.configurate.serialize.SerializationException; + +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.math.MathContext; +import java.util.function.Predicate; + +/** + * A Configurate type serializer for {@link BigDecimal}s. + */ +public class BigDecimalTypeSerializer extends ScalarSerializer { + + public BigDecimalTypeSerializer() { + super(BigDecimal.class); + } + + @Override + public BigDecimal deserialize(Type type, Object obj) throws SerializationException { + if (obj instanceof Double) { + return BigDecimal.valueOf((double) obj); + } + + if (obj instanceof Integer) { + return BigDecimal.valueOf((int) obj); + } + + if (obj instanceof Long) { + return BigDecimal.valueOf((long) obj); + } + + if (obj instanceof BigInteger) { + return new BigDecimal((BigInteger) obj); + } + + if (obj instanceof String) { + try { + return new BigDecimal((String) obj, MathContext.DECIMAL128); + } catch (final NumberFormatException | ArithmeticException e) { + throw new SerializationException(type, "Failed to coerce input value of type " + obj.getClass() + " to BigDecimal", e); + } + } + + throw new SerializationException(type, "Failed to coerce input value of type " + obj.getClass() + " to BigDecimal"); + } + + @Override + protected Object serialize(BigDecimal item, Predicate> typeSupported) { + return item.toString(); + } + + @Override + public @Nullable BigDecimal emptyValue(Type specificType, ConfigurationOptions options) { + return BigDecimal.ZERO; + } +} diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/serializers/LocationTypeSerializer.java b/Essentials/src/main/java/com/earth2me/essentials/config/serializers/LocationTypeSerializer.java new file mode 100644 index 00000000000..0c7a07b0fc8 --- /dev/null +++ b/Essentials/src/main/java/com/earth2me/essentials/config/serializers/LocationTypeSerializer.java @@ -0,0 +1,66 @@ +package com.earth2me.essentials.config.serializers; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.serialize.SerializationException; +import org.spongepowered.configurate.serialize.TypeSerializer; + +import java.lang.reflect.Type; +import java.util.UUID; + +/** + * A Configurate type serializer for {@link Location}s. + * + * Locations with a null or empty world will be considered invalid. + */ +public class LocationTypeSerializer implements TypeSerializer { + @Override + public Location deserialize(Type type, ConfigurationNode node) throws SerializationException { + final String worldValue = node.node("world").getString(); + if (worldValue == null || worldValue.isEmpty()) { + throw new SerializationException("No world value present!"); + } + + World world = null; + + try { + final UUID worldId = UUID.fromString(worldValue); + world = Bukkit.getWorld(worldId); + } catch (IllegalArgumentException ignored) { + } + + if (world == null) { + world = Bukkit.getWorld(worldValue); + } + + if (world == null) { + throw new SerializationException("No world value present!"); + } + + return new Location( + world, + node.node("x").getDouble(), + node.node("y").getDouble(), + node.node("z").getDouble(), + node.node("yaw").getFloat(), + node.node("pitch").getFloat()); + } + + @Override + public void serialize(Type type, @Nullable Location value, ConfigurationNode node) throws SerializationException { + if (value == null || value.getWorld() == null) { + node.raw(null); + return; + } + + node.node("world").set(String.class, value.getWorld().getName()); + node.node("x").set(Double.class, value.getX()); + node.node("y").set(Double.class, value.getY()); + node.node("z").set(Double.class, value.getZ()); + node.node("yaw").set(Float.class, value.getYaw()); + node.node("pitch").set(Float.class, value.getPitch()); + } +} From 59e63c968683217d13ad0d4860301e92a6066aa3 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Tue, 30 Mar 2021 10:00:26 -0400 Subject: [PATCH 29/61] Fix tests --- .../earth2me/essentials/config/EssentialsConfiguration.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index 831462f2228..644634ebca9 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -94,6 +94,10 @@ public void setProperty(String path, final Location location) { public Location getLocation(final String path) throws InvalidWorldException { final CommentedConfigurationNode node = path == null ? getRootNode() : getSection(path); + if (node == null) { + return null; + } + try { return node.get(Location.class); } catch (SerializationException e) { From 83091389d1ab0cda84a7e5202c647f2748d4e7c4 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Tue, 30 Mar 2021 10:41:46 -0400 Subject: [PATCH 30/61] Use default type serializers in addition to our own --- .../com/earth2me/essentials/config/EssentialsConfiguration.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index 644634ebca9..82fdf8f0697 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -40,6 +40,7 @@ public class EssentialsConfiguration { protected static final Logger LOGGER = Logger.getLogger("Essentials"); private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor(); private static final TypeSerializerCollection SERIALIZERS = TypeSerializerCollection.builder() + .registerAll(TypeSerializerCollection.defaults()) .register(BigDecimal.class, new BigDecimalTypeSerializer()) .register(Location.class, new LocationTypeSerializer()) .build(); From 15a8d86e109c2f7e9600eaf5dc6beb3b23f2498a Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 3 Apr 2021 00:06:30 -0400 Subject: [PATCH 31/61] Create data holder for userdata --- .../config/EssentialsConfiguration.java | 10 +- .../config/annotations/DeleteOnEmpty.java | 15 + .../config/holders/UserConfigHolder.java | 418 ++++++++++++++++++ .../processors/DeleteOnEmptyProcessor.java | 28 ++ 4 files changed, 469 insertions(+), 2 deletions(-) create mode 100644 Essentials/src/main/java/com/earth2me/essentials/config/annotations/DeleteOnEmpty.java create mode 100644 Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java create mode 100644 Essentials/src/main/java/com/earth2me/essentials/config/processors/DeleteOnEmptyProcessor.java diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index 82fdf8f0697..b3eb5de7653 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -1,5 +1,7 @@ package com.earth2me.essentials.config; +import com.earth2me.essentials.config.annotations.DeleteOnEmpty; +import com.earth2me.essentials.config.processors.DeleteOnEmptyProcessor; import com.earth2me.essentials.config.serializers.BigDecimalTypeSerializer; import com.earth2me.essentials.config.serializers.LocationTypeSerializer; import net.ess3.api.InvalidWorldException; @@ -9,6 +11,7 @@ import org.spongepowered.configurate.ConfigurationOptions; import org.spongepowered.configurate.loader.HeaderMode; import org.spongepowered.configurate.loader.ParsingException; +import org.spongepowered.configurate.objectmapping.ObjectMapper; import org.spongepowered.configurate.serialize.SerializationException; import org.spongepowered.configurate.serialize.TypeSerializerCollection; import org.spongepowered.configurate.yaml.NodeStyle; @@ -39,8 +42,11 @@ public class EssentialsConfiguration { protected static final Logger LOGGER = Logger.getLogger("Essentials"); private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor(); - private static final TypeSerializerCollection SERIALIZERS = TypeSerializerCollection.builder() - .registerAll(TypeSerializerCollection.defaults()) + private static final ObjectMapper.Factory MAPPER_FACTORY = ObjectMapper.factoryBuilder() + .addProcessor(DeleteOnEmpty.class, (data, value) -> new DeleteOnEmptyProcessor()) + .build(); + private static final TypeSerializerCollection SERIALIZERS = TypeSerializerCollection.defaults().childBuilder() + .registerAnnotatedObjects(MAPPER_FACTORY) .register(BigDecimal.class, new BigDecimalTypeSerializer()) .register(Location.class, new LocationTypeSerializer()) .build(); diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/annotations/DeleteOnEmpty.java b/Essentials/src/main/java/com/earth2me/essentials/config/annotations/DeleteOnEmpty.java new file mode 100644 index 00000000000..364ed3177af --- /dev/null +++ b/Essentials/src/main/java/com/earth2me/essentials/config/annotations/DeleteOnEmpty.java @@ -0,0 +1,15 @@ +package com.earth2me.essentials.config.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Used to indicate to Configurate that the annotated field should be + * treated as null if it is a Collection, Map, or String that is empty. + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface DeleteOnEmpty { +} diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java b/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java new file mode 100644 index 00000000000..8e7f66a5b34 --- /dev/null +++ b/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java @@ -0,0 +1,418 @@ +package com.earth2me.essentials.config.holders; + +import com.earth2me.essentials.config.annotations.DeleteOnEmpty; +import org.bukkit.Location; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.configurate.objectmapping.ConfigSerializable; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +@ConfigSerializable +public class UserConfigHolder { + private @MonotonicNonNull BigDecimal money; + + public BigDecimal money() { + return money; + } + + public void money(final BigDecimal value) { + this.money = value; + } + + @DeleteOnEmpty + private @MonotonicNonNull Map homes; + + public Map homes() { + if (this.homes == null) { + this.homes = new HashMap<>(); + } + return this.homes; + } + + public void homes(final Map value) { + this.homes = value; + } + + private @Nullable String nickname; + + public String nickname() { + return nickname; + } + + public void nickname(final String value) { + this.nickname = value; + } + + @DeleteOnEmpty + private @MonotonicNonNull Set unlimited; + + public Set unlimited() { + if (this.unlimited == null) { + this.unlimited = new HashSet<>(); + } + return this.unlimited; + } + + @DeleteOnEmpty + private @MonotonicNonNull Map> powertools; + + public Map> powertools() { + if (this.powertools == null) { + this.powertools = new HashMap<>(); + } + return this.powertools; + } + + private @MonotonicNonNull Location lastlocation; + + public Location lastLocation() { + return this.lastlocation; + } + + public void lastLocation(final Location value) { + if (value == null || value.getWorld() == null) { + return; + } + this.lastlocation = value; + } + + private @MonotonicNonNull Location logoutlocation; + + public Location logoutLocation() { + return this.logoutlocation; + } + + public void logoutLocation(final Location value) { + if (value == null || value.getWorld() == null) { + return; + } + this.logoutlocation = value; + } + + private @Nullable String jail; + + public String jail() { + return this.jail; + } + + public void jail(final String value) { + this.jail = value; + } + + @DeleteOnEmpty + private @MonotonicNonNull List mails; + + public List mails() { + if (this.mails == null) { + this.mails = new ArrayList<>(); + } + return this.mails; + } + + public void mails(final List value) { + this.mails = value; + } + + private boolean teleportenabled = true; + + public boolean teleportEnabled() { + return this.teleportenabled; + } + + public void teleportEnabled(final boolean value) { + this.teleportenabled = value; + } + + private boolean teleportauto = false; + + public boolean teleportAuto() { + return this.teleportauto; + } + + public void teleportAuto(final boolean value) { + this.teleportauto = value; + } + + @DeleteOnEmpty + private @MonotonicNonNull List ignore; + + public List ignore() { + if (this.ignore == null) { + this.ignore = new ArrayList<>(); + } + return this.ignore; + } + + public void ignore(final List value) { + this.ignore = value; + } + + private boolean godmode = false; + + public boolean godMode() { + return this.godmode; + } + + public void godMode(final boolean value) { + this.godmode = value; + } + + private boolean muted = false; + + public boolean muted() { + return this.muted; + } + + public void muted(final boolean value) { + this.muted = value; + } + + private @Nullable String muteReason; + + public String muteReason() { + return this.muteReason; + } + + public void muteReason(final String value) { + this.muteReason = value; + } + + private boolean jailed = false; + + public boolean jailed() { + return this.jailed; + } + + public void jailed(final boolean value) { + this.jailed = value; + } + + private @NonNull String ipAddress = ""; + + public String ipAddress() { + return this.ipAddress; + } + + public void ipAddress(final String value) { + this.ipAddress = value; + } + + private boolean afk = false; + + public boolean afk() { + return this.afk; + } + + public void afk(final boolean value) { + this.afk = value; + } + + @DeleteOnEmpty + private @Nullable String geolocation; + + public String geolocation() { + return this.geolocation; + } + + public void geolocation(final String value) { + this.geolocation = value; + } + + private boolean socialspy = false; + + public boolean socialSpy() { + return this.socialspy; + } + + public void socialSpy(final boolean value) { + this.socialspy = value; + } + + private boolean npc = false; + + public boolean npc() { + return this.npc; + } + + public void npc(final boolean value) { + this.npc = value; + } + + private @MonotonicNonNull String lastAccountName; + + public String lastAccountName() { + return this.lastAccountName; + } + + public void lastAccountName(final String value) { + this.lastAccountName = value; + } + + private boolean powertoolsenabled = true; + + public boolean powerToolsEnabled() { + return this.powertoolsenabled; + } + + public void powerToolsEnabled(final boolean value) { + this.powertoolsenabled = value; + } + + private boolean acceptingPay = true; + + public boolean acceptingPay() { + return this.acceptingPay; + } + + public void acceptingPay(final boolean value) { + this.acceptingPay = value; + } + + private @Nullable Boolean confirmClear; + + public Boolean confirmClear() { + return this.confirmClear; + } + + public void confirmClear(final Boolean value) { + this.confirmClear = value; + } + + private @Nullable Boolean lastMessageReplyRecipient; + + public Boolean lastMessageReplyRecipient() { + return this.lastMessageReplyRecipient; + } + + public void lastMessageReplyRecipient(final Boolean value) { + this.lastMessageReplyRecipient = value; + } + + private boolean baltopExempt = false; + + public boolean baltopExempt() { + return this.baltopExempt; + } + + public void baltopExempt(final boolean value) { + this.baltopExempt = value; + } + + @ConfigSerializable + static class Timestamps { + private @MonotonicNonNull Long lastteleport; + + public Long lastTeleport() { + if (this.lastteleport == null) { + this.lastteleport = 0L; + } + return this.lastteleport; + } + + public void lastTeleport(final Long value) { + this.lastteleport = value; + } + + private @MonotonicNonNull Long lastheal; + + public Long lastHeal() { + if (this.lastheal == null) { + this.lastheal = 0L; + } + return this.lastheal; + } + + public void lastHeal(final Long value) { + this.lastheal = value; + } + + private @MonotonicNonNull Long mute; + + public Long mute() { + if (this.mute == null) { + this.mute = 0L; + } + return this.mute; + } + + public void mute(final Long value) { + this.mute = value; + } + + private @MonotonicNonNull Long jail; + + public Long jail() { + if (this.jail == null) { + this.jail = 0L; + } + return this.jail; + } + + public void jail(final Long value) { + this.jail = value; + } + + private @MonotonicNonNull Long onlinejail; + + public Long onlineJail() { + if (this.onlinejail == null) { + this.onlinejail = 0L; + } + return this.onlinejail; + } + + public void onlineJail(final Long value) { + this.onlinejail = value; + } + + private @MonotonicNonNull Long logout; + + public Long logout() { + if (this.logout == null) { + this.logout = 0L; + } + return this.logout; + } + + public void logout(final Long value) { + this.logout = value; + } + + @DeleteOnEmpty + private @MonotonicNonNull Map kits; + + public Map kits() { + if (this.kits == null) { + this.kits = new HashMap<>(); + } + return this.kits; + } + + public void kits(final Map value) { + this.kits = value; + } + + @DeleteOnEmpty + private @MonotonicNonNull List commandCooldowns; + + public List commandCooldowns() { + if (this.commandCooldowns == null) { + this.commandCooldowns = new ArrayList<>(); + } + return this.commandCooldowns; + } + + public void commandCooldowns(final List value) { + this.commandCooldowns = value; + } + } +} diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/processors/DeleteOnEmptyProcessor.java b/Essentials/src/main/java/com/earth2me/essentials/config/processors/DeleteOnEmptyProcessor.java new file mode 100644 index 00000000000..2f84f0ed0d7 --- /dev/null +++ b/Essentials/src/main/java/com/earth2me/essentials/config/processors/DeleteOnEmptyProcessor.java @@ -0,0 +1,28 @@ +package com.earth2me.essentials.config.processors; + +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.objectmapping.meta.Processor; +import org.spongepowered.configurate.serialize.SerializationException; + +import java.util.Collection; +import java.util.Map; + +public class DeleteOnEmptyProcessor implements Processor { + @Override + public void process(final Object value, final ConfigurationNode destination) { + if (value == null) { + return; + } + try { + if (value instanceof Map && ((Map) value).isEmpty()) { + destination.set(null); + } else if (value instanceof Collection && ((Collection) value).isEmpty()) { + destination.set(null); + } else if (value instanceof CharSequence && ((CharSequence) value).length() == 0) { + destination.set(null); + } + } catch (SerializationException e) { + e.printStackTrace(); + } + } +} From fb48b353432f1f0bd859d32c9586e2ff4cbeb72d Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 3 Apr 2021 00:07:31 -0400 Subject: [PATCH 32/61] Create userdata name migrations --- .../essentials/EssentialsUpgrade.java | 55 +++++++++++++++++++ .../com/earth2me/essentials/UserData.java | 24 -------- 2 files changed, 55 insertions(+), 24 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java index e09d747f9ad..17bd573e64d 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java @@ -146,6 +146,60 @@ public static void uuidFileConvert(final IEssentials ess, final Boolean ignoreUF ess.getLogger().info("To rerun the conversion type /essentials uuidconvert"); } + public void convertStupidNames() { + if (doneFile.getBoolean("updateUsersLegacyPathNames", false)) { + return; + } + + LOGGER.info("Attempting to migrate legacy path names to Configurate"); + + final File userdataFolder = new File(ess.getDataFolder(), "userdata"); + if (!userdataFolder.exists() || !userdataFolder.isDirectory()) { + return; + } + final File[] userFiles = userdataFolder.listFiles(); + + for (final File file : userFiles) { + if (!file.isFile() || !file.getName().endsWith(".yml")) { + continue; + } + final EssentialsConfiguration config = new EssentialsConfiguration(file); + try { + config.load(); + + if (config.hasProperty("muteReason")) { + final String reason = config.getString("muteReason", null); + config.removeProperty("muteReason"); + config.setProperty("mute-reason", reason); + } + + if (config.hasProperty("ipAddress")) { + final String ip = config.getString("ipAddress", null); + config.removeProperty("ipAddress"); + config.setProperty("ip-address", ip); + } + + if (config.hasProperty("lastAccountName")) { + final String name = config.getString("lastAccountName", null); + config.removeProperty("lastAccountName"); + config.setProperty("last-account-name", name); + } + + if (config.hasProperty("acceptingPay")) { + final boolean isPay = config.getBoolean("acceptingPay", true); + config.removeProperty("acceptingPay"); + config.setProperty("accepting-pay", isPay); + } + } catch (final RuntimeException ex) { + LOGGER.log(Level.INFO, "File: " + file.toString()); + throw ex; + } + } + doneFile.setProperty("updateUsersLegacyPathNames", true); + doneFile.save(); + LOGGER.info("Done converting legacy path names to Configurate."); + } + public void convertIgnoreList() { final Pattern pattern = Pattern.compile("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"); if (doneFile.getBoolean("updateUsersIgnoreListUUID", false)) { @@ -765,5 +819,6 @@ public void afterSettings() { warnMetrics(); repairUserMap(); convertIgnoreList(); + convertStupidNames(); } } diff --git a/Essentials/src/main/java/com/earth2me/essentials/UserData.java b/Essentials/src/main/java/com/earth2me/essentials/UserData.java index acf15bfdf76..578d45bcec9 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/UserData.java +++ b/Essentials/src/main/java/com/earth2me/essentials/UserData.java @@ -858,30 +858,6 @@ public void setKitTimestamp(String name, final long time) { config.save(); } - public Set getConfigKeys() { - final Set keys = ConfigurateUtil.getKeys(config.getSection("info")); - if (!keys.isEmpty()) { - return keys; - } - return new HashSet<>(); - } - - public Map getConfigMap() { - final Map node = ConfigurateUtil.getRawMap(config.getSection("info")); - if (!node.isEmpty()) { - return node; - } - return new HashMap<>(); - } - - public Map getConfigMap(final String node) { - final Map nodeMap = ConfigurateUtil.getRawMap(config.getSection("info." + node)); - if (!nodeMap.isEmpty()) { - return nodeMap; - } - return new HashMap<>(); - } - private Map _getCommandCooldowns() { final CommentedConfigurationNode node = config.getSection("timestamps.command-cooldowns"); if (node == null) { From d58d4eafae9b8e6e75d95c518b7905d47dd9e5b7 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 3 Apr 2021 00:10:41 -0400 Subject: [PATCH 33/61] Revert removal of unused UserData methods --- .../com/earth2me/essentials/UserData.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Essentials/src/main/java/com/earth2me/essentials/UserData.java b/Essentials/src/main/java/com/earth2me/essentials/UserData.java index 578d45bcec9..acf15bfdf76 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/UserData.java +++ b/Essentials/src/main/java/com/earth2me/essentials/UserData.java @@ -858,6 +858,30 @@ public void setKitTimestamp(String name, final long time) { config.save(); } + public Set getConfigKeys() { + final Set keys = ConfigurateUtil.getKeys(config.getSection("info")); + if (!keys.isEmpty()) { + return keys; + } + return new HashSet<>(); + } + + public Map getConfigMap() { + final Map node = ConfigurateUtil.getRawMap(config.getSection("info")); + if (!node.isEmpty()) { + return node; + } + return new HashMap<>(); + } + + public Map getConfigMap(final String node) { + final Map nodeMap = ConfigurateUtil.getRawMap(config.getSection("info." + node)); + if (!nodeMap.isEmpty()) { + return nodeMap; + } + return new HashMap<>(); + } + private Map _getCommandCooldowns() { final CommentedConfigurationNode node = config.getSection("timestamps.command-cooldowns"); if (node == null) { From 035fa0c0436ee9d3b975672ad83c5dff00ee93d0 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 3 Apr 2021 00:14:56 -0400 Subject: [PATCH 34/61] Include reference to timestamps section --- .../essentials/config/holders/UserConfigHolder.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java b/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java index 8e7f66a5b34..d3d7661d94f 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java @@ -307,6 +307,12 @@ public void baltopExempt(final boolean value) { this.baltopExempt = value; } + private @NonNull Timestamps timestamps = new Timestamps(); + + public Timestamps timestamps() { + return this.timestamps; + } + @ConfigSerializable static class Timestamps { private @MonotonicNonNull Long lastteleport; From 9f0e7501a442b0fc24ff0792dbe5125a39329b59 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 3 Apr 2021 00:46:04 -0400 Subject: [PATCH 35/61] Add MaterialTypeSerializer --- .../config/EssentialsConfiguration.java | 3 +++ .../config/holders/UserConfigHolder.java | 5 ++-- .../serializers/MaterialTypeSerializer.java | 27 +++++++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 Essentials/src/main/java/com/earth2me/essentials/config/serializers/MaterialTypeSerializer.java diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index b3eb5de7653..9b3d679c410 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -4,8 +4,10 @@ import com.earth2me.essentials.config.processors.DeleteOnEmptyProcessor; import com.earth2me.essentials.config.serializers.BigDecimalTypeSerializer; import com.earth2me.essentials.config.serializers.LocationTypeSerializer; +import com.earth2me.essentials.config.serializers.MaterialTypeSerializer; import net.ess3.api.InvalidWorldException; import org.bukkit.Location; +import org.bukkit.Material; import org.spongepowered.configurate.CommentedConfigurationNode; import org.spongepowered.configurate.ConfigurateException; import org.spongepowered.configurate.ConfigurationOptions; @@ -49,6 +51,7 @@ public class EssentialsConfiguration { .registerAnnotatedObjects(MAPPER_FACTORY) .register(BigDecimal.class, new BigDecimalTypeSerializer()) .register(Location.class, new LocationTypeSerializer()) + .register(Material.class, new MaterialTypeSerializer()) .build(); private final AtomicInteger pendingWrites = new AtomicInteger(0); diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java b/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java index d3d7661d94f..14bfc1a8d5f 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java @@ -2,6 +2,7 @@ import com.earth2me.essentials.config.annotations.DeleteOnEmpty; import org.bukkit.Location; +import org.bukkit.Material; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -53,9 +54,9 @@ public void nickname(final String value) { } @DeleteOnEmpty - private @MonotonicNonNull Set unlimited; + private @MonotonicNonNull Set unlimited; - public Set unlimited() { + public Set unlimited() { if (this.unlimited == null) { this.unlimited = new HashSet<>(); } diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/serializers/MaterialTypeSerializer.java b/Essentials/src/main/java/com/earth2me/essentials/config/serializers/MaterialTypeSerializer.java new file mode 100644 index 00000000000..ca940a3b59d --- /dev/null +++ b/Essentials/src/main/java/com/earth2me/essentials/config/serializers/MaterialTypeSerializer.java @@ -0,0 +1,27 @@ +package com.earth2me.essentials.config.serializers; + +import org.bukkit.Material; +import org.spongepowered.configurate.serialize.ScalarSerializer; +import org.spongepowered.configurate.serialize.SerializationException; + +import java.lang.reflect.Type; +import java.util.function.Predicate; + +public class MaterialTypeSerializer extends ScalarSerializer { + public MaterialTypeSerializer() { + super(Material.class); + } + + @Override + public Material deserialize(Type type, Object obj) throws SerializationException { + if (obj instanceof String) { + return Material.matchMaterial((String) obj); + } + return null; + } + + @Override + protected Object serialize(Material item, Predicate> typeSupported) { + return item.name(); + } +} From c62ab1d729edfc18e7860553dd6689337490cebf Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sat, 3 Apr 2021 01:39:33 -0400 Subject: [PATCH 36/61] This is what human suffering looks like This doesn't work in any capacity i am tired --- .../com/earth2me/essentials/UserData.java | 572 ++++-------------- .../config/EssentialsConfiguration.java | 9 + .../config/holders/UserConfigHolder.java | 76 +-- 3 files changed, 182 insertions(+), 475 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/UserData.java b/Essentials/src/main/java/com/earth2me/essentials/UserData.java index acf15bfdf76..d385852fb5e 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/UserData.java +++ b/Essentials/src/main/java/com/earth2me/essentials/UserData.java @@ -2,17 +2,17 @@ import com.earth2me.essentials.config.ConfigurateUtil; import com.earth2me.essentials.config.EssentialsUserConfiguration; +import com.earth2me.essentials.config.holders.UserConfigHolder; import com.earth2me.essentials.utils.NumberUtil; import com.earth2me.essentials.utils.StringUtil; import com.google.common.collect.ImmutableMap; import net.ess3.api.IEssentials; -import net.ess3.api.InvalidWorldException; import net.ess3.api.MaxMoneyException; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.spongepowered.configurate.CommentedConfigurationNode; +import org.spongepowered.configurate.serialize.SerializationException; import java.io.File; import java.math.BigDecimal; @@ -27,51 +27,19 @@ import java.util.Map.Entry; import java.util.Set; import java.util.UUID; +import java.util.logging.Level; import java.util.regex.Pattern; -import java.util.stream.Collectors; import static com.earth2me.essentials.I18n.tl; public abstract class UserData extends PlayerExtension implements IConf { protected final transient IEssentials ess; private final EssentialsUserConfiguration config; + private UserConfigHolder holder; private BigDecimal money; - private Map homes; - private String nickname; - private Set unlimited; - private Map powertools; - private Location lastLocation; - private Location logoutLocation; - private long lastTeleportTimestamp; - private long lastHealTimestamp; - private String jail; - private List mails; - private boolean teleportEnabled; - private boolean autoTeleportEnabled; - private List ignoredPlayers; - private boolean godmode; - private boolean muted; - private String muteReason; - private long muteTimeout; - private boolean jailed; - private long jailTimeout; - private long lastLogin; - private long lastLogout; - private String lastLoginAddress; - private boolean afk; - private String geolocation; - private boolean isSocialSpyEnabled; - private boolean isNPC; - private String lastAccountName = null; - private boolean arePowerToolsEnabled; - private Map kitTimestamps; // Pattern, Date. Pattern for less pattern creations private Map commandCooldowns; - private boolean acceptingPay = true; // players accept pay by default - private Boolean confirmPay; - private Boolean confirmClear; - private boolean lastMessageReplyRecipient; - private boolean baltopExemptCache; + private Map kitTimestamps; protected UserData(final Player base, final IEssentials ess) { super(base); @@ -108,43 +76,23 @@ public final void cleanup() { @Override public final void reloadConfig() { config.load(); + try { + holder = config.getRootNode().get(UserConfigHolder.class); + } catch (SerializationException e) { + ess.getLogger().log(Level.SEVERE, "Error while reading user config: " + e.getMessage(), e); + throw new RuntimeException(e); + } + config.setSaveHook(() -> { + try { + config.getRootNode().set(UserConfigHolder.class, holder); + } catch (SerializationException e) { + ess.getLogger().log(Level.SEVERE, "Error while saving user config: " + e.getMessage(), e); + throw new RuntimeException(e); + } + }); money = _getMoney(); - unlimited = _getUnlimited(); - powertools = _getPowertools(); - homes = _getHomes(); - lastLocation = _getLastLocation(); - lastTeleportTimestamp = _getLastTeleportTimestamp(); - lastHealTimestamp = _getLastHealTimestamp(); - jail = _getJail(); - mails = _getMails(); - teleportEnabled = _getTeleportEnabled(); - autoTeleportEnabled = _getAutoTeleportEnabled(); - godmode = _getGodModeEnabled(); - muted = _getMuted(); - muteTimeout = _getMuteTimeout(); - muteReason = _getMuteReason(); - jailed = _getJailed(); - jailTimeout = _getJailTimeout(); - onlineJailed = _getOnlineJailedTime(); - lastLogin = _getLastLogin(); - lastLogout = _getLastLogout(); - lastLoginAddress = _getLastLoginAddress(); - afk = _getAfk(); - geolocation = _getGeoLocation(); - isSocialSpyEnabled = _isSocialSpyEnabled(); - isNPC = _isNPC(); - arePowerToolsEnabled = _arePowerToolsEnabled(); - kitTimestamps = _getKitTimestamps(); - nickname = _getNickname(); - ignoredPlayers = _getIgnoredPlayers(); - logoutLocation = _getLogoutLocation(); - lastAccountName = _getLastAccountName(); commandCooldowns = _getCommandCooldowns(); - acceptingPay = _getAcceptingPay(); - confirmPay = _getConfirmPay(); - confirmClear = _getConfirmClear(); - lastMessageReplyRecipient = _getLastMessageReplyRecipient(); - baltopExemptCache = _getBaltopExcludeCache(); + kitTimestamps = _getKitTimestamps(); } private BigDecimal _getMoney() { @@ -157,8 +105,8 @@ private BigDecimal _getMoney() { result = BigDecimal.ZERO; } - if (config.hasProperty("money")) { - result = config.getBigDecimal("money", result); + if (holder.money() != null) { + result = holder.money(); } if (result.compareTo(maxMoney) > 0) { result = maxMoney; @@ -166,7 +114,9 @@ private BigDecimal _getMoney() { if (result.compareTo(minMoney) < 0) { result = minMoney; } - return result; + holder.money(result); + + return holder.money(); } public BigDecimal getMoney() { @@ -187,18 +137,10 @@ public void setMoney(final BigDecimal value, final boolean throwError) throws Ma if (money.compareTo(minMoney) < 0) { money = minMoney; } - config.setProperty("money", money); + holder.money(money); stopTransaction(); } - private Map _getHomes() { - final CommentedConfigurationNode section = config.getSection("homes"); - if (section != null) { - return ConfigurateUtil.getRawMap(section); - } - return new HashMap<>(); - } - private String getHomeName(String search) { if (NumberUtil.isInt(search)) { try { @@ -211,49 +153,43 @@ private String getHomeName(String search) { public Location getHome(final String name) throws Exception { final String search = getHomeName(name); - return config.getLocation("homes." + search); + return holder.homes().get(search); } public Location getHome(final Location world) { - try { - if (getHomes().isEmpty()) { - return null; + if (getHomes().isEmpty()) { + return null; + } + Location loc; + for (final String home : getHomes()) { + loc = holder.homes().get(home); + if (world.getWorld() == loc.getWorld()) { + return loc; } - Location loc; - for (final String home : getHomes()) { - loc = config.getLocation("homes." + home); - if (world.getWorld() == loc.getWorld()) { - return loc; - } - } - loc = config.getLocation("homes." + getHomes().get(0)); - return loc; - } catch (final InvalidWorldException ex) { - return null; } + loc = holder.homes().get(getHomes().get(0)); + return loc; } public List getHomes() { - return new ArrayList<>(homes.keySet()); + return new ArrayList<>(holder.homes().keySet()); } public void setHome(String name, final Location loc) { //Invalid names will corrupt the yaml name = StringUtil.safeString(name); - homes.put(name, loc); - config.setProperty("homes." + name, loc); + holder.homes().put(name, loc); config.save(); } public void delHome(final String name) throws Exception { String search = getHomeName(name); - if (!homes.containsKey(search)) { + if (!holder.homes().containsKey(search)) { search = StringUtil.safeString(search); } - if (homes.containsKey(search)) { - homes.remove(search); - config.removeProperty("homes." + search); + if (holder.homes().containsKey(search)) { + holder.homes().remove(search); config.save(); } else { throw new Exception(tl("invalidHome", search)); @@ -261,256 +197,152 @@ public void delHome(final String name) throws Exception { } public boolean hasHome() { - return config.hasProperty("home"); + return !holder.homes().isEmpty(); } public boolean hasHome(final String name) { - return config.hasProperty("homes." + name); - } - - public String _getNickname() { - return config.getString("nickname", null); + return holder.homes().containsKey(name); } public String getNickname() { - return nickname; + return holder.nickname(); } public void setNickname(final String nick) { - nickname = nick; - config.setProperty("nickname", nick); + holder.nickname(nick); config.save(); } - private Set _getUnlimited() { - final Set retlist = new HashSet<>(); - final List configList = config.getList("unlimited", String.class); - for (final String s : configList) { - final Material mat = Material.matchMaterial(s); - if (mat != null) { - retlist.add(mat); - } - } - - return retlist; - } - public Set getUnlimited() { - return unlimited; + return holder.unlimited(); } public boolean hasUnlimited(final ItemStack stack) { - return unlimited.contains(stack.getType()); + return holder.unlimited().contains(stack.getType()); } public void setUnlimited(final ItemStack stack, final boolean state) { final boolean wasUpdated; if (state) { - wasUpdated = unlimited.add(stack.getType()); + wasUpdated = holder.unlimited().add(stack.getType()); } else { - wasUpdated = unlimited.remove(stack.getType()); + wasUpdated = holder.unlimited().remove(stack.getType()); } if (wasUpdated) { - applyUnlimited(); - } - } - - private void applyUnlimited() { - config.setProperty("unlimited", unlimited.stream().map(Enum::name).collect(Collectors.toList())); - config.save(); - } - - private Map _getPowertools() { - final CommentedConfigurationNode node = config.getSection("powertools"); - if (node != null) { - return ConfigurateUtil.getRawMap(node); + config.save(); } - return new HashMap<>(); } public void clearAllPowertools() { - powertools.clear(); - config.setRaw("powertools", powertools); + holder.powertools().clear(); config.save(); } - @SuppressWarnings("unchecked") public List getPowertool(final ItemStack stack) { - return (List) powertools.get(stack.getType().name().toLowerCase(Locale.ENGLISH)); + return getPowertool(stack.getType()); } - @SuppressWarnings("unchecked") public List getPowertool(final Material material) { - return (List) powertools.get(material.name().toLowerCase(Locale.ENGLISH)); + return holder.powertools().get(material.name().toLowerCase(Locale.ENGLISH)); } public void setPowertool(final ItemStack stack, final List commandList) { if (commandList == null || commandList.isEmpty()) { - powertools.remove(stack.getType().name().toLowerCase(Locale.ENGLISH)); + holder.powertools().remove(stack.getType().name().toLowerCase(Locale.ENGLISH)); } else { - powertools.put(stack.getType().name().toLowerCase(Locale.ENGLISH), commandList); + holder.powertools().put(stack.getType().name().toLowerCase(Locale.ENGLISH), commandList); } - config.setRaw("powertools", powertools); config.save(); } public boolean hasPowerTools() { - return !powertools.isEmpty(); - } - - private Location _getLastLocation() { - try { - return config.getLocation("lastlocation"); - } catch (final InvalidWorldException e) { - return null; - } + return !holder.powertools().isEmpty(); } public Location getLastLocation() { - return lastLocation; + return holder.lastLocation(); } public void setLastLocation(final Location loc) { if (loc == null || loc.getWorld() == null) { return; } - lastLocation = loc; - config.setProperty("lastlocation", loc); + holder.lastLocation(loc); config.save(); } - private Location _getLogoutLocation() { - try { - return config.getLocation("logoutlocation"); - } catch (final InvalidWorldException e) { - return null; - } - } - public Location getLogoutLocation() { - return logoutLocation; + return holder.logoutLocation(); } public void setLogoutLocation(final Location loc) { if (loc == null || loc.getWorld() == null) { return; } - logoutLocation = loc; - config.setProperty("logoutlocation", loc); + holder.logoutLocation(loc); config.save(); } - private long _getLastTeleportTimestamp() { - return config.getLong("timestamps.lastteleport", 0); - } - public long getLastTeleportTimestamp() { - return lastTeleportTimestamp; + return holder.timestamps().lastTeleport(); } public void setLastTeleportTimestamp(final long time) { - lastTeleportTimestamp = time; - config.setProperty("timestamps.lastteleport", time); + holder.timestamps().lastTeleport(time); config.save(); } - private long _getLastHealTimestamp() { - return config.getLong("timestamps.lastheal", 0); - } - public long getLastHealTimestamp() { - return lastHealTimestamp; + return holder.timestamps().lastHeal(); } public void setLastHealTimestamp(final long time) { - lastHealTimestamp = time; - config.setProperty("timestamps.lastheal", time); + holder.timestamps().lastHeal(time); config.save(); } - private String _getJail() { - return config.getString("jail", null); - } - public String getJail() { - return jail; + return holder.jail(); } public void setJail(final String jail) { - if (jail == null || jail.isEmpty()) { - this.jail = null; - config.removeProperty("jail"); - } else { - this.jail = jail; - config.setProperty("jail", jail); - } + holder.jail(jail); config.save(); } - private List _getMails() { - return config.getList("mail", String.class); - } - public List getMails() { - return mails; + return holder.mails(); } public void setMails(List mails) { - if (mails == null) { - config.removeProperty("mail"); - mails = _getMails(); - } else { - config.setProperty("mail", mails); - } - this.mails = mails; + holder.mails(mails); config.save(); } public void addMail(final String mail) { - mails.add(mail); - setMails(mails); - } - - private boolean _getTeleportEnabled() { - return config.getBoolean("teleportenabled", true); + holder.mails().add(mail); + config.save(); } public boolean isTeleportEnabled() { - return teleportEnabled; + return holder.teleportEnabled(); } public void setTeleportEnabled(final boolean set) { - teleportEnabled = set; - config.setProperty("teleportenabled", set); + holder.teleportEnabled(set); config.save(); } - private boolean _getAutoTeleportEnabled() { - return config.getBoolean("teleportauto", false); - } - public boolean isAutoTeleportEnabled() { - return autoTeleportEnabled; + return holder.teleportAuto(); } public void setAutoTeleportEnabled(final boolean set) { - autoTeleportEnabled = set; - config.setProperty("teleportauto", set); + holder.teleportAuto(set); config.save(); } - public List _getIgnoredPlayers() { - final List players = new ArrayList<>(); - for (final String uuid : config.getList("ignore", String.class)) { - try { - players.add(UUID.fromString(uuid)); - } catch (final IllegalArgumentException ignored) { - } - } - return Collections.synchronizedList(players); - } - @Deprecated public void setIgnoredPlayers(final List players) { final List uuids = new ArrayList<>(); @@ -525,17 +357,7 @@ public void setIgnoredPlayers(final List players) { } public void setIgnoredPlayerUUIDs(final List players) { - if (players == null || players.isEmpty()) { - ignoredPlayers = Collections.synchronizedList(new ArrayList<>()); - config.removeProperty("ignore"); - } else { - ignoredPlayers = players; - final List uuids = new ArrayList<>(); - for (final UUID uuid : players) { - uuids.add(uuid.toString()); - } - config.setProperty("ignore", uuids); - } + holder.ignore(players); config.save(); } @@ -549,101 +371,75 @@ public boolean isIgnoredPlayer(final String userName) { } public boolean isIgnoredPlayer(final IUser user) { - return ignoredPlayers.contains(user.getBase().getUniqueId()) && !user.isIgnoreExempt(); + return holder.ignore().contains(user.getBase().getUniqueId()) && !user.isIgnoreExempt(); + } + + public List _getIgnoredPlayers() { + return holder.ignore(); } public void setIgnoredPlayer(final IUser user, final boolean set) { final UUID uuid = user.getBase().getUniqueId(); if (set) { - if (!ignoredPlayers.contains(uuid)) { - ignoredPlayers.add(uuid); + if (!holder.ignore().contains(uuid)) { + holder.ignore().add(uuid); } } else { - ignoredPlayers.remove(uuid); + holder.ignore().remove(uuid); } - setIgnoredPlayerUUIDs(ignoredPlayers); - } - - private boolean _getGodModeEnabled() { - return config.getBoolean("godmode", false); + config.save(); } public boolean isGodModeEnabled() { - return godmode; + return holder.godMode(); } public void setGodModeEnabled(final boolean set) { - godmode = set; - config.setProperty("godmode", set); + holder.godMode(set); config.save(); } - public boolean _getMuted() { - return config.getBoolean("muted", false); - } - public boolean getMuted() { - return muted; + return holder.muted(); } public boolean isMuted() { - return muted; + return getMuted(); } public void setMuted(final boolean set) { - muted = set; - config.setProperty("muted", set); + holder.muted(set); config.save(); } - public String _getMuteReason() { - return config.getString("muteReason", null); - } - public String getMuteReason() { - return muteReason; + return holder.muteReason(); } public void setMuteReason(final String reason) { - if (reason == null) { - config.removeProperty("muteReason"); - muteReason = null; - } else { - muteReason = reason; - config.setProperty("muteReason", reason); - } + holder.muteReason(reason); config.save(); } public boolean hasMuteReason() { - return muteReason != null; - } - - private long _getMuteTimeout() { - return config.getLong("timestamps.mute", 0); + return holder.muteReason() != null; } public long getMuteTimeout() { - return muteTimeout; + return holder.timestamps().mute(); } public void setMuteTimeout(final long time) { - muteTimeout = time; - config.setProperty("timestamps.mute", time); + holder.timestamps().mute(time); config.save(); } - private boolean _getJailed() { - return config.getBoolean("jailed", false); - } - public boolean isJailed() { - return jailed; + return holder.jailed(); } public void setJailed(final boolean set) { - jailed = set; - config.setProperty("jailed", set); + holder.jailed(set); config.save(); } @@ -653,167 +449,101 @@ public boolean toggleJailed() { return ret; } - private long _getJailTimeout() { - return config.getLong("timestamps.jail", 0); - } - public long getJailTimeout() { - return jailTimeout; + return holder.timestamps().jail(); } public void setJailTimeout(final long time) { - jailTimeout = time; - config.setProperty("timestamps.jail", time); + holder.timestamps().jail(time); config.save(); } - private long onlineJailed; - - private long _getOnlineJailedTime() { - return config.getLong("timestamps.onlinejail", 0); - } - public long getOnlineJailedTime() { - return onlineJailed; + return holder.timestamps().onlineJail(); } public void setOnlineJailedTime(long onlineJailed) { - this.onlineJailed = onlineJailed; - config.setProperty("timestamps.onlinejail", onlineJailed); + holder.timestamps().onlineJail(onlineJailed); config.save(); } - private long _getLastLogin() { - return config.getLong("timestamps.login", 0); - } - public long getLastLogin() { - return lastLogin; + return holder.timestamps().login(); } public void setLastLogin(final long time) { - _setLastLogin(time); + holder.timestamps().login(time); if (base.getAddress() != null && base.getAddress().getAddress() != null) { - _setLastLoginAddress(base.getAddress().getAddress().getHostAddress()); + holder.ipAddress(base.getAddress().getAddress().getHostAddress()); } config.save(); } - private void _setLastLogin(final long time) { - lastLogin = time; - config.setProperty("timestamps.login", time); - } - - private long _getLastLogout() { - return config.getLong("timestamps.logout", 0); - } - public long getLastLogout() { - return lastLogout; + return holder.timestamps().logout(); } public void setLastLogout(final long time) { - lastLogout = time; - config.setProperty("timestamps.logout", time); + holder.timestamps().logout(time); config.save(); } - private String _getLastLoginAddress() { - return config.getString("ipAddress", ""); - } - public String getLastLoginAddress() { - return lastLoginAddress; - } - - private void _setLastLoginAddress(final String address) { - lastLoginAddress = address; - config.setProperty("ipAddress", address); - } - - private boolean _getAfk() { - return config.getBoolean("afk", false); + return holder.ipAddress(); } public boolean isAfk() { - return afk; + return holder.afk(); } public void _setAfk(final boolean set) { - afk = set; - config.setProperty("afk", set); + holder.afk(set); config.save(); } - private String _getGeoLocation() { - return config.getString("geolocation", null); - } - public String getGeoLocation() { - return geolocation; + return holder.geolocation(); } public void setGeoLocation(final String geolocation) { - if (geolocation == null || geolocation.isEmpty()) { - this.geolocation = null; - config.removeProperty("geolocation"); - } else { - this.geolocation = geolocation; - config.setProperty("geolocation", geolocation); - } + holder.geolocation(geolocation); config.save(); } - private boolean _isSocialSpyEnabled() { - return config.getBoolean("socialspy", false); - } - public boolean isSocialSpyEnabled() { - return isSocialSpyEnabled; + return holder.socialSpy(); } public void setSocialSpyEnabled(final boolean status) { - isSocialSpyEnabled = status; - config.setProperty("socialspy", status); + holder.socialSpy(status); config.save(); } - private boolean _isNPC() { - return config.getBoolean("npc", false); - } - public boolean isNPC() { - return isNPC; + return holder.npc(); } public void setNPC(final boolean set) { - isNPC = set; - config.setProperty("npc", set); + holder.npc(set); config.save(); } public String getLastAccountName() { - return lastAccountName; + return holder.lastAccountName(); } public void setLastAccountName(final String lastAccountName) { - this.lastAccountName = lastAccountName; - config.setProperty("lastAccountName", lastAccountName); + holder.lastAccountName(lastAccountName); config.save(); ess.getUserMap().trackUUID(getConfigUUID(), lastAccountName, true); } - public String _getLastAccountName() { - return config.getString("lastAccountName", null); - } - public boolean arePowerToolsEnabled() { - return arePowerToolsEnabled; + return holder.powerToolsEnabled(); } public void setPowerToolsEnabled(final boolean set) { - arePowerToolsEnabled = set; - config.setProperty("powertoolsenabled", set); + holder.powerToolsEnabled(set); config.save(); } @@ -823,12 +553,8 @@ public boolean togglePowerToolsEnabled() { return ret; } - private boolean _arePowerToolsEnabled() { - return config.getBoolean("powertoolsenabled", true); - } - private Map _getKitTimestamps() { - final Map node = ConfigurateUtil.getRawMap(config.getSection("timestamps.kits")); + final Map node = holder.timestamps().kits(); if (!node.isEmpty()) { final Map timestamps = new HashMap<>(); for (final Map.Entry entry : node.entrySet()) { @@ -854,7 +580,6 @@ public long getKitTimestamp(String name) { public void setKitTimestamp(String name, final long time) { name = name.replace('.', '_').replace('/', '_').toLowerCase(Locale.ENGLISH); kitTimestamps.put(name, time); - config.setRaw("timestamps.kits", kitTimestamps); config.save(); } @@ -883,15 +608,11 @@ public Map getConfigMap(final String node) { } private Map _getCommandCooldowns() { - final CommentedConfigurationNode node = config.getSection("timestamps.command-cooldowns"); - if (node == null) { - return null; - } - // See saveCommandCooldowns() for deserialization explanation - final List> section = ConfigurateUtil.getMapList(node); + final List section = holder.timestamps().commandCooldowns(); final HashMap result = new HashMap<>(); - for (final Map map : section) { + for (final Object obj : section) { + final Map map = (Map) obj; final Pattern pattern = Pattern.compile(map.get("pattern").toString()); final long expiry = ((Number) map.get("expiry")).longValue(); result.put(pattern, expiry); @@ -959,77 +680,52 @@ private void saveCommandCooldowns() { .build(); serialized.add(map); } - config.setProperty("timestamps.command-cooldowns", serialized); + holder.timestamps().commandCooldowns(serialized); save(); } - public boolean _getAcceptingPay() { - return config.getBoolean("acceptingPay", true); - } - public boolean isAcceptingPay() { - return acceptingPay; + return holder.acceptingPay(); } public void setAcceptingPay(final boolean acceptingPay) { - this.acceptingPay = acceptingPay; - config.setProperty("acceptingPay", acceptingPay); + holder.acceptingPay(acceptingPay); save(); } - private Boolean _getConfirmPay() { - return (Boolean) config.get("confirm-pay"); - } - public boolean isPromptingPayConfirm() { - return confirmPay != null ? confirmPay : ess.getSettings().isConfirmCommandEnabledByDefault("pay"); + return holder.confirmPay() != null ? holder.confirmPay() : ess.getSettings().isConfirmCommandEnabledByDefault("pay"); } public void setPromptingPayConfirm(final boolean prompt) { - this.confirmPay = prompt; - config.setProperty("confirm-pay", prompt); + holder.confirmPay(prompt); save(); } - private Boolean _getConfirmClear() { - return (Boolean) config.get("confirm-clear"); - } - public boolean isPromptingClearConfirm() { - return confirmClear != null ? confirmClear : ess.getSettings().isConfirmCommandEnabledByDefault("clearinventory"); + return holder.confirmClear() != null ? holder.confirmClear() : ess.getSettings().isConfirmCommandEnabledByDefault("clearinventory"); } public void setPromptingClearConfirm(final boolean prompt) { - this.confirmClear = prompt; - config.setProperty("confirm-clear", prompt); + holder.confirmClear(prompt); save(); } - private boolean _getLastMessageReplyRecipient() { - return config.getBoolean("last-message-reply-recipient", ess.getSettings().isLastMessageReplyRecipient()); - } - public boolean isLastMessageReplyRecipient() { - return this.lastMessageReplyRecipient; + return holder.lastMessageReplyRecipient() != null ? holder.lastMessageReplyRecipient() : ess.getSettings().isLastMessageReplyRecipient(); } public void setLastMessageReplyRecipient(final boolean enabled) { - this.lastMessageReplyRecipient = enabled; - config.setProperty("last-message-reply-recipient", enabled); + holder.lastMessageReplyRecipient(enabled); save(); } - public boolean _getBaltopExcludeCache() { - return config.getBoolean("baltop-exempt", false); - } - public boolean isBaltopExcludeCache() { - return baltopExemptCache; + return holder.baltopExempt(); } public void setBaltopExemptCache(boolean baltopExempt) { - this.baltopExemptCache = baltopExempt; - config.setProperty("baltop-exempt", baltopExempt); + holder.baltopExempt(baltopExempt); config.save(); } diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index 9b3d679c410..11638f46fd7 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -61,6 +61,7 @@ public class EssentialsConfiguration { private final YamlConfigurationLoader loader; private final String templateName; private CommentedConfigurationNode configurationNode; + private Runnable saveHook; public EssentialsConfiguration(final File configFile) { this(configFile, null); @@ -400,6 +401,10 @@ public void stopTransaction(final boolean blocking) { } } + public void setSaveHook(Runnable saveHook) { + this.saveHook = saveHook; + } + public synchronized void save() { if (!transaction.get()) { delaySave(); @@ -415,6 +420,10 @@ public synchronized void blockingSave() { } private Future delaySave() { + if (saveHook != null) { + saveHook.run(); + } + final CommentedConfigurationNode node = configurationNode.copy(); pendingWrites.incrementAndGet(); diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java b/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java index 14bfc1a8d5f..5e7a7dcdfdb 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java @@ -278,6 +278,16 @@ public void acceptingPay(final boolean value) { this.acceptingPay = value; } + private @Nullable Boolean confirmPay; + + public Boolean confirmPay() { + return this.confirmPay; + } + + public void confirmPay(final Boolean value) { + this.confirmPay = value; + } + private @Nullable Boolean confirmClear; public Boolean confirmClear() { @@ -315,85 +325,77 @@ public Timestamps timestamps() { } @ConfigSerializable - static class Timestamps { - private @MonotonicNonNull Long lastteleport; + public static class Timestamps { + private long lastteleport = 0L; - public Long lastTeleport() { - if (this.lastteleport == null) { - this.lastteleport = 0L; - } + public long lastTeleport() { return this.lastteleport; } - public void lastTeleport(final Long value) { + public void lastTeleport(final long value) { this.lastteleport = value; } - private @MonotonicNonNull Long lastheal; + private long lastheal = 0L; - public Long lastHeal() { - if (this.lastheal == null) { - this.lastheal = 0L; - } + public long lastHeal() { return this.lastheal; } - public void lastHeal(final Long value) { + public void lastHeal(final long value) { this.lastheal = value; } - private @MonotonicNonNull Long mute; + private long mute = 0L; - public Long mute() { - if (this.mute == null) { - this.mute = 0L; - } + public long mute() { return this.mute; } - public void mute(final Long value) { + public void mute(final long value) { this.mute = value; } - private @MonotonicNonNull Long jail; + private long jail = 0L; - public Long jail() { - if (this.jail == null) { - this.jail = 0L; - } + public long jail() { return this.jail; } - public void jail(final Long value) { + public void jail(final long value) { this.jail = value; } - private @MonotonicNonNull Long onlinejail; + private long onlinejail = 0L; - public Long onlineJail() { - if (this.onlinejail == null) { - this.onlinejail = 0L; - } + public long onlineJail() { return this.onlinejail; } - public void onlineJail(final Long value) { + public void onlineJail(final long value) { this.onlinejail = value; } - private @MonotonicNonNull Long logout; + private long logout = 0L; - public Long logout() { - if (this.logout == null) { - this.logout = 0L; - } + public long logout() { return this.logout; } - public void logout(final Long value) { + public void logout(final long value) { this.logout = value; } + private long login = 0L; + + public long login() { + return this.login; + } + + public void login(final long value) { + this.login = value; + } + @DeleteOnEmpty private @MonotonicNonNull Map kits; From 5b60e32f5aee839ef20ab61d30104cfa2bea95ce Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Thu, 8 Apr 2021 00:03:27 -0400 Subject: [PATCH 37/61] Fix broken map saving --- .../java/com/earth2me/essentials/IUser.java | 4 + .../com/earth2me/essentials/UserData.java | 99 ++++--------------- .../config/EssentialsConfiguration.java | 3 +- .../config/entities/CommandCooldown.java | 28 ++++++ .../config/holders/UserConfigHolder.java | 13 +-- 5 files changed, 61 insertions(+), 86 deletions(-) create mode 100644 Essentials/src/main/java/com/earth2me/essentials/config/entities/CommandCooldown.java diff --git a/Essentials/src/main/java/com/earth2me/essentials/IUser.java b/Essentials/src/main/java/com/earth2me/essentials/IUser.java index fa46f26d59e..42040f93d36 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/IUser.java +++ b/Essentials/src/main/java/com/earth2me/essentials/IUser.java @@ -2,6 +2,7 @@ import com.earth2me.essentials.api.IAsyncTeleport; import com.earth2me.essentials.commands.IEssentialsCommand; +import com.earth2me.essentials.config.entities.CommandCooldown; import net.ess3.api.ITeleport; import net.ess3.api.MaxMoneyException; import net.ess3.api.events.AfkStatusChangeEvent; @@ -169,8 +170,11 @@ public interface IUser { Map getConfigMap(String node); + @Deprecated Map getCommandCooldowns(); + List getCooldownsList(); + Date getCommandCooldownExpiry(String label); void addCommandCooldown(Pattern pattern, Date expiresAt, boolean save); diff --git a/Essentials/src/main/java/com/earth2me/essentials/UserData.java b/Essentials/src/main/java/com/earth2me/essentials/UserData.java index d385852fb5e..f48007aed33 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/UserData.java +++ b/Essentials/src/main/java/com/earth2me/essentials/UserData.java @@ -2,10 +2,10 @@ import com.earth2me.essentials.config.ConfigurateUtil; import com.earth2me.essentials.config.EssentialsUserConfiguration; +import com.earth2me.essentials.config.entities.CommandCooldown; import com.earth2me.essentials.config.holders.UserConfigHolder; import com.earth2me.essentials.utils.NumberUtil; import com.earth2me.essentials.utils.StringUtil; -import com.google.common.collect.ImmutableMap; import net.ess3.api.IEssentials; import net.ess3.api.MaxMoneyException; import org.bukkit.Location; @@ -17,14 +17,12 @@ import java.io.File; import java.math.BigDecimal; import java.util.ArrayList; -import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import java.util.UUID; import java.util.logging.Level; @@ -37,9 +35,6 @@ public abstract class UserData extends PlayerExtension implements IConf { private final EssentialsUserConfiguration config; private UserConfigHolder holder; private BigDecimal money; - // Pattern, Date. Pattern for less pattern creations - private Map commandCooldowns; - private Map kitTimestamps; protected UserData(final Player base, final IEssentials ess) { super(base); @@ -91,8 +86,6 @@ public final void reloadConfig() { } }); money = _getMoney(); - commandCooldowns = _getCommandCooldowns(); - kitTimestamps = _getKitTimestamps(); } private BigDecimal _getMoney() { @@ -553,33 +546,17 @@ public boolean togglePowerToolsEnabled() { return ret; } - private Map _getKitTimestamps() { - final Map node = holder.timestamps().kits(); - if (!node.isEmpty()) { - final Map timestamps = new HashMap<>(); - for (final Map.Entry entry : node.entrySet()) { - if (entry.getValue() instanceof Long) { - timestamps.put(entry.getKey().toLowerCase(Locale.ENGLISH), (Long) entry.getValue()); - } else if (entry.getValue() instanceof Integer) { - timestamps.put(entry.getKey().toLowerCase(Locale.ENGLISH), Long.valueOf((Integer) entry.getValue())); - } - } - return timestamps; - } - return new HashMap<>(); - } - public long getKitTimestamp(String name) { name = name.replace('.', '_').replace('/', '_').toLowerCase(Locale.ENGLISH); - if (kitTimestamps != null && kitTimestamps.containsKey(name)) { - return kitTimestamps.get(name); + if (holder.timestamps().kits() != null && holder.timestamps().kits().containsKey(name)) { + return holder.timestamps().kits().get(name); } return 0L; } public void setKitTimestamp(String name, final long time) { name = name.replace('.', '_').replace('/', '_').toLowerCase(Locale.ENGLISH); - kitTimestamps.put(name, time); + holder.timestamps().kits().put(name, time); config.save(); } @@ -607,83 +584,49 @@ public Map getConfigMap(final String node) { return new HashMap<>(); } - private Map _getCommandCooldowns() { - // See saveCommandCooldowns() for deserialization explanation - final List section = holder.timestamps().commandCooldowns(); - final HashMap result = new HashMap<>(); - for (final Object obj : section) { - final Map map = (Map) obj; - final Pattern pattern = Pattern.compile(map.get("pattern").toString()); - final long expiry = ((Number) map.get("expiry")).longValue(); - result.put(pattern, expiry); - } - return result; + public List getCooldownsList() { + return holder.timestamps().commandCooldowns(); } public Map getCommandCooldowns() { - if (this.commandCooldowns == null) { - return Collections.emptyMap(); + final Map map = new HashMap<>(); + for (final CommandCooldown c : getCooldownsList()) { + map.put(c.pattern(), c.value()); } - return Collections.unmodifiableMap(this.commandCooldowns); + return map; } public Date getCommandCooldownExpiry(final String label) { - if (commandCooldowns != null) { - for (final Entry entry : this.commandCooldowns.entrySet()) { - if (entry.getKey().matcher(label).matches()) { - return new Date(entry.getValue()); - } + for (CommandCooldown cooldown : getCooldownsList()) { + if (cooldown.pattern().matcher(label).matches()) { + return new Date(cooldown.value()); } } return null; } public void addCommandCooldown(final Pattern pattern, final Date expiresAt, final boolean save) { - if (this.commandCooldowns == null) { - this.commandCooldowns = new HashMap<>(); - } - this.commandCooldowns.put(pattern, expiresAt.getTime()); + final CommandCooldown cooldown = new CommandCooldown(); + cooldown.pattern(pattern); + cooldown.value(expiresAt.getTime()); + holder.timestamps().commandCooldowns().add(cooldown); if (save) { - saveCommandCooldowns(); + save(); } } public boolean clearCommandCooldown(final Pattern pattern) { - if (this.commandCooldowns == null) { + if (holder.timestamps().commandCooldowns().isEmpty()) { return false; // false for no modification } - if (this.commandCooldowns.remove(pattern) != null) { - saveCommandCooldowns(); + if (getCooldownsList().removeIf(cooldown -> cooldown.pattern().equals(pattern))) { + save(); return true; } return false; } - private void saveCommandCooldowns() { - // Serialization explanation: - // - // Serialization is done as a map list instead of a config section due to limitations. - // When serializing patterns (which commonly include full stops .) Bukkit/Essentials config framework - // interprets it as a path separator, thus it breaks up the regex into sub nodes causing invalid syntax. - // Thus each command cooldown is instead stored as a Map of {pattern: .., expiry: ..} to work around this. - final List serialized = new ArrayList<>(); - for (final Entry entry : this.commandCooldowns.entrySet()) { - // Don't save expired cooldowns - if (entry.getValue() < System.currentTimeMillis()) { - continue; - } - - final Map map = ImmutableMap.builder() - .put("pattern", entry.getKey().pattern()) - .put("expiry", entry.getValue()) - .build(); - serialized.add(map); - } - holder.timestamps().commandCooldowns(serialized); - save(); - } - public boolean isAcceptingPay() { return holder.acceptingPay(); } diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index 11638f46fd7..974df6d50a9 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -10,7 +10,6 @@ import org.bukkit.Material; import org.spongepowered.configurate.CommentedConfigurationNode; import org.spongepowered.configurate.ConfigurateException; -import org.spongepowered.configurate.ConfigurationOptions; import org.spongepowered.configurate.loader.HeaderMode; import org.spongepowered.configurate.loader.ParsingException; import org.spongepowered.configurate.objectmapping.ObjectMapper; @@ -79,7 +78,7 @@ public EssentialsConfiguration(final File configFile, final String templateName, public EssentialsConfiguration(final File configFile, final String templateName, final String header) { this.configFile = configFile; this.loader = YamlConfigurationLoader.builder() - .defaultOptions(ConfigurationOptions.defaults() + .defaultOptions(opts -> opts .header(header) .serializers(SERIALIZERS)) .headerMode(HeaderMode.PRESET) diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/entities/CommandCooldown.java b/Essentials/src/main/java/com/earth2me/essentials/config/entities/CommandCooldown.java new file mode 100644 index 00000000000..56bac7ae1d0 --- /dev/null +++ b/Essentials/src/main/java/com/earth2me/essentials/config/entities/CommandCooldown.java @@ -0,0 +1,28 @@ +package com.earth2me.essentials.config.entities; + +import org.spongepowered.configurate.objectmapping.ConfigSerializable; + +import java.util.regex.Pattern; + +@ConfigSerializable +public class CommandCooldown { + private Pattern pattern; + + public Pattern pattern() { + return this.pattern; + } + + public void pattern(final Pattern value) { + this.pattern = value; + } + + private Long value; + + public Long value() { + return this.value; + } + + public void value(final Long value) { + this.value = value; + } +} diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java b/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java index 5e7a7dcdfdb..5e888956948 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/holders/UserConfigHolder.java @@ -1,6 +1,7 @@ package com.earth2me.essentials.config.holders; import com.earth2me.essentials.config.annotations.DeleteOnEmpty; +import com.earth2me.essentials.config.entities.CommandCooldown; import org.bukkit.Location; import org.bukkit.Material; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @@ -397,30 +398,30 @@ public void login(final long value) { } @DeleteOnEmpty - private @MonotonicNonNull Map kits; + private @MonotonicNonNull Map kits; - public Map kits() { + public Map kits() { if (this.kits == null) { this.kits = new HashMap<>(); } return this.kits; } - public void kits(final Map value) { + public void kits(final Map value) { this.kits = value; } @DeleteOnEmpty - private @MonotonicNonNull List commandCooldowns; + private @MonotonicNonNull List commandCooldowns; - public List commandCooldowns() { + public List commandCooldowns() { if (this.commandCooldowns == null) { this.commandCooldowns = new ArrayList<>(); } return this.commandCooldowns; } - public void commandCooldowns(final List value) { + public void commandCooldowns(final List value) { this.commandCooldowns = value; } } From 7df21c90fdf41bc3425c2bdc887c87792fed9524 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 26 Apr 2021 09:55:46 -0400 Subject: [PATCH 38/61] Upload tests to actions --- .github/workflows/build.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6157aaebb6b..3f5d56caafd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,6 +39,11 @@ jobs: with: name: EssentialsX plugin jars path: jars/ + - name: Upload Tests + uses: actions/upload-artifact@master + with: + name: Tests + path: Essentials/build/reports/tests/ - name: Deploy with Gradle if: ${{ success() && github.event_name == 'push' && github.repository == 'EssentialsX/Essentials' && github.ref == 'refs/heads/2.x' }} env: From b4a2c5f46957e211e6d10bd8601d8cde5e370b3b Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 26 Apr 2021 09:59:08 -0400 Subject: [PATCH 39/61] Run always --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3f5d56caafd..1c7fbf0217c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,6 +36,7 @@ jobs: ./gradlew build --stacktrace - name: Upload Artifacts uses: actions/upload-artifact@master + if: ${{ always() }} with: name: EssentialsX plugin jars path: jars/ From 98391fd883df753ee3ddd441ae00c215328ddcf7 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 26 Apr 2021 10:02:49 -0400 Subject: [PATCH 40/61] aaaaaaaaaaaaaaaaaaaaaaaaa --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1c7fbf0217c..317494d9006 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,12 +36,12 @@ jobs: ./gradlew build --stacktrace - name: Upload Artifacts uses: actions/upload-artifact@master - if: ${{ always() }} with: name: EssentialsX plugin jars path: jars/ - name: Upload Tests uses: actions/upload-artifact@master + if: ${{ always() }} with: name: Tests path: Essentials/build/reports/tests/ From e8735123c7e10094cb114c648638b7b2a55e338c Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 26 Apr 2021 11:16:31 -0400 Subject: [PATCH 41/61] aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --- Essentials/src/main/java/com/earth2me/essentials/UserData.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/UserData.java b/Essentials/src/main/java/com/earth2me/essentials/UserData.java index f48007aed33..59fa5725be7 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/UserData.java +++ b/Essentials/src/main/java/com/earth2me/essentials/UserData.java @@ -6,6 +6,7 @@ import com.earth2me.essentials.config.holders.UserConfigHolder; import com.earth2me.essentials.utils.NumberUtil; import com.earth2me.essentials.utils.StringUtil; +import io.leangen.geantyref.TypeToken; import net.ess3.api.IEssentials; import net.ess3.api.MaxMoneyException; import org.bukkit.Location; @@ -72,7 +73,7 @@ public final void cleanup() { public final void reloadConfig() { config.load(); try { - holder = config.getRootNode().get(UserConfigHolder.class); + holder = config.getRootNode().get(TypeToken.get(UserConfigHolder.class)); } catch (SerializationException e) { ess.getLogger().log(Level.SEVERE, "Error while reading user config: " + e.getMessage(), e); throw new RuntimeException(e); From ca0f7db0c050751f7041ce734efe91aa3f47e14b Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 26 Apr 2021 12:42:59 -0400 Subject: [PATCH 42/61] FeelsWeirdMan thanks zml :) --- .github/workflows/build.yml | 1 - Essentials/build.gradle | 2 ++ Essentials/src/main/java/com/earth2me/essentials/UserData.java | 3 +-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 317494d9006..3f5d56caafd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -41,7 +41,6 @@ jobs: path: jars/ - name: Upload Tests uses: actions/upload-artifact@master - if: ${{ always() }} with: name: Tests path: Essentials/build/reports/tests/ diff --git a/Essentials/build.gradle b/Essentials/build.gradle index c08f22befba..430340eb6cf 100644 --- a/Essentials/build.gradle +++ b/Essentials/build.gradle @@ -10,6 +10,7 @@ dependencies { api 'org.spongepowered:configurate-yaml:4.0.0' implementation 'org.yaml:snakeyaml:1.+' + implementation 'org.checkerframework:checker-qual:3.7.1' // Providers api project(':providers:BaseProviders') @@ -40,4 +41,5 @@ shadowJar { relocate 'org.spongepowered.configurate', 'com.earth2me.essentials.libs.configurate' relocate 'org.yaml.snakeyaml', 'com.earth2me.essentials.libs.snakeyaml' relocate 'io.leangen.geantyref', 'com.earth2me.essentials.libs.geantyref' + relocate 'org.checkerframework', 'come.earth2me.essentials.libs.checkerframework' } diff --git a/Essentials/src/main/java/com/earth2me/essentials/UserData.java b/Essentials/src/main/java/com/earth2me/essentials/UserData.java index 59fa5725be7..f48007aed33 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/UserData.java +++ b/Essentials/src/main/java/com/earth2me/essentials/UserData.java @@ -6,7 +6,6 @@ import com.earth2me.essentials.config.holders.UserConfigHolder; import com.earth2me.essentials.utils.NumberUtil; import com.earth2me.essentials.utils.StringUtil; -import io.leangen.geantyref.TypeToken; import net.ess3.api.IEssentials; import net.ess3.api.MaxMoneyException; import org.bukkit.Location; @@ -73,7 +72,7 @@ public final void cleanup() { public final void reloadConfig() { config.load(); try { - holder = config.getRootNode().get(TypeToken.get(UserConfigHolder.class)); + holder = config.getRootNode().get(UserConfigHolder.class); } catch (SerializationException e) { ess.getLogger().log(Level.SEVERE, "Error while reading user config: " + e.getMessage(), e); throw new RuntimeException(e); From 03a164ccafdbb3a701de13f461c4e553d3cb4456 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Tue, 27 Apr 2021 07:45:55 -0400 Subject: [PATCH 43/61] Remove unused parameter in Warps --- .../src/main/java/com/earth2me/essentials/Essentials.java | 2 +- Essentials/src/main/java/com/earth2me/essentials/Warps.java | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java index da6bfefc4cb..94f5549e506 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Essentials.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Essentials.java @@ -266,7 +266,7 @@ public void onEnable() { upgrade.afterSettings(); execTimer.mark("Upgrade2"); - warps = new Warps(getServer(), this.getDataFolder()); + warps = new Warps(this.getDataFolder()); confList.add(warps); execTimer.mark("Init(Warp)"); diff --git a/Essentials/src/main/java/com/earth2me/essentials/Warps.java b/Essentials/src/main/java/com/earth2me/essentials/Warps.java index c163d551058..f1f671fc039 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Warps.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Warps.java @@ -6,7 +6,6 @@ import net.ess3.api.InvalidNameException; import net.ess3.api.InvalidWorldException; import org.bukkit.Location; -import org.bukkit.Server; import java.io.File; import java.util.ArrayList; @@ -25,10 +24,8 @@ public class Warps implements IConf, net.ess3.api.IWarps { private static final Logger logger = Logger.getLogger("Essentials"); private final Map warpPoints = new HashMap<>(); private final File warpsFolder; - private final Server server; - public Warps(final Server server, final File dataFolder) { - this.server = server; + public Warps(final File dataFolder) { warpsFolder = new File(dataFolder, "warps"); if (!warpsFolder.exists()) { warpsFolder.mkdirs(); From b0864d6ccdc756addc2954b4982fa9ea06ab7575 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sun, 2 May 2021 15:10:22 -0400 Subject: [PATCH 44/61] Restore build.yml --- .github/workflows/build.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3f5d56caafd..6157aaebb6b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,11 +39,6 @@ jobs: with: name: EssentialsX plugin jars path: jars/ - - name: Upload Tests - uses: actions/upload-artifact@master - with: - name: Tests - path: Essentials/build/reports/tests/ - name: Deploy with Gradle if: ${{ success() && github.event_name == 'push' && github.repository == 'EssentialsX/Essentials' && github.ref == 'refs/heads/2.x' }} env: From 44b2daaae54e1aba6e2f1b028e10c6a897b0bed2 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 31 May 2021 11:33:25 -0400 Subject: [PATCH 45/61] Update Essentials/build.gradle Co-authored-by: MD <1917406+mdcfe@users.noreply.github.com> --- Essentials/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Essentials/build.gradle b/Essentials/build.gradle index 430340eb6cf..4d55741afac 100644 --- a/Essentials/build.gradle +++ b/Essentials/build.gradle @@ -41,5 +41,5 @@ shadowJar { relocate 'org.spongepowered.configurate', 'com.earth2me.essentials.libs.configurate' relocate 'org.yaml.snakeyaml', 'com.earth2me.essentials.libs.snakeyaml' relocate 'io.leangen.geantyref', 'com.earth2me.essentials.libs.geantyref' - relocate 'org.checkerframework', 'come.earth2me.essentials.libs.checkerframework' + relocate 'org.checkerframework', 'com.earth2me.essentials.libs.checkerframework' } From 1f6126859b3d38589f28d72503932743aee72288 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 31 May 2021 11:33:58 -0400 Subject: [PATCH 46/61] Update Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java Co-authored-by: MD <1917406+mdcfe@users.noreply.github.com> --- .../main/java/com/earth2me/essentials/EssentialsUpgrade.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java index 17bd573e64d..e0d7a8d611d 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java @@ -151,7 +151,7 @@ public void convertStupidNames() { return; } - LOGGER.info("Attempting to migrate legacy path names to Configurate"); + LOGGER.info("Attempting to migrate legacy userdata keys to Configurate"); final File userdataFolder = new File(ess.getDataFolder(), "userdata"); if (!userdataFolder.exists() || !userdataFolder.isDirectory()) { From a5c2018ad5375796f07da3e41e042630a2e7a484 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 31 May 2021 11:34:05 -0400 Subject: [PATCH 47/61] Update Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java Co-authored-by: MD <1917406+mdcfe@users.noreply.github.com> --- .../main/java/com/earth2me/essentials/EssentialsUpgrade.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java index e0d7a8d611d..ef7c30c1e17 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java @@ -197,7 +197,7 @@ public void convertStupidNames() { } doneFile.setProperty("updateUsersLegacyPathNames", true); doneFile.save(); - LOGGER.info("Done converting legacy path names to Configurate."); + LOGGER.info("Done converting legacy userdata keys to Configurate."); } public void convertIgnoreList() { From 326800617bdc736f5d4e0b54761fc267eb4f1272 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 31 May 2021 11:34:46 -0400 Subject: [PATCH 48/61] Update Essentials/build.gradle Co-authored-by: MD <1917406+mdcfe@users.noreply.github.com> --- Essentials/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Essentials/build.gradle b/Essentials/build.gradle index 4d55741afac..21c14626faa 100644 --- a/Essentials/build.gradle +++ b/Essentials/build.gradle @@ -8,7 +8,7 @@ dependencies { api 'org.bstats:bstats-bukkit:1.8' - api 'org.spongepowered:configurate-yaml:4.0.0' + api 'org.spongepowered:configurate-yaml:4.1.1' implementation 'org.yaml:snakeyaml:1.+' implementation 'org.checkerframework:checker-qual:3.7.1' From e4ae4efe8f9a09b41957a60524f11e0e9f2b41eb Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 31 May 2021 18:51:58 -0400 Subject: [PATCH 49/61] Re-add custom property "api" --- .../com/earth2me/essentials/UserData.java | 44 ++++++++----------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/UserData.java b/Essentials/src/main/java/com/earth2me/essentials/UserData.java index f48007aed33..e191f24af52 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/UserData.java +++ b/Essentials/src/main/java/com/earth2me/essentials/UserData.java @@ -19,7 +19,6 @@ import java.util.ArrayList; import java.util.Date; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; @@ -560,30 +559,6 @@ public void setKitTimestamp(String name, final long time) { config.save(); } - public Set getConfigKeys() { - final Set keys = ConfigurateUtil.getKeys(config.getSection("info")); - if (!keys.isEmpty()) { - return keys; - } - return new HashSet<>(); - } - - public Map getConfigMap() { - final Map node = ConfigurateUtil.getRawMap(config.getSection("info")); - if (!node.isEmpty()) { - return node; - } - return new HashMap<>(); - } - - public Map getConfigMap(final String node) { - final Map nodeMap = ConfigurateUtil.getRawMap(config.getSection("info." + node)); - if (!nodeMap.isEmpty()) { - return nodeMap; - } - return new HashMap<>(); - } - public List getCooldownsList() { return holder.timestamps().commandCooldowns(); } @@ -689,6 +664,23 @@ public void stopTransaction() { } public void setConfigProperty(String node, Object object) { - throw new UnsupportedOperationException("This method is unused in EssentialsX and is scheduled for removal. Please use another method!"); + setConfigPropertyRaw("info." + node, object); + } + + public void setConfigPropertyRaw(String node, Object object) { + config.setRaw(node, object); + config.save(); + } + + public Set getConfigKeys() { + return ConfigurateUtil.getKeys(config.getSection("info")); + } + + public Map getConfigMap() { + return ConfigurateUtil.getRawMap(config.getSection("info")); + } + + public Map getConfigMap(final String node) { + return ConfigurateUtil.getRawMap(config.getSection("info." + node)); } } From bbcb0b55270842d5f345b470397fed3b1bd5d43f Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 31 May 2021 18:52:08 -0400 Subject: [PATCH 50/61] Remove unused interface --- Essentials/src/main/java/net/ess3/api/ISpawnStorage.java | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 Essentials/src/main/java/net/ess3/api/ISpawnStorage.java diff --git a/Essentials/src/main/java/net/ess3/api/ISpawnStorage.java b/Essentials/src/main/java/net/ess3/api/ISpawnStorage.java deleted file mode 100644 index 9a12c740f60..00000000000 --- a/Essentials/src/main/java/net/ess3/api/ISpawnStorage.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.ess3.api; - -import com.earth2me.essentials.IConf; - -/** - * This interface contains basic API functions for Essentials Spawn. - */ -public interface ISpawnStorage extends IConf { -} From d961c5cd98b2722b206e16e922d3f76672466bba Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 31 May 2021 19:06:35 -0400 Subject: [PATCH 51/61] Remove outdated comment --- Essentials/src/main/java/com/earth2me/essentials/Kits.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/Kits.java b/Essentials/src/main/java/com/earth2me/essentials/Kits.java index c5a7896e494..193efc33069 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Kits.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Kits.java @@ -62,11 +62,6 @@ public Map getKit(String name) { name = name.replace('.', '_').replace('/', '_'); if (getKits() != null) { final CommentedConfigurationNode kits = getKits(); - // For some reason, YAML doesn't sees keys as always lowercase even if they aren't defined like that. - // Workaround is to toLowercase when getting from the config, but showing normally elsewhere. - // ODDLY ENOUGH when you get the configuration section for ALL kits, it will return the proper - // case of each kit. But when you check for each kit's configuration section, it won't return the kit - // you just found if you don't toLowercase it. final CommentedConfigurationNode kitSection = kits.node(name.toLowerCase()); if (!kitSection.virtual() && kitSection.isMap()) { return ConfigurateUtil.getRawMap(kitSection); From 19a43770bc10480080d4ca30e6ef21394c380434 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 31 May 2021 19:09:21 -0400 Subject: [PATCH 52/61] Make upgrade method more descriptive --- .../main/java/com/earth2me/essentials/EssentialsUpgrade.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java index ef7c30c1e17..16fe6e9f816 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsUpgrade.java @@ -146,7 +146,7 @@ public static void uuidFileConvert(final IEssentials ess, final Boolean ignoreUF ess.getLogger().info("To rerun the conversion type /essentials uuidconvert"); } - public void convertStupidNames() { + public void convertStupidCamelCaseUserdataKeys() { if (doneFile.getBoolean("updateUsersLegacyPathNames", false)) { return; } @@ -819,6 +819,6 @@ public void afterSettings() { warnMetrics(); repairUserMap(); convertIgnoreList(); - convertStupidNames(); + convertStupidCamelCaseUserdataKeys(); } } From 91dc4ccdc415b176c39561250a9c409b36212372 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 31 May 2021 19:10:43 -0400 Subject: [PATCH 53/61] Upgrade VaultEconomyProvider to Configurate --- .../essentials/economy/vault/VaultEconomyProvider.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/economy/vault/VaultEconomyProvider.java b/Essentials/src/main/java/com/earth2me/essentials/economy/vault/VaultEconomyProvider.java index a2907449642..ffe6f1f2e20 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/economy/vault/VaultEconomyProvider.java +++ b/Essentials/src/main/java/com/earth2me/essentials/economy/vault/VaultEconomyProvider.java @@ -1,9 +1,9 @@ package com.earth2me.essentials.economy.vault; import com.earth2me.essentials.Essentials; -import com.earth2me.essentials.EssentialsUserConf; import com.earth2me.essentials.api.NoLoanPermittedException; import com.earth2me.essentials.api.UserDoesNotExistException; +import com.earth2me.essentials.config.EssentialsUserConfiguration; import com.earth2me.essentials.utils.NumberUtil; import com.google.common.base.Charsets; import net.ess3.api.MaxMoneyException; @@ -303,12 +303,12 @@ public boolean createPlayerAccount(OfflinePlayer player) { LOGGER.log(Level.SEVERE, MessageFormat.format(WARN_NPC_RECREATE_1, player.getName(), player.getUniqueId().toString()), new RuntimeException()); LOGGER.log(Level.SEVERE, WARN_NPC_RECREATE_2); } - final EssentialsUserConf npcConfig = new EssentialsUserConf(player.getName(), player.getUniqueId(), npcFile); + final EssentialsUserConfiguration npcConfig = new EssentialsUserConfiguration(player.getName(), player.getUniqueId(), npcFile); npcConfig.load(); npcConfig.setProperty("npc", true); npcConfig.setProperty("lastAccountName", player.getName()); npcConfig.setProperty("money", ess.getSettings().getStartingBalance()); - npcConfig.forceSave(); + npcConfig.blockingSave(); ess.getUserMap().trackUUID(player.getUniqueId(), player.getName(), false); return true; } From 6e898ee947e7304f9cd671bcf5e1bd8ea87e168d Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 31 May 2021 19:12:18 -0400 Subject: [PATCH 54/61] Reclarify comment in Kits --- Essentials/src/main/java/com/earth2me/essentials/Kits.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Essentials/src/main/java/com/earth2me/essentials/Kits.java b/Essentials/src/main/java/com/earth2me/essentials/Kits.java index 193efc33069..5cb419babc1 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Kits.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Kits.java @@ -62,6 +62,8 @@ public Map getKit(String name) { name = name.replace('.', '_').replace('/', '_'); if (getKits() != null) { final CommentedConfigurationNode kits = getKits(); + // Other parts of the codebase/3rd party plugins expect us to lowercase kit names here. + // This isn't strictly needed for the future of Essentials, but for compatibility it's here. final CommentedConfigurationNode kitSection = kits.node(name.toLowerCase()); if (!kitSection.virtual() && kitSection.isMap()) { return ConfigurateUtil.getRawMap(kitSection); From b71c4b7add82d388ee16f81f61d5321dc1f3294e Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sun, 6 Jun 2021 16:17:13 -0400 Subject: [PATCH 55/61] Fix XMPP access to relocated classes --- .../java/com/earth2me/essentials/config/ConfigurateUtil.java | 4 ++++ .../main/java/com/earth2me/essentials/xmpp/UserManager.java | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/ConfigurateUtil.java b/Essentials/src/main/java/com/earth2me/essentials/config/ConfigurateUtil.java index 8daaec77478..fccaf0ffbed 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/ConfigurateUtil.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/ConfigurateUtil.java @@ -17,6 +17,10 @@ public final class ConfigurateUtil { private ConfigurateUtil() { } + public static Set getRootNodeKeys(final EssentialsConfiguration config) { + return getKeys(config.getRootNode()); + } + public static Set getKeys(final CommentedConfigurationNode node) { if (node == null || !node.isMap()) { return Collections.emptySet(); diff --git a/EssentialsXMPP/src/main/java/com/earth2me/essentials/xmpp/UserManager.java b/EssentialsXMPP/src/main/java/com/earth2me/essentials/xmpp/UserManager.java index 73f6ba0f5d9..d559b4aa883 100644 --- a/EssentialsXMPP/src/main/java/com/earth2me/essentials/xmpp/UserManager.java +++ b/EssentialsXMPP/src/main/java/com/earth2me/essentials/xmpp/UserManager.java @@ -37,7 +37,7 @@ final String getAddress(final String username) { } final String getUserByAddress(final String search) { - final Set usernames = ConfigurateUtil.getKeys(users.getRootNode()); + final Set usernames = ConfigurateUtil.getRootNodeKeys(users); for (final String username : usernames) { final String address = users.getString(username + "." + ADDRESS, null); if (search.equalsIgnoreCase(address)) { @@ -68,7 +68,7 @@ private void setUser(final String username, final String address, final boolean public final void reloadConfig() { users.load(); spyusers.clear(); - final Set keys = ConfigurateUtil.getKeys(users.getRootNode()); + final Set keys = ConfigurateUtil.getRootNodeKeys(users); for (final String key : keys) { if (isSpy(key)) { final String address = getAddress(key); From af47a97908d79227672bc452de3449abe4012597 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sun, 6 Jun 2021 17:04:36 -0400 Subject: [PATCH 56/61] Update Essentials/src/main/java/com/earth2me/essentials/api/IJails.java Co-authored-by: Riley Park --- .../src/main/java/com/earth2me/essentials/api/IJails.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/api/IJails.java b/Essentials/src/main/java/com/earth2me/essentials/api/IJails.java index 89370f0682a..94947c9c298 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/api/IJails.java +++ b/Essentials/src/main/java/com/earth2me/essentials/api/IJails.java @@ -77,7 +77,7 @@ public interface IJails extends IConf { void setJail(String jailName, Location loc) throws Exception; /** - * Beings a transaction + * Begins a transaction */ void startTransaction(); From 878fbb77c7f5e2e86e70b0c5ccae5ff8c4e64dc1 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sun, 6 Jun 2021 18:33:32 -0400 Subject: [PATCH 57/61] Apply suggestions from code review Co-authored-by: zml --- .../com/earth2me/essentials/config/EssentialsConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java index 974df6d50a9..90b66f4e4a9 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java +++ b/Essentials/src/main/java/com/earth2me/essentials/config/EssentialsConfiguration.java @@ -305,7 +305,7 @@ private CommentedConfigurationNode getInternal(final String path) { } public boolean hasProperty(final String path) { - return !configurationNode.node(toSplitRoot(path)).virtual(); + return !configurationNode.node(toSplitRoot(path)).isNull(); } public Object[] toSplitRoot(String node) { From 7a1a9893cb57075db1daaf4c382d5fee2734afa2 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sun, 6 Jun 2021 18:33:50 -0400 Subject: [PATCH 58/61] Make a less troll-y command cost map --- .../java/com/earth2me/essentials/Settings.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/Settings.java b/Essentials/src/main/java/com/earth2me/essentials/Settings.java index 31ce8194830..4efe6227631 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Settings.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Settings.java @@ -63,7 +63,7 @@ public class Settings implements net.ess3.api.ISettings { private boolean forceDisableTeleportSafety; private Set disabledCommands = new HashSet<>(); private final transient Map disabledBukkitCommands = new HashMap<>(); - private CommentedConfigurationNode commandCosts; + private Map commandCosts; private Set socialSpyCommands = new HashSet<>(); private Set muteCommands = new HashSet<>(); private String nicknamePrefix = "~"; @@ -342,10 +342,10 @@ public BigDecimal getCommandCost(final IEssentialsCommand cmd) { return getCommandCost(cmd.getName()); } - private CommentedConfigurationNode _getCommandCosts() { + private Map _getCommandCosts() { final Map section = ConfigurateUtil.getMap(config.getSection("command-costs")); if (!section.isEmpty()) { - final CommentedConfigurationNode newSection = config.newSection(); + final Map newMap = new HashMap<>(); for (Map.Entry entry : section.entrySet()) { final String command = entry.getKey(); final CommentedConfigurationNode node = entry.getValue(); @@ -354,14 +354,14 @@ private CommentedConfigurationNode _getCommandCosts() { } try { if (ConfigurateUtil.isDouble(node)) { - newSection.node(command.toLowerCase(Locale.ENGLISH)).set(node.getDouble()); + newMap.put(command.toLowerCase(Locale.ENGLISH), BigDecimal.valueOf(node.getDouble())); } else if (ConfigurateUtil.isInt(node)) { - newSection.node(command.toLowerCase(Locale.ENGLISH)).set((double) node.getInt()); + newMap.put(command.toLowerCase(Locale.ENGLISH), BigDecimal.valueOf(node.getInt())); } else if (ConfigurateUtil.isString(node)) { final String costString = node.getString(); //noinspection ConstantConditions final double cost = Double.parseDouble(costString.trim().replace("$", "").replace(getCurrencySymbol(), "").replaceAll("\\W", "")); - newSection.node(command.toLowerCase(Locale.ENGLISH)).set(cost); + newMap.put(command.toLowerCase(Locale.ENGLISH), BigDecimal.valueOf(cost)); } else { ess.getLogger().warning("Invalid command cost for: " + command); } @@ -369,7 +369,7 @@ private CommentedConfigurationNode _getCommandCosts() { ess.getLogger().warning("Invalid command cost for: " + command); } } - return newSection; + return newMap; } return null; } @@ -377,8 +377,8 @@ private CommentedConfigurationNode _getCommandCosts() { @Override public BigDecimal getCommandCost(String name) { name = name.replace('.', '_').replace('/', '_'); - if (commandCosts != null) { - return ConfigurateUtil.toBigDecimal(commandCosts.getString(name), BigDecimal.ZERO); + if (commandCosts != null && commandCosts.containsKey(name)) { + return commandCosts.get(name); } return BigDecimal.ZERO; } From 7047f430ec4c5f3e1b286d3b856a493462c9f4c7 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sun, 6 Jun 2021 18:34:10 -0400 Subject: [PATCH 59/61] Make zml happy in createkit command --- .../essentials/commands/Commandcreatekit.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandcreatekit.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandcreatekit.java index 9a362f0e62e..590d28779ba 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandcreatekit.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandcreatekit.java @@ -11,7 +11,6 @@ import org.bukkit.Material; import org.bukkit.Server; import org.bukkit.inventory.ItemStack; -import org.spongepowered.configurate.BasicConfigurationNode; import org.spongepowered.configurate.ConfigurationNode; import org.spongepowered.configurate.yaml.NodeStyle; import org.spongepowered.configurate.yaml.YamlConfigurationLoader; @@ -70,19 +69,17 @@ public void run(final Server server, final User user, final String commandLabel, private void uploadPaste(final CommandSource sender, final String kitName, final long delay, final List list) { executorService.submit(() -> { try { - final ConfigurationNode config = BasicConfigurationNode.root(); + final StringWriter sw = new StringWriter(); + final YamlConfigurationLoader loader = YamlConfigurationLoader.builder().sink(() -> new BufferedWriter(sw)).indent(2).nodeStyle(NodeStyle.BLOCK).build(); + + final ConfigurationNode config = loader.createNode(); config.node("kits", kitName, "delay").set(delay); config.node("kits", kitName, "items").set(list); - final StringWriter sw = new StringWriter(); - - final YamlConfigurationLoader loader = YamlConfigurationLoader.builder().sink(() -> new BufferedWriter(sw)).indent(2).nodeStyle(NodeStyle.BLOCK).build(); + sw.append("# Copy the kit code below into the kits section in your config.yml file\n"); loader.save(config); - String fileContents = "# Copy the kit code below into the kits section in your config.yml file\n"; - fileContents += sw.toString(); - sw.flush(); - sw.close(); + final String fileContents = sw.toString(); final HttpURLConnection connection = (HttpURLConnection) new URL(PASTE_UPLOAD_URL).openConnection(); connection.setRequestMethod("POST"); From b7dfc0420194c4bfdb1ae3b4a7ede053942eb890 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 7 Jun 2021 07:32:18 -0400 Subject: [PATCH 60/61] Fix checker-qual scope + remove its relocation --- Essentials/build.gradle | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Essentials/build.gradle b/Essentials/build.gradle index 21c14626faa..7e68285a871 100644 --- a/Essentials/build.gradle +++ b/Essentials/build.gradle @@ -10,7 +10,7 @@ dependencies { api 'org.spongepowered:configurate-yaml:4.1.1' implementation 'org.yaml:snakeyaml:1.+' - implementation 'org.checkerframework:checker-qual:3.7.1' + testImplementation 'org.checkerframework:checker-qual:3.7.1' // Providers api project(':providers:BaseProviders') @@ -41,5 +41,4 @@ shadowJar { relocate 'org.spongepowered.configurate', 'com.earth2me.essentials.libs.configurate' relocate 'org.yaml.snakeyaml', 'com.earth2me.essentials.libs.snakeyaml' relocate 'io.leangen.geantyref', 'com.earth2me.essentials.libs.geantyref' - relocate 'org.checkerframework', 'com.earth2me.essentials.libs.checkerframework' } From 3de18d86a06a6f323177522a5e5687c5b977b47f Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Mon, 7 Jun 2021 07:33:51 -0400 Subject: [PATCH 61/61] Prevent small amounts of trolling --- Essentials/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Essentials/build.gradle b/Essentials/build.gradle index 7e68285a871..9292f206e2f 100644 --- a/Essentials/build.gradle +++ b/Essentials/build.gradle @@ -8,7 +8,7 @@ dependencies { api 'org.bstats:bstats-bukkit:1.8' - api 'org.spongepowered:configurate-yaml:4.1.1' + implementation 'org.spongepowered:configurate-yaml:4.1.1' implementation 'org.yaml:snakeyaml:1.+' testImplementation 'org.checkerframework:checker-qual:3.7.1'