From acd97a1cb0746a11ee9c510643ce2e2ab65fd0f1 Mon Sep 17 00:00:00 2001 From: William Date: Tue, 11 Oct 2022 20:42:15 +0100 Subject: [PATCH] Migrate config to Annotaml --- bukkit/build.gradle | 2 + .../william278/husksync/BukkitHuskSync.java | 28 +- .../husksync/migrator/LegacyMigrator.java | 11 +- .../husksync/migrator/MpdbMigrator.java | 15 +- .../husksync/player/BukkitPlayer.java | 18 +- common/build.gradle | 2 + .../william278/husksync/config/Locales.java | 44 +- .../william278/husksync/config/Settings.java | 390 +++++++----------- .../husksync/data/StatusDataFlag.java | 29 +- .../husksync/database/MySqlDatabase.java | 34 +- .../husksync/listener/EventListener.java | 9 +- .../husksync/player/OnlineUser.java | 56 ++- .../husksync/redis/RedisManager.java | 11 +- .../husksync/player/DummyPlayer.java | 3 +- 14 files changed, 300 insertions(+), 352 deletions(-) diff --git a/bukkit/build.gradle b/bukkit/build.gradle index d190e99e..36c20272 100644 --- a/bukkit/build.gradle +++ b/bukkit/build.gradle @@ -12,6 +12,7 @@ dependencies { compileOnly 'dev.dejvokep:boosted-yaml:1.3' compileOnly 'com.zaxxer:HikariCP:5.0.1' compileOnly 'net.william278:DesertWell:1.1' + compileOnly 'net.william278:Annotaml:2.0' } shadowJar { @@ -35,4 +36,5 @@ shadowJar { relocate 'org.bstats', 'net.william278.husksync.libraries.bstats' relocate 'net.william278.mpdbconverter', 'net.william278.husksync.libraries.mpdbconverter' relocate 'net.william278.hslmigrator', 'net.william278.husksync.libraries.hslconverter' + relocate 'net.william278.annotaml', 'net.william278.husksync.libraries.annotaml' } \ No newline at end of file diff --git a/bukkit/src/main/java/net/william278/husksync/BukkitHuskSync.java b/bukkit/src/main/java/net/william278/husksync/BukkitHuskSync.java index b0074b0c..e0ffacbd 100644 --- a/bukkit/src/main/java/net/william278/husksync/BukkitHuskSync.java +++ b/bukkit/src/main/java/net/william278/husksync/BukkitHuskSync.java @@ -1,12 +1,7 @@ package net.william278.husksync; -import dev.dejvokep.boostedyaml.YamlDocument; -import dev.dejvokep.boostedyaml.dvs.versioning.BasicVersioning; -import dev.dejvokep.boostedyaml.settings.dumper.DumperSettings; -import dev.dejvokep.boostedyaml.settings.general.GeneralSettings; -import dev.dejvokep.boostedyaml.settings.loader.LoaderSettings; -import dev.dejvokep.boostedyaml.settings.updater.UpdaterSettings; import net.kyori.adventure.platform.bukkit.BukkitAudiences; +import net.william278.annotaml.Annotaml; import net.william278.desertwell.Version; import net.william278.husksync.command.BukkitCommand; import net.william278.husksync.command.BukkitCommandType; @@ -45,6 +40,7 @@ import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicBoolean; @@ -102,14 +98,14 @@ public class BukkitHuskSync extends JavaPlugin implements HuskSync { getLoggingAdapter().log(Level.INFO, "Loading plugin configuration settings & locales..."); initialized.set(reload().join()); if (initialized.get()) { - logger.showDebugLogs(settings.getBooleanValue(Settings.ConfigOption.DEBUG_LOGGING)); + logger.showDebugLogs(settings.debugLogging); getLoggingAdapter().log(Level.INFO, "Successfully loaded plugin configuration settings & locales"); } else { throw new HuskSyncInitializationException("Failed to load plugin configuration settings and/or locales"); } // Prepare data adapter - if (settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_COMPRESS_DATA)) { + if (settings.compressData) { dataAdapter = new CompressedDataAdapter(); } else { dataAdapter = new JsonDataAdapter(); @@ -189,7 +185,7 @@ public class BukkitHuskSync extends JavaPlugin implements HuskSync { } // Check for updates - if (settings.getBooleanValue(Settings.ConfigOption.CHECK_FOR_UPDATES)) { + if (settings.checkForUpdates) { getLoggingAdapter().log(Level.INFO, "Checking for updates..."); getLatestVersionIfOutdated().thenAccept(newestVersion -> newestVersion.ifPresent(newVersion -> getLoggingAdapter().log(Level.WARNING, @@ -325,11 +321,17 @@ public class BukkitHuskSync extends JavaPlugin implements HuskSync { public CompletableFuture reload() { return CompletableFuture.supplyAsync(() -> { try { - this.settings = Settings.load(YamlDocument.create(new File(getDataFolder(), "config.yml"), Objects.requireNonNull(resourceReader.getResource("config.yml")), GeneralSettings.builder().setUseDefaults(false).build(), LoaderSettings.builder().setAutoUpdate(true).build(), DumperSettings.builder().setEncoding(DumperSettings.Encoding.UNICODE).build(), UpdaterSettings.builder().setVersioning(new BasicVersioning("config_version")).build())); - - this.locales = Locales.load(YamlDocument.create(new File(getDataFolder(), "messages-" + settings.getStringValue(Settings.ConfigOption.LANGUAGE) + ".yml"), Objects.requireNonNull(resourceReader.getResource("locales/" + settings.getStringValue(Settings.ConfigOption.LANGUAGE) + ".yml")))); + // Load plugin settings + this.settings = Annotaml.create(new File(getDataFolder(), "config.yml"), new Settings()).get(); + + // Load locales from language preset default + final Locales languagePresets = Annotaml.create(Locales.class, + Objects.requireNonNull(getResource("locales/" + settings.language + ".yml"))).get(); + this.locales = Annotaml.create(new File(getDataFolder(), "messages_" + settings.language + ".yml"), + languagePresets).get(); return true; - } catch (IOException | NullPointerException e) { + } catch (IOException | NullPointerException | InvocationTargetException | IllegalAccessException | + InstantiationException e) { getLoggingAdapter().log(Level.SEVERE, "Failed to load data from the config", e); return false; } diff --git a/bukkit/src/main/java/net/william278/husksync/migrator/LegacyMigrator.java b/bukkit/src/main/java/net/william278/husksync/migrator/LegacyMigrator.java index 11c3bdff..e99594e8 100644 --- a/bukkit/src/main/java/net/william278/husksync/migrator/LegacyMigrator.java +++ b/bukkit/src/main/java/net/william278/husksync/migrator/LegacyMigrator.java @@ -4,7 +4,6 @@ import com.zaxxer.hikari.HikariDataSource; import me.william278.husksync.bukkit.data.DataSerializer; import net.william278.hslmigrator.HSLConverter; import net.william278.husksync.HuskSync; -import net.william278.husksync.config.Settings; import net.william278.husksync.data.*; import net.william278.husksync.player.User; import org.bukkit.Material; @@ -38,11 +37,11 @@ public class LegacyMigrator extends Migrator { public LegacyMigrator(@NotNull HuskSync plugin) { super(plugin); this.hslConverter = HSLConverter.getInstance(); - this.sourceHost = plugin.getSettings().getStringValue(Settings.ConfigOption.DATABASE_HOST); - this.sourcePort = plugin.getSettings().getIntegerValue(Settings.ConfigOption.DATABASE_PORT); - this.sourceUsername = plugin.getSettings().getStringValue(Settings.ConfigOption.DATABASE_USERNAME); - this.sourcePassword = plugin.getSettings().getStringValue(Settings.ConfigOption.DATABASE_PASSWORD); - this.sourceDatabase = plugin.getSettings().getStringValue(Settings.ConfigOption.DATABASE_NAME); + this.sourceHost = plugin.getSettings().mySqlHost; + this.sourcePort = plugin.getSettings().mySqlPort; + this.sourceUsername = plugin.getSettings().mySqlUsername; + this.sourcePassword = plugin.getSettings().mySqlPassword; + this.sourceDatabase = plugin.getSettings().mySqlDatabase; this.sourcePlayersTable = "husksync_players"; this.sourceDataTable = "husksync_data"; this.minecraftVersion = plugin.getMinecraftVersion().toString(); diff --git a/bukkit/src/main/java/net/william278/husksync/migrator/MpdbMigrator.java b/bukkit/src/main/java/net/william278/husksync/migrator/MpdbMigrator.java index df5dbd1d..e8938d46 100644 --- a/bukkit/src/main/java/net/william278/husksync/migrator/MpdbMigrator.java +++ b/bukkit/src/main/java/net/william278/husksync/migrator/MpdbMigrator.java @@ -2,7 +2,6 @@ package net.william278.husksync.migrator; import com.zaxxer.hikari.HikariDataSource; import net.william278.husksync.BukkitHuskSync; -import net.william278.husksync.config.Settings; import net.william278.husksync.data.*; import net.william278.husksync.player.User; import net.william278.mpdbconverter.MPDBConverter; @@ -16,7 +15,9 @@ import org.jetbrains.annotations.NotNull; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; @@ -41,11 +42,11 @@ public class MpdbMigrator extends Migrator { public MpdbMigrator(@NotNull BukkitHuskSync plugin, @NotNull Plugin mySqlPlayerDataBridge) { super(plugin); this.mpdbConverter = MPDBConverter.getInstance(mySqlPlayerDataBridge); - this.sourceHost = plugin.getSettings().getStringValue(Settings.ConfigOption.DATABASE_HOST); - this.sourcePort = plugin.getSettings().getIntegerValue(Settings.ConfigOption.DATABASE_PORT); - this.sourceUsername = plugin.getSettings().getStringValue(Settings.ConfigOption.DATABASE_USERNAME); - this.sourcePassword = plugin.getSettings().getStringValue(Settings.ConfigOption.DATABASE_PASSWORD); - this.sourceDatabase = plugin.getSettings().getStringValue(Settings.ConfigOption.DATABASE_NAME); + this.sourceHost = plugin.getSettings().mySqlHost; + this.sourcePort = plugin.getSettings().mySqlPort; + this.sourceUsername = plugin.getSettings().mySqlUsername; + this.sourcePassword = plugin.getSettings().mySqlPassword; + this.sourceDatabase = plugin.getSettings().mySqlDatabase; this.sourceInventoryTable = "mpdb_inventory"; this.sourceEnderChestTable = "mpdb_enderchest"; this.sourceExperienceTable = "mpdb_experience"; diff --git a/bukkit/src/main/java/net/william278/husksync/player/BukkitPlayer.java b/bukkit/src/main/java/net/william278/husksync/player/BukkitPlayer.java index 3fe73400..49f340ff 100644 --- a/bukkit/src/main/java/net/william278/husksync/player/BukkitPlayer.java +++ b/bukkit/src/main/java/net/william278/husksync/player/BukkitPlayer.java @@ -5,6 +5,7 @@ import de.themoep.minedown.adventure.MineDownParser; import net.kyori.adventure.audience.Audience; import net.william278.desertwell.Version; import net.william278.husksync.BukkitHuskSync; +import net.william278.husksync.config.Settings; import net.william278.husksync.data.*; import net.william278.husksync.editor.ItemEditorMenu; import org.bukkit.*; @@ -83,19 +84,18 @@ public class BukkitPlayer extends OnlineUser { } @Override - public CompletableFuture setStatus(@NotNull StatusData statusData, - @NotNull List statusDataFlags) { + public CompletableFuture setStatus(@NotNull StatusData statusData, @NotNull Settings settings) { return CompletableFuture.runAsync(() -> { double currentMaxHealth = Objects.requireNonNull(player.getAttribute(Attribute.GENERIC_MAX_HEALTH)) .getBaseValue(); - if (statusDataFlags.contains(StatusDataFlag.SET_MAX_HEALTH)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.MAX_HEALTH)) { if (statusData.maxHealth != 0d) { Objects.requireNonNull(player.getAttribute(Attribute.GENERIC_MAX_HEALTH)) .setBaseValue(statusData.maxHealth); currentMaxHealth = statusData.maxHealth; } } - if (statusDataFlags.contains(StatusDataFlag.SET_HEALTH)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.HEALTH)) { final double currentHealth = player.getHealth(); if (statusData.health != currentHealth) { final double healthToSet = currentHealth > currentMaxHealth ? currentMaxHealth : statusData.health; @@ -113,24 +113,24 @@ public class BukkitPlayer extends OnlineUser { } player.setHealthScaled(statusData.healthScale != 0D); } - if (statusDataFlags.contains(StatusDataFlag.SET_HUNGER)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.HUNGER)) { player.setFoodLevel(statusData.hunger); player.setSaturation(statusData.saturation); player.setExhaustion(statusData.saturationExhaustion); } - if (statusDataFlags.contains(StatusDataFlag.SET_SELECTED_ITEM_SLOT)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.INVENTORIES)) { player.getInventory().setHeldItemSlot(statusData.selectedItemSlot); } - if (statusDataFlags.contains(StatusDataFlag.SET_EXPERIENCE)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.EXPERIENCE)) { player.setTotalExperience(statusData.totalExperience); player.setLevel(statusData.expLevel); player.setExp(statusData.expProgress); } - if (statusDataFlags.contains(StatusDataFlag.SET_GAME_MODE)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.GAME_MODE)) { Bukkit.getScheduler().runTask(BukkitHuskSync.getInstance(), () -> player.setGameMode(GameMode.valueOf(statusData.gameMode))); } - if (statusDataFlags.contains(StatusDataFlag.SET_FLYING)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.LOCATION)) { Bukkit.getScheduler().runTask(BukkitHuskSync.getInstance(), () -> { if (statusData.isFlying) { player.setAllowFlight(true); diff --git a/common/build.gradle b/common/build.gradle index 40b1d11a..187027bd 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -4,6 +4,7 @@ dependencies { implementation 'net.kyori:adventure-api:4.11.0' implementation 'com.google.code.gson:gson:2.9.0' implementation 'dev.dejvokep:boosted-yaml:1.3' + implementation 'net.william278:Annotaml:2.0' implementation 'net.william278:DesertWell:1.1' implementation 'net.william278:PagineDown:1.1' implementation('com.zaxxer:HikariCP:5.0.1') { @@ -33,4 +34,5 @@ shadowJar { relocate 'dev.dejvokep', 'net.william278.husksync.libraries' relocate 'net.william278.desertwell', 'net.william278.husksync.libraries.desertwell' relocate 'net.william278.paginedown', 'net.william278.husksync.libraries.paginedown' + relocate 'net.william278.annotaml', 'net.william278.husksync.libraries.annotaml' } \ No newline at end of file diff --git a/common/src/main/java/net/william278/husksync/config/Locales.java b/common/src/main/java/net/william278/husksync/config/Locales.java index 7378d30e..feea3732 100644 --- a/common/src/main/java/net/william278/husksync/config/Locales.java +++ b/common/src/main/java/net/william278/husksync/config/Locales.java @@ -1,32 +1,37 @@ package net.william278.husksync.config; import de.themoep.minedown.adventure.MineDown; -import dev.dejvokep.boostedyaml.YamlDocument; +import net.william278.annotaml.YamlFile; import net.william278.paginedown.ListOptions; import org.apache.commons.text.StringEscapeUtils; import org.jetbrains.annotations.NotNull; import java.util.Arrays; import java.util.HashMap; +import java.util.Map; import java.util.Optional; /** - * Loaded locales used by the plugin to display various locales + * Loaded locales used by the plugin to display styled messages */ +@YamlFile(rootedMap = true, header = """ + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + ┃ HuskHomes Locales ┃ + ┃ Developed by William278 ┃ + ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + ┣╸ See plugin about menu for international locale credits + ┣╸ Formatted in MineDown: https://github.com/Phoenix616/MineDown + ┗╸ Translate HuskSync: https://william278.net/docs/husksync/Translations""") public class Locales { + /** + * The raw set of locales loaded from yaml + */ @NotNull - private final HashMap rawLocales; - - private Locales(@NotNull YamlDocument localesConfig) { - this.rawLocales = new HashMap<>(); - for (String localeId : localesConfig.getRoutesAsStrings(false)) { - rawLocales.put(localeId, localesConfig.getString(localeId)); - } - } + public Map rawLocales = new HashMap<>(); /** - * Returns an un-formatted locale loaded from the locales file + * Returns a raw, un-formatted locale loaded from the locales file * * @param localeId String identifier of the locale, corresponding to a key in the file * @return An {@link Optional} containing the locale corresponding to the id, if it exists @@ -36,7 +41,9 @@ public class Locales { } /** - * Returns an un-formatted locale loaded from the locales file, with replacements applied + * Returns a raw, un-formatted locale loaded from the locales file, with replacements applied + *

+ * Note that replacements will not be MineDown-escaped; use {@link #escapeMineDown(String)} to escape replacements * * @param localeId String identifier of the locale, corresponding to a key in the file * @param replacements Ordered array of replacement strings to fill in placeholders with @@ -77,12 +84,13 @@ public class Locales { * @param replacements Ordered array of replacement strings to fill in placeholders with * @return the raw locale, with inserted placeholders */ + @NotNull private String applyReplacements(@NotNull String rawLocale, @NotNull String... replacements) { int replacementIndexer = 1; for (String replacement : replacements) { String replacementString = "%" + replacementIndexer + "%"; rawLocale = rawLocale.replace(replacementString, replacement); - replacementIndexer = replacementIndexer + 1; + replacementIndexer += 1; } return rawLocale; } @@ -143,14 +151,8 @@ public class Locales { .setSpaceBeforeFooter(false); } - /** - * Load the locales from a BoostedYaml {@link YamlDocument} locales file - * - * @param localesConfig The loaded {@link YamlDocument} locales.yml file - * @return the loaded {@link Locales} - */ - public static Locales load(@NotNull YamlDocument localesConfig) { - return new Locales(localesConfig); + @SuppressWarnings("unused") + public Locales() { } } diff --git a/common/src/main/java/net/william278/husksync/config/Settings.java b/common/src/main/java/net/william278/husksync/config/Settings.java index 3453033b..7ab05e23 100644 --- a/common/src/main/java/net/william278/husksync/config/Settings.java +++ b/common/src/main/java/net/william278/husksync/config/Settings.java @@ -1,276 +1,190 @@ package net.william278.husksync.config; -import dev.dejvokep.boostedyaml.YamlDocument; +import net.william278.annotaml.YamlComment; +import net.william278.annotaml.YamlFile; +import net.william278.annotaml.YamlKey; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.Arrays; +import java.util.Map; +import java.util.Optional; /** - * Settings used for the plugin, as read from the config file + * Plugin settings, read from config.yml */ +@YamlFile(header = """ + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + ┃ HuskSync Config ┃ + ┃ Developed by William278 ┃ + ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + ┣╸ Information: https://william278.net/project/husksync + ┗╸ Documentation: https://william278.net/docs/husksync""", + + versionField = "config_version", versionNumber = 2) public class Settings { - /** - * Map of {@link ConfigOption}s read from the config file - */ - private final Map configOptions; - - // Load the settings from the document - private Settings(@NotNull YamlDocument config) { - this.configOptions = new HashMap<>(); - Arrays.stream(ConfigOption.values()).forEach(configOption -> configOptions - .put(configOption, switch (configOption.optionType) { - case BOOLEAN -> configOption.getBooleanValue(config); - case STRING -> configOption.getStringValue(config); - case DOUBLE -> configOption.getDoubleValue(config); - case FLOAT -> configOption.getFloatValue(config); - case INTEGER -> configOption.getIntValue(config); - case STRING_LIST -> configOption.getStringListValue(config); - })); - } + // Top-level settings + public String language = "en-gb"; - // Default constructor for empty settings - protected Settings(@NotNull Map configOptions) { - this.configOptions = configOptions; - } + @YamlKey("check_for_updates") + public boolean checkForUpdates = true; - /** - * Get the value of the specified {@link ConfigOption} - * - * @param option the {@link ConfigOption} to check - * @return the value of the {@link ConfigOption} as a boolean - * @throws ClassCastException if the option is not a boolean - */ - public boolean getBooleanValue(@NotNull ConfigOption option) throws ClassCastException { - return (Boolean) configOptions.get(option); - } + @YamlKey("cluster_id") + public String clusterId = ""; - /** - * Get the value of the specified {@link ConfigOption} - * - * @param option the {@link ConfigOption} to check - * @return the value of the {@link ConfigOption} as a string - * @throws ClassCastException if the option is not a string - */ - public String getStringValue(@NotNull ConfigOption option) throws ClassCastException { - return (String) configOptions.get(option); - } + @YamlKey("debug_logging") + public boolean debugLogging = false; - /** - * Get the value of the specified {@link ConfigOption} - * - * @param option the {@link ConfigOption} to check - * @return the value of the {@link ConfigOption} as a double - * @throws ClassCastException if the option is not a double - */ - public double getDoubleValue(@NotNull ConfigOption option) throws ClassCastException { - return (Double) configOptions.get(option); - } - /** - * Get the value of the specified {@link ConfigOption} - * - * @param option the {@link ConfigOption} to check - * @return the value of the {@link ConfigOption} as a float - * @throws ClassCastException if the option is not a float - */ - public double getFloatValue(@NotNull ConfigOption option) throws ClassCastException { - return (Float) configOptions.get(option); - } + // Database settings + @YamlComment("Database connection settings") + @YamlKey("database.credentials.host") + public String mySqlHost = "localhost"; - /** - * Get the value of the specified {@link ConfigOption} - * - * @param option the {@link ConfigOption} to check - * @return the value of the {@link ConfigOption} as an integer - * @throws ClassCastException if the option is not an integer - */ - public int getIntegerValue(@NotNull ConfigOption option) throws ClassCastException { - return (Integer) configOptions.get(option); - } + @YamlKey("database.credentials.port") + public int mySqlPort = 3306; - /** - * Get the value of the specified {@link ConfigOption} - * - * @param option the {@link ConfigOption} to check - * @return the value of the {@link ConfigOption} as a string {@link List} - * @throws ClassCastException if the option is not a string list - */ - @SuppressWarnings("unchecked") - public List getStringListValue(@NotNull ConfigOption option) throws ClassCastException { - return (List) configOptions.get(option); + @YamlKey("database.credentials.database") + public String mySqlDatabase = "HuskSync"; + + @YamlKey("database.mysql.credentials.username") + public String mySqlUsername = "root"; + + @YamlKey("database.credentials.password") + public String mySqlPassword = "pa55w0rd"; + + @YamlKey("database.credentials.parameters") + public String mySqlConnectionParameters = "?autoReconnect=true&useSSL=false"; + + @YamlComment("MySQL connection pool properties") + @YamlKey("database.connection_pool.maximum_pool_size") + public int mySqlConnectionPoolSize = 10; + + @YamlKey("database.connection_pool.minimum_idle") + public int mySqlConnectionPoolIdle = 10; + + @YamlKey("database.connection_pool.maximum_lifetime") + public long mySqlConnectionPoolLifetime = 1800000; + + @YamlKey("database.connection_pool.keepalive_time") + public long mySqlConnectionPoolKeepAlive = 0; + + @YamlKey("database.connection_pool.connection_timeout") + public long mySqlConnectionPoolTimeout = 5000; + + @YamlKey("database.table_names") + public Map tableNames = TableName.getDefaults(); + + @NotNull + public String getTableName(@NotNull TableName tableName) { + return Optional.ofNullable(tableNames.get(tableName.name().toLowerCase())) + .orElse(tableName.defaultName); } - /** - * Load the settings from a BoostedYaml {@link YamlDocument} config file - * - * @param config The loaded {@link YamlDocument} config.yml file - * @return the loaded {@link Settings} - */ - public static Settings load(@NotNull YamlDocument config) { - return new Settings(config); + // Redis settings + @YamlComment("Redis connection settings") + @YamlKey("redis.credentials.host") + public String redisHost = "localhost"; + + @YamlKey("redis.credentials.port") + public int redisPort = 6379; + + @YamlKey("redis.credentials.password") + public String redisPassword = ""; + + @YamlKey("redis.use_ssl") + public boolean redisUseSsl = false; + + + // Synchronization settings + @YamlComment("Synchronization settings") + @YamlKey("synchronization.max_user_data_snapshots") + public int maxUserDataSnapshots = 5; + + @YamlKey("synchronization.save_on_world_save") + public boolean saveOnWorldSave = true; + + @YamlKey("synchronization.save_on_death") + public boolean saveOnDeath = false; + + @YamlKey("synchronization.compress_data") + public boolean compressData = true; + + @YamlKey("synchronization.save_dead_player_inventories") + public boolean saveDeadPlayerInventories = true; + + @YamlKey("synchronization.network_latency_milliseconds") + public int networkLatencyMilliseconds = 500; + + @YamlKey("synchronization.features") + public Map synchronizationFeatures = SynchronizationFeature.getDefaults(); + + public boolean getSynchronizationFeature(@NotNull SynchronizationFeature feature) { + return Optional.ofNullable(synchronizationFeatures.get(feature.name().toLowerCase())) + .orElse(feature.enabledByDefault); } + /** - * Represents an option stored by a path in config.yml + * Represents the names of tables in the database */ - public enum ConfigOption { - LANGUAGE("language", OptionType.STRING, "en-gb"), - CHECK_FOR_UPDATES("check_for_updates", OptionType.BOOLEAN, true), - - CLUSTER_ID("cluster_id", OptionType.STRING, ""), - DEBUG_LOGGING("debug_logging", OptionType.BOOLEAN, false), - - DATABASE_HOST("database.credentials.host", OptionType.STRING, "localhost"), - DATABASE_PORT("database.credentials.port", OptionType.INTEGER, 3306), - DATABASE_NAME("database.credentials.database", OptionType.STRING, "HuskSync"), - DATABASE_USERNAME("database.credentials.username", OptionType.STRING, "root"), - DATABASE_PASSWORD("database.credentials.password", OptionType.STRING, "pa55w0rd"), - DATABASE_CONNECTION_PARAMS("database.credentials.params", OptionType.STRING, "?autoReconnect=true&useSSL=false"), - DATABASE_CONNECTION_POOL_MAX_SIZE("database.connection_pool.maximum_pool_size", OptionType.INTEGER, 10), - DATABASE_CONNECTION_POOL_MIN_IDLE("database.connection_pool.minimum_idle", OptionType.INTEGER, 10), - DATABASE_CONNECTION_POOL_MAX_LIFETIME("database.connection_pool.maximum_lifetime", OptionType.INTEGER, 1800000), - DATABASE_CONNECTION_POOL_KEEPALIVE("database.connection_pool.keepalive_time", OptionType.INTEGER, 0), - DATABASE_CONNECTION_POOL_TIMEOUT("database.connection_pool.connection_timeout", OptionType.INTEGER, 5000), - DATABASE_USERS_TABLE_NAME("database.table_names.users_table", OptionType.STRING, "husksync_users"), - DATABASE_USER_DATA_TABLE_NAME("database.table_names.user_data_table", OptionType.STRING, "husksync_user_data"), - - REDIS_HOST("redis.credentials.host", OptionType.STRING, "localhost"), - REDIS_PORT("redis.credentials.port", OptionType.INTEGER, 6379), - REDIS_PASSWORD("redis.credentials.password", OptionType.STRING, ""), - REDIS_USE_SSL("redis.use_ssl", OptionType.BOOLEAN, false), - - SYNCHRONIZATION_MAX_USER_DATA_SNAPSHOTS("synchronization.max_user_data_snapshots", OptionType.INTEGER, 5), - SYNCHRONIZATION_SAVE_ON_WORLD_SAVE("synchronization.save_on_world_save", OptionType.BOOLEAN, true), - SYNCHRONIZATION_COMPRESS_DATA("synchronization.compress_data", OptionType.BOOLEAN, true), - SYNCHRONIZATION_NETWORK_LATENCY_MILLISECONDS("synchronization.network_latency_milliseconds", OptionType.INTEGER, 500), - SYNCHRONIZATION_SAVE_DEAD_PLAYER_INVENTORIES("synchronization.save_dead_player_inventories", OptionType.BOOLEAN, true), - SYNCHRONIZATION_SYNC_INVENTORIES("synchronization.features.inventories", OptionType.BOOLEAN, true), - SYNCHRONIZATION_SYNC_ENDER_CHESTS("synchronization.features.ender_chests", OptionType.BOOLEAN, true), - SYNCHRONIZATION_SYNC_HEALTH("synchronization.features.health", OptionType.BOOLEAN, true), - SYNCHRONIZATION_SYNC_MAX_HEALTH("synchronization.features.max_health", OptionType.BOOLEAN, true), - SYNCHRONIZATION_SYNC_HUNGER("synchronization.features.hunger", OptionType.BOOLEAN, true), - SYNCHRONIZATION_SYNC_EXPERIENCE("synchronization.features.experience", OptionType.BOOLEAN, true), - SYNCHRONIZATION_SYNC_POTION_EFFECTS("synchronization.features.potion_effects", OptionType.BOOLEAN, true), - SYNCHRONIZATION_SYNC_ADVANCEMENTS("synchronization.features.advancements", OptionType.BOOLEAN, true), - SYNCHRONIZATION_SYNC_GAME_MODE("synchronization.features.game_mode", OptionType.BOOLEAN, true), - SYNCHRONIZATION_SYNC_STATISTICS("synchronization.features.statistics", OptionType.BOOLEAN, true), - SYNCHRONIZATION_SYNC_PERSISTENT_DATA_CONTAINER("synchronization.features.persistent_data_container", OptionType.BOOLEAN, true), - SYNCHRONIZATION_SYNC_LOCATION("synchronization.features.location", OptionType.BOOLEAN, true); - - /** - * The path in the config.yml file to the value - */ - @NotNull - public final String configPath; - - /** - * The {@link OptionType} of this option - */ - @NotNull - public final OptionType optionType; - - /** - * The default value of this option if not set in config - */ - @Nullable - private final Object defaultValue; - - ConfigOption(@NotNull String configPath, @NotNull OptionType optionType, @Nullable Object defaultValue) { - this.configPath = configPath; - this.optionType = optionType; - this.defaultValue = defaultValue; - } + public enum TableName { + USERS("husksync_users"), + USER_DATA("husksync_user_data"); - ConfigOption(@NotNull String configPath, @NotNull OptionType optionType) { - this.configPath = configPath; - this.optionType = optionType; - this.defaultValue = null; - } - - /** - * Get the value at the path specified (or return default if set), as a string - * - * @param config The {@link YamlDocument} config file - * @return the value defined in the config, as a string - */ - public String getStringValue(@NotNull YamlDocument config) { - return defaultValue != null - ? config.getString(configPath, (String) defaultValue) - : config.getString(configPath); - } + private final String defaultName; - /** - * Get the value at the path specified (or return default if set), as a boolean - * - * @param config The {@link YamlDocument} config file - * @return the value defined in the config, as a boolean - */ - public boolean getBooleanValue(@NotNull YamlDocument config) { - return defaultValue != null - ? config.getBoolean(configPath, (Boolean) defaultValue) - : config.getBoolean(configPath); + TableName(@NotNull String defaultName) { + this.defaultName = defaultName; } - /** - * Get the value at the path specified (or return default if set), as a double - * - * @param config The {@link YamlDocument} config file - * @return the value defined in the config, as a double - */ - public double getDoubleValue(@NotNull YamlDocument config) { - return defaultValue != null - ? config.getDouble(configPath, (Double) defaultValue) - : config.getDouble(configPath); + private Map.Entry toEntry() { + return Map.entry(name().toLowerCase(), defaultName); } - /** - * Get the value at the path specified (or return default if set), as a float - * - * @param config The {@link YamlDocument} config file - * @return the value defined in the config, as a float - */ - public float getFloatValue(@NotNull YamlDocument config) { - return defaultValue != null - ? config.getFloat(configPath, (Float) defaultValue) - : config.getFloat(configPath); + @SuppressWarnings("unchecked") + private static Map getDefaults() { + return Map.ofEntries(Arrays.stream(values()) + .map(TableName::toEntry) + .toArray(Map.Entry[]::new)); } + } - /** - * Get the value at the path specified (or return default if set), as an int - * - * @param config The {@link YamlDocument} config file - * @return the value defined in the config, as an int - */ - public int getIntValue(@NotNull YamlDocument config) { - return defaultValue != null - ? config.getInt(configPath, (Integer) defaultValue) - : config.getInt(configPath); + /** + * Represents enabled synchronisation features + */ + public enum SynchronizationFeature { + + INVENTORIES(true), + ENDER_CHESTS(true), + HEALTH(true), + MAX_HEALTH(true), + HUNGER(true), + EXPERIENCE(true), + POTION_EFFECTS(true), + ADVANCEMENTS(true), + GAME_MODE(true), + STATISTICS(true), + PERSISTENT_DATA_CONTAINER(false), + LOCATION(false); + + private final boolean enabledByDefault; + + SynchronizationFeature(boolean enabledByDefault) { + this.enabledByDefault = enabledByDefault; } - /** - * Get the value at the path specified (or return default if set), as a string {@link List} - * - * @param config The {@link YamlDocument} config file - * @return the value defined in the config, as a string {@link List} - */ - public List getStringListValue(@NotNull YamlDocument config) { - return config.getStringList(configPath, new ArrayList<>()); + private Map.Entry toEntry() { + return Map.entry(name().toLowerCase(), enabledByDefault); } - /** - * Represents the type of the object - */ - public enum OptionType { - BOOLEAN, - STRING, - DOUBLE, - FLOAT, - INTEGER, - STRING_LIST + @SuppressWarnings("unchecked") + private static Map getDefaults() { + return Map.ofEntries(Arrays.stream(values()) + .map(SynchronizationFeature::toEntry) + .toArray(Map.Entry[]::new)); } } -} +} \ No newline at end of file diff --git a/common/src/main/java/net/william278/husksync/data/StatusDataFlag.java b/common/src/main/java/net/william278/husksync/data/StatusDataFlag.java index 60a94934..110f85aa 100644 --- a/common/src/main/java/net/william278/husksync/data/StatusDataFlag.java +++ b/common/src/main/java/net/william278/husksync/data/StatusDataFlag.java @@ -8,29 +8,34 @@ import java.util.List; /** * Flags for setting {@link StatusData}, indicating which elements should be synced + * + * @deprecated Use the more direct {@link Settings#getSynchronizationFeature(Settings.SynchronizationFeature)} instead */ +@Deprecated(since = "2.1") public enum StatusDataFlag { - SET_HEALTH(Settings.ConfigOption.SYNCHRONIZATION_SYNC_HEALTH), - SET_MAX_HEALTH(Settings.ConfigOption.SYNCHRONIZATION_SYNC_MAX_HEALTH), - SET_HUNGER(Settings.ConfigOption.SYNCHRONIZATION_SYNC_HUNGER), - SET_EXPERIENCE(Settings.ConfigOption.SYNCHRONIZATION_SYNC_EXPERIENCE), - SET_GAME_MODE(Settings.ConfigOption.SYNCHRONIZATION_SYNC_GAME_MODE), - SET_FLYING(Settings.ConfigOption.SYNCHRONIZATION_SYNC_LOCATION), - SET_SELECTED_ITEM_SLOT(Settings.ConfigOption.SYNCHRONIZATION_SYNC_INVENTORIES); + SET_HEALTH(Settings.SynchronizationFeature.HEALTH), + SET_MAX_HEALTH(Settings.SynchronizationFeature.MAX_HEALTH), + SET_HUNGER(Settings.SynchronizationFeature.HUNGER), + SET_EXPERIENCE(Settings.SynchronizationFeature.EXPERIENCE), + SET_GAME_MODE(Settings.SynchronizationFeature.GAME_MODE), + SET_FLYING(Settings.SynchronizationFeature.LOCATION), + SET_SELECTED_ITEM_SLOT(Settings.SynchronizationFeature.INVENTORIES); - private final Settings.ConfigOption configOption; + private final Settings.SynchronizationFeature feature; - StatusDataFlag(@NotNull Settings.ConfigOption configOption) { - this.configOption = configOption; + StatusDataFlag(@NotNull Settings.SynchronizationFeature feature) { + this.feature = feature; } /** * Returns all status data flags * * @return all status data flags as a list + * @deprecated Use {@link Settings#getSynchronizationFeature(Settings.SynchronizationFeature)} instead */ @NotNull + @Deprecated(since = "2.1") @SuppressWarnings("unused") public static List getAll() { return Arrays.stream(StatusDataFlag.values()).toList(); @@ -41,11 +46,13 @@ public enum StatusDataFlag { * * @param settings the settings to use for determining which flags are enabled * @return all status data flags that are enabled for setting + * @deprecated Use {@link Settings#getSynchronizationFeature(Settings.SynchronizationFeature)} instead */ @NotNull + @Deprecated(since = "2.1") public static List getFromSettings(@NotNull Settings settings) { return Arrays.stream(StatusDataFlag.values()).filter( - flag -> settings.getBooleanValue(flag.configOption)).toList(); + flag -> settings.getSynchronizationFeature(flag.feature)).toList(); } } diff --git a/common/src/main/java/net/william278/husksync/database/MySqlDatabase.java b/common/src/main/java/net/william278/husksync/database/MySqlDatabase.java index 2de6a27e..a7e2c0a0 100644 --- a/common/src/main/java/net/william278/husksync/database/MySqlDatabase.java +++ b/common/src/main/java/net/william278/husksync/database/MySqlDatabase.java @@ -40,9 +40,9 @@ public class MySqlDatabase extends Database { private final int hikariMaximumPoolSize; private final int hikariMinimumIdle; - private final int hikariMaximumLifetime; - private final int hikariKeepAliveTime; - private final int hikariConnectionTimeOut; + private final long hikariMaximumLifetime; + private final long hikariKeepAliveTime; + private final long hikariConnectionTimeOut; private static final String DATA_POOL_NAME = "HuskSyncHikariPool"; @@ -53,21 +53,21 @@ public class MySqlDatabase extends Database { public MySqlDatabase(@NotNull Settings settings, @NotNull ResourceReader resourceReader, @NotNull Logger logger, @NotNull DataAdapter dataAdapter, @NotNull EventCannon eventCannon) { - super(settings.getStringValue(Settings.ConfigOption.DATABASE_USERS_TABLE_NAME), - settings.getStringValue(Settings.ConfigOption.DATABASE_USER_DATA_TABLE_NAME), - Math.max(1, Math.min(20, settings.getIntegerValue(Settings.ConfigOption.SYNCHRONIZATION_MAX_USER_DATA_SNAPSHOTS))), + super(settings.getTableName(Settings.TableName.USERS), + settings.getTableName(Settings.TableName.USER_DATA), + Math.max(1, Math.min(20, settings.maxUserDataSnapshots)), resourceReader, dataAdapter, eventCannon, logger); - this.mySqlHost = settings.getStringValue(Settings.ConfigOption.DATABASE_HOST); - this.mySqlPort = settings.getIntegerValue(Settings.ConfigOption.DATABASE_PORT); - this.mySqlDatabaseName = settings.getStringValue(Settings.ConfigOption.DATABASE_NAME); - this.mySqlUsername = settings.getStringValue(Settings.ConfigOption.DATABASE_USERNAME); - this.mySqlPassword = settings.getStringValue(Settings.ConfigOption.DATABASE_PASSWORD); - this.mySqlConnectionParameters = settings.getStringValue(Settings.ConfigOption.DATABASE_CONNECTION_PARAMS); - this.hikariMaximumPoolSize = settings.getIntegerValue(Settings.ConfigOption.DATABASE_CONNECTION_POOL_MAX_SIZE); - this.hikariMinimumIdle = settings.getIntegerValue(Settings.ConfigOption.DATABASE_CONNECTION_POOL_MIN_IDLE); - this.hikariMaximumLifetime = settings.getIntegerValue(Settings.ConfigOption.DATABASE_CONNECTION_POOL_MAX_LIFETIME); - this.hikariKeepAliveTime = settings.getIntegerValue(Settings.ConfigOption.DATABASE_CONNECTION_POOL_KEEPALIVE); - this.hikariConnectionTimeOut = settings.getIntegerValue(Settings.ConfigOption.DATABASE_CONNECTION_POOL_TIMEOUT); + this.mySqlHost = settings.mySqlHost; + this.mySqlPort = settings.mySqlPort; + this.mySqlDatabaseName = settings.mySqlDatabase; + this.mySqlUsername = settings.mySqlUsername; + this.mySqlPassword = settings.mySqlPassword; + this.mySqlConnectionParameters = settings.mySqlConnectionParameters; + this.hikariMaximumPoolSize = settings.mySqlConnectionPoolSize; + this.hikariMinimumIdle = settings.mySqlConnectionPoolIdle; + this.hikariMaximumLifetime = settings.mySqlConnectionPoolLifetime; + this.hikariKeepAliveTime = settings.mySqlConnectionPoolKeepAlive; + this.hikariConnectionTimeOut = settings.mySqlConnectionPoolTimeout; } /** diff --git a/common/src/main/java/net/william278/husksync/listener/EventListener.java b/common/src/main/java/net/william278/husksync/listener/EventListener.java index b2300a60..7ec6ff18 100644 --- a/common/src/main/java/net/william278/husksync/listener/EventListener.java +++ b/common/src/main/java/net/william278/husksync/listener/EventListener.java @@ -1,11 +1,10 @@ package net.william278.husksync.listener; import net.william278.husksync.HuskSync; -import net.william278.husksync.config.Settings; -import net.william278.husksync.data.ItemData; import net.william278.husksync.data.DataSaveCause; -import net.william278.husksync.player.OnlineUser; +import net.william278.husksync.data.ItemData; import net.william278.husksync.editor.ItemEditorMenuType; +import net.william278.husksync.player.OnlineUser; import org.jetbrains.annotations.NotNull; import java.util.HashSet; @@ -57,7 +56,7 @@ public abstract class EventListener { CompletableFuture.runAsync(() -> { try { // Hold reading data for the network latency threshold, to ensure the source server has set the redis key - Thread.sleep(Math.max(0, plugin.getSettings().getIntegerValue(Settings.ConfigOption.SYNCHRONIZATION_NETWORK_LATENCY_MILLISECONDS))); + Thread.sleep(Math.max(0, plugin.getSettings().networkLatencyMilliseconds)); } catch (InterruptedException e) { plugin.getLoggingAdapter().log(Level.SEVERE, "An exception occurred handling a player join", e); } finally { @@ -170,7 +169,7 @@ public abstract class EventListener { * @param usersInWorld a list of users in the world that is being saved */ protected final void handleAsyncWorldSave(@NotNull List usersInWorld) { - if (disabling || !plugin.getSettings().getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_SAVE_ON_WORLD_SAVE)) { + if (disabling || !plugin.getSettings().saveOnWorldSave) { return; } usersInWorld.forEach(user -> user.getUserData(plugin.getLoggingAdapter(), plugin.getSettings()).join().ifPresent( diff --git a/common/src/main/java/net/william278/husksync/player/OnlineUser.java b/common/src/main/java/net/william278/husksync/player/OnlineUser.java index da718143..82fcc349 100644 --- a/common/src/main/java/net/william278/husksync/player/OnlineUser.java +++ b/common/src/main/java/net/william278/husksync/player/OnlineUser.java @@ -39,9 +39,30 @@ public abstract class OnlineUser extends User { * @param statusData the player's {@link StatusData} * @param statusDataFlags the flags to use for setting the status data * @return a future returning void when complete + * @deprecated Use {@link #setStatus(StatusData, Settings)} instead + */ + @Deprecated(since = "2.1") + public final CompletableFuture setStatus(@NotNull StatusData statusData, + @NotNull List statusDataFlags) { + final Settings settings = new Settings(); + settings.synchronizationFeatures.put(Settings.SynchronizationFeature.HEALTH.name().toLowerCase(), statusDataFlags.contains(StatusDataFlag.SET_HEALTH)); + settings.synchronizationFeatures.put(Settings.SynchronizationFeature.MAX_HEALTH.name().toLowerCase(), statusDataFlags.contains(StatusDataFlag.SET_MAX_HEALTH)); + settings.synchronizationFeatures.put(Settings.SynchronizationFeature.HUNGER.name().toLowerCase(), statusDataFlags.contains(StatusDataFlag.SET_HUNGER)); + settings.synchronizationFeatures.put(Settings.SynchronizationFeature.EXPERIENCE.name().toLowerCase(), statusDataFlags.contains(StatusDataFlag.SET_EXPERIENCE)); + settings.synchronizationFeatures.put(Settings.SynchronizationFeature.INVENTORIES.name().toLowerCase(), statusDataFlags.contains(StatusDataFlag.SET_SELECTED_ITEM_SLOT)); + settings.synchronizationFeatures.put(Settings.SynchronizationFeature.LOCATION.name().toLowerCase(), statusDataFlags.contains(StatusDataFlag.SET_GAME_MODE) || statusDataFlags.contains(StatusDataFlag.SET_FLYING)); + return setStatus(statusData, settings); + } + + /** + * Set the player's {@link StatusData} + * + * @param statusData the player's {@link StatusData} + * @param settings settings, containing information about which features should be synced + * @return a future returning void when complete */ public abstract CompletableFuture setStatus(@NotNull StatusData statusData, - @NotNull List statusDataFlags); + @NotNull Settings settings); /** * Get the player's inventory {@link ItemData} contents @@ -237,27 +258,26 @@ public abstract class OnlineUser extends User { final UserData finalData = preSyncEvent.getUserData(); final List> dataSetOperations = new ArrayList<>() {{ if (!isOffline() && !preSyncEvent.isCancelled()) { - if (settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_SYNC_INVENTORIES)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.INVENTORIES)) { finalData.getInventory().ifPresent(itemData -> add(setInventory(itemData))); } - if (settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_SYNC_ENDER_CHESTS)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.ENDER_CHESTS)) { finalData.getEnderChest().ifPresent(itemData -> add(setEnderChest(itemData))); } - finalData.getStatus().ifPresent(statusData -> add(setStatus(statusData, - StatusDataFlag.getFromSettings(settings)))); - if (settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_SYNC_POTION_EFFECTS)) { + finalData.getStatus().ifPresent(statusData -> add(setStatus(statusData, settings))); + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.POTION_EFFECTS)) { finalData.getPotionEffects().ifPresent(potionEffectData -> add(setPotionEffects(potionEffectData))); } - if (settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_SYNC_ADVANCEMENTS)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.ADVANCEMENTS)) { finalData.getAdvancements().ifPresent(advancementData -> add(setAdvancements(advancementData))); } - if (settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_SYNC_STATISTICS)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.STATISTICS)) { finalData.getStatistics().ifPresent(statisticData -> add(setStatistics(statisticData))); } - if (settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_SYNC_LOCATION)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.LOCATION)) { finalData.getLocation().ifPresent(locationData -> add(setLocation(locationData))); } - if (settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_SYNC_PERSISTENT_DATA_CONTAINER)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.PERSISTENT_DATA_CONTAINER)) { finalData.getPersistentDataContainer().ifPresent(persistentDataContainerData -> add(setPersistentDataContainer(persistentDataContainerData))); } @@ -294,30 +314,30 @@ public abstract class OnlineUser extends User { final UserDataBuilder builder = UserData.builder(getMinecraftVersion()); final List> dataGetOperations = new ArrayList<>() {{ if (!isOffline()) { - if (settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_SYNC_INVENTORIES)) { - if (isDead() && settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_SAVE_DEAD_PLAYER_INVENTORIES)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.INVENTORIES)) { + if (isDead() && settings.saveDeadPlayerInventories) { add(CompletableFuture.runAsync(() -> builder.setInventory(ItemData.empty()))); } else { add(getInventory().thenAccept(builder::setInventory)); } } - if (settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_SYNC_ENDER_CHESTS)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.ENDER_CHESTS)) { add(getEnderChest().thenAccept(builder::setEnderChest)); } add(getStatus().thenAccept(builder::setStatus)); - if (settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_SYNC_POTION_EFFECTS)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.POTION_EFFECTS)) { add(getPotionEffects().thenAccept(builder::setPotionEffects)); } - if (settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_SYNC_ADVANCEMENTS)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.ADVANCEMENTS)) { add(getAdvancements().thenAccept(builder::setAdvancements)); } - if (settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_SYNC_STATISTICS)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.STATISTICS)) { add(getStatistics().thenAccept(builder::setStatistics)); } - if (settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_SYNC_LOCATION)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.LOCATION)) { add(getLocation().thenAccept(builder::setLocation)); } - if (settings.getBooleanValue(Settings.ConfigOption.SYNCHRONIZATION_SYNC_PERSISTENT_DATA_CONTAINER)) { + if (settings.getSynchronizationFeature(Settings.SynchronizationFeature.PERSISTENT_DATA_CONTAINER)) { add(getPersistentDataContainer().thenAccept(builder::setPersistentDataContainer)); } } diff --git a/common/src/main/java/net/william278/husksync/redis/RedisManager.java b/common/src/main/java/net/william278/husksync/redis/RedisManager.java index 5df81ede..b4745cd7 100644 --- a/common/src/main/java/net/william278/husksync/redis/RedisManager.java +++ b/common/src/main/java/net/william278/husksync/redis/RedisManager.java @@ -1,7 +1,6 @@ package net.william278.husksync.redis; import net.william278.husksync.HuskSync; -import net.william278.husksync.config.Settings; import net.william278.husksync.data.UserData; import net.william278.husksync.player.User; import org.jetbrains.annotations.NotNull; @@ -33,13 +32,13 @@ public class RedisManager { public RedisManager(@NotNull HuskSync plugin) { this.plugin = plugin; - clusterId = plugin.getSettings().getStringValue(Settings.ConfigOption.CLUSTER_ID); + clusterId = plugin.getSettings().clusterId; // Set redis credentials - this.redisHost = plugin.getSettings().getStringValue(Settings.ConfigOption.REDIS_HOST); - this.redisPort = plugin.getSettings().getIntegerValue(Settings.ConfigOption.REDIS_PORT); - this.redisPassword = plugin.getSettings().getStringValue(Settings.ConfigOption.REDIS_PASSWORD); - this.redisUseSsl = plugin.getSettings().getBooleanValue(Settings.ConfigOption.REDIS_USE_SSL); + this.redisHost = plugin.getSettings().redisHost; + this.redisPort = plugin.getSettings().redisPort; + this.redisPassword = plugin.getSettings().redisPassword; + this.redisUseSsl = plugin.getSettings().redisUseSsl; // Configure the jedis pool this.jedisPoolConfig = new JedisPoolConfig(); diff --git a/common/src/test/java/net/william278/husksync/player/DummyPlayer.java b/common/src/test/java/net/william278/husksync/player/DummyPlayer.java index 1a059a99..7b5c8be1 100644 --- a/common/src/test/java/net/william278/husksync/player/DummyPlayer.java +++ b/common/src/test/java/net/william278/husksync/player/DummyPlayer.java @@ -1,6 +1,7 @@ package net.william278.husksync.player; import de.themoep.minedown.adventure.MineDown; +import net.william278.husksync.config.Settings; import net.william278.husksync.data.*; import net.william278.husksync.editor.ItemEditorMenu; import net.william278.desertwell.Version; @@ -31,7 +32,7 @@ public class DummyPlayer extends OnlineUser { } @Override - public CompletableFuture setStatus(@NotNull StatusData statusData, @NotNull List statusDataFlags) { + public CompletableFuture setStatus(@NotNull StatusData statusData, @NotNull Settings settings) { return CompletableFuture.runAsync(() -> { // do nothing });