getRawLocale(@NotNull String localeId) {
- return Optional.ofNullable(rawLocales.get(localeId)).map(StringEscapeUtils::unescapeJava);
+ return Optional.ofNullable(locales.get(localeId)).map(StringEscapeUtils::unescapeJava);
}
/**
- * Returns a raw, unformatted 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
+ * Note that replacements will not be MineDown-escaped; use {@link #escapeText(String)} to escape replacements
*
* @param localeId String identifier of the locale, corresponding to a key in the file
- * @param replacements An ordered array of replacement strings to fill in placeholders with
+ * @param replacements Ordered array of replacement strings to fill in placeholders with
* @return An {@link Optional} containing the replacement-applied locale corresponding to the id, if it exists
*/
public Optional getRawLocale(@NotNull String localeId, @NotNull String... replacements) {
@@ -73,34 +80,45 @@ public class Locales {
}
/**
- * Returns a MineDown-formatted locale from the Locales file
+ * Returns a MineDown-formatted locale from the locales file
*
* @param localeId String identifier of the locale, corresponding to a key in the file
* @return An {@link Optional} containing the formatted locale corresponding to the id, if it exists
*/
public Optional getLocale(@NotNull String localeId) {
- return getRawLocale(localeId).map(MineDown::new);
+ return getRawLocale(localeId).map(this::format);
}
/**
- * Returns a MineDown-formatted locale from the Locales file, with replacements applied
+ * Returns a MineDown-formatted locale from the locales file, with replacements applied
*
* Note that replacements will be MineDown-escaped before application
*
* @param localeId String identifier of the locale, corresponding to a key in the file
- * @param replacements An ordered array of replacement strings to fill in placeholders with
+ * @param replacements Ordered array of replacement strings to fill in placeholders with
* @return An {@link Optional} containing the replacement-applied, formatted locale corresponding to the id, if it exists
*/
public Optional getLocale(@NotNull String localeId, @NotNull String... replacements) {
- return getRawLocale(localeId, Arrays.stream(replacements).map(Locales::escapeMineDown)
- .toArray(String[]::new)).map(MineDown::new);
+ return getRawLocale(localeId, Arrays.stream(replacements).map(Locales::escapeText)
+ .toArray(String[]::new)).map(this::format);
+ }
+
+ /**
+ * Returns a MineDown-formatted string
+ *
+ * @param text The text to format
+ * @return A {@link MineDown} object containing the formatted text
+ */
+ @NotNull
+ public MineDown format(@NotNull String text) {
+ return new MineDown(text);
}
/**
* Apply placeholder replacements to a raw locale
*
* @param rawLocale The raw, unparsed locale
- * @param replacements An ordered array of replacement strings to fill in placeholders with
+ * @param replacements Ordered array of replacement strings to fill in placeholders with
* @return the raw locale, with inserted placeholders
*/
@NotNull
@@ -116,15 +134,12 @@ public class Locales {
/**
* Escape a string from {@link MineDown} formatting for use in a MineDown-formatted locale
- *
- * Although MineDown provides {@link MineDown#escape(String)}, that method fails to escape events
- * properly when using the escaped string in a replacement, so this is used instead
*
* @param string The string to escape
* @return The escaped string
*/
@NotNull
- public static String escapeMineDown(@NotNull String string) {
+ public static String escapeText(@NotNull String string) {
final StringBuilder value = new StringBuilder();
for (int i = 0; i < string.length(); ++i) {
char c = string.charAt(i);
@@ -137,22 +152,30 @@ public class Locales {
value.append(c);
}
- return value.toString();
+ return value.toString().replace("__", "_\\_");
}
- /**
- * Truncates a String to a specified length, and appends an ellipsis if it is longer than the specified length
- *
- * @param string The string to truncate
- * @param length The maximum length of the string
- * @return The truncated string
- */
@NotNull
- public static String truncate(@NotNull String string, int length) {
- if (string.length() > length) {
- return string.substring(0, length) + "…";
+ public String truncateText(@NotNull String string, int truncateAfter) {
+ if (string.isBlank()) {
+ return string;
}
- return string;
+ return string.length() > truncateAfter ? string.substring(0, truncateAfter) + "…" : string;
+ }
+
+ @NotNull
+ public String getNotApplicable() {
+ return getRawLocale("not_applicable").orElse("N/A");
+ }
+
+ @NotNull
+ public String getListJoiner() {
+ return getRawLocale("list_separator").orElse(", ");
+ }
+
+ @NotNull
+ public String getNone() {
+ return getRawLocale("none").orElse("(none)");
}
/**
@@ -185,10 +208,6 @@ public class Locales {
.setSpaceBeforeFooter(false);
}
- @SuppressWarnings("unused")
- public Locales() {
- }
-
/**
* Determines the slot a system notification should be displayed in
*/
diff --git a/common/src/main/java/net/william278/husksync/config/Server.java b/common/src/main/java/net/william278/husksync/config/Server.java
index bf7771d3..2beaa772 100644
--- a/common/src/main/java/net/william278/husksync/config/Server.java
+++ b/common/src/main/java/net/william278/husksync/config/Server.java
@@ -19,64 +19,57 @@
package net.william278.husksync.config;
-import net.william278.annotaml.Annotaml;
-import net.william278.annotaml.YamlFile;
-import net.william278.annotaml.YamlKey;
-import net.william278.husksync.HuskSync;
+import de.exlll.configlib.Configuration;
+import de.exlll.configlib.YamlConfigurations;
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.nio.file.Path;
-import java.util.List;
+import java.nio.file.Paths;
+import java.util.stream.Stream;
-/**
- * Represents a server on a proxied network.
- */
-@YamlFile(header = """
- ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
- ┃ HuskSync Server ID config ┃
- ┃ Developed by William278 ┃
- ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
- ┣╸ This file should contain the ID of this server as defined in your proxy config.
- ┗╸ If you join it using /server alpha, then set it to 'alpha' (case-sensitive)""")
+@Getter
+@Configuration
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class Server {
- @YamlKey("name")
- private String serverName;
+ static final String CONFIG_HEADER = """
+ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
+ ┃ HuskSync - Server ID ┃
+ ┃ Developed by William278 ┃
+ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
+ ┣╸ This file should contain the ID of this server as defined in your proxy config.
+ ┗╸ If you join it using /server alpha, then set it to 'alpha' (case-sensitive)""";
- private Server(@NotNull String serverName) {
- this.serverName = serverName;
- }
-
- @SuppressWarnings("unused")
- private Server() {
- }
+ private String name = getDefault();
@NotNull
- public static Server getDefault(@NotNull HuskSync plugin) {
- return new Server(getDefaultServerName(plugin));
+ public static Server of(@NotNull String name) {
+ return new Server(name);
}
/**
* Find a sensible default name for the server name property
*/
@NotNull
- private static String getDefaultServerName(@NotNull HuskSync plugin) {
- try {
- // Fetch server default from supported plugins if present
- for (String s : List.of("HuskHomes", "HuskTowns")) {
- final File serverFile = Path.of(plugin.getDataFolder().getParent(), s, "server.yml").toFile();
- if (serverFile.exists()) {
- return Annotaml.create(serverFile, Server.class).get().getName();
- }
- }
-
- // Fetch server default from user dir name
- final Path serverDirectory = Path.of(System.getProperty("user.dir"));
- return serverDirectory.getFileName().toString().trim();
- } catch (Throwable e) {
- return "server";
- }
+ private static String getDefault() {
+ final String serverFolder = System.getProperty("user.dir");
+ return serverFolder == null ? "server" : Stream
+ .of("HuskHomes", "HuskTowns", "HuskClaims")
+ .map(s -> Paths.get(serverFolder, "plugins", s, "server.yml").toFile())
+ .filter(File::exists).findFirst()
+ .map(file -> YamlConfigurations.load(
+ file.toPath(),
+ Server.class,
+ ConfigProvider.YAML_CONFIGURATION_PROPERTIES.header(CONFIG_HEADER).build()
+ ))
+ .map(Server::getName)
+ .orElse(Path.of(serverFolder).getFileName().toString().trim());
}
@Override
@@ -88,12 +81,4 @@ public class Server {
return super.equals(other);
}
- /**
- * Proxy-defined name of this server.
- */
- @NotNull
- public String getName() {
- return serverName;
- }
-
}
\ No newline at end of file
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 b9dcb5dd..bba3a8c8 100644
--- a/common/src/main/java/net/william278/husksync/config/Settings.java
+++ b/common/src/main/java/net/william278/husksync/config/Settings.java
@@ -19,9 +19,11 @@
package net.william278.husksync.config;
-import net.william278.annotaml.YamlComment;
-import net.william278.annotaml.YamlFile;
-import net.william278.annotaml.YamlKey;
+import de.exlll.configlib.Comment;
+import de.exlll.configlib.Configuration;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
import net.william278.husksync.data.DataSnapshot;
import net.william278.husksync.data.Identifier;
import net.william278.husksync.database.Database;
@@ -29,441 +31,246 @@ import net.william278.husksync.listener.EventListener;
import net.william278.husksync.sync.DataSyncer;
import org.jetbrains.annotations.NotNull;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
/**
* Plugin settings, read from config.yml
*/
-@YamlFile(header = """
- ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
- ┃ HuskSync Config ┃
- ┃ Developed by William278 ┃
- ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
- ┣╸ Information: https://william278.net/project/husksync
- ┣╸ Config Help: https://william278.net/docs/husksync/config-file/
- ┗╸ Documentation: https://william278.net/docs/husksync""")
+@SuppressWarnings("FieldMayBeFinal")
+@Getter
+@Configuration
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Settings {
- // Top-level settings
- @YamlComment("Locale of the default language file to use. Docs: https://william278.net/docs/husksync/translations")
- @YamlKey("language")
- private String language = "en-gb";
+ protected static final String CONFIG_HEADER = """
+ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
+ ┃ HuskSync Config ┃
+ ┃ Developed by William278 ┃
+ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
+ ┣╸ Information: https://william278.net/project/husksync
+ ┣╸ Config Help: https://william278.net/docs/husksync/config-file/
+ ┗╸ Documentation: https://william278.net/docs/husksync""";
- @YamlComment("Whether to automatically check for plugin updates on startup")
- @YamlKey("check_for_updates")
+ // Top-level settings
+ @Comment("Locale of the default language file to use. Docs: https://william278.net/docs/husksync/translations")
+ private String language = Locales.DEFAULT_LOCALE;
+
+ @Comment("Whether to automatically check for plugin updates on startup")
private boolean checkForUpdates = true;
- @YamlComment("Specify a common ID for grouping servers running HuskSync. "
+ @Comment("Specify a common ID for grouping servers running HuskSync. "
+ "Don't modify this unless you know what you're doing!")
- @YamlKey("cluster_id")
private String clusterId = "";
- @YamlComment("Enable development debug logging")
- @YamlKey("debug_logging")
+ @Comment("Enable development debug logging")
private boolean debugLogging = false;
- @YamlComment("Whether to provide modern, rich TAB suggestions for commands (if available)")
- @YamlKey("brigadier_tab_completion")
+ @Comment("Whether to provide modern, rich TAB suggestions for commands (if available)")
private boolean brigadierTabCompletion = false;
- @YamlComment("Whether to enable the Player Analytics hook. Docs: https://william278.net/docs/husksync/plan-hook")
- @YamlKey("enable_plan_hook")
+ @Comment("Whether to enable the Player Analytics hook. Docs: https://william278.net/docs/husksync/plan-hook")
private boolean enablePlanHook = true;
// Database settings
- @YamlComment("Type of database to use (MYSQL, MARIADB)")
- @YamlKey("database.type")
- private Database.Type databaseType = Database.Type.MYSQL;
+ @Comment("Database settings")
+ private DatabaseSettings database = new DatabaseSettings();
- @YamlComment("Specify credentials here for your MYSQL or MARIADB database")
- @YamlKey("database.credentials.host")
- private String mySqlHost = "localhost";
+ @Getter
+ @Configuration
+ @NoArgsConstructor(access = AccessLevel.PRIVATE)
+ public static class DatabaseSettings {
- @YamlKey("database.credentials.port")
- private int mySqlPort = 3306;
+ @Comment("Type of database to use (MYSQL, MARIADB)")
+ private Database.Type type = Database.Type.MYSQL;
- @YamlKey("database.credentials.database")
- private String mySqlDatabase = "HuskSync";
+ @Comment("Specify credentials here for your MYSQL or MARIADB database")
+ private DatabaseCredentials credentials = new DatabaseCredentials();
- @YamlKey("database.credentials.username")
- private String mySqlUsername = "root";
+ @Getter
+ @Configuration
+ @NoArgsConstructor(access = AccessLevel.PRIVATE)
+ public static class DatabaseCredentials {
+ private String host = "localhost";
+ private int port = 3306;
+ private String database = "HuskSync";
+ private String username = "root";
+ private String password = "pa55w0rd";
+ private String parameters = String.join("&",
+ "?autoReconnect=true", "useSSL=false",
+ "useUnicode=true", "characterEncoding=UTF-8");
+ }
- @YamlKey("database.credentials.password")
- private String mySqlPassword = "pa55w0rd";
+ @Comment({"MYSQL / MARIADB database Hikari connection pool properties.",
+ "Don't modify this unless you know what you're doing!"})
+ private PoolSettings connectionPool = new PoolSettings();
- @YamlKey("database.credentials.parameters")
- private String mySqlConnectionParameters = "?autoReconnect=true"
- + "&useSSL=false"
- + "&useUnicode=true"
- + "&characterEncoding=UTF-8";
+ @Getter
+ @Configuration
+ @NoArgsConstructor(access = AccessLevel.PRIVATE)
+ public static class PoolSettings {
+ private int maximumPoolSize = 10;
+ private int minimumIdle = 10;
+ private long maximumLifetime = 1800000;
+ private long keepaliveTime = 0;
+ private long connectionTimeout = 5000;
+ }
- @YamlComment("MYSQL / MARIADB database Hikari connection pool properties. "
- + "Don't modify this unless you know what you're doing!")
- @YamlKey("database.connection_pool.maximum_pool_size")
- private int mySqlConnectionPoolSize = 10;
-
- @YamlKey("database.connection_pool.minimum_idle")
- private int mySqlConnectionPoolIdle = 10;
-
- @YamlKey("database.connection_pool.maximum_lifetime")
- private long mySqlConnectionPoolLifetime = 1800000;
-
- @YamlKey("database.connection_pool.keepalive_time")
- private long mySqlConnectionPoolKeepAlive = 0;
-
- @YamlKey("database.connection_pool.connection_timeout")
- private long mySqlConnectionPoolTimeout = 5000;
-
- @YamlComment("Names of tables to use on your database. Don't modify this unless you know what you're doing!")
- @YamlKey("database.table_names")
- private Map tableNames = TableName.getDefaults();
+ @Comment("Names of tables to use on your database. Don't modify this unless you know what you're doing!")
+ @Getter(AccessLevel.NONE)
+ private Map tableNames = Database.TableName.getDefaults();
+ @NotNull
+ public String getTableName(@NotNull Database.TableName tableName) {
+ return tableNames.getOrDefault(tableName.name().toLowerCase(Locale.ENGLISH), tableName.getDefaultName());
+ }
+ }
// Redis settings
- @YamlComment("Specify the credentials of your Redis database here. Set \"password\" to '' if you don't have one")
- @YamlKey("redis.credentials.host")
- private String redisHost = "localhost";
+ @Comment("Redis settings")
+ private RedisSettings redis = new RedisSettings();
- @YamlKey("redis.credentials.port")
- private int redisPort = 6379;
+ @Getter
+ @Configuration
+ @NoArgsConstructor(access = AccessLevel.PRIVATE)
+ public static class RedisSettings {
- @YamlKey("redis.credentials.password")
- private String redisPassword = "";
+ @Comment("Specify the credentials of your Redis database here. Set \"password\" to '' if you don't have one")
+ private RedisCredentials credentials = new RedisCredentials();
- @YamlKey("redis.use_ssl")
- private boolean redisUseSsl = false;
+ @Getter
+ @Configuration
+ @NoArgsConstructor(access = AccessLevel.PRIVATE)
+ public static class RedisCredentials {
+ private String host = "localhost";
+ private int port = 6379;
+ private String password = "";
+ private boolean useSsl = false;
+ }
- @YamlComment("If you're using Redis Sentinel, specify the master set name. If you don't know what this is, don't change anything here.")
- @YamlKey("redis.sentinel.master")
- private String redisSentinelMaster = "";
+ @Comment({"Advanced configuration for users of Redis sentinel.",
+ "If you don't know what this is, do not modify anything in this section."})
+ private RedisSentinel sentinel = new RedisSentinel();
- @YamlComment("List of host:port pairs")
- @YamlKey("redis.sentinel.nodes")
- private List redisSentinelNodes = new ArrayList<>();
-
- @YamlKey("redis.sentinel.password")
- private String redisSentinelPassword = "";
+ @Getter
+ @Configuration
+ @NoArgsConstructor(access = AccessLevel.PRIVATE)
+ public static class RedisSentinel {
+ @Comment("The master set name for the Redis sentinel.")
+ private String master = "";
+ @Comment("List of host:port pairs")
+ private List nodes = new ArrayList<>();
+ private String password = "";
+ }
+ }
// Synchronization settings
- @YamlComment("The data synchronization mode to use (LOCKSTEP or DELAY). LOCKSTEP is recommended for most networks."
- + " Docs: https://william278.net/docs/husksync/sync-modes")
- @YamlKey("synchronization.mode")
- private DataSyncer.Mode syncMode = DataSyncer.Mode.LOCKSTEP;
+ @Comment("Redis settings")
+ private SynchronizationSettings synchronization = new SynchronizationSettings();
- @YamlComment("The number of data snapshot backups that should be kept at once per user")
- @YamlKey("synchronization.max_user_data_snapshots")
- private int maxUserDataSnapshots = 16;
+ @Getter
+ @Configuration
+ @NoArgsConstructor(access = AccessLevel.PRIVATE)
+ public static class SynchronizationSettings {
- @YamlComment("Number of hours between new snapshots being saved as backups (Use \"0\" to backup all snapshots)")
- @YamlKey("synchronization.snapshot_backup_frequency")
- private int snapshotBackupFrequency = 4;
+ @Comment("The data synchronization mode to use (LOCKSTEP or DELAY). LOCKSTEP is recommended for most networks."
+ + " Docs: https://william278.net/docs/husksync/sync-modes")
+ private DataSyncer.Mode mode = DataSyncer.Mode.LOCKSTEP;
- @YamlComment("List of save cause IDs for which a snapshot will be automatically pinned (so it won't be rotated)."
- + " Docs: https://william278.net/docs/husksync/data-rotation#save-causes")
- @YamlKey("synchronization.auto_pinned_save_causes")
- private List autoPinnedSaveCauses = List.of(
- DataSnapshot.SaveCause.INVENTORY_COMMAND.name(),
- DataSnapshot.SaveCause.ENDERCHEST_COMMAND.name(),
- DataSnapshot.SaveCause.BACKUP_RESTORE.name(),
- DataSnapshot.SaveCause.LEGACY_MIGRATION.name(),
- DataSnapshot.SaveCause.MPDB_MIGRATION.name()
- );
+ @Comment("The number of data snapshot backups that should be kept at once per user")
+ private int maxUserDataSnapshots = 16;
- @YamlComment("Whether to create a snapshot for users on a world when the server saves that world")
- @YamlKey("synchronization.save_on_world_save")
- private boolean saveOnWorldSave = true;
+ @Comment("Number of hours between new snapshots being saved as backups (Use \"0\" to backup all snapshots)")
+ private int snapshotBackupFrequency = 4;
- @YamlComment("Whether to create a snapshot for users when they die (containing their death drops)")
- @YamlKey("synchronization.save_on_death.enabled")
- private boolean saveOnDeath = false;
+ @Comment("List of save cause IDs for which a snapshot will be automatically pinned (so it won't be rotated)."
+ + " Docs: https://william278.net/docs/husksync/data-rotation#save-causes")
+ @Getter(AccessLevel.NONE)
+ private List autoPinnedSaveCauses = List.of(
+ DataSnapshot.SaveCause.INVENTORY_COMMAND.name(),
+ DataSnapshot.SaveCause.ENDERCHEST_COMMAND.name(),
+ DataSnapshot.SaveCause.BACKUP_RESTORE.name(),
+ DataSnapshot.SaveCause.LEGACY_MIGRATION.name(),
+ DataSnapshot.SaveCause.MPDB_MIGRATION.name()
+ );
- @YamlComment("What items to save in death snapshots? (DROPS or ITEMS_TO_KEEP). "
- + " Note that ITEMS_TO_KEEP (suggested for keepInventory servers) requires a Paper 1.19.4+ server.")
- @YamlKey("synchronization.save_on_death.items_to_save")
- private DeathItemsMode deathItemsMode = DeathItemsMode.DROPS;
+ @Comment("Whether to create a snapshot for users on a world when the server saves that world")
+ private boolean saveOnWorldSave = true;
- @YamlComment("Should a death snapshot still be created even if the items to save on the player's death are empty?")
- @YamlKey("synchronization.save_on_death.save_empty_items")
- private boolean saveEmptyDeathItems = true;
+ @Comment("Configuration for how and when to sync player data when they die")
+ private SaveOnDeathSettings saveOnDeath = new SaveOnDeathSettings();
- @YamlComment("Whether dead players who log out and log in to a different server should have their items saved.")
- @YamlKey("synchronization.save_on_death.sync_dead_players_changing_server")
- private boolean synchronizeDeadPlayersChangingServer = true;
+ @Getter
+ @Configuration
+ @NoArgsConstructor(access = AccessLevel.PRIVATE)
+ public static class SaveOnDeathSettings {
+ @Comment("Whether to create a snapshot for users when they die (containing their death drops)")
+ private boolean enabled = false;
- @YamlComment("Whether to use the snappy data compression algorithm. Keep on unless you know what you're doing")
- @YamlKey("synchronization.compress_data")
- private boolean compressData = true;
+ @Comment("What items to save in death snapshots? (DROPS or ITEMS_TO_KEEP). "
+ + " Note that ITEMS_TO_KEEP (suggested for keepInventory servers) requires a Paper 1.19.4+ server.")
+ private DeathItemsMode itemsToSave = DeathItemsMode.DROPS;
- @YamlComment("Where to display sync notifications (ACTION_BAR, CHAT, TOAST or NONE)")
- @YamlKey("synchronization.notification_display_slot")
- private Locales.NotificationSlot notificationSlot = Locales.NotificationSlot.ACTION_BAR;
+ @Comment("Should a death snapshot still be created even if the items to save on the player's death are empty?")
+ private boolean saveEmptyItems = true;
- @YamlComment("(Experimental) Persist Cartography Table locked maps to let them be viewed on any server")
- @YamlKey("synchronization.persist_locked_maps")
- private boolean persistLockedMaps = true;
+ @Comment("Whether dead players who log out and log in to a different server should have their items saved.")
+ private boolean syncDeadPlayersChangingServer = true;
- @YamlComment("Whether to synchronize player max health (requires health syncing to be enabled)")
- @YamlKey("synchronization.synchronize_max_health")
- private boolean synchronizeMaxHealth = true;
-
- @YamlComment("If using the DELAY sync method, how long should this server listen for Redis key data updates before "
- + "pulling data from the database instead (i.e., if the user did not change servers).")
- @YamlKey("synchronization.network_latency_milliseconds")
- private int networkLatencyMilliseconds = 500;
-
- @YamlComment("Which data types to synchronize (Docs: https://william278.net/docs/husksync/sync-features)")
- @YamlKey("synchronization.features")
- private Map synchronizationFeatures = Identifier.getConfigMap();
-
- @YamlComment("Commands which should be blocked before a player has finished syncing (Use * to block all commands)")
- @YamlKey("synchronization.blacklisted_commands_while_locked")
- private List blacklistedCommandsWhileLocked = new ArrayList<>(List.of("*"));
-
- @YamlComment("Event priorities for listeners (HIGHEST, NORMAL, LOWEST). Change if you encounter plugin conflicts")
- @YamlKey("synchronization.event_priorities")
- private Map syncEventPriorities = EventListener.ListenerType.getDefaults();
-
-
- // Zero-args constructor for instantiation via Annotaml
- @SuppressWarnings("unused")
- public Settings() {
- }
-
-
- @NotNull
- public String getLanguage() {
- return language;
- }
-
- public boolean doCheckForUpdates() {
- return checkForUpdates;
- }
-
- @NotNull
- public String getClusterId() {
- return clusterId;
- }
-
- public boolean doDebugLogging() {
- return debugLogging;
- }
-
- public boolean doBrigadierTabCompletion() {
- return brigadierTabCompletion;
- }
-
- public boolean usePlanHook() {
- return enablePlanHook;
- }
-
- @NotNull
- public Database.Type getDatabaseType() {
- return databaseType;
- }
-
- @NotNull
- public String getMySqlHost() {
- return mySqlHost;
- }
-
- public int getMySqlPort() {
- return mySqlPort;
- }
-
- @NotNull
- public String getMySqlDatabase() {
- return mySqlDatabase;
- }
-
- @NotNull
- public String getMySqlUsername() {
- return mySqlUsername;
- }
-
- @NotNull
- public String getMySqlPassword() {
- return mySqlPassword;
- }
-
- @NotNull
- public String getMySqlConnectionParameters() {
- return mySqlConnectionParameters;
- }
-
- @NotNull
- public String getTableName(@NotNull TableName tableName) {
- return tableNames.getOrDefault(tableName.name().toLowerCase(Locale.ENGLISH), tableName.defaultName);
- }
-
- public int getMySqlConnectionPoolSize() {
- return mySqlConnectionPoolSize;
- }
-
- public int getMySqlConnectionPoolIdle() {
- return mySqlConnectionPoolIdle;
- }
-
- public long getMySqlConnectionPoolLifetime() {
- return mySqlConnectionPoolLifetime;
- }
-
- public long getMySqlConnectionPoolKeepAlive() {
- return mySqlConnectionPoolKeepAlive;
- }
-
- public long getMySqlConnectionPoolTimeout() {
- return mySqlConnectionPoolTimeout;
- }
-
- @NotNull
- public String getRedisHost() {
- return redisHost;
- }
-
- public int getRedisPort() {
- return redisPort;
- }
-
- @NotNull
- public String getRedisPassword() {
- return redisPassword;
- }
-
- public boolean redisUseSsl() {
- return redisUseSsl;
- }
-
- @NotNull
- public String getRedisSentinelMaster() {
- return redisSentinelMaster;
- }
-
- @NotNull
- public List getRedisSentinelNodes() {
- return redisSentinelNodes;
- }
-
- @NotNull
- public String getRedisSentinelPassword() {
- return redisSentinelPassword;
- }
-
- @NotNull
- public DataSyncer.Mode getSyncMode() {
- return syncMode;
- }
-
- public int getMaxUserDataSnapshots() {
- return maxUserDataSnapshots;
- }
-
- public int getBackupFrequency() {
- return snapshotBackupFrequency;
- }
-
- public boolean doSaveOnWorldSave() {
- return saveOnWorldSave;
- }
-
- public boolean doSaveOnDeath() {
- return saveOnDeath;
- }
-
- @NotNull
- public DeathItemsMode getDeathItemsMode() {
- return deathItemsMode;
- }
-
- public boolean doSaveEmptyDeathItems() {
- return saveEmptyDeathItems;
- }
-
- public boolean doCompressData() {
- return compressData;
- }
-
- public boolean doAutoPin(@NotNull DataSnapshot.SaveCause cause) {
- return autoPinnedSaveCauses.contains(cause.name());
- }
-
- @NotNull
- public Locales.NotificationSlot getNotificationDisplaySlot() {
- return notificationSlot;
- }
-
- public boolean doPersistLockedMaps() {
- return persistLockedMaps;
- }
-
- public boolean doSynchronizeDeadPlayersChangingServer() {
- return synchronizeDeadPlayersChangingServer;
- }
-
- public boolean doSynchronizeMaxHealth() {
- return synchronizeMaxHealth;
- }
-
- public int getNetworkLatencyMilliseconds() {
- return networkLatencyMilliseconds;
- }
-
- @NotNull
- public Map getSynchronizationFeatures() {
- return synchronizationFeatures;
- }
-
- public boolean isSyncFeatureEnabled(@NotNull Identifier id) {
- return id.isCustom() || getSynchronizationFeatures().getOrDefault(id.getKeyValue(), id.isEnabledByDefault());
- }
-
- @NotNull
- public List getBlacklistedCommandsWhileLocked() {
- return blacklistedCommandsWhileLocked;
- }
-
- @NotNull
- public EventListener.Priority getEventPriority(@NotNull EventListener.ListenerType type) {
- try {
- return EventListener.Priority.valueOf(syncEventPriorities.get(type.name().toLowerCase(Locale.ENGLISH)));
- } catch (IllegalArgumentException e) {
- return EventListener.Priority.NORMAL;
+ /**
+ * Represents the mode of saving items on death
+ */
+ public enum DeathItemsMode {
+ DROPS,
+ ITEMS_TO_KEEP
+ }
}
- }
- /**
- * Represents the mode of saving items on death
- */
- public enum DeathItemsMode {
- DROPS,
- ITEMS_TO_KEEP
- }
+ @Comment("Whether to use the snappy data compression algorithm. Keep on unless you know what you're doing")
+ private boolean compressData = true;
- /**
- * Represents the names of tables in the database
- */
- public enum TableName {
- USERS("husksync_users"),
- USER_DATA("husksync_user_data");
+ @Comment("Where to display sync notifications (ACTION_BAR, CHAT, TOAST or NONE)")
+ private Locales.NotificationSlot notificationDisplaySlot = Locales.NotificationSlot.ACTION_BAR;
- private final String defaultName;
+ @Comment("Persist maps locked in a Cartography Table to let them be viewed on any server")
+ private boolean persistLockedMaps = true;
- TableName(@NotNull String defaultName) {
- this.defaultName = defaultName;
+ @Comment("Whether to synchronize player max health (requires health syncing to be enabled)")
+ private boolean synchronizeMaxHealth = true;
+
+ @Comment("If using the DELAY sync method, how long should this server listen for Redis key data updates before "
+ + "pulling data from the database instead (i.e., if the user did not change servers).")
+ private int networkLatencyMilliseconds = 500;
+
+ @Comment("Which data types to synchronize (Docs: https://william278.net/docs/husksync/sync-features)")
+ @Getter(AccessLevel.NONE)
+ private Map features = Identifier.getConfigMap();
+
+ @Comment("Commands which should be blocked before a player has finished syncing (Use * to block all commands)")
+ private List blacklistedCommandsWhileLocked = new ArrayList<>(List.of("*"));
+
+ @Comment("Event priorities for listeners (HIGHEST, NORMAL, LOWEST). Change if you encounter plugin conflicts")
+ @Getter(AccessLevel.NONE)
+ private Map eventPriorities = EventListener.ListenerType.getDefaults();
+
+ public boolean doAutoPin(@NotNull DataSnapshot.SaveCause cause) {
+ return autoPinnedSaveCauses.contains(cause.name());
+ }
+ public boolean isFeatureEnabled(@NotNull Identifier id) {
+ return id.isCustom() || features.getOrDefault(id.getKeyValue(), id.isEnabledByDefault());
}
@NotNull
- private Map.Entry toEntry() {
- return Map.entry(name().toLowerCase(Locale.ENGLISH), defaultName);
- }
-
- @SuppressWarnings("unchecked")
- @NotNull
- private static Map getDefaults() {
- return Map.ofEntries(Arrays.stream(values())
- .map(TableName::toEntry)
- .toArray(Map.Entry[]::new));
+ public EventListener.Priority getEventPriority(@NotNull EventListener.ListenerType type) {
+ try {
+ return EventListener.Priority.valueOf(eventPriorities.get(type.name().toLowerCase(Locale.ENGLISH)));
+ } catch (IllegalArgumentException e) {
+ return EventListener.Priority.NORMAL;
+ }
}
}
diff --git a/common/src/main/java/net/william278/husksync/data/DataSnapshot.java b/common/src/main/java/net/william278/husksync/data/DataSnapshot.java
index 772b6263..d9022279 100644
--- a/common/src/main/java/net/william278/husksync/data/DataSnapshot.java
+++ b/common/src/main/java/net/william278/husksync/data/DataSnapshot.java
@@ -26,7 +26,6 @@ import net.william278.desertwell.util.Version;
import net.william278.husksync.HuskSync;
import net.william278.husksync.adapter.Adaptable;
import net.william278.husksync.adapter.DataAdapter;
-import net.william278.husksync.config.Locales;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -718,7 +717,7 @@ public class DataSnapshot {
}
return new Unpacked(
id,
- pinned || plugin.getSettings().doAutoPin(saveCause),
+ pinned || plugin.getSettings().getSynchronization().doAutoPin(saveCause),
timestamp,
saveCause,
serverName,
@@ -821,8 +820,7 @@ public class DataSnapshot {
@NotNull
public String getDisplayName() {
- return Locales.truncate(name().toLowerCase(Locale.ENGLISH)
- .replaceAll("_", " "), 18);
+ return name().toLowerCase(Locale.ENGLISH);
}
@NotNull
diff --git a/common/src/main/java/net/william278/husksync/data/UserDataHolder.java b/common/src/main/java/net/william278/husksync/data/UserDataHolder.java
index b12c323d..44e01b6a 100644
--- a/common/src/main/java/net/william278/husksync/data/UserDataHolder.java
+++ b/common/src/main/java/net/william278/husksync/data/UserDataHolder.java
@@ -43,7 +43,7 @@ public interface UserDataHolder extends DataHolder {
@NotNull
default Map getData() {
return getPlugin().getRegisteredDataTypes().stream()
- .filter(type -> type.isCustom() || getPlugin().getSettings().isSyncFeatureEnabled(type))
+ .filter(type -> type.isCustom() || getPlugin().getSettings().getSynchronization().isFeatureEnabled(type))
.map(id -> Map.entry(id, getData(id)))
.filter(data -> data.getValue().isPresent())
.collect(HashMap::new, (map, data) -> map.put(data.getKey(), data.getValue().get()), HashMap::putAll);
@@ -105,7 +105,7 @@ public interface UserDataHolder extends DataHolder {
try {
for (Map.Entry entry : unpacked.getData().entrySet()) {
final Identifier identifier = entry.getKey();
- if (plugin.getSettings().isSyncFeatureEnabled(identifier)) {
+ if (plugin.getSettings().getSynchronization().isFeatureEnabled(identifier)) {
if (identifier.isCustom()) {
getCustomDataStore().put(identifier, entry.getValue());
}
diff --git a/common/src/main/java/net/william278/husksync/database/Database.java b/common/src/main/java/net/william278/husksync/database/Database.java
index b6dc6995..81d432b6 100644
--- a/common/src/main/java/net/william278/husksync/database/Database.java
+++ b/common/src/main/java/net/william278/husksync/database/Database.java
@@ -19,6 +19,7 @@
package net.william278.husksync.database;
+import lombok.Getter;
import net.william278.husksync.HuskSync;
import net.william278.husksync.config.Settings;
import net.william278.husksync.data.DataSnapshot;
@@ -31,10 +32,7 @@ import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.OffsetDateTime;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.UUID;
+import java.util.*;
/**
* An abstract representation of the plugin database, storing player data.
@@ -71,8 +69,9 @@ public abstract class Database {
*/
@NotNull
protected final String formatStatementTables(@NotNull String sql) {
- return sql.replaceAll("%users_table%", plugin.getSettings().getTableName(Settings.TableName.USERS))
- .replaceAll("%user_data_table%", plugin.getSettings().getTableName(Settings.TableName.USER_DATA));
+ final Settings.DatabaseSettings settings = plugin.getSettings().getDatabase();
+ return sql.replaceAll("%users_table%", settings.getTableName(TableName.USERS))
+ .replaceAll("%user_data_table%", settings.getTableName(TableName.USER_DATA));
}
/**
@@ -193,7 +192,7 @@ public abstract class Database {
*/
@Blocking
private void addAndRotateSnapshot(@NotNull User user, @NotNull DataSnapshot.Packed snapshot) {
- final int backupFrequency = plugin.getSettings().getBackupFrequency();
+ final int backupFrequency = plugin.getSettings().getSynchronization().getSnapshotBackupFrequency();
if (!snapshot.isPinned() && backupFrequency > 0) {
this.rotateLatestSnapshot(user, snapshot.getTimestamp().minusHours(backupFrequency));
}
@@ -297,4 +296,31 @@ public abstract class Database {
}
}
+ /**
+ * Represents the names of tables in the database
+ */
+ @Getter
+ public enum TableName {
+ USERS("husksync_users"),
+ USER_DATA("husksync_user_data");
+
+ private final String defaultName;
+
+ TableName(@NotNull String defaultName) {
+ this.defaultName = defaultName;
+ }
+
+ @NotNull
+ private Map.Entry toEntry() {
+ return Map.entry(name().toLowerCase(Locale.ENGLISH), defaultName);
+ }
+
+ @SuppressWarnings("unchecked")
+ @NotNull
+ public static Map getDefaults() {
+ return Map.ofEntries(Arrays.stream(values())
+ .map(TableName::toEntry)
+ .toArray(Map.Entry[]::new));
+ }
+ }
}
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 546f9019..9c486481 100644
--- a/common/src/main/java/net/william278/husksync/database/MySqlDatabase.java
+++ b/common/src/main/java/net/william278/husksync/database/MySqlDatabase.java
@@ -34,6 +34,8 @@ import java.time.OffsetDateTime;
import java.util.*;
import java.util.logging.Level;
+import static net.william278.husksync.config.Settings.DatabaseSettings;
+
public class MySqlDatabase extends Database {
private static final String DATA_POOL_NAME = "HuskSyncHikariPool";
@@ -43,9 +45,10 @@ public class MySqlDatabase extends Database {
public MySqlDatabase(@NotNull HuskSync plugin) {
super(plugin);
- this.flavor = plugin.getSettings().getDatabaseType().getProtocol();
- this.driverClass = plugin.getSettings().getDatabaseType() == Type.MARIADB
- ? "org.mariadb.jdbc.Driver" : "com.mysql.cj.jdbc.Driver";
+
+ final Type type = plugin.getSettings().getDatabase().getType();
+ this.flavor = type.getProtocol();
+ this.driverClass = type == Type.MARIADB ? "org.mariadb.jdbc.Driver" : "com.mysql.cj.jdbc.Driver";
}
/**
@@ -67,26 +70,28 @@ public class MySqlDatabase extends Database {
@Override
public void initialize() throws IllegalStateException {
// Initialize the Hikari pooled connection
+ final DatabaseSettings.DatabaseCredentials credentials = plugin.getSettings().getDatabase().getCredentials();
dataSource = new HikariDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setJdbcUrl(String.format("jdbc:%s://%s:%s/%s%s",
flavor,
- plugin.getSettings().getMySqlHost(),
- plugin.getSettings().getMySqlPort(),
- plugin.getSettings().getMySqlDatabase(),
- plugin.getSettings().getMySqlConnectionParameters()
+ credentials.getHost(),
+ credentials.getPort(),
+ credentials.getDatabase(),
+ credentials.getParameters()
));
// Authenticate with the database
- dataSource.setUsername(plugin.getSettings().getMySqlUsername());
- dataSource.setPassword(plugin.getSettings().getMySqlPassword());
+ dataSource.setUsername(credentials.getUsername());
+ dataSource.setPassword(credentials.getPassword());
// Set connection pool options
- dataSource.setMaximumPoolSize(plugin.getSettings().getMySqlConnectionPoolSize());
- dataSource.setMinimumIdle(plugin.getSettings().getMySqlConnectionPoolIdle());
- dataSource.setMaxLifetime(plugin.getSettings().getMySqlConnectionPoolLifetime());
- dataSource.setKeepaliveTime(plugin.getSettings().getMySqlConnectionPoolKeepAlive());
- dataSource.setConnectionTimeout(plugin.getSettings().getMySqlConnectionPoolTimeout());
+ final DatabaseSettings.PoolSettings pool = plugin.getSettings().getDatabase().getConnectionPool();
+ dataSource.setMaximumPoolSize(pool.getMaximumPoolSize());
+ dataSource.setMinimumIdle(pool.getMinimumIdle());
+ dataSource.setMaxLifetime(pool.getMaximumLifetime());
+ dataSource.setKeepaliveTime(pool.getKeepaliveTime());
+ dataSource.setConnectionTimeout(pool.getConnectionTimeout());
dataSource.setPoolName(DATA_POOL_NAME);
// Set additional connection pool properties
@@ -306,7 +311,8 @@ public class MySqlDatabase extends Database {
protected void rotateSnapshots(@NotNull User user) {
final List unpinnedUserData = getAllSnapshots(user).stream()
.filter(dataSnapshot -> !dataSnapshot.isPinned()).toList();
- if (unpinnedUserData.size() > plugin.getSettings().getMaxUserDataSnapshots()) {
+ final int maxSnapshots = plugin.getSettings().getSynchronization().getMaxUserDataSnapshots();
+ if (unpinnedUserData.size() > maxSnapshots) {
try (Connection connection = getConnection()) {
try (PreparedStatement statement = connection.prepareStatement(formatStatementTables("""
DELETE FROM `%user_data_table%`
@@ -314,7 +320,7 @@ public class MySqlDatabase extends Database {
AND `pinned` IS FALSE
ORDER BY `timestamp` ASC
LIMIT %entry_count%;""".replace("%entry_count%",
- Integer.toString(unpinnedUserData.size() - plugin.getSettings().getMaxUserDataSnapshots()))))) {
+ Integer.toString(unpinnedUserData.size() - maxSnapshots))))) {
statement.setString(1, user.getUuid().toString());
statement.executeUpdate();
}
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 adb499ca..a5eae805 100644
--- a/common/src/main/java/net/william278/husksync/listener/EventListener.java
+++ b/common/src/main/java/net/william278/husksync/listener/EventListener.java
@@ -30,6 +30,8 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
+import static net.william278.husksync.config.Settings.SynchronizationSettings.SaveOnDeathSettings;
+
/**
* Handles what should happen when events are fired
*/
@@ -74,7 +76,7 @@ public abstract class EventListener {
* @param usersInWorld a list of users in the world that is being saved
*/
protected final void saveOnWorldSave(@NotNull List usersInWorld) {
- if (plugin.isDisabling() || !plugin.getSettings().doSaveOnWorldSave()) {
+ if (plugin.isDisabling() || !plugin.getSettings().getSynchronization().isSaveOnWorldSave()) {
return;
}
usersInWorld.stream()
@@ -91,8 +93,9 @@ public abstract class EventListener {
* @param items The items that should be saved for this user on their death
*/
protected void saveOnPlayerDeath(@NotNull OnlineUser user, @NotNull Data.Items items) {
- if (plugin.isDisabling() || !plugin.getSettings().doSaveOnDeath() || plugin.isLocked(user.getUuid())
- || user.isNpc() || (!plugin.getSettings().doSaveEmptyDeathItems() && items.isEmpty())) {
+ final SaveOnDeathSettings settings = plugin.getSettings().getSynchronization().getSaveOnDeath();
+ if (plugin.isDisabling() || !settings.isEnabled() || plugin.isLocked(user.getUuid())
+ || user.isNpc() || (!settings.isSaveEmptyItems() && items.isEmpty())) {
return;
}
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 72b6f50a..e91aa9b9 100644
--- a/common/src/main/java/net/william278/husksync/redis/RedisManager.java
+++ b/common/src/main/java/net/william278/husksync/redis/RedisManager.java
@@ -20,6 +20,7 @@
package net.william278.husksync.redis;
import net.william278.husksync.HuskSync;
+import net.william278.husksync.config.Settings;
import net.william278.husksync.data.DataSnapshot;
import net.william278.husksync.user.User;
import org.jetbrains.annotations.Blocking;
@@ -62,25 +63,28 @@ public class RedisManager extends JedisPubSub {
*/
@Blocking
public void initialize() throws IllegalStateException {
- final String password = plugin.getSettings().getRedisPassword();
- final String host = plugin.getSettings().getRedisHost();
- final int port = plugin.getSettings().getRedisPort();
- final boolean useSSL = plugin.getSettings().redisUseSsl();
+ final Settings.RedisSettings.RedisCredentials credentials = plugin.getSettings().getRedis().getCredentials();
+ final String password = credentials.getPassword();
+ final String host = credentials.getHost();
+ final int port = credentials.getPort();
+ final boolean useSSL = credentials.isUseSsl();
// Create the jedis pool
final JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(0);
config.setTestOnBorrow(true);
config.setTestOnReturn(true);
- Set redisSentinelNodes = new HashSet<>(plugin.getSettings().getRedisSentinelNodes());
+
+ final Settings.RedisSettings.RedisSentinel sentinel = plugin.getSettings().getRedis().getSentinel();
+ Set redisSentinelNodes = new HashSet<>(sentinel.getNodes());
if (redisSentinelNodes.isEmpty()) {
this.jedisPool = password.isEmpty()
? new JedisPool(config, host, port, 0, useSSL)
: new JedisPool(config, host, port, 0, password, useSSL);
} else {
- String sentinelPassword = plugin.getSettings().getRedisSentinelPassword();
- String redisSentinelMaster = plugin.getSettings().getRedisSentinelMaster();
- this.jedisPool = new JedisSentinelPool(redisSentinelMaster, redisSentinelNodes, password.isEmpty() ? null : password, sentinelPassword.isEmpty() ? null : sentinelPassword);
+ final String sentinelPassword = sentinel.getPassword();
+ this.jedisPool = new JedisSentinelPool(sentinel.getMaster(), redisSentinelNodes, password.isEmpty()
+ ? null : password, sentinelPassword.isEmpty() ? null : sentinelPassword);
}
// Ping the server to check the connection
@@ -219,8 +223,9 @@ public class RedisManager extends JedisPubSub {
);
redisMessage.dispatch(plugin, RedisMessage.Type.REQUEST_USER_DATA);
});
- return future.orTimeout(
- plugin.getSettings().getNetworkLatencyMilliseconds(),
+ return future
+ .orTimeout(
+ plugin.getSettings().getSynchronization().getNetworkLatencyMilliseconds(),
TimeUnit.MILLISECONDS
)
.exceptionally(throwable -> {
diff --git a/common/src/main/java/net/william278/husksync/sync/DataSyncer.java b/common/src/main/java/net/william278/husksync/sync/DataSyncer.java
index 5f948746..e3763e48 100644
--- a/common/src/main/java/net/william278/husksync/sync/DataSyncer.java
+++ b/common/src/main/java/net/william278/husksync/sync/DataSyncer.java
@@ -90,7 +90,8 @@ public abstract class DataSyncer {
// Calculates the max attempts the system should listen for user data for based on the latency value
private long getMaxListenAttempts() {
return BASE_LISTEN_ATTEMPTS + (
- (Math.max(100, plugin.getSettings().getNetworkLatencyMilliseconds()) / 1000) * 20 / LISTEN_DELAY
+ (Math.max(100, plugin.getSettings().getSynchronization().getNetworkLatencyMilliseconds()) / 1000)
+ * 20 / LISTEN_DELAY
);
}
diff --git a/common/src/main/java/net/william278/husksync/sync/DelayDataSyncer.java b/common/src/main/java/net/william278/husksync/sync/DelayDataSyncer.java
index 9262ca33..a00e67c7 100644
--- a/common/src/main/java/net/william278/husksync/sync/DelayDataSyncer.java
+++ b/common/src/main/java/net/william278/husksync/sync/DelayDataSyncer.java
@@ -53,7 +53,7 @@ public class DelayDataSyncer extends DataSyncer {
}).orElse(false)
);
},
- Math.max(0, plugin.getSettings().getNetworkLatencyMilliseconds() / 50L)
+ Math.max(0, plugin.getSettings().getSynchronization().getNetworkLatencyMilliseconds() / 50L)
);
}
diff --git a/common/src/main/java/net/william278/husksync/user/OnlineUser.java b/common/src/main/java/net/william278/husksync/user/OnlineUser.java
index 6d23fb6f..0bebbec3 100644
--- a/common/src/main/java/net/william278/husksync/user/OnlineUser.java
+++ b/common/src/main/java/net/william278/husksync/user/OnlineUser.java
@@ -147,7 +147,7 @@ public abstract class OnlineUser extends User implements CommandUser, UserDataHo
*/
public void completeSync(boolean succeeded, @NotNull DataSnapshot.UpdateCause cause, @NotNull HuskSync plugin) {
if (succeeded) {
- switch (plugin.getSettings().getNotificationDisplaySlot()) {
+ switch (plugin.getSettings().getSynchronization().getNotificationDisplaySlot()) {
case CHAT -> cause.getCompletedLocale(plugin).ifPresent(this::sendMessage);
case ACTION_BAR -> cause.getCompletedLocale(plugin).ifPresent(this::sendActionBar);
case TOAST -> cause.getCompletedLocale(plugin)
diff --git a/common/src/main/resources/locales/bg-bg.yml b/common/src/main/resources/locales/bg-bg.yml
index b3954bcf..ffb9a2a6 100644
--- a/common/src/main/resources/locales/bg-bg.yml
+++ b/common/src/main/resources/locales/bg-bg.yml
@@ -1,62 +1,63 @@
-synchronization_complete: '[⏵ Данните синхронизирани!](#00fb9a)'
-synchronization_failed: '[⏵ Провалихме се да синхронизираме Вашите данни! Моля свържете се с администратор.](#ff7e5e)'
-inventory_viewer_menu_title: '&0Инвентара на %1%'
-ender_chest_viewer_menu_title: '&0Ендър Сандъка на %1%'
-inventory_viewer_opened: '[Преглеждане снапшота на](#00fb9a) [%1%](#00fb9a bold) [ инвентар от ⌚ %2%](#00fb9a)'
-ender_chest_viewer_opened: '[Преглеждане снапшота на](#00fb9a) [%1%](#00fb9a bold) [ Ендър Сандък от ⌚ %2%](#00fb9a)'
-data_update_complete: '[🔔 Вашите данни бяха обновени!](#00fb9a)'
-data_update_failed: '[🔔 Провалихме се да обновим Вашите данни! Моля свържете се с администратор.](#ff7e5e)'
-user_registration_complete: '[⭐ User registration complete!](#00fb9a)'
-data_manager_title: '[Преглеждане потребителският снапшот](#00fb9a) [%1%](#00fb9a show_text=&7Версия на UUID:\n&8%2%) [за](#00fb9a) [%3%](#00fb9a bold show_text=&7UUID на Играча:\n&8%4%)[:](#00fb9a)'
-data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Клеймо на Версията:\n&8Когато данните са били запазени)'
-data_manager_pinned: '[※ Закачен снапшот](#d8ff2b show_text=&7Закачен:\n&8Снапшота на този потребител няма да бъде автоматично завъртан.)'
-data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Причина на Запазване:\n&8Какво е накарало данните да бъдат запазени)'
-data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name of the server the data was saved on)'
-data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:\n&8Estimated file size of the snapshot (in KiB))\n'
-data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Точки кръв) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Точки глад) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7Ниво опит) [🏹 %5%](dark_aqua show_text=&7Режим на игра)'
-data_manager_advancements_statistics: '[⭐ Напредъци: %1%](color=#ffc43b-#f5c962 show_text=&7Напредъци, в които имате прогрес:\n&8%2%) [⌛ Изиграно Време: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7Изиграно време в играта\n&8⚠ Базирано на статистики от играта)\n'
-data_manager_item_buttons: '[View:](gray) [[🪣 Инвентар…]](color=#a17b5f-#f5b98c show_text=&7Натиснете, за да прегледате run_command=/inventory %1% %2%) [[⌀ Ендър Сандък…]](#b649c4-#d254ff show_text=&7Натиснете, за да проверите run_command=/enderchest %1% %2%)'
-data_manager_management_buttons: '[Управление:](gray) [[❌ Изтрий…]](#ff3300 show_text=&7Натиснете, за да изтриете този снапшот от потребителски данни.\n&8Това няма да засегне текущите данни на потребителя.\nff3300&⚠ Това не може да бъде отменено! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Възстанови…]](#00fb9a show_text=&7Натиснете, за да възстановите тези потребителски данни.\n&8Това ще зададе данните на потребителя на този снапшот.\nff3300&⚠ Текущите данни на %1% ще бъдат пренаписани! suggest_command=/husksync:userdata restore %1% %2%) [[※ Закачи/Откачи…]](#d8ff2b show_text=&7Натиснете, за да закачите или откачите този снапшот с потребителски данни\n&8Закачените снапшоти няма да бъдат автоматично завъртани run_command=/userdata pin %1% %2%)'
-data_manager_system_buttons: '[System:](gray) [[⏷ File Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to a file.\n&8Data dumps can be found in ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ Web Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to the mc-logs service\n&8You will be provided with a URL containing the data. run_command=/husksync:userdata dump %1% %2% web)'
-data_manager_advancements_preview_remaining: 'и още %1%…'
-data_list_title: '[Лист от](#00fb9a) [снапшоти на данните на потребителя](#00fb9a) [%1%](#00fb9a bold show_text=&7UUID: %2%)\n'
-data_list_item: '[%1%](gray show_text=&7User Data Snapshot for %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Pinned:\n&8Pinned snapshots won''t be automatically rotated. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Version timestamp:&7\n&8When the data was saved\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Save cause:\n&8What caused the data to be saved run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:&7\n&8Estimated file size of the snapshot (in KiB) run_command=/userdata view %2% %3%)'
-data_deleted: '[❌ Успешно изтрихме снапшота с потребителски данни](#00fb9a) [%1%](#00fb9a show_text=&7Версия на UUID:\n&8%2%) [за](#00fb9a) [%3%.](#00fb9a show_text=&7UUID на Играча:\n&8%4%)'
-data_restored: '[⏪ Успешно възстановихме](#00fb9a) [текущите потребителски данни за](#00fb9a) [%1%](#00fb9a show_text=&7UUID на Играча:\n&8%2%) [от снапшот](#00fb9a) [%3%.](#00fb9a show_text=&7Версия на UUID:\n&8%4%)'
-data_pinned: '[※ Успешно закачихме снапшота с потребителски данни](#00fb9a) [%1%](#00fb9a show_text=&7Версия на UUID:\n&8%2%) [за](#00fb9a) [%3%.](#00fb9a show_text=&7UUID на Играча:\n&8%4%)'
-data_unpinned: '[※ Успешно откачихме снапшота с потребителски данни](#00fb9a) [%1%](#00fb9a show_text=&7Версия на UUID:\n&8%2%) [за](#00fb9a) [%3%.](#00fb9a show_text=&7UUID на Играча:\n&8%4%)'
-data_dumped: '[☂ Successfully dumped the user data snapshot %1% for %2% to:](#00fb9a) &7%3%'
-list_footer: '\n%1%[Page](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
-list_previous_page_button: '[◀](white show_text=&7View previous page run_command=%2% %1%) '
-list_next_page_button: ' [▶](white show_text=&7View next page run_command=%2% %1%)'
-list_page_jumpers: '(%1%)'
-list_page_jumper_button: '[%1%](show_text=&7Jump to page %1% run_command=%2% %1%)'
-list_page_jumper_current_page: '[%1%](#00fb9a)'
-list_page_jumper_separator: ' '
-list_page_jumper_group_separator: '…'
-save_cause_disconnect: 'disconnect'
-save_cause_world_save: 'world save'
-save_cause_death: 'death'
-save_cause_server_shutdown: 'server shutdown'
-save_cause_inventory_command: 'inventory command'
-save_cause_enderchest_command: 'enderchest command'
-save_cause_backup_restore: 'backup restore'
-save_cause_api: 'API'
-save_cause_mpdb_migration: 'MPDB migration'
-save_cause_legacy_migration: 'legacy migration'
-save_cause_converted_from_v2: 'converted from v2'
-up_to_date: '[HuskSync](#00fb9a bold) [| You are running the latest version of HuskSync (v%1%).](#00fb9a)'
-update_available: '[HuskSync](#ff7e5e bold) [| A new version of HuskSync is available: v%1% (running: v%2%).](#ff7e5e)'
-reload_complete: '[HuskSync](#00fb9a bold) [| Презаредихме конфигурацията и файловете със съобщения.](#00fb9a)\n[⚠ Ensure config files are up-to-date on all servers!](#00fb9a)\n[A restart is needed for config changes to take effect.](#00fb9a italic)'
-system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
-error_invalid_syntax: '[Грешка:](#ff3300) [Неправилен синтаксис. Използвайте:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
-error_invalid_player: '[Грешка:](#ff3300) [Не можахме да открием играч с това име.](#ff7e5e)'
-error_no_permission: '[Грешка:](#ff3300) [Нямате право да използвате тази команда](#ff7e5e)'
-error_console_command_only: '[Грешка:](#ff3300) [Тази команда може да бъде използвана единствено през конзолата](#ff7e5e)'
-error_in_game_command_only: 'Грешка: Тази команда може да бъде използвана само от играта.'
-error_no_data_to_display: '[Грешка:](#ff3300) [Не можахме да открием никакви данни за потребителя, които да покажем.](#ff7e5e)'
-error_invalid_version_uuid: '[Грешка:](#ff3300) [Не можахме да открием никакви потребителски данни за тази версия на това UUID.](#ff7e5e)'
-husksync_command_description: 'Manage the HuskSync plugin'
-userdata_command_description: 'View, manage & restore player userdata'
-inventory_command_description: 'View & edit a player''s inventory'
-enderchest_command_description: 'View & edit a player''s Ender Chest'
\ No newline at end of file
+locales:
+ synchronization_complete: '[⏵ Данните синхронизирани!](#00fb9a)'
+ synchronization_failed: '[⏵ Провалихме се да синхронизираме Вашите данни! Моля свържете се с администратор.](#ff7e5e)'
+ inventory_viewer_menu_title: '&0Инвентара на %1%'
+ ender_chest_viewer_menu_title: '&0Ендър Сандъка на %1%'
+ inventory_viewer_opened: '[Преглеждане снапшота на](#00fb9a) [%1%](#00fb9a bold) [ инвентар от ⌚ %2%](#00fb9a)'
+ ender_chest_viewer_opened: '[Преглеждане снапшота на](#00fb9a) [%1%](#00fb9a bold) [ Ендър Сандък от ⌚ %2%](#00fb9a)'
+ data_update_complete: '[🔔 Вашите данни бяха обновени!](#00fb9a)'
+ data_update_failed: '[🔔 Провалихме се да обновим Вашите данни! Моля свържете се с администратор.](#ff7e5e)'
+ user_registration_complete: '[⭐ User registration complete!](#00fb9a)'
+ data_manager_title: '[Преглеждане потребителският снапшот](#00fb9a) [%1%](#00fb9a show_text=&7Версия на UUID:\n&8%2%) [за](#00fb9a) [%3%](#00fb9a bold show_text=&7UUID на Играча:\n&8%4%)[:](#00fb9a)'
+ data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Клеймо на Версията:\n&8Когато данните са били запазени)'
+ data_manager_pinned: '[※ Закачен снапшот](#d8ff2b show_text=&7Закачен:\n&8Снапшота на този потребител няма да бъде автоматично завъртан.)'
+ data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Причина на Запазване:\n&8Какво е накарало данните да бъдат запазени)'
+ data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name of the server the data was saved on)'
+ data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:\n&8Estimated file size of the snapshot (in KiB))\n'
+ data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Точки кръв) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Точки глад) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7Ниво опит) [🏹 %5%](dark_aqua show_text=&7Режим на игра)'
+ data_manager_advancements_statistics: '[⭐ Напредъци: %1%](color=#ffc43b-#f5c962 show_text=&7Напредъци, в които имате прогрес:\n&8%2%) [⌛ Изиграно Време: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7Изиграно време в играта\n&8⚠ Базирано на статистики от играта)\n'
+ data_manager_item_buttons: '[View:](gray) [[🪣 Инвентар…]](color=#a17b5f-#f5b98c show_text=&7Натиснете, за да прегледате run_command=/inventory %1% %2%) [[⌀ Ендър Сандък…]](#b649c4-#d254ff show_text=&7Натиснете, за да проверите run_command=/enderchest %1% %2%)'
+ data_manager_management_buttons: '[Управление:](gray) [[❌ Изтрий…]](#ff3300 show_text=&7Натиснете, за да изтриете този снапшот от потребителски данни.\n&8Това няма да засегне текущите данни на потребителя.\nff3300&⚠ Това не може да бъде отменено! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Възстанови…]](#00fb9a show_text=&7Натиснете, за да възстановите тези потребителски данни.\n&8Това ще зададе данните на потребителя на този снапшот.\nff3300&⚠ Текущите данни на %1% ще бъдат пренаписани! suggest_command=/husksync:userdata restore %1% %2%) [[※ Закачи/Откачи…]](#d8ff2b show_text=&7Натиснете, за да закачите или откачите този снапшот с потребителски данни\n&8Закачените снапшоти няма да бъдат автоматично завъртани run_command=/userdata pin %1% %2%)'
+ data_manager_system_buttons: '[System:](gray) [[⏷ File Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to a file.\n&8Data dumps can be found in ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ Web Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to the mc-logs service\n&8You will be provided with a URL containing the data. run_command=/husksync:userdata dump %1% %2% web)'
+ data_manager_advancements_preview_remaining: 'и още %1%…'
+ data_list_title: '[Лист от](#00fb9a) [снапшоти на данните на потребителя](#00fb9a) [%1%](#00fb9a bold show_text=&7UUID: %2%)\n'
+ data_list_item: '[%1%](gray show_text=&7User Data Snapshot for %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Pinned:\n&8Pinned snapshots won''t be automatically rotated. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Version timestamp:&7\n&8When the data was saved\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Save cause:\n&8What caused the data to be saved run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:&7\n&8Estimated file size of the snapshot (in KiB) run_command=/userdata view %2% %3%)'
+ data_deleted: '[❌ Успешно изтрихме снапшота с потребителски данни](#00fb9a) [%1%](#00fb9a show_text=&7Версия на UUID:\n&8%2%) [за](#00fb9a) [%3%.](#00fb9a show_text=&7UUID на Играча:\n&8%4%)'
+ data_restored: '[⏪ Успешно възстановихме](#00fb9a) [текущите потребителски данни за](#00fb9a) [%1%](#00fb9a show_text=&7UUID на Играча:\n&8%2%) [от снапшот](#00fb9a) [%3%.](#00fb9a show_text=&7Версия на UUID:\n&8%4%)'
+ data_pinned: '[※ Успешно закачихме снапшота с потребителски данни](#00fb9a) [%1%](#00fb9a show_text=&7Версия на UUID:\n&8%2%) [за](#00fb9a) [%3%.](#00fb9a show_text=&7UUID на Играча:\n&8%4%)'
+ data_unpinned: '[※ Успешно откачихме снапшота с потребителски данни](#00fb9a) [%1%](#00fb9a show_text=&7Версия на UUID:\n&8%2%) [за](#00fb9a) [%3%.](#00fb9a show_text=&7UUID на Играча:\n&8%4%)'
+ data_dumped: '[☂ Successfully dumped the user data snapshot %1% for %2% to:](#00fb9a) &7%3%'
+ list_footer: '\n%1%[Page](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
+ list_previous_page_button: '[◀](white show_text=&7View previous page run_command=%2% %1%) '
+ list_next_page_button: ' [▶](white show_text=&7View next page run_command=%2% %1%)'
+ list_page_jumpers: '(%1%)'
+ list_page_jumper_button: '[%1%](show_text=&7Jump to page %1% run_command=%2% %1%)'
+ list_page_jumper_current_page: '[%1%](#00fb9a)'
+ list_page_jumper_separator: ' '
+ list_page_jumper_group_separator: '…'
+ save_cause_disconnect: 'disconnect'
+ save_cause_world_save: 'world save'
+ save_cause_death: 'death'
+ save_cause_server_shutdown: 'server shutdown'
+ save_cause_inventory_command: 'inventory command'
+ save_cause_enderchest_command: 'enderchest command'
+ save_cause_backup_restore: 'backup restore'
+ save_cause_api: 'API'
+ save_cause_mpdb_migration: 'MPDB migration'
+ save_cause_legacy_migration: 'legacy migration'
+ save_cause_converted_from_v2: 'converted from v2'
+ up_to_date: '[HuskSync](#00fb9a bold) [| You are running the latest version of HuskSync (v%1%).](#00fb9a)'
+ update_available: '[HuskSync](#ff7e5e bold) [| A new version of HuskSync is available: v%1% (running: v%2%).](#ff7e5e)'
+ reload_complete: '[HuskSync](#00fb9a bold) [| Презаредихме конфигурацията и файловете със съобщения.](#00fb9a)\n[⚠ Ensure config files are up-to-date on all servers!](#00fb9a)\n[A restart is needed for config changes to take effect.](#00fb9a italic)'
+ system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
+ error_invalid_syntax: '[Грешка:](#ff3300) [Неправилен синтаксис. Използвайте:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
+ error_invalid_player: '[Грешка:](#ff3300) [Не можахме да открием играч с това име.](#ff7e5e)'
+ error_no_permission: '[Грешка:](#ff3300) [Нямате право да използвате тази команда](#ff7e5e)'
+ error_console_command_only: '[Грешка:](#ff3300) [Тази команда може да бъде използвана единствено през конзолата](#ff7e5e)'
+ error_in_game_command_only: 'Грешка: Тази команда може да бъде използвана само от играта.'
+ error_no_data_to_display: '[Грешка:](#ff3300) [Не можахме да открием никакви данни за потребителя, които да покажем.](#ff7e5e)'
+ error_invalid_version_uuid: '[Грешка:](#ff3300) [Не можахме да открием никакви потребителски данни за тази версия на това UUID.](#ff7e5e)'
+ husksync_command_description: 'Manage the HuskSync plugin'
+ userdata_command_description: 'View, manage & restore player userdata'
+ inventory_command_description: 'View & edit a player''s inventory'
+ enderchest_command_description: 'View & edit a player''s Ender Chest'
\ No newline at end of file
diff --git a/common/src/main/resources/locales/de-de.yml b/common/src/main/resources/locales/de-de.yml
index f386f064..b7bedb44 100644
--- a/common/src/main/resources/locales/de-de.yml
+++ b/common/src/main/resources/locales/de-de.yml
@@ -1,62 +1,63 @@
-synchronization_complete: '[⏵ Daten synchronisiert!](#00fb9a)'
-synchronization_failed: '[⏵ Ein Fehler ist beim Synchronisieren deiner Daten aufgetreten! Bitte kontaktiere einen Administrator.](#ff7e5e)'
-inventory_viewer_menu_title: '&0Inventar von %1%'
-ender_chest_viewer_menu_title: '&0Endertruhe von %1%'
-inventory_viewer_opened: '[Du siehst den Schnappschuss des Inventares von](#00fb9a) [%1%](#00fb9a bold) [von ⌚ %2%](#00fb9a)'
-ender_chest_viewer_opened: '[Du siehst den Schnappschuss der Endertruhe von](#00fb9a) [%1%](#00fb9a bold) [von ⌚ %2%](#00fb9a)'
-data_update_complete: '[🔔 Deine Daten wurden aktualisiert!](#00fb9a)'
-data_update_failed: '[🔔 Ein Fehler ist beim Aktualisieren deiner Daten aufgetreten! Bitte kontaktiere einen Administrator.](#ff7e5e)'
-user_registration_complete: '[⭐ Benutzer-Registrierung abgeschlossen!](#00fb9a)'
-data_manager_title: '[Du siehst den Nutzerdaten-Schnappschuss](#00fb9a) [%1%](#00fb9a show_text=&7Versions-UUID:\n&8%2%) [für %3%](#00fb9a bold show_text=&7Spieler-UUID:\n&8%4%)[:](#00fb9a)'
-data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Versions-Zeitstempel:\n&8Zeitpunkt der Speicherung der Daten)'
-data_manager_pinned: '[※ Schnappschuss angeheftet](#d8ff2b show_text=&7Angeheftet:\n&8Dieser Nutzerdaten-Schnappschuss wird nicht automatisch rotiert.)'
-data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Speicherungsgrund:\n&8Der Grund für das Speichern der Daten)'
-data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name des Servers, auf dem die Daten gespeichert wurden)'
-data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Schnappschuss-Größe:\n&8Geschätzte Dateigröße des Schnappschusses (in KiB))\n'
-data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Lebenspunkte) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Hungerpunkte) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7XP-Level) [🏹 %5%](dark_aqua show_text=&7Spielmodus)'
-data_manager_advancements_statistics: '[⭐ Erfolge: %1%](color=#ffc43b-#f5c962 show_text=&7Erfolge in denen du Fortschritt gemacht hast:\n&8%2%) [⌛ Spielzeit: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7Deine verbrachte Zeit im Spiel\n&8⚠ Basierend auf Spielstatistiken)\n'
-data_manager_item_buttons: '[Sehen:](gray) [[🪣 Inventar…]](color=#a17b5f-#f5b98c show_text=&7Klicke zum Ansehen run_command=/inventory %1% %2%) [[⌀ Endertruhe…]](#b649c4-#d254ff show_text=&7Klicke zum Ansehen run_command=/enderchest %1% %2%)'
-data_manager_management_buttons: '[Verwalten:](gray) [[❌ Löschen…]](#ff3300 show_text=&7Klicke, um diesen Nutzerdaten-Schnappschuss zu löschen.\n&8Dies betrifft nicht die aktuellen Nutzerdaten.\nff3300&⚠ Dieser Schritt kann nicht rückgängig gemacht werden! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Wiederherstellen…]](#00fb9a show_text=&7Klicke, um die Nutzerdaten wiederherzustellen.\n&8Dies wird die Nutzerdaten auf den Stand des Schnappschusses setzen.\nff3300&⚠ Die aktuellen Nutzerdaten von %1% werden überschrieben! suggest_command=/husksync:userdata restore %1% %2%) [[※ Anheften/Loslösen…]](#d8ff2b show_text=&7Klicke, um diesen Nutzerdaten-Schnappschuss anzuheften oder loszulösen\n&8Angeheftete Nutzerdaten-Schnappschüsse werden nicht automatisch rotiert run_command=/userdata pin %1% %2%)'
-data_manager_system_buttons: '[System:](gray) [[⏷ Daten-Dump…]](dark_gray show_text=&7Klicke, um diesen rohen Nutzerdaten-Schnappschuss in eine Datei zu speichern.\n&8Daten-Dumps können unter ~/plugins/HuskSync/dumps/ gefunden werden. run_command=/husksync:userdata dump %1% %2% file) [[☂ Web-Dump…]](dark_gray show_text=&7Klicke, um diesen rohen Nutzerdaten-Schnappschuss auf den mc-logs Service hochzuladen.\n&8Du erhältst dann eine URL, die die Daten enthält. run_command=/husksync:userdata dump %1% %2% web)'
-data_manager_advancements_preview_remaining: 'und %1% weitere…'
-data_list_title: '[Nutzerdaten-Schnappschüsse von %1%:](#00fb9a) [(%2%-%3% von](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
-data_list_item: '[%1%](gray show_text=&7Nutzerdaten-Schnappschuss für %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Angeheftet:\n&8Angeheftete Schnappschüsse werden nicht automatisch rotiert. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Versions-Zeitstempel:&7\n&8Zeitpunkt der Speicherung der Daten\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Speicherungsgrund:\n&8Grund für das Speichern der Daten run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Schnappschuss-Größe:&7\n&8Geschätzte Dateigröße des Schnappschusses (in KiB) run_command=/userdata view %2% %3%)'
-data_deleted: '[❌ Nutzerdaten-Schnappschuss erfolgreich gelöscht](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [für](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
-data_restored: '[⏪ Erfgreich wiederhergestellt](#00fb9a) [Aktuelle Nutzerdaten des Schnappschusses von %1%](#00fb9a show_text=&7Spieler-UUID:\n&8%2%) [%3%.](#00fb9a show_text=&7Versions-UUID:\n&8%4%)'
-data_pinned: '[※ Nutzerdaten-Schnappschuss erfolgreich angepinnt](#00fb9a) [%1%](#00fb9a show_text=&7Versions-UUID:\n&8%2%) [für](#00fb9a) [%3%.](#00fb9a show_text=&7Spieler-UUID:\n&8%4%)'
-data_unpinned: '[※ Nutzerdaten-Schnappschuss erfolgreich losgelöst](#00fb9a) [%1%](#00fb9a show_text=&7Versions-UUID:\n&8%2%) [für](#00fb9a) [%3%.](#00fb9a show_text=&7Spieler-UUID:\n&8%4%)'
-data_dumped: '[☂ Nutzerdaten-Schnappschuss %1% für %2% erfolgreich gedumpt nach:](#00fb9a) &7%3%'
-list_footer: '\n%1%[Seite](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
-list_previous_page_button: '[◀](white show_text=&7Siehe vorherige Seite run_command=%2% %1%) '
-list_next_page_button: ' [▶](white show_text=&7Siehe nächste Seite run_command=%2% %1%)'
-list_page_jumpers: '(%1%)'
-list_page_jumper_button: '[%1%](show_text=&7Springe zu Seite %1% run_command=%2% %1%)'
-list_page_jumper_current_page: '[%1%](#00fb9a)'
-list_page_jumper_separator: ' '
-list_page_jumper_group_separator: '…'
-save_cause_disconnect: 'Server verlassen'
-save_cause_world_save: 'Welt gespeichert'
-save_cause_death: 'Tod'
-save_cause_server_shutdown: 'Server gestoppt'
-save_cause_inventory_command: 'Inventar Befehl'
-save_cause_enderchest_command: 'Enderchest Befehl'
-save_cause_backup_restore: 'Backup wiederhergestellt'
-save_cause_api: 'API'
-save_cause_mpdb_migration: 'MPDB Migration'
-save_cause_legacy_migration: 'Legacy Migration'
-save_cause_converted_from_v2: 'Import von v2'
-reload_complete: '[HuskSync](#00fb9a bold) [| Die Konfigurations- und Sprachdateien wurden neu geladen.](#00fb9a)\n[⚠ Stelle sicher, dass die Konfigurationsdateien auf allen Servern aktuell sind!](#00fb9a)\n[Ein Neustart wird benötigt, damit Konfigurations-Änderungen wirkbar werden.](#00fb9a italic)'
-up_to_date: '[HuskSync](#00fb9a bold) [| Du verwendest die neuste Version von HuskSync (v%1%).](#00fb9a)'
-update_available: '[HuskSync](#ff7e5e bold) [| Eine neue Version von HuskSync ist verfügbar: v%1% (Aktuelle Version: v%2%).](#ff7e5e)'
-system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
-error_invalid_syntax: '[Fehler:](#ff3300) [Falsche Syntax. Nutze:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
-error_invalid_player: '[Fehler:](#ff3300) [Es konnte kein Spieler mit diesem Namen gefunden werden.](#ff7e5e)'
-error_no_permission: '[Fehler:](#ff3300) [Du hast nicht die benötigten Berechtigungen um diesen Befehl auszuführen](#ff7e5e)'
-error_console_command_only: '[Fehler:](#ff3300) [Dieser Befehl kann nur über die Konsole ausgeführt werden.](#ff7e5e)'
-error_in_game_command_only: 'Fehler: Dieser Befehl kann nur im Spiel genutzt werden.'
-error_no_data_to_display: '[Fehler:](#ff3300) [Es konnten keine Nutzerdaten zum Anzeigen gefunden werden.](#ff7e5e)'
-error_invalid_version_uuid: '[Fehler:](#ff3300) [Es konnten keine Nutzerdaten für diese Versions-UUID gefunden werden.](#ff7e5e)'
-husksync_command_description: 'Das HuskSync-Plugin verwalten'
-userdata_command_description: 'Nutzerdaten eines Spielers anzeigen, verwalten und wiederherstellen'
-inventory_command_description: 'Inventar eines Spielers ansehen und bearbeiten'
-enderchest_command_description: 'Endertruhe eines Spielers ansehen und bearbeiten'
+locales:
+ synchronization_complete: '[⏵ Daten synchronisiert!](#00fb9a)'
+ synchronization_failed: '[⏵ Ein Fehler ist beim Synchronisieren deiner Daten aufgetreten! Bitte kontaktiere einen Administrator.](#ff7e5e)'
+ inventory_viewer_menu_title: '&0Inventar von %1%'
+ ender_chest_viewer_menu_title: '&0Endertruhe von %1%'
+ inventory_viewer_opened: '[Du siehst den Schnappschuss des Inventares von](#00fb9a) [%1%](#00fb9a bold) [von ⌚ %2%](#00fb9a)'
+ ender_chest_viewer_opened: '[Du siehst den Schnappschuss der Endertruhe von](#00fb9a) [%1%](#00fb9a bold) [von ⌚ %2%](#00fb9a)'
+ data_update_complete: '[🔔 Deine Daten wurden aktualisiert!](#00fb9a)'
+ data_update_failed: '[🔔 Ein Fehler ist beim Aktualisieren deiner Daten aufgetreten! Bitte kontaktiere einen Administrator.](#ff7e5e)'
+ user_registration_complete: '[⭐ Benutzer-Registrierung abgeschlossen!](#00fb9a)'
+ data_manager_title: '[Du siehst den Nutzerdaten-Schnappschuss](#00fb9a) [%1%](#00fb9a show_text=&7Versions-UUID:\n&8%2%) [für %3%](#00fb9a bold show_text=&7Spieler-UUID:\n&8%4%)[:](#00fb9a)'
+ data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Versions-Zeitstempel:\n&8Zeitpunkt der Speicherung der Daten)'
+ data_manager_pinned: '[※ Schnappschuss angeheftet](#d8ff2b show_text=&7Angeheftet:\n&8Dieser Nutzerdaten-Schnappschuss wird nicht automatisch rotiert.)'
+ data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Speicherungsgrund:\n&8Der Grund für das Speichern der Daten)'
+ data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name des Servers, auf dem die Daten gespeichert wurden)'
+ data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Schnappschuss-Größe:\n&8Geschätzte Dateigröße des Schnappschusses (in KiB))\n'
+ data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Lebenspunkte) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Hungerpunkte) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7XP-Level) [🏹 %5%](dark_aqua show_text=&7Spielmodus)'
+ data_manager_advancements_statistics: '[⭐ Erfolge: %1%](color=#ffc43b-#f5c962 show_text=&7Erfolge in denen du Fortschritt gemacht hast:\n&8%2%) [⌛ Spielzeit: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7Deine verbrachte Zeit im Spiel\n&8⚠ Basierend auf Spielstatistiken)\n'
+ data_manager_item_buttons: '[Sehen:](gray) [[🪣 Inventar…]](color=#a17b5f-#f5b98c show_text=&7Klicke zum Ansehen run_command=/inventory %1% %2%) [[⌀ Endertruhe…]](#b649c4-#d254ff show_text=&7Klicke zum Ansehen run_command=/enderchest %1% %2%)'
+ data_manager_management_buttons: '[Verwalten:](gray) [[❌ Löschen…]](#ff3300 show_text=&7Klicke, um diesen Nutzerdaten-Schnappschuss zu löschen.\n&8Dies betrifft nicht die aktuellen Nutzerdaten.\nff3300&⚠ Dieser Schritt kann nicht rückgängig gemacht werden! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Wiederherstellen…]](#00fb9a show_text=&7Klicke, um die Nutzerdaten wiederherzustellen.\n&8Dies wird die Nutzerdaten auf den Stand des Schnappschusses setzen.\nff3300&⚠ Die aktuellen Nutzerdaten von %1% werden überschrieben! suggest_command=/husksync:userdata restore %1% %2%) [[※ Anheften/Loslösen…]](#d8ff2b show_text=&7Klicke, um diesen Nutzerdaten-Schnappschuss anzuheften oder loszulösen\n&8Angeheftete Nutzerdaten-Schnappschüsse werden nicht automatisch rotiert run_command=/userdata pin %1% %2%)'
+ data_manager_system_buttons: '[System:](gray) [[⏷ Daten-Dump…]](dark_gray show_text=&7Klicke, um diesen rohen Nutzerdaten-Schnappschuss in eine Datei zu speichern.\n&8Daten-Dumps können unter ~/plugins/HuskSync/dumps/ gefunden werden. run_command=/husksync:userdata dump %1% %2% file) [[☂ Web-Dump…]](dark_gray show_text=&7Klicke, um diesen rohen Nutzerdaten-Schnappschuss auf den mc-logs Service hochzuladen.\n&8Du erhältst dann eine URL, die die Daten enthält. run_command=/husksync:userdata dump %1% %2% web)'
+ data_manager_advancements_preview_remaining: 'und %1% weitere…'
+ data_list_title: '[Nutzerdaten-Schnappschüsse von %1%:](#00fb9a) [(%2%-%3% von](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
+ data_list_item: '[%1%](gray show_text=&7Nutzerdaten-Schnappschuss für %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Angeheftet:\n&8Angeheftete Schnappschüsse werden nicht automatisch rotiert. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Versions-Zeitstempel:&7\n&8Zeitpunkt der Speicherung der Daten\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Speicherungsgrund:\n&8Grund für das Speichern der Daten run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Schnappschuss-Größe:&7\n&8Geschätzte Dateigröße des Schnappschusses (in KiB) run_command=/userdata view %2% %3%)'
+ data_deleted: '[❌ Nutzerdaten-Schnappschuss erfolgreich gelöscht](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [für](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
+ data_restored: '[⏪ Erfgreich wiederhergestellt](#00fb9a) [Aktuelle Nutzerdaten des Schnappschusses von %1%](#00fb9a show_text=&7Spieler-UUID:\n&8%2%) [%3%.](#00fb9a show_text=&7Versions-UUID:\n&8%4%)'
+ data_pinned: '[※ Nutzerdaten-Schnappschuss erfolgreich angepinnt](#00fb9a) [%1%](#00fb9a show_text=&7Versions-UUID:\n&8%2%) [für](#00fb9a) [%3%.](#00fb9a show_text=&7Spieler-UUID:\n&8%4%)'
+ data_unpinned: '[※ Nutzerdaten-Schnappschuss erfolgreich losgelöst](#00fb9a) [%1%](#00fb9a show_text=&7Versions-UUID:\n&8%2%) [für](#00fb9a) [%3%.](#00fb9a show_text=&7Spieler-UUID:\n&8%4%)'
+ data_dumped: '[☂ Nutzerdaten-Schnappschuss %1% für %2% erfolgreich gedumpt nach:](#00fb9a) &7%3%'
+ list_footer: '\n%1%[Seite](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
+ list_previous_page_button: '[◀](white show_text=&7Siehe vorherige Seite run_command=%2% %1%) '
+ list_next_page_button: ' [▶](white show_text=&7Siehe nächste Seite run_command=%2% %1%)'
+ list_page_jumpers: '(%1%)'
+ list_page_jumper_button: '[%1%](show_text=&7Springe zu Seite %1% run_command=%2% %1%)'
+ list_page_jumper_current_page: '[%1%](#00fb9a)'
+ list_page_jumper_separator: ' '
+ list_page_jumper_group_separator: '…'
+ save_cause_disconnect: 'Server verlassen'
+ save_cause_world_save: 'Welt gespeichert'
+ save_cause_death: 'Tod'
+ save_cause_server_shutdown: 'Server gestoppt'
+ save_cause_inventory_command: 'Inventar Befehl'
+ save_cause_enderchest_command: 'Enderchest Befehl'
+ save_cause_backup_restore: 'Backup wiederhergestellt'
+ save_cause_api: 'API'
+ save_cause_mpdb_migration: 'MPDB Migration'
+ save_cause_legacy_migration: 'Legacy Migration'
+ save_cause_converted_from_v2: 'Import von v2'
+ reload_complete: '[HuskSync](#00fb9a bold) [| Die Konfigurations- und Sprachdateien wurden neu geladen.](#00fb9a)\n[⚠ Stelle sicher, dass die Konfigurationsdateien auf allen Servern aktuell sind!](#00fb9a)\n[Ein Neustart wird benötigt, damit Konfigurations-Änderungen wirkbar werden.](#00fb9a italic)'
+ up_to_date: '[HuskSync](#00fb9a bold) [| Du verwendest die neuste Version von HuskSync (v%1%).](#00fb9a)'
+ update_available: '[HuskSync](#ff7e5e bold) [| Eine neue Version von HuskSync ist verfügbar: v%1% (Aktuelle Version: v%2%).](#ff7e5e)'
+ system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
+ error_invalid_syntax: '[Fehler:](#ff3300) [Falsche Syntax. Nutze:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
+ error_invalid_player: '[Fehler:](#ff3300) [Es konnte kein Spieler mit diesem Namen gefunden werden.](#ff7e5e)'
+ error_no_permission: '[Fehler:](#ff3300) [Du hast nicht die benötigten Berechtigungen um diesen Befehl auszuführen](#ff7e5e)'
+ error_console_command_only: '[Fehler:](#ff3300) [Dieser Befehl kann nur über die Konsole ausgeführt werden.](#ff7e5e)'
+ error_in_game_command_only: 'Fehler: Dieser Befehl kann nur im Spiel genutzt werden.'
+ error_no_data_to_display: '[Fehler:](#ff3300) [Es konnten keine Nutzerdaten zum Anzeigen gefunden werden.](#ff7e5e)'
+ error_invalid_version_uuid: '[Fehler:](#ff3300) [Es konnten keine Nutzerdaten für diese Versions-UUID gefunden werden.](#ff7e5e)'
+ husksync_command_description: 'Das HuskSync-Plugin verwalten'
+ userdata_command_description: 'Nutzerdaten eines Spielers anzeigen, verwalten und wiederherstellen'
+ inventory_command_description: 'Inventar eines Spielers ansehen und bearbeiten'
+ enderchest_command_description: 'Endertruhe eines Spielers ansehen und bearbeiten'
diff --git a/common/src/main/resources/locales/en-gb.yml b/common/src/main/resources/locales/en-gb.yml
index 6ef9b54f..18a1d91f 100644
--- a/common/src/main/resources/locales/en-gb.yml
+++ b/common/src/main/resources/locales/en-gb.yml
@@ -1,62 +1,63 @@
-synchronization_complete: '[⏵ Data synchronized!](#00fb9a)'
-synchronization_failed: '[⏵ Failed to synchronize your data! Please contact an administrator.](#ff7e5e)'
-inventory_viewer_menu_title: '&0%1%''s Inventory'
-ender_chest_viewer_menu_title: '&0%1%''s Ender Chest'
-inventory_viewer_opened: '[Viewing snapshot of](#00fb9a) [%1%](#00fb9a bold)[''s inventory as of ⌚ %2%](#00fb9a)'
-ender_chest_viewer_opened: '[Viewing snapshot of](#00fb9a) [%1%](#00fb9a bold)[''s Ender Chest as of ⌚ %2%](#00fb9a)'
-data_update_complete: '[🔔 Your data has been updated!](#00fb9a)'
-data_update_failed: '[🔔 Failed to update your data! Please contact an administrator.](#ff7e5e)'
-user_registration_complete: '[⭐ User registration complete!](#00fb9a)'
-data_manager_title: '[Viewing user data snapshot](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%](#00fb9a bold show_text=&7Player UUID:\n&8%4%)[:](#00fb9a)'
-data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Version timestamp:\n&8When the data was saved)'
-data_manager_pinned: '[※ Snapshot pinned](#d8ff2b show_text=&7Pinned:\n&8This user data snapshot won''t be automatically rotated.)'
-data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Save cause:\n&8What caused the data to be saved)'
-data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name of the server the data was saved on)'
-data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:\n&8Estimated file size of the snapshot (in KiB))\n'
-data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Health points) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Hunger points) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7XP level) [🏹 %5%](dark_aqua show_text=&7Game mode)'
-data_manager_advancements_statistics: '[⭐ Advancements: %1%](color=#ffc43b-#f5c962 show_text=&7Advancements you have progress in:\n&8%2%) [⌛ Play Time: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7In-game play time\n&8⚠ Based on in-game statistics)\n'
-data_manager_item_buttons: '[View:](gray) [[🪣 Inventory…]](color=#a17b5f-#f5b98c show_text=&7Click to view run_command=/inventory %1% %2%) [[⌀ Ender Chest…]](#b649c4-#d254ff show_text=&7Click to view run_command=/enderchest %1% %2%)'
-data_manager_management_buttons: '[Manage:](gray) [[❌ Delete…]](#ff3300 show_text=&7Click to delete this snapshot of user data.\n&8This will not affect the user''s current data.\nff3300&⚠ This cannot be undone! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Restore…]](#00fb9a show_text=&7Click to restore this user data.\n&8This will set the user''s data to this snapshot.\nff3300&⚠ %1%''s current data will be overwritten! suggest_command=/husksync:userdata restore %1% %2%) [[※ Pin/Unpin…]](#d8ff2b show_text=&7Click to pin or unpin this user data snapshot\n&8Pinned snapshots won''t be automatically rotated run_command=/userdata pin %1% %2%)'
-data_manager_system_buttons: '[System:](gray) [[⏷ File Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to a file.\n&8Data dumps can be found in ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ Web Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to the mc-logs service\n&8You will be provided with a URL containing the data. run_command=/husksync:userdata dump %1% %2% web)'
-data_manager_advancements_preview_remaining: 'and %1% more…'
-data_list_title: '[%1%''s user data snapshots:](#00fb9a) [(%2%-%3% of](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
-data_list_item: '[%1%](gray show_text=&7User Data Snapshot for %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Pinned:\n&8Pinned snapshots won''t be automatically rotated. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Version timestamp:&7\n&8When the data was saved\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Save cause:\n&8What caused the data to be saved run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:&7\n&8Estimated file size of the snapshot (in KiB) run_command=/userdata view %2% %3%)'
-data_deleted: '[❌ Successfully deleted user data snapshot](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
-data_restored: '[⏪ Successfully restored](#00fb9a) [%1%](#00fb9a show_text=&7Player UUID:\n&8%2%)[''s current user data from snapshot](#00fb9a) [%3%.](#00fb9a show_text=&7Version UUID:\n&8%4%)'
-data_pinned: '[※ Successfully pinned user data snapshot](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
-data_unpinned: '[※ Successfully unpinned user data snapshot](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
-data_dumped: '[☂ Successfully dumped the user data snapshot %1% for %2% to:](#00fb9a) &7%3%'
-list_footer: '\n%1%[Page](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
-list_previous_page_button: '[◀](white show_text=&7View previous page run_command=%2% %1%) '
-list_next_page_button: ' [▶](white show_text=&7View next page run_command=%2% %1%)'
-list_page_jumpers: '(%1%)'
-list_page_jumper_button: '[%1%](show_text=&7Jump to page %1% run_command=%2% %1%)'
-list_page_jumper_current_page: '[%1%](#00fb9a)'
-list_page_jumper_separator: ' '
-list_page_jumper_group_separator: '…'
-save_cause_disconnect: 'disconnect'
-save_cause_world_save: 'world save'
-save_cause_death: 'death'
-save_cause_server_shutdown: 'server shutdown'
-save_cause_inventory_command: 'inventory command'
-save_cause_enderchest_command: 'enderchest command'
-save_cause_backup_restore: 'backup restore'
-save_cause_api: 'API'
-save_cause_mpdb_migration: 'MPDB migration'
-save_cause_legacy_migration: 'legacy migration'
-save_cause_converted_from_v2: 'converted from v2'
-up_to_date: '[HuskSync](#00fb9a bold) [| You are running the latest version of HuskSync (v%1%).](#00fb9a)'
-update_available: '[HuskSync](#ff7e5e bold) [| A new version of HuskSync is available: v%1% (running: v%2%).](#ff7e5e)'
-reload_complete: '[HuskSync](#00fb9a bold) [| Reloaded config and message files.](#00fb9a)\n[⚠ Ensure config files are up-to-date on all servers!](#00fb9a)\n[A restart is needed for config changes to take effect.](#00fb9a italic)'
-system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
-error_invalid_syntax: '[Error:](#ff3300) [Incorrect syntax. Usage:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
-error_invalid_player: '[Error:](#ff3300) [Could not find a player by that name.](#ff7e5e)'
-error_no_permission: '[Error:](#ff3300) [You do not have permission to execute this command](#ff7e5e)'
-error_console_command_only: '[Error:](#ff3300) [That command can only be run through console](#ff7e5e)'
-error_in_game_command_only: 'Error: That command can only be used in-game.'
-error_no_data_to_display: '[Error:](#ff3300) [Could not find any user data to display.](#ff7e5e)'
-error_invalid_version_uuid: '[Error:](#ff3300) [Could not find any user data for that version UUID.](#ff7e5e)'
-husksync_command_description: 'Manage the HuskSync plugin'
-userdata_command_description: 'View, manage & restore player userdata'
-inventory_command_description: 'View & edit a player''s inventory'
-enderchest_command_description: 'View & edit a player''s Ender Chest'
\ No newline at end of file
+locales:
+ synchronization_complete: '[⏵ Data synchronized!](#00fb9a)'
+ synchronization_failed: '[⏵ Failed to synchronize your data! Please contact an administrator.](#ff7e5e)'
+ inventory_viewer_menu_title: '&0%1%''s Inventory'
+ ender_chest_viewer_menu_title: '&0%1%''s Ender Chest'
+ inventory_viewer_opened: '[Viewing snapshot of](#00fb9a) [%1%](#00fb9a bold)[''s inventory as of ⌚ %2%](#00fb9a)'
+ ender_chest_viewer_opened: '[Viewing snapshot of](#00fb9a) [%1%](#00fb9a bold)[''s Ender Chest as of ⌚ %2%](#00fb9a)'
+ data_update_complete: '[🔔 Your data has been updated!](#00fb9a)'
+ data_update_failed: '[🔔 Failed to update your data! Please contact an administrator.](#ff7e5e)'
+ user_registration_complete: '[⭐ User registration complete!](#00fb9a)'
+ data_manager_title: '[Viewing user data snapshot](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%](#00fb9a bold show_text=&7Player UUID:\n&8%4%)[:](#00fb9a)'
+ data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Version timestamp:\n&8When the data was saved)'
+ data_manager_pinned: '[※ Snapshot pinned](#d8ff2b show_text=&7Pinned:\n&8This user data snapshot won''t be automatically rotated.)'
+ data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Save cause:\n&8What caused the data to be saved)'
+ data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name of the server the data was saved on)'
+ data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:\n&8Estimated file size of the snapshot (in KiB))\n'
+ data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Health points) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Hunger points) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7XP level) [🏹 %5%](dark_aqua show_text=&7Game mode)'
+ data_manager_advancements_statistics: '[⭐ Advancements: %1%](color=#ffc43b-#f5c962 show_text=&7Advancements you have progress in:\n&8%2%) [⌛ Play Time: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7In-game play time\n&8⚠ Based on in-game statistics)\n'
+ data_manager_item_buttons: '[View:](gray) [[🪣 Inventory…]](color=#a17b5f-#f5b98c show_text=&7Click to view run_command=/inventory %1% %2%) [[⌀ Ender Chest…]](#b649c4-#d254ff show_text=&7Click to view run_command=/enderchest %1% %2%)'
+ data_manager_management_buttons: '[Manage:](gray) [[❌ Delete…]](#ff3300 show_text=&7Click to delete this snapshot of user data.\n&8This will not affect the user''s current data.\nff3300&⚠ This cannot be undone! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Restore…]](#00fb9a show_text=&7Click to restore this user data.\n&8This will set the user''s data to this snapshot.\nff3300&⚠ %1%''s current data will be overwritten! suggest_command=/husksync:userdata restore %1% %2%) [[※ Pin/Unpin…]](#d8ff2b show_text=&7Click to pin or unpin this user data snapshot\n&8Pinned snapshots won''t be automatically rotated run_command=/userdata pin %1% %2%)'
+ data_manager_system_buttons: '[System:](gray) [[⏷ File Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to a file.\n&8Data dumps can be found in ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ Web Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to the mc-logs service\n&8You will be provided with a URL containing the data. run_command=/husksync:userdata dump %1% %2% web)'
+ data_manager_advancements_preview_remaining: 'and %1% more…'
+ data_list_title: '[%1%''s user data snapshots:](#00fb9a) [(%2%-%3% of](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
+ data_list_item: '[%1%](gray show_text=&7User Data Snapshot for %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Pinned:\n&8Pinned snapshots won''t be automatically rotated. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Version timestamp:&7\n&8When the data was saved\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Save cause:\n&8What caused the data to be saved run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:&7\n&8Estimated file size of the snapshot (in KiB) run_command=/userdata view %2% %3%)'
+ data_deleted: '[❌ Successfully deleted user data snapshot](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
+ data_restored: '[⏪ Successfully restored](#00fb9a) [%1%](#00fb9a show_text=&7Player UUID:\n&8%2%)[''s current user data from snapshot](#00fb9a) [%3%.](#00fb9a show_text=&7Version UUID:\n&8%4%)'
+ data_pinned: '[※ Successfully pinned user data snapshot](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
+ data_unpinned: '[※ Successfully unpinned user data snapshot](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
+ data_dumped: '[☂ Successfully dumped the user data snapshot %1% for %2% to:](#00fb9a) &7%3%'
+ list_footer: '\n%1%[Page](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
+ list_previous_page_button: '[◀](white show_text=&7View previous page run_command=%2% %1%) '
+ list_next_page_button: ' [▶](white show_text=&7View next page run_command=%2% %1%)'
+ list_page_jumpers: '(%1%)'
+ list_page_jumper_button: '[%1%](show_text=&7Jump to page %1% run_command=%2% %1%)'
+ list_page_jumper_current_page: '[%1%](#00fb9a)'
+ list_page_jumper_separator: ' '
+ list_page_jumper_group_separator: '…'
+ save_cause_disconnect: 'disconnect'
+ save_cause_world_save: 'world save'
+ save_cause_death: 'death'
+ save_cause_server_shutdown: 'server shutdown'
+ save_cause_inventory_command: 'inventory command'
+ save_cause_enderchest_command: 'enderchest command'
+ save_cause_backup_restore: 'backup restore'
+ save_cause_api: 'API'
+ save_cause_mpdb_migration: 'MPDB migration'
+ save_cause_legacy_migration: 'legacy migration'
+ save_cause_converted_from_v2: 'converted from v2'
+ up_to_date: '[HuskSync](#00fb9a bold) [| You are running the latest version of HuskSync (v%1%).](#00fb9a)'
+ update_available: '[HuskSync](#ff7e5e bold) [| A new version of HuskSync is available: v%1% (running: v%2%).](#ff7e5e)'
+ reload_complete: '[HuskSync](#00fb9a bold) [| Reloaded config and message files.](#00fb9a)\n[⚠ Ensure config files are up-to-date on all servers!](#00fb9a)\n[A restart is needed for config changes to take effect.](#00fb9a italic)'
+ system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
+ error_invalid_syntax: '[Error:](#ff3300) [Incorrect syntax. Usage:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
+ error_invalid_player: '[Error:](#ff3300) [Could not find a player by that name.](#ff7e5e)'
+ error_no_permission: '[Error:](#ff3300) [You do not have permission to execute this command](#ff7e5e)'
+ error_console_command_only: '[Error:](#ff3300) [That command can only be run through console](#ff7e5e)'
+ error_in_game_command_only: 'Error: That command can only be used in-game.'
+ error_no_data_to_display: '[Error:](#ff3300) [Could not find any user data to display.](#ff7e5e)'
+ error_invalid_version_uuid: '[Error:](#ff3300) [Could not find any user data for that version UUID.](#ff7e5e)'
+ husksync_command_description: 'Manage the HuskSync plugin'
+ userdata_command_description: 'View, manage & restore player userdata'
+ inventory_command_description: 'View & edit a player''s inventory'
+ enderchest_command_description: 'View & edit a player''s Ender Chest'
\ No newline at end of file
diff --git a/common/src/main/resources/locales/es-es.yml b/common/src/main/resources/locales/es-es.yml
index ed75091a..08593485 100644
--- a/common/src/main/resources/locales/es-es.yml
+++ b/common/src/main/resources/locales/es-es.yml
@@ -1,62 +1,63 @@
-synchronization_complete: '[⏵ ¡Datos sincronizados!](#00fb9a)'
-synchronization_failed: '[⏵ Fallo al sincronizar los datos, por favor, contacte con un administrador.](#ff7e5e)'
-inventory_viewer_menu_title: '&0%1% Inventario de:'
-ender_chest_viewer_menu_title: '&0%1% Enderchest de:'
-inventory_viewer_opened: '[Viendo una snapshot de](#00fb9a) [%1%](#00fb9a bold) [Inventario a partir de ⌚ %2%](#00fb9a)'
-ender_chest_viewer_opened: '[Viendo una snapshot de](#00fb9a) [%1%](#00fb9a bold) [Enderchest a partir de ⌚ %2%](#00fb9a)'
-data_update_complete: '[🔔 ¡Tus datos han sido actualizados!](#00fb9a)'
-data_update_failed: '[🔔 Error al actualizar tus datos, por favor, contacte con un administrador.](#ff7e5e)'
-user_registration_complete: '[⭐ User registration complete!](#00fb9a)'
-data_manager_title: '[Viendo una snapshot sobre la informacion del jugador](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%](#00fb9a bold show_text=&7Player UUID:\n&8%4%)[:](#00fb9a)'
-data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Version del registro:\n&8Cuando los datos se han guardado)'
-data_manager_pinned: '[※ Snapshot anclada](#d8ff2b show_text=&Anclado:\n&8La informacion de este jugador no se rotará automaticamente.)'
-data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Motivo del guardado:\n&8Lo que ha causado que se guarde)'
-data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name of the server the data was saved on)'
-data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:\n&8Estimated file size of the snapshot (in KiB))\n'
-data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Puntos de vida) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Puntos de hambre) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7Nivel de exp) [🏹 %5%](dark_aqua show_text=&7Gamemode)'
-data_manager_advancements_statistics: '[⭐ Logros: %1%](color=#ffc43b-#f5c962 show_text=&7Logros que has conseguido:\n&8%2%) [⌛ Tiempo de juego: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7In-game play time\n&8⚠ Based on in-game statistics)\n'
-data_manager_item_buttons: '[View:](gray) [[🪣 Inventario…]](color=#a17b5f-#f5b98c show_text=&7Click para ver run_command=/inventory %1% %2%) [[⌀ Enderchest…]](#b649c4-#d254ff show_text=&7Click para ver run_command=/enderchest %1% %2%)'
-data_manager_management_buttons: '[Manage:](gray) [[❌ Borrar…]](#ff3300 show_text=&7Click para borrar la snapshot del usuario.\n&8Esto no afectará a la informacion actual del jugador.\nff3300&⚠ ¡Esto no se puede deshacer! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Restaurar…]](#00fb9a show_text=&7Click para restaurar la informacion de este usuario.\n&8Esto hará que la informacion actual cambie por esta snapshot.\nff3300&⚠ %1% la informacion actual será sustituida! suggest_command=/husksync:userdata restore %1% %2%) [[※ Pin/Unpin…]](#d8ff2b show_text=&7Click para anclar/desanclar esta snapshot\n&8Las snapshot ancladas no seran rotadas automaticamente run_command=/userdata pin %1% %2%)'
-data_manager_system_buttons: '[System:](gray) [[⏷ File Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to a file.\n&8Data dumps can be found in ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ Web Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to the mc-logs service\n&8You will be provided with a URL containing the data. run_command=/husksync:userdata dump %1% %2% web)'
-data_manager_advancements_preview_remaining: 'y %1% más…'
-data_list_title: '[%1%''s user data snapshots:](#00fb9a) [(%2%-%3% of](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
-data_list_item: '[%1%](gray show_text=&7User Data Snapshot for %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Pinned:\n&8Pinned snapshots won''t be automatically rotated. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Version timestamp:&7\n&8When the data was saved\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Save cause:\n&8What caused the data to be saved run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:&7\n&8Estimated file size of the snapshot (in KiB) run_command=/userdata view %2% %3%)'
-data_deleted: '[❌ Se ha eliminado correctamente la snapshot del usuario](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
-data_restored: '[⏪ Restaurado correctamente](#00fb9a) [%1%](#00fb9a show_text=&7UUID del jugador:\n&8%2%)[Informacion actual de la snapshot del jugador](#00fb9a) [%3%.](#00fb9a show_text=&7Version UUID:\n&8%4%)'
-data_pinned: '[※ Se ha anclado perfectamente la snapshot del jugador](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7UUID del usuario:\n&8%4%)'
-data_unpinned: '[※ Se ha desanclado perfectamente la snapshot del jugador](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7UUID del usuario:\n&8%4%)'
-data_dumped: '[☂ Successfully dumped the user data snapshot %1% for %2% to:](#00fb9a) &7%3%'
-list_footer: '\n%1%[Page](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
-list_previous_page_button: '[◀](white show_text=&7View previous page run_command=%2% %1%) '
-list_next_page_button: ' [▶](white show_text=&7View next page run_command=%2% %1%)'
-list_page_jumpers: '(%1%)'
-list_page_jumper_button: '[%1%](show_text=&7Jump to page %1% run_command=%2% %1%)'
-list_page_jumper_current_page: '[%1%](#00fb9a)'
-list_page_jumper_separator: ' '
-list_page_jumper_group_separator: '…'
-save_cause_disconnect: 'disconnect'
-save_cause_world_save: 'world save'
-save_cause_death: 'death'
-save_cause_server_shutdown: 'server shutdown'
-save_cause_inventory_command: 'inventory command'
-save_cause_enderchest_command: 'enderchest command'
-save_cause_backup_restore: 'backup restore'
-save_cause_api: 'API'
-save_cause_mpdb_migration: 'MPDB migration'
-save_cause_legacy_migration: 'legacy migration'
-save_cause_converted_from_v2: 'converted from v2'
-up_to_date: '[HuskSync](#00fb9a bold) [| You are running the latest version of HuskSync (v%1%).](#00fb9a)'
-update_available: '[HuskSync](#ff7e5e bold) [| A new version of HuskSync is available: v%1% (running: v%2%).](#ff7e5e)'
-reload_complete: '[HuskSync](#00fb9a bold) [| Recargada la configuración y los archivos de lenguaje.](#00fb9a)\n[⚠ Ensure config files are up-to-date on all servers!](#00fb9a)\n[A restart is needed for config changes to take effect.](#00fb9a italic)'
-system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
-error_invalid_syntax: '[Error:](#ff3300) [Sintanxis incorrecta. Usa:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
-error_invalid_player: '[Error:](#ff3300) [No se ha podido encontrar un jugador con ese nombre.](#ff7e5e)'
-error_no_permission: '[Error:](#ff3300) [No tienes permisos para ejecutar este comando.](#ff7e5e)'
-error_console_command_only: '[Error:](#ff3300) [Este comando solo se puede ejecutar desde la consola.](#ff7e5e)'
-error_in_game_command_only: 'Error: Ese comando solo se puede utilizar desde el juego.'
-error_no_data_to_display: '[Error:](#ff3300) [No se ha podido encontrar informacion sobre el jugador.](#ff7e5e)'
-error_invalid_version_uuid: '[Error:](#ff3300) [No se ha podido encontrar informacion sobre la UUID de ese jugador.](#ff7e5e)'
-husksync_command_description: 'Manage the HuskSync plugin'
-userdata_command_description: 'View, manage & restore player userdata'
-inventory_command_description: 'View & edit a player''s inventory'
-enderchest_command_description: 'View & edit a player''s Ender Chest'
\ No newline at end of file
+locales:
+ synchronization_complete: '[⏵ ¡Datos sincronizados!](#00fb9a)'
+ synchronization_failed: '[⏵ Fallo al sincronizar los datos, por favor, contacte con un administrador.](#ff7e5e)'
+ inventory_viewer_menu_title: '&0%1% Inventario de:'
+ ender_chest_viewer_menu_title: '&0%1% Enderchest de:'
+ inventory_viewer_opened: '[Viendo una snapshot de](#00fb9a) [%1%](#00fb9a bold) [Inventario a partir de ⌚ %2%](#00fb9a)'
+ ender_chest_viewer_opened: '[Viendo una snapshot de](#00fb9a) [%1%](#00fb9a bold) [Enderchest a partir de ⌚ %2%](#00fb9a)'
+ data_update_complete: '[🔔 ¡Tus datos han sido actualizados!](#00fb9a)'
+ data_update_failed: '[🔔 Error al actualizar tus datos, por favor, contacte con un administrador.](#ff7e5e)'
+ user_registration_complete: '[⭐ User registration complete!](#00fb9a)'
+ data_manager_title: '[Viendo una snapshot sobre la informacion del jugador](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%](#00fb9a bold show_text=&7Player UUID:\n&8%4%)[:](#00fb9a)'
+ data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Version del registro:\n&8Cuando los datos se han guardado)'
+ data_manager_pinned: '[※ Snapshot anclada](#d8ff2b show_text=&Anclado:\n&8La informacion de este jugador no se rotará automaticamente.)'
+ data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Motivo del guardado:\n&8Lo que ha causado que se guarde)'
+ data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name of the server the data was saved on)'
+ data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:\n&8Estimated file size of the snapshot (in KiB))\n'
+ data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Puntos de vida) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Puntos de hambre) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7Nivel de exp) [🏹 %5%](dark_aqua show_text=&7Gamemode)'
+ data_manager_advancements_statistics: '[⭐ Logros: %1%](color=#ffc43b-#f5c962 show_text=&7Logros que has conseguido:\n&8%2%) [⌛ Tiempo de juego: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7In-game play time\n&8⚠ Based on in-game statistics)\n'
+ data_manager_item_buttons: '[View:](gray) [[🪣 Inventario…]](color=#a17b5f-#f5b98c show_text=&7Click para ver run_command=/inventory %1% %2%) [[⌀ Enderchest…]](#b649c4-#d254ff show_text=&7Click para ver run_command=/enderchest %1% %2%)'
+ data_manager_management_buttons: '[Manage:](gray) [[❌ Borrar…]](#ff3300 show_text=&7Click para borrar la snapshot del usuario.\n&8Esto no afectará a la informacion actual del jugador.\nff3300&⚠ ¡Esto no se puede deshacer! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Restaurar…]](#00fb9a show_text=&7Click para restaurar la informacion de este usuario.\n&8Esto hará que la informacion actual cambie por esta snapshot.\nff3300&⚠ %1% la informacion actual será sustituida! suggest_command=/husksync:userdata restore %1% %2%) [[※ Pin/Unpin…]](#d8ff2b show_text=&7Click para anclar/desanclar esta snapshot\n&8Las snapshot ancladas no seran rotadas automaticamente run_command=/userdata pin %1% %2%)'
+ data_manager_system_buttons: '[System:](gray) [[⏷ File Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to a file.\n&8Data dumps can be found in ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ Web Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to the mc-logs service\n&8You will be provided with a URL containing the data. run_command=/husksync:userdata dump %1% %2% web)'
+ data_manager_advancements_preview_remaining: 'y %1% más…'
+ data_list_title: '[%1%''s user data snapshots:](#00fb9a) [(%2%-%3% of](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
+ data_list_item: '[%1%](gray show_text=&7User Data Snapshot for %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Pinned:\n&8Pinned snapshots won''t be automatically rotated. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Version timestamp:&7\n&8When the data was saved\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Save cause:\n&8What caused the data to be saved run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:&7\n&8Estimated file size of the snapshot (in KiB) run_command=/userdata view %2% %3%)'
+ data_deleted: '[❌ Se ha eliminado correctamente la snapshot del usuario](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
+ data_restored: '[⏪ Restaurado correctamente](#00fb9a) [%1%](#00fb9a show_text=&7UUID del jugador:\n&8%2%)[Informacion actual de la snapshot del jugador](#00fb9a) [%3%.](#00fb9a show_text=&7Version UUID:\n&8%4%)'
+ data_pinned: '[※ Se ha anclado perfectamente la snapshot del jugador](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7UUID del usuario:\n&8%4%)'
+ data_unpinned: '[※ Se ha desanclado perfectamente la snapshot del jugador](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7UUID del usuario:\n&8%4%)'
+ data_dumped: '[☂ Successfully dumped the user data snapshot %1% for %2% to:](#00fb9a) &7%3%'
+ list_footer: '\n%1%[Page](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
+ list_previous_page_button: '[◀](white show_text=&7View previous page run_command=%2% %1%) '
+ list_next_page_button: ' [▶](white show_text=&7View next page run_command=%2% %1%)'
+ list_page_jumpers: '(%1%)'
+ list_page_jumper_button: '[%1%](show_text=&7Jump to page %1% run_command=%2% %1%)'
+ list_page_jumper_current_page: '[%1%](#00fb9a)'
+ list_page_jumper_separator: ' '
+ list_page_jumper_group_separator: '…'
+ save_cause_disconnect: 'disconnect'
+ save_cause_world_save: 'world save'
+ save_cause_death: 'death'
+ save_cause_server_shutdown: 'server shutdown'
+ save_cause_inventory_command: 'inventory command'
+ save_cause_enderchest_command: 'enderchest command'
+ save_cause_backup_restore: 'backup restore'
+ save_cause_api: 'API'
+ save_cause_mpdb_migration: 'MPDB migration'
+ save_cause_legacy_migration: 'legacy migration'
+ save_cause_converted_from_v2: 'converted from v2'
+ up_to_date: '[HuskSync](#00fb9a bold) [| You are running the latest version of HuskSync (v%1%).](#00fb9a)'
+ update_available: '[HuskSync](#ff7e5e bold) [| A new version of HuskSync is available: v%1% (running: v%2%).](#ff7e5e)'
+ reload_complete: '[HuskSync](#00fb9a bold) [| Recargada la configuración y los archivos de lenguaje.](#00fb9a)\n[⚠ Ensure config files are up-to-date on all servers!](#00fb9a)\n[A restart is needed for config changes to take effect.](#00fb9a italic)'
+ system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
+ error_invalid_syntax: '[Error:](#ff3300) [Sintanxis incorrecta. Usa:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
+ error_invalid_player: '[Error:](#ff3300) [No se ha podido encontrar un jugador con ese nombre.](#ff7e5e)'
+ error_no_permission: '[Error:](#ff3300) [No tienes permisos para ejecutar este comando.](#ff7e5e)'
+ error_console_command_only: '[Error:](#ff3300) [Este comando solo se puede ejecutar desde la consola.](#ff7e5e)'
+ error_in_game_command_only: 'Error: Ese comando solo se puede utilizar desde el juego.'
+ error_no_data_to_display: '[Error:](#ff3300) [No se ha podido encontrar informacion sobre el jugador.](#ff7e5e)'
+ error_invalid_version_uuid: '[Error:](#ff3300) [No se ha podido encontrar informacion sobre la UUID de ese jugador.](#ff7e5e)'
+ husksync_command_description: 'Manage the HuskSync plugin'
+ userdata_command_description: 'View, manage & restore player userdata'
+ inventory_command_description: 'View & edit a player''s inventory'
+ enderchest_command_description: 'View & edit a player''s Ender Chest'
\ No newline at end of file
diff --git a/common/src/main/resources/locales/id-id.yml b/common/src/main/resources/locales/id-id.yml
index 770c8c18..cfa5c3fe 100644
--- a/common/src/main/resources/locales/id-id.yml
+++ b/common/src/main/resources/locales/id-id.yml
@@ -1,62 +1,63 @@
-synchronization_complete: '[⏵ Data disinkronkan!](#00fb9a)'
-synchronization_failed: '[⏵ Gagal menyinkronkan datamu! Mohon hubungi administrator.](#ff7e5e)'
-inventory_viewer_menu_title: '&0Inventaris milik %1%'
-ender_chest_viewer_menu_title: '&0Peti Ender milik %1%'
-inventory_viewer_opened: '[Melihat cuplikan inventaris milik](#00fb9a) [%1%](#00fb9a bold)[pada ⌚ %2%](#00fb9a)'
-ender_chest_viewer_opened: '[Melihat cuplikan Peti Ender milik](#00fb9a) [%1%](#00fb9a bold)[pada ⌚ %2%](#00fb9a)'
-data_update_complete: '[🔔 Datamu telah diperbarui!](#00fb9a)'
-data_update_failed: '[🔔 Gagal memperbarui datamu! Mohon hubungi administrator.](#ff7e5e)'
-user_registration_complete: '[⭐ Pendaftaran pengguna selesai!](#00fb9a)'
-data_manager_title: '[Melihat cuplikan data pengguna](#00fb9a) [%1%](#00fb9a show_text=&7Versi UUID:\n&8%2%) [untuk](#00fb9a) [%3%](#00fb9a bold show_text=&7UUID pemain:\n&8%4%)[:](#00fb9a)'
-data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Versi stempel waktu:\n&8Ketika data disimpan)'
-data_manager_pinned: '[※ Cuplikan disematkan](#d8ff2b show_text=&7Disematkan:\n&8Cuplikan data pengguna ini tidak akan diputar secara otomatis.)'
-data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Penyebab penyimpanan:\n&8Apa yang menyebabkan data disimpan)'
-data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Nama server tempat data disimpan)'
-data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Ukuran cuplikan:\n&8Perkiraan ukuran file cuplikan (dalam KiB))\n'
-data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Poin kesehatan) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Poin kelaparan) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7Level XP) [🏹 %5%](dark_aqua show_text=&7Mode game)'
-data_manager_advancements_statistics: '[⭐ Kemajuan: %1%](color=#ffc43b-#f5c962 show_text=&7Kemajuan yang telah kamu capai:\n&8%2%) [⌛ Waktu Bermain: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7Waktu bermain dalam game\n&8⚠ Statistik berdasarkan dalam game)\n'
-data_manager_item_buttons: '[Lihat:](gray) [[🪣 Inventaris…]](color=#a17b5f-#f5b98c show_text=&7Klik untuk lihat run_command=/inventory %1% %2%) [[⌀ Peti Ender…]](#b649c4-#d254ff show_text=&7Klik untuk lihat run_command=/enderchest %1% %2%)'
-data_manager_management_buttons: '[Kelola:](gray) [[❌ Hapus…]](#ff3300 show_text=&7Klik untuk menghapus cuplikan data pengguna ini.\n&8Ini tidak akan berdampak pada data pengguna saat ini.\nff3300&⚠ Hal ini tidak dapat dibatalkan! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Pulihkan…]](#00fb9a show_text=&7Klik untuk memulihkan data pengguna ini.\n&8Ini akan mengatur data pengguna ke cuplikan ini.\nff3300&⚠ Data %1% saat ini akan ditimpa! suggest_command=/husksync:userdata restore %1% %2%) [[※ Sematkan/Tidak disematkan…]](#d8ff2b show_text=&7Klik untuk menyematkan atau tidak cuplikan data pengguna ini\n&8Cuplikan yang disematkan tidak akan diputar otomatis run_command=/userdata pin %1% %2%)'
-data_manager_system_buttons: '[Sistem:](gray) [[⏷ Pembuangan File…]](dark_gray show_text=&7Klik untuk membuang cuplikan data mentah pengguna ini ke sebuah file.\n&8Data yang dibuang dapat ditemukan di ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ Pembuangan Web…]](dark_gray show_text=&7Klik untuk membuang cuplikan data mentah pengguna ini ke layanan mc-logs\n&8Kamu akan diberikan URL yang berisi data. run_command=/husksync:userdata dump %1% %2% web)'
-data_manager_advancements_preview_remaining: 'dan %1% lagi…'
-data_list_title: '[Cuplikan data %1%:](#00fb9a) [(%2%-%3% dari](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
-data_list_item: '[%1%](gray show_text=&7Cuplikan data pengguna untuk %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Disematkan:\n&8Cuplikan yang disematkan tidak akan dirotasi otomatis. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Versi stampel waktu:&7\n&8Saat data disimpan\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Disimpan karena:\n&8Apa yang menyebabkan data disimpan run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Ukuran cuplikan:&7\n&8Perkiraan ukuran file cuplikan (dalam KiB) run_command=/userdata view %2% %3%)'
-data_deleted: '[❌ Berhasil menghapus cuplikan data pengguna](#00fb9a) [%1%](#00fb9a show_text=&7Versi UUID:\n&8%2%) [untuk](#00fb9a) [%3%.](#00fb9a show_text=&7UUID Pemain:\n&8%4%)'
-data_restored: '[⏪ Berhasil dipulihkan](#00fb9a) [%1%](#00fb9a show_text=&7UUID Pemain:\n&8%2%)[data pengguna saat ini dari cuplikan](#00fb9a) [%3%.](#00fb9a show_text=&7Versi UUID:\n&8%4%)'
-data_pinned: '[※ Berhasil menyematkan cuplikan data pengguna](#00fb9a) [%1%](#00fb9a show_text=&7Versi UUID:\n&8%2%) [untuk](#00fb9a) [%3%.](#00fb9a show_text=&7UUID Pemain:\n&8%4%)'
-data_unpinned: '[※ Berhasil melepaskan cuplikan data pengguna yang disematkan](#00fb9a) [%1%](#00fb9a show_text=&7Versi UUID:\n&8%2%) [untuk](#00fb9a) [%3%.](#00fb9a show_text=&7UUID Pemain:\n&8%4%)'
-data_dumped: '[☂ Berhasil membuang cuplikan data pengguna %1% untuk %2% ke:](#00fb9a) &7%3%'
-list_footer: '\n%1%[Halaman](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
-list_previous_page_button: '[◀](white show_text=&7Lihat halaman sebelumnya run_command=%2% %1%) '
-list_next_page_button: ' [▶](white show_text=&7Lihat halaman selanjutnya run_command=%2% %1%)'
-list_page_jumpers: '(%1%)'
-list_page_jumper_button: '[%1%](show_text=&7Loncat ke halaman %1% run_command=%2% %1%)'
-list_page_jumper_current_page: '[%1%](#00fb9a)'
-list_page_jumper_separator: ' '
-list_page_jumper_group_separator: '…'
-save_cause_disconnect: 'memutuskan sambungan'
-save_cause_world_save: 'penyimpanan dunia'
-save_cause_death: 'kematian'
-save_cause_server_shutdown: 'pematian server'
-save_cause_inventory_command: 'perintah inventaris'
-save_cause_enderchest_command: 'perintah enderchest'
-save_cause_backup_restore: 'pemulihan cadangan'
-save_cause_api: 'API'
-save_cause_mpdb_migration: 'migrasi MPDB'
-save_cause_legacy_migration: 'migrasi peninggalan'
-save_cause_converted_from_v2: 'dikonversi dari v2'
-up_to_date: '[HuskSync](#00fb9a bold) [| Kamu menjalankan versi terbaru dari HuskSync (v%1%).](#00fb9a)'
-update_available: '[HuskSync](#ff7e5e bold) [| Versi baru HuskSync tersedia: v%1% (menjalankan: v%2%).](#ff7e5e)'
-reload_complete: '[HuskSync](#00fb9a bold) [| Memuat ulang file konfigurasi dan pesan.](#00fb9a)\n[⚠ Pastikan file konfigurasi sudah diperbarui di semua server!](#00fb9a)\n[Diperlukan pengaktifan ulang agar perubahan konfigurasi dapat diterapkan.](#00fb9a italic)'
-system_status_header: '[HuskSync](#00fb9a bold) [| Laporan status sistem:](#00fb9a)'
-error_invalid_syntax: '[Kesalahan:](#ff3300) [Sintaks salah. Penggunaan:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Klik untuk menyarankan suggest_command=%1%)'
-error_invalid_player: '[Kesalahan:](#ff3300) [Tidak dapat menemukan pemain dengan nama tersebut.](#ff7e5e)'
-error_no_permission: '[Kesalahan:](#ff3300) [Kamu tidak memiliki izin untuk menjalankan perintah ini](#ff7e5e)'
-error_console_command_only: '[Kesalahan:](#ff3300) [Perintah itu hanya dapat dijalankan melalui konsol](#ff7e5e)'
-error_in_game_command_only: 'Kesalahan: Perintah itu hanya dapat dijalankan dalam game.'
-error_no_data_to_display: '[Kesalahan:](#ff3300) [Tidak dapat menemukan data pengguna untuk ditampilkan.](#ff7e5e)'
-error_invalid_version_uuid: '[Kesalahan:](#ff3300) [Tidak dapat menemukan data pengguna untuk versi UUID itu.](#ff7e5e)'
-husksync_command_description: 'Mengelola plugin HuskSync'
-userdata_command_description: 'Lihat, kelola & pulihkan data pengguna pemain'
-inventory_command_description: 'Lihat & edit inventaris pemain'
-enderchest_command_description: 'Lihat & edit Ender Chest pemain'
+locales:
+ synchronization_complete: '[⏵ Data disinkronkan!](#00fb9a)'
+ synchronization_failed: '[⏵ Gagal menyinkronkan datamu! Mohon hubungi administrator.](#ff7e5e)'
+ inventory_viewer_menu_title: '&0Inventaris milik %1%'
+ ender_chest_viewer_menu_title: '&0Peti Ender milik %1%'
+ inventory_viewer_opened: '[Melihat cuplikan inventaris milik](#00fb9a) [%1%](#00fb9a bold)[pada ⌚ %2%](#00fb9a)'
+ ender_chest_viewer_opened: '[Melihat cuplikan Peti Ender milik](#00fb9a) [%1%](#00fb9a bold)[pada ⌚ %2%](#00fb9a)'
+ data_update_complete: '[🔔 Datamu telah diperbarui!](#00fb9a)'
+ data_update_failed: '[🔔 Gagal memperbarui datamu! Mohon hubungi administrator.](#ff7e5e)'
+ user_registration_complete: '[⭐ Pendaftaran pengguna selesai!](#00fb9a)'
+ data_manager_title: '[Melihat cuplikan data pengguna](#00fb9a) [%1%](#00fb9a show_text=&7Versi UUID:\n&8%2%) [untuk](#00fb9a) [%3%](#00fb9a bold show_text=&7UUID pemain:\n&8%4%)[:](#00fb9a)'
+ data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Versi stempel waktu:\n&8Ketika data disimpan)'
+ data_manager_pinned: '[※ Cuplikan disematkan](#d8ff2b show_text=&7Disematkan:\n&8Cuplikan data pengguna ini tidak akan diputar secara otomatis.)'
+ data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Penyebab penyimpanan:\n&8Apa yang menyebabkan data disimpan)'
+ data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Nama server tempat data disimpan)'
+ data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Ukuran cuplikan:\n&8Perkiraan ukuran file cuplikan (dalam KiB))\n'
+ data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Poin kesehatan) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Poin kelaparan) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7Level XP) [🏹 %5%](dark_aqua show_text=&7Mode game)'
+ data_manager_advancements_statistics: '[⭐ Kemajuan: %1%](color=#ffc43b-#f5c962 show_text=&7Kemajuan yang telah kamu capai:\n&8%2%) [⌛ Waktu Bermain: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7Waktu bermain dalam game\n&8⚠ Statistik berdasarkan dalam game)\n'
+ data_manager_item_buttons: '[Lihat:](gray) [[🪣 Inventaris…]](color=#a17b5f-#f5b98c show_text=&7Klik untuk lihat run_command=/inventory %1% %2%) [[⌀ Peti Ender…]](#b649c4-#d254ff show_text=&7Klik untuk lihat run_command=/enderchest %1% %2%)'
+ data_manager_management_buttons: '[Kelola:](gray) [[❌ Hapus…]](#ff3300 show_text=&7Klik untuk menghapus cuplikan data pengguna ini.\n&8Ini tidak akan berdampak pada data pengguna saat ini.\nff3300&⚠ Hal ini tidak dapat dibatalkan! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Pulihkan…]](#00fb9a show_text=&7Klik untuk memulihkan data pengguna ini.\n&8Ini akan mengatur data pengguna ke cuplikan ini.\nff3300&⚠ Data %1% saat ini akan ditimpa! suggest_command=/husksync:userdata restore %1% %2%) [[※ Sematkan/Tidak disematkan…]](#d8ff2b show_text=&7Klik untuk menyematkan atau tidak cuplikan data pengguna ini\n&8Cuplikan yang disematkan tidak akan diputar otomatis run_command=/userdata pin %1% %2%)'
+ data_manager_system_buttons: '[Sistem:](gray) [[⏷ Pembuangan File…]](dark_gray show_text=&7Klik untuk membuang cuplikan data mentah pengguna ini ke sebuah file.\n&8Data yang dibuang dapat ditemukan di ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ Pembuangan Web…]](dark_gray show_text=&7Klik untuk membuang cuplikan data mentah pengguna ini ke layanan mc-logs\n&8Kamu akan diberikan URL yang berisi data. run_command=/husksync:userdata dump %1% %2% web)'
+ data_manager_advancements_preview_remaining: 'dan %1% lagi…'
+ data_list_title: '[Cuplikan data %1%:](#00fb9a) [(%2%-%3% dari](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
+ data_list_item: '[%1%](gray show_text=&7Cuplikan data pengguna untuk %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Disematkan:\n&8Cuplikan yang disematkan tidak akan dirotasi otomatis. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Versi stampel waktu:&7\n&8Saat data disimpan\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Disimpan karena:\n&8Apa yang menyebabkan data disimpan run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Ukuran cuplikan:&7\n&8Perkiraan ukuran file cuplikan (dalam KiB) run_command=/userdata view %2% %3%)'
+ data_deleted: '[❌ Berhasil menghapus cuplikan data pengguna](#00fb9a) [%1%](#00fb9a show_text=&7Versi UUID:\n&8%2%) [untuk](#00fb9a) [%3%.](#00fb9a show_text=&7UUID Pemain:\n&8%4%)'
+ data_restored: '[⏪ Berhasil dipulihkan](#00fb9a) [%1%](#00fb9a show_text=&7UUID Pemain:\n&8%2%)[data pengguna saat ini dari cuplikan](#00fb9a) [%3%.](#00fb9a show_text=&7Versi UUID:\n&8%4%)'
+ data_pinned: '[※ Berhasil menyematkan cuplikan data pengguna](#00fb9a) [%1%](#00fb9a show_text=&7Versi UUID:\n&8%2%) [untuk](#00fb9a) [%3%.](#00fb9a show_text=&7UUID Pemain:\n&8%4%)'
+ data_unpinned: '[※ Berhasil melepaskan cuplikan data pengguna yang disematkan](#00fb9a) [%1%](#00fb9a show_text=&7Versi UUID:\n&8%2%) [untuk](#00fb9a) [%3%.](#00fb9a show_text=&7UUID Pemain:\n&8%4%)'
+ data_dumped: '[☂ Berhasil membuang cuplikan data pengguna %1% untuk %2% ke:](#00fb9a) &7%3%'
+ list_footer: '\n%1%[Halaman](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
+ list_previous_page_button: '[◀](white show_text=&7Lihat halaman sebelumnya run_command=%2% %1%) '
+ list_next_page_button: ' [▶](white show_text=&7Lihat halaman selanjutnya run_command=%2% %1%)'
+ list_page_jumpers: '(%1%)'
+ list_page_jumper_button: '[%1%](show_text=&7Loncat ke halaman %1% run_command=%2% %1%)'
+ list_page_jumper_current_page: '[%1%](#00fb9a)'
+ list_page_jumper_separator: ' '
+ list_page_jumper_group_separator: '…'
+ save_cause_disconnect: 'memutuskan sambungan'
+ save_cause_world_save: 'penyimpanan dunia'
+ save_cause_death: 'kematian'
+ save_cause_server_shutdown: 'pematian server'
+ save_cause_inventory_command: 'perintah inventaris'
+ save_cause_enderchest_command: 'perintah enderchest'
+ save_cause_backup_restore: 'pemulihan cadangan'
+ save_cause_api: 'API'
+ save_cause_mpdb_migration: 'migrasi MPDB'
+ save_cause_legacy_migration: 'migrasi peninggalan'
+ save_cause_converted_from_v2: 'dikonversi dari v2'
+ up_to_date: '[HuskSync](#00fb9a bold) [| Kamu menjalankan versi terbaru dari HuskSync (v%1%).](#00fb9a)'
+ update_available: '[HuskSync](#ff7e5e bold) [| Versi baru HuskSync tersedia: v%1% (menjalankan: v%2%).](#ff7e5e)'
+ reload_complete: '[HuskSync](#00fb9a bold) [| Memuat ulang file konfigurasi dan pesan.](#00fb9a)\n[⚠ Pastikan file konfigurasi sudah diperbarui di semua server!](#00fb9a)\n[Diperlukan pengaktifan ulang agar perubahan konfigurasi dapat diterapkan.](#00fb9a italic)'
+ system_status_header: '[HuskSync](#00fb9a bold) [| Laporan status sistem:](#00fb9a)'
+ error_invalid_syntax: '[Kesalahan:](#ff3300) [Sintaks salah. Penggunaan:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Klik untuk menyarankan suggest_command=%1%)'
+ error_invalid_player: '[Kesalahan:](#ff3300) [Tidak dapat menemukan pemain dengan nama tersebut.](#ff7e5e)'
+ error_no_permission: '[Kesalahan:](#ff3300) [Kamu tidak memiliki izin untuk menjalankan perintah ini](#ff7e5e)'
+ error_console_command_only: '[Kesalahan:](#ff3300) [Perintah itu hanya dapat dijalankan melalui konsol](#ff7e5e)'
+ error_in_game_command_only: 'Kesalahan: Perintah itu hanya dapat dijalankan dalam game.'
+ error_no_data_to_display: '[Kesalahan:](#ff3300) [Tidak dapat menemukan data pengguna untuk ditampilkan.](#ff7e5e)'
+ error_invalid_version_uuid: '[Kesalahan:](#ff3300) [Tidak dapat menemukan data pengguna untuk versi UUID itu.](#ff7e5e)'
+ husksync_command_description: 'Mengelola plugin HuskSync'
+ userdata_command_description: 'Lihat, kelola & pulihkan data pengguna pemain'
+ inventory_command_description: 'Lihat & edit inventaris pemain'
+ enderchest_command_description: 'Lihat & edit Ender Chest pemain'
diff --git a/common/src/main/resources/locales/it-it.yml b/common/src/main/resources/locales/it-it.yml
index bf07d31b..c6ce7f85 100644
--- a/common/src/main/resources/locales/it-it.yml
+++ b/common/src/main/resources/locales/it-it.yml
@@ -1,62 +1,63 @@
-synchronization_complete: '[⏵ Dati sincronizzati!](#00fb9a)'
-synchronization_failed: '[⏵ Sincronizzazione fallita! Perfavore contatta un amministratore.](#ff7e5e)'
-inventory_viewer_menu_title: '&0Inventario di %1%'
-ender_chest_viewer_menu_title: '&0Enderchest di %1%'
-inventory_viewer_opened: '[Stai vedendo l''istantanea di](#00fb9a) [%1%](#00fb9a bold) [inventario del ⌚ %2%](#00fb9a)'
-ender_chest_viewer_opened: '[Stai vedendo l''istantanea di](#00fb9a) [%1%](#00fb9a bold) [Ender Chest del ⌚ %2%](#00fb9a)'
-data_update_complete: '[🔔 I tuoi dati sono stati aggiornati!](#00fb9a)'
-data_update_failed: '[🔔 Aggiornamento dei tuoi dati fallito! Perfavore contatta un amministratore.](#ff7e5e)'
-user_registration_complete: '[⭐ User registration complete!](#00fb9a)'
-data_manager_title: '[Stai vedendo l''istantanea](#00fb9a) [%1%](#00fb9a show_text=&7Versione di UUID:\n&8%2%) [di](#00fb9a) [%3%](#00fb9a bold show_text=&7Player UUID:\n&8%4%)[:](#00fb9a)'
-data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7:\n&8Quando i dati sono stati salvati)'
-data_manager_pinned: '[※ Istantanea fissata](#d8ff2b show_text=&7Pinned:\n&8Quest''istantanea non sarà cancellata automaticamente.)'
-data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Causa di salvataggio:\n&8Cosa ha causato il salvataggio dei dati)'
-data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name of the server the data was saved on)'
-data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Peso dell''istantanea:\n&8Peso stimato del file (in KiB))\n'
-data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Vita) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Fame) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7Livello di XP) [🏹 %5%](dark_aqua show_text=&7Modalità di gioco)'
-data_manager_advancements_statistics: '[⭐ Progressi: %1%](color=#ffc43b-#f5c962 show_text=&7Progressi compiuti in:\n&8%2%) [⌛ Tempo di gioco: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7Tempo di gioco\n&8⚠ Basato sulle statistiche di gioco)\n'
-data_manager_item_buttons: '[View:](gray) [[🪣 Inventario…]](color=#a17b5f-#f5b98c show_text=&7Clicca per visualizzare run_command=/inventory %1% %2%) [[⌀ Ender Chest…]](#b649c4-#d254ff show_text=&7Clicca per visualizzare run_command=/enderchest %1% %2%)'
-data_manager_management_buttons: '[Gestisci:](gray) [[❌ Cancella…]](#ff3300 show_text=&7Fare clic per eliminare questa istantanea.\n&8Questo non influisce sui dati attuali dell''utente.\nff3300&⚠ Questo non può essere annullato! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Ripristina…]](#00fb9a show_text=&7Clicca per ripristinare i dati dell''utente.\n&8I dati dell''utente saranno ripristinati a quest''istantanea.\nff3300&⚠ I dati di %1% saranno sovrascritti! suggest_command=/husksync:userdata restore %1% %2%) [[※ fissa/sblocca...]](#d8ff2b show_text=&7Clicca per fissare o sbloccare quest''istantanea\n&8Le istantanee fissate non saranno cancellate automaticamente run_command=/userdata pin %1% %2%)'
-data_manager_system_buttons: '[Sistema:](gray) [[⏷ Dump del File…]](dark_gray show_text=&7Clicca per ottenere il dump dei dati del giocatore.\n&8I dati salvati sono posizioanti nella cartella ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ Dump su Web…]](dark_gray show_text=&7Clicca per ottenere il dump del file su mc-logs\n&8 Ti verrà consegnato l''url per visionare il dump. run_command=/husksync:userdata dump %1% %2% web)'
-data_manager_advancements_preview_remaining: 'e %1% altro…'
-data_list_title: '[Lista delle istantanee di %1%:](#00fb9a) [(%2%-%3% of](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
-data_list_item: '[%1%](gray show_text=&7Instantanea di %2%&8⚡ id: %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Fissata:\n&8Se fissata, l''istantanea non viene mai modificata. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Data di salvataggio:&7\n&8Momento preciso in cui è stato salvato il dato\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Causa di salvataggio:\n&8Che cosa ha causato il salvataggio run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Peso dell''istantanea:&7\n&8Peso stimato del file (in KiB) run_command=/userdata view %2% %3%)'
-data_deleted: '[❌ Istantanea eliminata con successo](#00fb9a) [%1%](#00fb9a show_text=&7Versione di UUID:\n&8%2%) [per](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
-data_restored: '[⏪ Ripristato con successo](#00fb9a) [Dati dall''istantanea di](#00fb9a)[%1%](#00fb9a show_text=&7Player UUID:\n&8%2%) [%3%.](#00fb9a show_text=&7Versione di UUID:\n&8%4%)'
-data_pinned: '[※ Instantanea fissata](#00fb9a) [%1%](#00fb9a show_text=&7UUID della versione:\n&8%2%) [per](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
-data_unpinned: '[※ L''istantanea dei dati utente è stata sbloccata con successo](#00fb9a) [%1%](#00fb9a show_text=&7Versione di UUID:\n&8%2%) [per](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
-data_dumped: '[☂ Hai ottenuto il dump dell''istantanea %1% di %2% nel formato:](#00fb9a) &7%3%'
-list_footer: '\n%1%[Pagina](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
-list_previous_page_button: '[◀](white show_text=&7Visualizza pagina precedente run_command=%2% %1%) '
-list_next_page_button: ' [▶](white show_text=&7Visualizza pagina successiva run_command=%2% %1%)'
-list_page_jumpers: '(%1%)'
-list_page_jumper_button: '[%1%](show_text=&7Vai alla pagina %1% run_command=%2% %1%)'
-list_page_jumper_current_page: '[%1%](#00fb9a)'
-list_page_jumper_separator: ' '
-list_page_jumper_group_separator: '…'
-save_cause_disconnect: 'disconnect'
-save_cause_world_save: 'world save'
-save_cause_death: 'death'
-save_cause_server_shutdown: 'server shutdown'
-save_cause_inventory_command: 'inventory command'
-save_cause_enderchest_command: 'enderchest command'
-save_cause_backup_restore: 'backup restore'
-save_cause_api: 'API'
-save_cause_mpdb_migration: 'MPDB migration'
-save_cause_legacy_migration: 'legacy migration'
-save_cause_converted_from_v2: 'converted from v2'
-up_to_date: '[HuskSync](#00fb9a bold) [| Il plugin è all''ultima versione disponibile (v%1%).](#00fb9a)'
-update_available: '[HuskSync](#ff7e5e bold) [| Disponibile una nuova versione: v%1% (running: v%2%).](#ff7e5e)'
-reload_complete: '[HuskSync](#00fb9a bold) [| Configurazione e messaggi ricaricati.](#00fb9a)\n[⚠ Ensure config files are up-to-date on all servers!](#00fb9a)\n[A restart is needed for config changes to take effect.](#00fb9a italic)'
-system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
-error_invalid_syntax: '[Errore:](#ff3300) [Sintassi errata. Usa:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
-error_invalid_player: '[Errore:](#ff3300) [Impossibile trovare un giocatore con questo nome.](#ff7e5e)'
-error_no_permission: '[Errore:](#ff3300) [Non hai il permesso di usare questo comando](#ff7e5e)'
-error_console_command_only: '[Errore:](#ff3300) [Questo comando può essere eseguito solo dalla](#ff7e5e)'
-error_in_game_command_only: 'Errore: Questo comando può essere utilizzato solo in gioco.'
-error_no_data_to_display: '[Errore:](#ff3300) [Impossibile trovare dati da visualizzare.](#ff7e5e)'
-error_invalid_version_uuid: '[Errore:](#ff3300) [Impossibile trovare dati utente per questa versione di UUID.](#ff7e5e)'
-husksync_command_description: 'Gestisci il plugin HuskSync'
-userdata_command_description: 'Vedi, gestisci e recupera i dati del giocatore'
-inventory_command_description: 'Vedi e modifica l''Inventario di un giocatore'
-enderchest_command_description: 'Vedi e modifica l''Ender Chest di un giocatore'
+locales:
+ synchronization_complete: '[⏵ Dati sincronizzati!](#00fb9a)'
+ synchronization_failed: '[⏵ Sincronizzazione fallita! Perfavore contatta un amministratore.](#ff7e5e)'
+ inventory_viewer_menu_title: '&0Inventario di %1%'
+ ender_chest_viewer_menu_title: '&0Enderchest di %1%'
+ inventory_viewer_opened: '[Stai vedendo l''istantanea di](#00fb9a) [%1%](#00fb9a bold) [inventario del ⌚ %2%](#00fb9a)'
+ ender_chest_viewer_opened: '[Stai vedendo l''istantanea di](#00fb9a) [%1%](#00fb9a bold) [Ender Chest del ⌚ %2%](#00fb9a)'
+ data_update_complete: '[🔔 I tuoi dati sono stati aggiornati!](#00fb9a)'
+ data_update_failed: '[🔔 Aggiornamento dei tuoi dati fallito! Perfavore contatta un amministratore.](#ff7e5e)'
+ user_registration_complete: '[⭐ User registration complete!](#00fb9a)'
+ data_manager_title: '[Stai vedendo l''istantanea](#00fb9a) [%1%](#00fb9a show_text=&7Versione di UUID:\n&8%2%) [di](#00fb9a) [%3%](#00fb9a bold show_text=&7Player UUID:\n&8%4%)[:](#00fb9a)'
+ data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7:\n&8Quando i dati sono stati salvati)'
+ data_manager_pinned: '[※ Istantanea fissata](#d8ff2b show_text=&7Pinned:\n&8Quest''istantanea non sarà cancellata automaticamente.)'
+ data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Causa di salvataggio:\n&8Cosa ha causato il salvataggio dei dati)'
+ data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name of the server the data was saved on)'
+ data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Peso dell''istantanea:\n&8Peso stimato del file (in KiB))\n'
+ data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Vita) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Fame) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7Livello di XP) [🏹 %5%](dark_aqua show_text=&7Modalità di gioco)'
+ data_manager_advancements_statistics: '[⭐ Progressi: %1%](color=#ffc43b-#f5c962 show_text=&7Progressi compiuti in:\n&8%2%) [⌛ Tempo di gioco: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7Tempo di gioco\n&8⚠ Basato sulle statistiche di gioco)\n'
+ data_manager_item_buttons: '[View:](gray) [[🪣 Inventario…]](color=#a17b5f-#f5b98c show_text=&7Clicca per visualizzare run_command=/inventory %1% %2%) [[⌀ Ender Chest…]](#b649c4-#d254ff show_text=&7Clicca per visualizzare run_command=/enderchest %1% %2%)'
+ data_manager_management_buttons: '[Gestisci:](gray) [[❌ Cancella…]](#ff3300 show_text=&7Fare clic per eliminare questa istantanea.\n&8Questo non influisce sui dati attuali dell''utente.\nff3300&⚠ Questo non può essere annullato! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Ripristina…]](#00fb9a show_text=&7Clicca per ripristinare i dati dell''utente.\n&8I dati dell''utente saranno ripristinati a quest''istantanea.\nff3300&⚠ I dati di %1% saranno sovrascritti! suggest_command=/husksync:userdata restore %1% %2%) [[※ fissa/sblocca...]](#d8ff2b show_text=&7Clicca per fissare o sbloccare quest''istantanea\n&8Le istantanee fissate non saranno cancellate automaticamente run_command=/userdata pin %1% %2%)'
+ data_manager_system_buttons: '[Sistema:](gray) [[⏷ Dump del File…]](dark_gray show_text=&7Clicca per ottenere il dump dei dati del giocatore.\n&8I dati salvati sono posizioanti nella cartella ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ Dump su Web…]](dark_gray show_text=&7Clicca per ottenere il dump del file su mc-logs\n&8 Ti verrà consegnato l''url per visionare il dump. run_command=/husksync:userdata dump %1% %2% web)'
+ data_manager_advancements_preview_remaining: 'e %1% altro…'
+ data_list_title: '[Lista delle istantanee di %1%:](#00fb9a) [(%2%-%3% of](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
+ data_list_item: '[%1%](gray show_text=&7Instantanea di %2%&8⚡ id: %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Fissata:\n&8Se fissata, l''istantanea non viene mai modificata. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Data di salvataggio:&7\n&8Momento preciso in cui è stato salvato il dato\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Causa di salvataggio:\n&8Che cosa ha causato il salvataggio run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Peso dell''istantanea:&7\n&8Peso stimato del file (in KiB) run_command=/userdata view %2% %3%)'
+ data_deleted: '[❌ Istantanea eliminata con successo](#00fb9a) [%1%](#00fb9a show_text=&7Versione di UUID:\n&8%2%) [per](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
+ data_restored: '[⏪ Ripristato con successo](#00fb9a) [Dati dall''istantanea di](#00fb9a)[%1%](#00fb9a show_text=&7Player UUID:\n&8%2%) [%3%.](#00fb9a show_text=&7Versione di UUID:\n&8%4%)'
+ data_pinned: '[※ Instantanea fissata](#00fb9a) [%1%](#00fb9a show_text=&7UUID della versione:\n&8%2%) [per](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
+ data_unpinned: '[※ L''istantanea dei dati utente è stata sbloccata con successo](#00fb9a) [%1%](#00fb9a show_text=&7Versione di UUID:\n&8%2%) [per](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
+ data_dumped: '[☂ Hai ottenuto il dump dell''istantanea %1% di %2% nel formato:](#00fb9a) &7%3%'
+ list_footer: '\n%1%[Pagina](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
+ list_previous_page_button: '[◀](white show_text=&7Visualizza pagina precedente run_command=%2% %1%) '
+ list_next_page_button: ' [▶](white show_text=&7Visualizza pagina successiva run_command=%2% %1%)'
+ list_page_jumpers: '(%1%)'
+ list_page_jumper_button: '[%1%](show_text=&7Vai alla pagina %1% run_command=%2% %1%)'
+ list_page_jumper_current_page: '[%1%](#00fb9a)'
+ list_page_jumper_separator: ' '
+ list_page_jumper_group_separator: '…'
+ save_cause_disconnect: 'disconnect'
+ save_cause_world_save: 'world save'
+ save_cause_death: 'death'
+ save_cause_server_shutdown: 'server shutdown'
+ save_cause_inventory_command: 'inventory command'
+ save_cause_enderchest_command: 'enderchest command'
+ save_cause_backup_restore: 'backup restore'
+ save_cause_api: 'API'
+ save_cause_mpdb_migration: 'MPDB migration'
+ save_cause_legacy_migration: 'legacy migration'
+ save_cause_converted_from_v2: 'converted from v2'
+ up_to_date: '[HuskSync](#00fb9a bold) [| Il plugin è all''ultima versione disponibile (v%1%).](#00fb9a)'
+ update_available: '[HuskSync](#ff7e5e bold) [| Disponibile una nuova versione: v%1% (running: v%2%).](#ff7e5e)'
+ reload_complete: '[HuskSync](#00fb9a bold) [| Configurazione e messaggi ricaricati.](#00fb9a)\n[⚠ Ensure config files are up-to-date on all servers!](#00fb9a)\n[A restart is needed for config changes to take effect.](#00fb9a italic)'
+ system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
+ error_invalid_syntax: '[Errore:](#ff3300) [Sintassi errata. Usa:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
+ error_invalid_player: '[Errore:](#ff3300) [Impossibile trovare un giocatore con questo nome.](#ff7e5e)'
+ error_no_permission: '[Errore:](#ff3300) [Non hai il permesso di usare questo comando](#ff7e5e)'
+ error_console_command_only: '[Errore:](#ff3300) [Questo comando può essere eseguito solo dalla](#ff7e5e)'
+ error_in_game_command_only: 'Errore: Questo comando può essere utilizzato solo in gioco.'
+ error_no_data_to_display: '[Errore:](#ff3300) [Impossibile trovare dati da visualizzare.](#ff7e5e)'
+ error_invalid_version_uuid: '[Errore:](#ff3300) [Impossibile trovare dati utente per questa versione di UUID.](#ff7e5e)'
+ husksync_command_description: 'Gestisci il plugin HuskSync'
+ userdata_command_description: 'Vedi, gestisci e recupera i dati del giocatore'
+ inventory_command_description: 'Vedi e modifica l''Inventario di un giocatore'
+ enderchest_command_description: 'Vedi e modifica l''Ender Chest di un giocatore'
diff --git a/common/src/main/resources/locales/ja-jp.yml b/common/src/main/resources/locales/ja-jp.yml
index 65ce07c4..4b0db924 100644
--- a/common/src/main/resources/locales/ja-jp.yml
+++ b/common/src/main/resources/locales/ja-jp.yml
@@ -1,62 +1,63 @@
-synchronization_complete: '[⏵データが同期されました!](#00fb9a)'
-synchronization_failed: '[⏵ データの同期に失敗しました!管理者に連絡してください。](#ff7e5e)'
-inventory_viewer_menu_title: '&0%1%のインベントリ'
-ender_chest_viewer_menu_title: '&0%1%のエンダーチェスト'
-inventory_viewer_opened: '[⌚ %2%](#00fb9a) [%1%](#00fb9a bold) [のインベントリのスナップショットを閲覧する](#00fb9a)'
-ender_chest_viewer_opened: '[⌚ %2%](#00fb9a) [%1%](#00fb9a bold) [のエンダーチェストのスナップショットを閲覧する](#00fb9a)'
-data_update_complete: '[🔔 データが更新されました!](#00fb9a)'
-data_update_failed: '[🔔 データの更新に失敗しました!管理者に連絡してください。](#ff7e5e)'
-user_registration_complete: '[⭐ ユーザー登録が完了しました!](#00fb9a)'
-data_manager_title: '[%3%](#00fb9a bold show_text=&7プレイヤーUUID:\n&8%4%) [のユーザーデータスナップショット](#00fb9a)[%1%](#00fb9a show_text=&7バージョンUUID:\n&8%2%)[を表示:](#00fb9a)'
-data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7バージョンタイムスタンプ:\n&8データの保存時期)'
-data_manager_pinned: '[※ ピン留めされたスナップショット](#d8ff2b show_text=&7ピン留め:\n&8このユーザーデータのスナップショットは自動的にローテーションされません。)'
-data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7保存理由:\n&8データが保存された理由)'
-data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name of the server the data was saved on)'
-data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7スナップショットサイズ:\n&8スナップショットの推定ファイルサイズ(単位:KiB))\n'
-data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7体力) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7空腹度) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7経験値レベル) [🏹 %5%](dark_aqua show_text=&7ゲームモード)'
-data_manager_advancements_statistics: '[⭐ 進捗: %1%](color=#ffc43b-#f5c962 show_text=&7達成した進捗:\n&8%2%) [⌛ プレイ時間: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7ゲーム内のプレイ時間\n&8⚠ ゲーム内の統計に基づく)\n'
-data_manager_item_buttons: '[表示:](gray) [[🪣 インベントリ…]](color=#a17b5f-#f5b98c show_text=&7クリックで表示 run_command=/husksync:inventory %1% %2%) [[⌀ エンダーチェスト…]](#b649c4-#d254ff show_text=&7クリックで表示 run_command=/husksync:enderchest %1% %2%)'
-data_manager_management_buttons: '[管理:](gray) [[❌ 消去…]](#ff3300 show_text=&7クリックでこのユーザーデータのスナップショットを消去します。\n&8これはユーザーの現在のデータには影響しません。\nff3300&⚠ この操作は元に戻せません! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ 復元…]](#00fb9a show_text=&7クリックでこのユーザーデータを復元します。\n&8これにより、ユーザーデータはこのスナップショットに設定されます。\nff3300&⚠ %1% の現在のデータは上書きされます! suggest_command=/husksync:userdata restore %1% %2%) [[※ ピン留め/ピン外し…]](#d8ff2b show_text=&7クリックでこのユーザーデータのスナップショットをピン留め、若しくはピンを外します。\n&8ピン留めされたスナップショットは自動的にローテーションしません。 run_command=/userdata pin %1% %2%)'
-data_manager_system_buttons: '[システム:](gray) [[⏷ ファイルダンプ…]](dark_gray show_text=&7クリックで未加工のユーザーデータスナップショットをダンプファイルにします。\n&8データダンプの場所は ~/plugins/HuskSync/dumps/ です run_command=/husksync:userdata dump %1% %2% file) [[☂ Webダンプ…]](dark_gray show_text=&7クリックでユーザーデータスナップショットをmc-logsサービスにダンプします。\n&8データを含むURLが提供されます。 run_command=/husksync:userdata dump %1% %2% web)'
-data_manager_advancements_preview_remaining: 'さらに %1% 件…'
-data_list_title: '[%1% のユーザーデータスナップショット:](#00fb9a) [(%4%件中](#00fb9a bold) [%2%-%3%件](#00fb9a)[)](#00fb9a)\n'
-data_list_item: '[%1%](gray show_text=&7%2% のユーザーデータスナップショット&8⚡ %4% run_command=/husksync:userdata view %2% %3%) [%5%](#d8ff2b show_text=&7ピン留め:\n&8ピン留めされたスナップショットは自動的にローテーションしません。 run_command=/husksync:userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7バージョンタイムスタンプ:&7\n&8データの保存時期\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7保存理由:\n&8データが保存された理由 run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7スナップショットサイズ:&7\n&8スナップショットの推定ファイルサイズ (単位:KiB) run_command=/userdata view %2% %3%)'
-data_deleted: '[❌](#00fb9a) [%3%](#00fb9a show_text=&7Player UUID:\n&8%4%) [のユーザーデータスナップショット](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [の消去に成功しました。](#00fb9a)'
-data_restored: '[⏪](#00fb9a) [スナップショット](#00fb9a) [%3%](#00fb9a show_text=&7Version UUID:\n&8%4%) [から](#00fb9a) [%1%](#00fb9a show_text=&7Player UUID:\n&8%2%) [の現在のユーザーデータの復元に成功しました。](#00fb9a)'
-data_pinned: '[※](#00fb9a) [%3%](#00fb9a show_text=&7Player UUID:\n&8%4%) [のユーザーデータスナップショット](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [のピン留めに成功しました。](#00fb9a)'
-data_unpinned: '[※](#00fb9a) [%3%](#00fb9a show_text=&7Player UUID:\n&8%4%) [のユーザーデータスナップショット](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [のピン外しに成功しました。](#00fb9a)'
-data_dumped: '[☂ %2% のユーザーデータスナップショット %1% のダンプに成功:](#00fb9a) &7%3%'
-list_footer: '\n%1%[ページ](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
-list_previous_page_button: '[◀](white show_text=&7前のページへ run_command=%2% %1%) '
-list_next_page_button: ' [▶](white show_text=&7次のページへ run_command=%2% %1%)'
-list_page_jumpers: '(%1%)'
-list_page_jumper_button: '[%1%](show_text=&7%1% ページ目へ run_command=%2% %1%)'
-list_page_jumper_current_page: '[%1%](#00fb9a)'
-list_page_jumper_separator: ' '
-list_page_jumper_group_separator: '…'
-save_cause_disconnect: 'disconnect'
-save_cause_world_save: 'world save'
-save_cause_death: 'death'
-save_cause_server_shutdown: 'server shutdown'
-save_cause_inventory_command: 'inventory command'
-save_cause_enderchest_command: 'enderchest command'
-save_cause_backup_restore: 'backup restore'
-save_cause_api: 'API'
-save_cause_mpdb_migration: 'MPDB migration'
-save_cause_legacy_migration: 'legacy migration'
-save_cause_converted_from_v2: 'converted from v2'
-up_to_date: '[HuskSync](#00fb9a bold) [| HuskSyncの最新バージョンを実行しています(v%1%).](#00fb9a)'
-update_available: '[HuskSync](#ff7e5e bold) [| HuskSyncの最新バージョンが更新されています: v%1% (実行中: v%2%).](#ff7e5e)'
-reload_complete: '[HuskSync](#00fb9a bold) [| 設定ファイルとメッセージファイルを再読み込みしました。](#00fb9a)\n[⚠ すべてのサーバーで設定ファイルが最新であることを確認してください!](#00fb9a)\n[設定の変更を有効にするには再起動が必要です。](#00fb9a italic)'
-system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
-error_invalid_syntax: '[Error:](#ff3300) [構文が正しくありません。使用法:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&クリックでサジェスト suggest_command=%1%)'
-error_invalid_player: '[Error:](#ff3300) [そのプレイヤーは見つかりませんでした](#ff7e5e)'
-error_no_permission: '[Error:](#ff3300) [このコマンドを実行する権限がありません](#ff7e5e)'
-error_console_command_only: '[Error:](#ff3300) [そのコマンドは%1%コンソールからのみ実行できます](#ff7e5e)'
-error_in_game_command_only: 'Error: そのコマンドはゲーム内でしか使えません。'
-error_no_data_to_display: '[Error:](#ff3300) [表示するユーザーデータが見つかりませんでした。](#ff7e5e)'
-error_invalid_version_uuid: '[Error:](#ff3300) [そのバージョンUUIDのユーザーデータが見つかりませんでした。](#ff7e5e)'
-husksync_command_description: 'HuskSyncプラグインを管理する'
-userdata_command_description: 'プレーヤーのユーザーデータを表示・管理・復元する'
-inventory_command_description: 'プレイヤーのインベントリを閲覧・編集する'
-enderchest_command_description: 'プレイヤーのエンダーチェストを閲覧・編集する'
+locales:
+ synchronization_complete: '[⏵データが同期されました!](#00fb9a)'
+ synchronization_failed: '[⏵ データの同期に失敗しました!管理者に連絡してください。](#ff7e5e)'
+ inventory_viewer_menu_title: '&0%1%のインベントリ'
+ ender_chest_viewer_menu_title: '&0%1%のエンダーチェスト'
+ inventory_viewer_opened: '[⌚ %2%](#00fb9a) [%1%](#00fb9a bold) [のインベントリのスナップショットを閲覧する](#00fb9a)'
+ ender_chest_viewer_opened: '[⌚ %2%](#00fb9a) [%1%](#00fb9a bold) [のエンダーチェストのスナップショットを閲覧する](#00fb9a)'
+ data_update_complete: '[🔔 データが更新されました!](#00fb9a)'
+ data_update_failed: '[🔔 データの更新に失敗しました!管理者に連絡してください。](#ff7e5e)'
+ user_registration_complete: '[⭐ ユーザー登録が完了しました!](#00fb9a)'
+ data_manager_title: '[%3%](#00fb9a bold show_text=&7プレイヤーUUID:\n&8%4%) [のユーザーデータスナップショット](#00fb9a)[%1%](#00fb9a show_text=&7バージョンUUID:\n&8%2%)[を表示:](#00fb9a)'
+ data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7バージョンタイムスタンプ:\n&8データの保存時期)'
+ data_manager_pinned: '[※ ピン留めされたスナップショット](#d8ff2b show_text=&7ピン留め:\n&8このユーザーデータのスナップショットは自動的にローテーションされません。)'
+ data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7保存理由:\n&8データが保存された理由)'
+ data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name of the server the data was saved on)'
+ data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7スナップショットサイズ:\n&8スナップショットの推定ファイルサイズ(単位:KiB))\n'
+ data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7体力) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7空腹度) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7経験値レベル) [🏹 %5%](dark_aqua show_text=&7ゲームモード)'
+ data_manager_advancements_statistics: '[⭐ 進捗: %1%](color=#ffc43b-#f5c962 show_text=&7達成した進捗:\n&8%2%) [⌛ プレイ時間: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7ゲーム内のプレイ時間\n&8⚠ ゲーム内の統計に基づく)\n'
+ data_manager_item_buttons: '[表示:](gray) [[🪣 インベントリ…]](color=#a17b5f-#f5b98c show_text=&7クリックで表示 run_command=/husksync:inventory %1% %2%) [[⌀ エンダーチェスト…]](#b649c4-#d254ff show_text=&7クリックで表示 run_command=/husksync:enderchest %1% %2%)'
+ data_manager_management_buttons: '[管理:](gray) [[❌ 消去…]](#ff3300 show_text=&7クリックでこのユーザーデータのスナップショットを消去します。\n&8これはユーザーの現在のデータには影響しません。\nff3300&⚠ この操作は元に戻せません! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ 復元…]](#00fb9a show_text=&7クリックでこのユーザーデータを復元します。\n&8これにより、ユーザーデータはこのスナップショットに設定されます。\nff3300&⚠ %1% の現在のデータは上書きされます! suggest_command=/husksync:userdata restore %1% %2%) [[※ ピン留め/ピン外し…]](#d8ff2b show_text=&7クリックでこのユーザーデータのスナップショットをピン留め、若しくはピンを外します。\n&8ピン留めされたスナップショットは自動的にローテーションしません。 run_command=/userdata pin %1% %2%)'
+ data_manager_system_buttons: '[システム:](gray) [[⏷ ファイルダンプ…]](dark_gray show_text=&7クリックで未加工のユーザーデータスナップショットをダンプファイルにします。\n&8データダンプの場所は ~/plugins/HuskSync/dumps/ です run_command=/husksync:userdata dump %1% %2% file) [[☂ Webダンプ…]](dark_gray show_text=&7クリックでユーザーデータスナップショットをmc-logsサービスにダンプします。\n&8データを含むURLが提供されます。 run_command=/husksync:userdata dump %1% %2% web)'
+ data_manager_advancements_preview_remaining: 'さらに %1% 件…'
+ data_list_title: '[%1% のユーザーデータスナップショット:](#00fb9a) [(%4%件中](#00fb9a bold) [%2%-%3%件](#00fb9a)[)](#00fb9a)\n'
+ data_list_item: '[%1%](gray show_text=&7%2% のユーザーデータスナップショット&8⚡ %4% run_command=/husksync:userdata view %2% %3%) [%5%](#d8ff2b show_text=&7ピン留め:\n&8ピン留めされたスナップショットは自動的にローテーションしません。 run_command=/husksync:userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7バージョンタイムスタンプ:&7\n&8データの保存時期\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7保存理由:\n&8データが保存された理由 run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7スナップショットサイズ:&7\n&8スナップショットの推定ファイルサイズ (単位:KiB) run_command=/userdata view %2% %3%)'
+ data_deleted: '[❌](#00fb9a) [%3%](#00fb9a show_text=&7Player UUID:\n&8%4%) [のユーザーデータスナップショット](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [の消去に成功しました。](#00fb9a)'
+ data_restored: '[⏪](#00fb9a) [スナップショット](#00fb9a) [%3%](#00fb9a show_text=&7Version UUID:\n&8%4%) [から](#00fb9a) [%1%](#00fb9a show_text=&7Player UUID:\n&8%2%) [の現在のユーザーデータの復元に成功しました。](#00fb9a)'
+ data_pinned: '[※](#00fb9a) [%3%](#00fb9a show_text=&7Player UUID:\n&8%4%) [のユーザーデータスナップショット](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [のピン留めに成功しました。](#00fb9a)'
+ data_unpinned: '[※](#00fb9a) [%3%](#00fb9a show_text=&7Player UUID:\n&8%4%) [のユーザーデータスナップショット](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [のピン外しに成功しました。](#00fb9a)'
+ data_dumped: '[☂ %2% のユーザーデータスナップショット %1% のダンプに成功:](#00fb9a) &7%3%'
+ list_footer: '\n%1%[ページ](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
+ list_previous_page_button: '[◀](white show_text=&7前のページへ run_command=%2% %1%) '
+ list_next_page_button: ' [▶](white show_text=&7次のページへ run_command=%2% %1%)'
+ list_page_jumpers: '(%1%)'
+ list_page_jumper_button: '[%1%](show_text=&7%1% ページ目へ run_command=%2% %1%)'
+ list_page_jumper_current_page: '[%1%](#00fb9a)'
+ list_page_jumper_separator: ' '
+ list_page_jumper_group_separator: '…'
+ save_cause_disconnect: 'disconnect'
+ save_cause_world_save: 'world save'
+ save_cause_death: 'death'
+ save_cause_server_shutdown: 'server shutdown'
+ save_cause_inventory_command: 'inventory command'
+ save_cause_enderchest_command: 'enderchest command'
+ save_cause_backup_restore: 'backup restore'
+ save_cause_api: 'API'
+ save_cause_mpdb_migration: 'MPDB migration'
+ save_cause_legacy_migration: 'legacy migration'
+ save_cause_converted_from_v2: 'converted from v2'
+ up_to_date: '[HuskSync](#00fb9a bold) [| HuskSyncの最新バージョンを実行しています(v%1%).](#00fb9a)'
+ update_available: '[HuskSync](#ff7e5e bold) [| HuskSyncの最新バージョンが更新されています: v%1% (実行中: v%2%).](#ff7e5e)'
+ reload_complete: '[HuskSync](#00fb9a bold) [| 設定ファイルとメッセージファイルを再読み込みしました。](#00fb9a)\n[⚠ すべてのサーバーで設定ファイルが最新であることを確認してください!](#00fb9a)\n[設定の変更を有効にするには再起動が必要です。](#00fb9a italic)'
+ system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
+ error_invalid_syntax: '[Error:](#ff3300) [構文が正しくありません。使用法:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&クリックでサジェスト suggest_command=%1%)'
+ error_invalid_player: '[Error:](#ff3300) [そのプレイヤーは見つかりませんでした](#ff7e5e)'
+ error_no_permission: '[Error:](#ff3300) [このコマンドを実行する権限がありません](#ff7e5e)'
+ error_console_command_only: '[Error:](#ff3300) [そのコマンドは%1%コンソールからのみ実行できます](#ff7e5e)'
+ error_in_game_command_only: 'Error: そのコマンドはゲーム内でしか使えません。'
+ error_no_data_to_display: '[Error:](#ff3300) [表示するユーザーデータが見つかりませんでした。](#ff7e5e)'
+ error_invalid_version_uuid: '[Error:](#ff3300) [そのバージョンUUIDのユーザーデータが見つかりませんでした。](#ff7e5e)'
+ husksync_command_description: 'HuskSyncプラグインを管理する'
+ userdata_command_description: 'プレーヤーのユーザーデータを表示・管理・復元する'
+ inventory_command_description: 'プレイヤーのインベントリを閲覧・編集する'
+ enderchest_command_description: 'プレイヤーのエンダーチェストを閲覧・編集する'
diff --git a/common/src/main/resources/locales/ko-kr.yml b/common/src/main/resources/locales/ko-kr.yml
index bdb21f05..d923f9f1 100644
--- a/common/src/main/resources/locales/ko-kr.yml
+++ b/common/src/main/resources/locales/ko-kr.yml
@@ -1,62 +1,63 @@
-synchronization_complete: '[⏵ 데이터 연동됨!](#00fb9a)'
-synchronization_failed: '[⏵ 데이터 연동에 실패하였습니다! 관리자에게 문의해 주세요.](#ff7e5e)'
-inventory_viewer_menu_title: '&0%1%님의 인벤토리'
-ender_chest_viewer_menu_title: '&0%1%님의 엔더상자'
-inventory_viewer_opened: '[%1%](#00fb9a bold)[님의 ⌚ %2%의 인벤토리를 엽니다](#00fb9a)'
-ender_chest_viewer_opened: '[%1%](#00fb9a bold)[님의 ⌚ %2%의 엔더상자를 엽니다](#00fb9a)'
-data_update_complete: '[🔔 당신의 데이터가 업데이트 되었습니다!](#00fb9a)'
-data_update_failed: '[🔔 데이터 업데이트에 실패하였습니다! 관리자에게 문의해 주세요.](#ff7e5e)'
-user_registration_complete: '[⭐ 유저 등록이 완료되었습니다!](#00fb9a)'
-data_manager_title: '[%3%](#00fb9a bold show_text=&7플레이어 UUID:\n&8%4%)[님의 ](#00fb9a) [%1%](#00fb9a show_text=&7버전 UUID:\n&8%2%) [데이터 스냅샷을 표시합니다](#00fb9a)[:](#00fb9a)'
-data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7저장 시각:\n&8데이터가 저장된 시각)'
-data_manager_pinned: '[※ 스냅샷 고정됨](#d8ff2b show_text=&7고정됨:\n&8이 유저의 데이터 스냅샷은 자동으로 갱신되지 않습니다.)'
-data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7저장 사유:\n&8데이터가 저장된 사유입니다.)'
-data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7서버:\n&8데이터 저장이 이루어진 서버입니다.)'
-data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7스냅샷 크기:\n&8스냅샷 파일의 대략적인 크기입니다. (단위 KiB))\n'
-data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7체력) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7허기) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7경험치 레벨) [🏹 %5%](dark_aqua show_text=&7게임 모드)'
-data_manager_advancements_statistics: '[⭐ 도전 과제: %1%](color=#ffc43b-#f5c962 show_text=&7진행한 도전 과제:\n&8%2%) [⌛ 플레이 타임: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7인게임 플레이 시간\n&8⚠ 인게임 통계에 기반합니다.)\n'
-data_manager_item_buttons: '[보기:](gray) [[🪣 인벤토리…]](color=#a17b5f-#f5b98c show_text=&7클릭하여 확인 run_command=/inventory %1% %2%) [[⌀ 엔더상자…]](#b649c4-#d254ff show_text=&7클릭하여 확인 run_command=/enderchest %1% %2%)'
-data_manager_management_buttons: '[관리:](gray) [[❌ 삭제…]](#ff3300 show_text=&7클릭하여 이 유저 스냅샷 데이터를 삭제\n&8이 기능은 현재 유저의 인벤토리 데이터에는 영향을 미치지 않습니다.\nff3300&⚠ 이 작업은 되돌릴 수 없습니다! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ 복구…]](#00fb9a show_text=&7클릭하여 유저 데이터 복구\n&8유저의 데이터가 이 스냅샷의 데이터로 변경됩니다.\nff3300&⚠ %1%님의 현재 데이터에 덧씌워 집니다! suggest_command=/husksync:userdata restore %1% %2%) [[※ 고정/고정 해제…]](#d8ff2b show_text=&7클릭하여 유저 데이터를 고정 또는 고정 해제\n&8고정된 스냅샷은 자동적으로 갱신되지 않습니다. run_command=/userdata pin %1% %2%)'
-data_manager_system_buttons: '[시스템:](gray) [[⏷ 파일 덤프…]](dark_gray show_text=&7클릭하여 이 유저 데이터 스냅샷을 덤프하기\n&8데이터 덤프 파일은 ~/plugins/HuskSync/dumps/ 에서 찾을 수 있습니다. run_command=/husksync:userdata dump %1% %2% file) [[☂ 웹 덤프…]](dark_gray show_text=&7클릭하여 유저 데이터 스냅샷을 mc-log 서비스에 덤프하기\n&8데이터를 포함한 URL이 제공됩니다. run_command=/husksync:userdata dump %1% %2% web)'
-data_manager_advancements_preview_remaining: '외 %1%개...'
-data_list_title: '[%1%님의 유저 데이터 스냅샷 목록:](#00fb9a) [(%2%-%3% 중](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
-data_list_item: '[%1%](gray show_text=&7%2%&7님의 유저 데이터 스냅샷&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7고정됨:\n&8고정된 스냅샷은 자동적으로 갱신되지 않습니다. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7저장 시각:&7\n&8데이터가 저장된 시각입니다.\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7저장 사유:\n&8데이터가 저장된 사유입니다. run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7스냅샷 크기:&7\n&8스냅샷 파일의 대략적인 크기입니다. (단위 KiB) run_command=/userdata view %2% %3%)'
-data_deleted: '[❌ 성공적으로](#00fb9a) [%3%](#00fb9a show_text=&7플레이어 UUID:\n&8%4%) [님의 유저 데이터 스냅샷](#00fb9a) [%1%](#00fb9a show_text=&7버전 UUID:\n&8%2%)[을 삭제하였습니다.](#00fb9a)'
-data_restored: '[⏪ 성공적으로 복구되었습니다.](#00fb9a) [%1%](#00fb9a show_text=&7플레이어 UUID:\n&8%2%)[님의 현재 유저 데이터 스냅샷이](#00fb9a) [%3%](#00fb9a show_text=&7버전 UUID:\n&8%4%)[으로 변경되었습니다.](#00fb9a)'
-data_pinned: '[※ 성공적으로](#00fb9a) [%3%](#00fb9a show_text=&7플레이어 UUID:\n&8%4%)[님의 유저 데이터 스냅샷](#00fb9a) [%1%](#00fb9a show_text=&7버전 UUID:\n&8%2%)[을 고정하였습니다.](#00fb9a)'
-data_unpinned: '[※ 성공적으로](#00fb9a) [%3%](#00fb9a show_text=&7플레이어 UUID:\n&8%4%) [님의 유저 데이터 스냅샷](#00fb9a) [%1%](#00fb9a show_text=&7버전 UUID:\n&8%2%)[을 고정 해제하였습니다.](#00fb9a)'
-data_dumped: '[☂ 성공적으로 %2%님의 유저 데이터 스냅샷 %1%를 다음으로 덤프하였습니다:](#00fb9a) &7%3%'
-list_footer: '\n%1%[페이지](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
-list_previous_page_button: '[◀](white show_text=&7이전 페이지 보기 run_command=%2% %1%) '
-list_next_page_button: ' [▶](white show_text=&7다음 페이지 보기 run_command=%2% %1%)'
-list_page_jumpers: '(%1%)'
-list_page_jumper_button: '[%1%](show_text=&7%1% 페이지 보기 run_command=%2% %1%)'
-list_page_jumper_current_page: '[%1%](#00fb9a)'
-list_page_jumper_separator: ' '
-list_page_jumper_group_separator: '…'
-save_cause_disconnect: 'disconnect'
-save_cause_world_save: 'world save'
-save_cause_death: 'death'
-save_cause_server_shutdown: 'server shutdown'
-save_cause_inventory_command: 'inventory command'
-save_cause_enderchest_command: 'enderchest command'
-save_cause_backup_restore: 'backup restore'
-save_cause_api: 'API'
-save_cause_mpdb_migration: 'MPDB migration'
-save_cause_legacy_migration: 'legacy migration'
-save_cause_converted_from_v2: 'converted from v2'
-up_to_date: '[HuskSync](#00fb9a bold) [| 가장 최신 버전의 HuskSync를 실행 중입니다 (v%1%).](#00fb9a)'
-update_available: '[HuskSync](#ff7e5e bold) [| 새로운 버전의 HuskSync가 존재합니다: v%1% (현재 버전: v%2%).](#ff7e5e)'
-reload_complete: '[HuskSync](#00fb9a bold) [| 콘피그와 메시지 파일을 다시 불러왔습니다.](#00fb9a)\n[⚠ 모든 서버의 컨피그 파일을 변경하였는지 확인하세요!](#00fb9a)\n[몇몇 설정은 재시작 후에 적용됩니다.](#00fb9a italic)'
-system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
-error_invalid_syntax: '[오류:](#ff3300) [잘못된 사용법. 사용법:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&클릭하여 입력할 수 있습니다. suggest_command=%1%)'
-error_invalid_player: '[오류:](#ff3300) [해당 이름의 사용자를 찾을 수 없습니다.](#ff7e5e)'
-error_no_permission: '[오류:](#ff3300) [해당 명령어를 사용할 권한이 없습니다.](#ff7e5e)'
-error_console_command_only: '[오류:](#ff3300) [해당 명령어는 콘솔을 통해서만 사용할 수 있습니다.](#ff7e5e)'
-error_in_game_command_only: '오류: 해당 명령어는 게임 내부에서만 사용할 수 있습니다.'
-error_no_data_to_display: '[오류:](#ff3300) [표시할 유저 데이터를 찾을 수 없습니다.](#ff7e5e)'
-error_invalid_version_uuid: '[오류:](#ff3300) [해당 버전 UUID의 유저 데이터 스냅샷을 찾을 수 없습니다.](#ff7e5e)'
-husksync_command_description: 'HuskSync 플러그인을 관리합니다.'
-userdata_command_description: '확인, 관리 또는 복구합니다.'
-inventory_command_description: '플레이어의 인벤토리를 열람 또는 편집합니다.'
-enderchest_command_description: '플레이어의 엔더상자를 열람 또는 편집합니다.'
\ No newline at end of file
+locales:
+ synchronization_complete: '[⏵ 데이터 연동됨!](#00fb9a)'
+ synchronization_failed: '[⏵ 데이터 연동에 실패하였습니다! 관리자에게 문의해 주세요.](#ff7e5e)'
+ inventory_viewer_menu_title: '&0%1%님의 인벤토리'
+ ender_chest_viewer_menu_title: '&0%1%님의 엔더상자'
+ inventory_viewer_opened: '[%1%](#00fb9a bold)[님의 ⌚ %2%의 인벤토리를 엽니다](#00fb9a)'
+ ender_chest_viewer_opened: '[%1%](#00fb9a bold)[님의 ⌚ %2%의 엔더상자를 엽니다](#00fb9a)'
+ data_update_complete: '[🔔 당신의 데이터가 업데이트 되었습니다!](#00fb9a)'
+ data_update_failed: '[🔔 데이터 업데이트에 실패하였습니다! 관리자에게 문의해 주세요.](#ff7e5e)'
+ user_registration_complete: '[⭐ 유저 등록이 완료되었습니다!](#00fb9a)'
+ data_manager_title: '[%3%](#00fb9a bold show_text=&7플레이어 UUID:\n&8%4%)[님의 ](#00fb9a) [%1%](#00fb9a show_text=&7버전 UUID:\n&8%2%) [데이터 스냅샷을 표시합니다](#00fb9a)[:](#00fb9a)'
+ data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7저장 시각:\n&8데이터가 저장된 시각)'
+ data_manager_pinned: '[※ 스냅샷 고정됨](#d8ff2b show_text=&7고정됨:\n&8이 유저의 데이터 스냅샷은 자동으로 갱신되지 않습니다.)'
+ data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7저장 사유:\n&8데이터가 저장된 사유입니다.)'
+ data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7서버:\n&8데이터 저장이 이루어진 서버입니다.)'
+ data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7스냅샷 크기:\n&8스냅샷 파일의 대략적인 크기입니다. (단위 KiB))\n'
+ data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7체력) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7허기) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7경험치 레벨) [🏹 %5%](dark_aqua show_text=&7게임 모드)'
+ data_manager_advancements_statistics: '[⭐ 도전 과제: %1%](color=#ffc43b-#f5c962 show_text=&7진행한 도전 과제:\n&8%2%) [⌛ 플레이 타임: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7인게임 플레이 시간\n&8⚠ 인게임 통계에 기반합니다.)\n'
+ data_manager_item_buttons: '[보기:](gray) [[🪣 인벤토리…]](color=#a17b5f-#f5b98c show_text=&7클릭하여 확인 run_command=/inventory %1% %2%) [[⌀ 엔더상자…]](#b649c4-#d254ff show_text=&7클릭하여 확인 run_command=/enderchest %1% %2%)'
+ data_manager_management_buttons: '[관리:](gray) [[❌ 삭제…]](#ff3300 show_text=&7클릭하여 이 유저 스냅샷 데이터를 삭제\n&8이 기능은 현재 유저의 인벤토리 데이터에는 영향을 미치지 않습니다.\nff3300&⚠ 이 작업은 되돌릴 수 없습니다! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ 복구…]](#00fb9a show_text=&7클릭하여 유저 데이터 복구\n&8유저의 데이터가 이 스냅샷의 데이터로 변경됩니다.\nff3300&⚠ %1%님의 현재 데이터에 덧씌워 집니다! suggest_command=/husksync:userdata restore %1% %2%) [[※ 고정/고정 해제…]](#d8ff2b show_text=&7클릭하여 유저 데이터를 고정 또는 고정 해제\n&8고정된 스냅샷은 자동적으로 갱신되지 않습니다. run_command=/userdata pin %1% %2%)'
+ data_manager_system_buttons: '[시스템:](gray) [[⏷ 파일 덤프…]](dark_gray show_text=&7클릭하여 이 유저 데이터 스냅샷을 덤프하기\n&8데이터 덤프 파일은 ~/plugins/HuskSync/dumps/ 에서 찾을 수 있습니다. run_command=/husksync:userdata dump %1% %2% file) [[☂ 웹 덤프…]](dark_gray show_text=&7클릭하여 유저 데이터 스냅샷을 mc-log 서비스에 덤프하기\n&8데이터를 포함한 URL이 제공됩니다. run_command=/husksync:userdata dump %1% %2% web)'
+ data_manager_advancements_preview_remaining: '외 %1%개...'
+ data_list_title: '[%1%님의 유저 데이터 스냅샷 목록:](#00fb9a) [(%2%-%3% 중](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
+ data_list_item: '[%1%](gray show_text=&7%2%&7님의 유저 데이터 스냅샷&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7고정됨:\n&8고정된 스냅샷은 자동적으로 갱신되지 않습니다. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7저장 시각:&7\n&8데이터가 저장된 시각입니다.\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7저장 사유:\n&8데이터가 저장된 사유입니다. run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7스냅샷 크기:&7\n&8스냅샷 파일의 대략적인 크기입니다. (단위 KiB) run_command=/userdata view %2% %3%)'
+ data_deleted: '[❌ 성공적으로](#00fb9a) [%3%](#00fb9a show_text=&7플레이어 UUID:\n&8%4%) [님의 유저 데이터 스냅샷](#00fb9a) [%1%](#00fb9a show_text=&7버전 UUID:\n&8%2%)[을 삭제하였습니다.](#00fb9a)'
+ data_restored: '[⏪ 성공적으로 복구되었습니다.](#00fb9a) [%1%](#00fb9a show_text=&7플레이어 UUID:\n&8%2%)[님의 현재 유저 데이터 스냅샷이](#00fb9a) [%3%](#00fb9a show_text=&7버전 UUID:\n&8%4%)[으로 변경되었습니다.](#00fb9a)'
+ data_pinned: '[※ 성공적으로](#00fb9a) [%3%](#00fb9a show_text=&7플레이어 UUID:\n&8%4%)[님의 유저 데이터 스냅샷](#00fb9a) [%1%](#00fb9a show_text=&7버전 UUID:\n&8%2%)[을 고정하였습니다.](#00fb9a)'
+ data_unpinned: '[※ 성공적으로](#00fb9a) [%3%](#00fb9a show_text=&7플레이어 UUID:\n&8%4%) [님의 유저 데이터 스냅샷](#00fb9a) [%1%](#00fb9a show_text=&7버전 UUID:\n&8%2%)[을 고정 해제하였습니다.](#00fb9a)'
+ data_dumped: '[☂ 성공적으로 %2%님의 유저 데이터 스냅샷 %1%를 다음으로 덤프하였습니다:](#00fb9a) &7%3%'
+ list_footer: '\n%1%[페이지](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
+ list_previous_page_button: '[◀](white show_text=&7이전 페이지 보기 run_command=%2% %1%) '
+ list_next_page_button: ' [▶](white show_text=&7다음 페이지 보기 run_command=%2% %1%)'
+ list_page_jumpers: '(%1%)'
+ list_page_jumper_button: '[%1%](show_text=&7%1% 페이지 보기 run_command=%2% %1%)'
+ list_page_jumper_current_page: '[%1%](#00fb9a)'
+ list_page_jumper_separator: ' '
+ list_page_jumper_group_separator: '…'
+ save_cause_disconnect: 'disconnect'
+ save_cause_world_save: 'world save'
+ save_cause_death: 'death'
+ save_cause_server_shutdown: 'server shutdown'
+ save_cause_inventory_command: 'inventory command'
+ save_cause_enderchest_command: 'enderchest command'
+ save_cause_backup_restore: 'backup restore'
+ save_cause_api: 'API'
+ save_cause_mpdb_migration: 'MPDB migration'
+ save_cause_legacy_migration: 'legacy migration'
+ save_cause_converted_from_v2: 'converted from v2'
+ up_to_date: '[HuskSync](#00fb9a bold) [| 가장 최신 버전의 HuskSync를 실행 중입니다 (v%1%).](#00fb9a)'
+ update_available: '[HuskSync](#ff7e5e bold) [| 새로운 버전의 HuskSync가 존재합니다: v%1% (현재 버전: v%2%).](#ff7e5e)'
+ reload_complete: '[HuskSync](#00fb9a bold) [| 콘피그와 메시지 파일을 다시 불러왔습니다.](#00fb9a)\n[⚠ 모든 서버의 컨피그 파일을 변경하였는지 확인하세요!](#00fb9a)\n[몇몇 설정은 재시작 후에 적용됩니다.](#00fb9a italic)'
+ system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
+ error_invalid_syntax: '[오류:](#ff3300) [잘못된 사용법. 사용법:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&클릭하여 입력할 수 있습니다. suggest_command=%1%)'
+ error_invalid_player: '[오류:](#ff3300) [해당 이름의 사용자를 찾을 수 없습니다.](#ff7e5e)'
+ error_no_permission: '[오류:](#ff3300) [해당 명령어를 사용할 권한이 없습니다.](#ff7e5e)'
+ error_console_command_only: '[오류:](#ff3300) [해당 명령어는 콘솔을 통해서만 사용할 수 있습니다.](#ff7e5e)'
+ error_in_game_command_only: '오류: 해당 명령어는 게임 내부에서만 사용할 수 있습니다.'
+ error_no_data_to_display: '[오류:](#ff3300) [표시할 유저 데이터를 찾을 수 없습니다.](#ff7e5e)'
+ error_invalid_version_uuid: '[오류:](#ff3300) [해당 버전 UUID의 유저 데이터 스냅샷을 찾을 수 없습니다.](#ff7e5e)'
+ husksync_command_description: 'HuskSync 플러그인을 관리합니다.'
+ userdata_command_description: '확인, 관리 또는 복구합니다.'
+ inventory_command_description: '플레이어의 인벤토리를 열람 또는 편집합니다.'
+ enderchest_command_description: '플레이어의 엔더상자를 열람 또는 편집합니다.'
\ No newline at end of file
diff --git a/common/src/main/resources/locales/nl-nl.yml b/common/src/main/resources/locales/nl-nl.yml
index d459e5ce..101d9003 100644
--- a/common/src/main/resources/locales/nl-nl.yml
+++ b/common/src/main/resources/locales/nl-nl.yml
@@ -1,62 +1,63 @@
-synchronization_complete: '[⏵ Data gesynchroniseerd!](#00fb9a)'
-synchronization_failed: '[⏵ Synchroniseren van jouw gegevens is niet gelukt! Neem contact op met een beheerder.](#ff7e5e)'
-inventory_viewer_menu_title: '&0%1%''s Inventaris'
-ender_chest_viewer_menu_title: '&0%1%''s Enderkist'
-inventory_viewer_opened: '[Momentopname bekijken van](#00fb9a) [%1%](#00fb9a bold)[''s inventaris per ⌚ %2%](#00fb9a)'
-ender_chest_viewer_opened: '[Momentopname bekijken van](#00fb9a) [%1%](#00fb9a bold)[''s Enderkist per ⌚ %2%](#00fb9a)'
-data_update_complete: '[🔔 Jouw gegevens zijn bijgewerkt!](#00fb9a)'
-data_update_failed: '[🔔 Het is niet gelukt om jouw gegevens bij te werken! Neem contact op met een beheerder.](#ff7e5e)'
-user_registration_complete: '[⭐ Gebruikersregistratie voltooid!](#00fb9a)'
-data_manager_title: '[Momentopname van gebruikersgegevens bekijken](#00fb9a) [%1%](#00fb9a show_text=&7Versie UUID:\n&8%2%) [voor](#00fb9a) [%3%](#00fb9a bold show_text=&7Speler UUID:\n&8%4%)[:](#00fb9a)'
-data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Versie tijdmarkering:\n&8Toen de gegevens werden opgeslagen)'
-data_manager_pinned: '[※ Momentopname vastgezet](#d8ff2b show_text=&7Vastgezet:\n&8Deze momentopname van gebruikersgegevens wordt niet automatisch gerouleerd.)'
-data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Reden opslaan:\n&8Waarom de data is opgeslagen)'
-data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name of the server the data was saved on)'
-data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Grootte van momentopname:\n&8Geschatte bestandsgrootte van de momentopname (in KiB))\n'
-data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Gezondheids punten) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Honger punten) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7XP level) [🏹 %5%](dark_aqua show_text=&7Speltype)'
-data_manager_advancements_statistics: '[⭐ Advancements: %1%](color=#ffc43b-#f5c962 show_text=&7Advancements waarin je voortgang hebt:\n&8%2%) [⌛ Speeltijd: %3%uren](color=#62a9f5-#7ab8fa show_text=&7In-game speeltijd\n&8⚠ Gebaseerd op in-game statistieken)\n'
-data_manager_item_buttons: '[View:](gray) [[🪣 Inventaris…]](color=#a17b5f-#f5b98c show_text=&7Klikken om te bekijken run_command=/inventory %1% %2%) [[⌀ Enderkist…]](#b649c4-#d254ff show_text=&7Klikken om te bekijken run_command=/enderchest %1% %2%)'
-data_manager_management_buttons: '[Beheren:](gray) [[❌ Verwijderen…]](#ff3300 show_text=&7Klik om deze momentopname van gebruikersgegevens te verwijderen.\n&8Dit heeft geen invloed op de huidige gegevens van de gebruiker.\nff3300&⚠ Dit kan niet ongedaan gemaakt worden! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Herstellen…]](#00fb9a show_text=&7Klik om deze gebruikersgegevens te herstellen.\n&8Hierdoor worden de gegevens van de gebruiker ingesteld op deze momentopname.\nff3300&⚠ %1%''s huidige gegevens worden overschreven! suggest_command=/husksync:userdata restore %1% %2%) [[※ Vastzetten/losmaken…]](#d8ff2b show_text=&7Klik om deze momentopname van gebruikersgegevens vast te zetten of los te maken\n&8Vastgezette momentopnamen worden niet automatisch gerouleerd run_command=/userdata pin %1% %2%)'
-data_manager_system_buttons: '[Systeem:](gray) [[⏷ Bestandsdump…]](dark_gray show_text=&7Klik om deze ruwe gebruikersgegevenssnapshot naar een bestand te dumperen.\n&8Gegevensdumps zijn te vinden in ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ Webdump…]](dark_gray show_text=&7Klik om deze ruwe gebruikersgegevenssnapshot naar de mc-logs-service te dumpen\n&8Je ontvangt een URL met de gegevens. run_command=/husksync:userdata dump %1% %2% web)'
-data_manager_advancements_preview_remaining: 'en %1% meer…'
-data_list_title: '[%1%''s momentopnamen van gebruikersgegevens:](#00fb9a) [(%2%-%3% van](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
-data_list_item: '[%1%](gray show_text=&7Gebruikersgegevens momentopname voor %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Vastgezet:\n&8Vastgezette momentopnamen worden niet automatisch gerouleerd. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Versie tijdmarkering:&7\n&8Wanneer de data was opgeslagen\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Reden opslaan:\n&8Waarom de data is opgeslagen run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Grootte van momentopname:&7\n&8Geschatte bestandsgrootte van de momentopname (in KiB) run_command=/userdata view %2% %3%)'
-data_deleted: '[❌ Momentopname van gebruikersgegevens is verwijderd](#00fb9a) [%1%](#00fb9a show_text=&7Versie UUID:\n&8%2%) [voor](#00fb9a) [%3%.](#00fb9a show_text=&7Speler UUID:\n&8%4%)'
-data_restored: '[⏪ Succesvol hersteld](#00fb9a) [%1%](#00fb9a show_text=&7Speler UUID:\n&8%2%)[''s huidige gebruikersgegevens uit momentopname](#00fb9a) [%3%.](#00fb9a show_text=&7Versie UUID:\n&8%4%)'
-data_pinned: '[※ Momentopname van gebruikersgegevens is vastgezet](#00fb9a) [%1%](#00fb9a show_text=&7Versie UUID:\n&8%2%) [voor](#00fb9a) [%3%.](#00fb9a show_text=&7Speler UUID:\n&8%4%)'
-data_unpinned: '[※ Momentopname van gebruikersgegevens is losgemaakt](#00fb9a) [%1%](#00fb9a show_text=&7Versie UUID:\n&8%2%) [voor](#00fb9a) [%3%.](#00fb9a show_text=&7Speler UUID:\n&8%4%)'
-data_dumped: '[☂ De momentopname van gebruikersgegevens %1% voor %2% is met succes gedumpt naar:](#00fb9a) &7%3%'
-list_footer: '\n%1%[Pagina](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
-list_previous_page_button: '[◀](white show_text=&7Bekijk vorige pagina run_command=%2% %1%) '
-list_next_page_button: ' [▶](white show_text=&7Bekijk volgende pagina run_command=%2% %1%)'
-list_page_jumpers: '(%1%)'
-list_page_jumper_button: '[%1%](show_text=&7Ga naar pagina %1% run_command=%2% %1%)'
-list_page_jumper_current_page: '[%1%](#00fb9a)'
-list_page_jumper_separator: ' '
-list_page_jumper_group_separator: '…'
-save_cause_disconnect: 'disconnect'
-save_cause_world_save: 'world save'
-save_cause_death: 'death'
-save_cause_server_shutdown: 'server shutdown'
-save_cause_inventory_command: 'inventory command'
-save_cause_enderchest_command: 'enderchest command'
-save_cause_backup_restore: 'backup restore'
-save_cause_api: 'API'
-save_cause_mpdb_migration: 'MPDB migration'
-save_cause_legacy_migration: 'legacy migration'
-save_cause_converted_from_v2: 'converted from v2'
-up_to_date: '[HuskSync](#00fb9a bold) [| Je gebruikt de nieuwste versie van HuskSync (v%1%).](#00fb9a)'
-update_available: '[HuskSync](#ff7e5e bold) [| Er is een nieuwe versie van HuskSync beschikbaar: v%1% (huidige versie: v%2%).](#ff7e5e)'
-reload_complete: '[HuskSync](#00fb9a bold) [| Configuratie- en berichtbestanden opnieuw geladen.](#00fb9a)\n[⚠ Controleer of de configuratiebestanden up-to-date zijn op alle servers!](#00fb9a)\n[Een herstart is nodig voor de configuratiewijzigingen van kracht te laten worden.](#00fb9a italic)'
-system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
-error_invalid_syntax: '[Error:](#ff3300) [Onjuiste syntaxis. Gebruik:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
-error_invalid_player: '[Error:](#ff3300) [Kan geen speler met die naam vinden.](#ff7e5e)'
-error_no_permission: '[Error:](#ff3300) [Je hebt geen toestemming om deze opdracht uit te voeren](#ff7e5e)'
-error_console_command_only: '[Error:](#ff3300) [Dat command kan alleen via de console worden uitgevoerd](#ff7e5e)'
-error_in_game_command_only: 'Error: Dat command kan alleen in-game worden gebruikt.'
-error_no_data_to_display: '[Error:](#ff3300) [Kon geen gebruikersgegevens vinden om weer te geven.](#ff7e5e)'
-error_invalid_version_uuid: '[Error:](#ff3300) [Kon geen gebruikersgegevens vinden voor dat versie-UUID.](#ff7e5e)'
-husksync_command_description: 'Beheer de HuskSync plugin'
-userdata_command_description: 'Bekijk, beheer en herstel de gebruikersgegevens van spelers'
-inventory_command_description: 'Bekijk en bewerk de inventaris van een speler'
-enderchest_command_description: 'Bekijk en bewerk de Enderkist van een speler'
+locales:
+ synchronization_complete: '[⏵ Data gesynchroniseerd!](#00fb9a)'
+ synchronization_failed: '[⏵ Synchroniseren van jouw gegevens is niet gelukt! Neem contact op met een beheerder.](#ff7e5e)'
+ inventory_viewer_menu_title: '&0%1%''s Inventaris'
+ ender_chest_viewer_menu_title: '&0%1%''s Enderkist'
+ inventory_viewer_opened: '[Momentopname bekijken van](#00fb9a) [%1%](#00fb9a bold)[''s inventaris per ⌚ %2%](#00fb9a)'
+ ender_chest_viewer_opened: '[Momentopname bekijken van](#00fb9a) [%1%](#00fb9a bold)[''s Enderkist per ⌚ %2%](#00fb9a)'
+ data_update_complete: '[🔔 Jouw gegevens zijn bijgewerkt!](#00fb9a)'
+ data_update_failed: '[🔔 Het is niet gelukt om jouw gegevens bij te werken! Neem contact op met een beheerder.](#ff7e5e)'
+ user_registration_complete: '[⭐ Gebruikersregistratie voltooid!](#00fb9a)'
+ data_manager_title: '[Momentopname van gebruikersgegevens bekijken](#00fb9a) [%1%](#00fb9a show_text=&7Versie UUID:\n&8%2%) [voor](#00fb9a) [%3%](#00fb9a bold show_text=&7Speler UUID:\n&8%4%)[:](#00fb9a)'
+ data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Versie tijdmarkering:\n&8Toen de gegevens werden opgeslagen)'
+ data_manager_pinned: '[※ Momentopname vastgezet](#d8ff2b show_text=&7Vastgezet:\n&8Deze momentopname van gebruikersgegevens wordt niet automatisch gerouleerd.)'
+ data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Reden opslaan:\n&8Waarom de data is opgeslagen)'
+ data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name of the server the data was saved on)'
+ data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Grootte van momentopname:\n&8Geschatte bestandsgrootte van de momentopname (in KiB))\n'
+ data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Gezondheids punten) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Honger punten) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7XP level) [🏹 %5%](dark_aqua show_text=&7Speltype)'
+ data_manager_advancements_statistics: '[⭐ Advancements: %1%](color=#ffc43b-#f5c962 show_text=&7Advancements waarin je voortgang hebt:\n&8%2%) [⌛ Speeltijd: %3%uren](color=#62a9f5-#7ab8fa show_text=&7In-game speeltijd\n&8⚠ Gebaseerd op in-game statistieken)\n'
+ data_manager_item_buttons: '[View:](gray) [[🪣 Inventaris…]](color=#a17b5f-#f5b98c show_text=&7Klikken om te bekijken run_command=/inventory %1% %2%) [[⌀ Enderkist…]](#b649c4-#d254ff show_text=&7Klikken om te bekijken run_command=/enderchest %1% %2%)'
+ data_manager_management_buttons: '[Beheren:](gray) [[❌ Verwijderen…]](#ff3300 show_text=&7Klik om deze momentopname van gebruikersgegevens te verwijderen.\n&8Dit heeft geen invloed op de huidige gegevens van de gebruiker.\nff3300&⚠ Dit kan niet ongedaan gemaakt worden! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Herstellen…]](#00fb9a show_text=&7Klik om deze gebruikersgegevens te herstellen.\n&8Hierdoor worden de gegevens van de gebruiker ingesteld op deze momentopname.\nff3300&⚠ %1%''s huidige gegevens worden overschreven! suggest_command=/husksync:userdata restore %1% %2%) [[※ Vastzetten/losmaken…]](#d8ff2b show_text=&7Klik om deze momentopname van gebruikersgegevens vast te zetten of los te maken\n&8Vastgezette momentopnamen worden niet automatisch gerouleerd run_command=/userdata pin %1% %2%)'
+ data_manager_system_buttons: '[Systeem:](gray) [[⏷ Bestandsdump…]](dark_gray show_text=&7Klik om deze ruwe gebruikersgegevenssnapshot naar een bestand te dumperen.\n&8Gegevensdumps zijn te vinden in ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ Webdump…]](dark_gray show_text=&7Klik om deze ruwe gebruikersgegevenssnapshot naar de mc-logs-service te dumpen\n&8Je ontvangt een URL met de gegevens. run_command=/husksync:userdata dump %1% %2% web)'
+ data_manager_advancements_preview_remaining: 'en %1% meer…'
+ data_list_title: '[%1%''s momentopnamen van gebruikersgegevens:](#00fb9a) [(%2%-%3% van](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
+ data_list_item: '[%1%](gray show_text=&7Gebruikersgegevens momentopname voor %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Vastgezet:\n&8Vastgezette momentopnamen worden niet automatisch gerouleerd. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Versie tijdmarkering:&7\n&8Wanneer de data was opgeslagen\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Reden opslaan:\n&8Waarom de data is opgeslagen run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Grootte van momentopname:&7\n&8Geschatte bestandsgrootte van de momentopname (in KiB) run_command=/userdata view %2% %3%)'
+ data_deleted: '[❌ Momentopname van gebruikersgegevens is verwijderd](#00fb9a) [%1%](#00fb9a show_text=&7Versie UUID:\n&8%2%) [voor](#00fb9a) [%3%.](#00fb9a show_text=&7Speler UUID:\n&8%4%)'
+ data_restored: '[⏪ Succesvol hersteld](#00fb9a) [%1%](#00fb9a show_text=&7Speler UUID:\n&8%2%)[''s huidige gebruikersgegevens uit momentopname](#00fb9a) [%3%.](#00fb9a show_text=&7Versie UUID:\n&8%4%)'
+ data_pinned: '[※ Momentopname van gebruikersgegevens is vastgezet](#00fb9a) [%1%](#00fb9a show_text=&7Versie UUID:\n&8%2%) [voor](#00fb9a) [%3%.](#00fb9a show_text=&7Speler UUID:\n&8%4%)'
+ data_unpinned: '[※ Momentopname van gebruikersgegevens is losgemaakt](#00fb9a) [%1%](#00fb9a show_text=&7Versie UUID:\n&8%2%) [voor](#00fb9a) [%3%.](#00fb9a show_text=&7Speler UUID:\n&8%4%)'
+ data_dumped: '[☂ De momentopname van gebruikersgegevens %1% voor %2% is met succes gedumpt naar:](#00fb9a) &7%3%'
+ list_footer: '\n%1%[Pagina](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
+ list_previous_page_button: '[◀](white show_text=&7Bekijk vorige pagina run_command=%2% %1%) '
+ list_next_page_button: ' [▶](white show_text=&7Bekijk volgende pagina run_command=%2% %1%)'
+ list_page_jumpers: '(%1%)'
+ list_page_jumper_button: '[%1%](show_text=&7Ga naar pagina %1% run_command=%2% %1%)'
+ list_page_jumper_current_page: '[%1%](#00fb9a)'
+ list_page_jumper_separator: ' '
+ list_page_jumper_group_separator: '…'
+ save_cause_disconnect: 'disconnect'
+ save_cause_world_save: 'world save'
+ save_cause_death: 'death'
+ save_cause_server_shutdown: 'server shutdown'
+ save_cause_inventory_command: 'inventory command'
+ save_cause_enderchest_command: 'enderchest command'
+ save_cause_backup_restore: 'backup restore'
+ save_cause_api: 'API'
+ save_cause_mpdb_migration: 'MPDB migration'
+ save_cause_legacy_migration: 'legacy migration'
+ save_cause_converted_from_v2: 'converted from v2'
+ up_to_date: '[HuskSync](#00fb9a bold) [| Je gebruikt de nieuwste versie van HuskSync (v%1%).](#00fb9a)'
+ update_available: '[HuskSync](#ff7e5e bold) [| Er is een nieuwe versie van HuskSync beschikbaar: v%1% (huidige versie: v%2%).](#ff7e5e)'
+ reload_complete: '[HuskSync](#00fb9a bold) [| Configuratie- en berichtbestanden opnieuw geladen.](#00fb9a)\n[⚠ Controleer of de configuratiebestanden up-to-date zijn op alle servers!](#00fb9a)\n[Een herstart is nodig voor de configuratiewijzigingen van kracht te laten worden.](#00fb9a italic)'
+ system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
+ error_invalid_syntax: '[Error:](#ff3300) [Onjuiste syntaxis. Gebruik:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
+ error_invalid_player: '[Error:](#ff3300) [Kan geen speler met die naam vinden.](#ff7e5e)'
+ error_no_permission: '[Error:](#ff3300) [Je hebt geen toestemming om deze opdracht uit te voeren](#ff7e5e)'
+ error_console_command_only: '[Error:](#ff3300) [Dat command kan alleen via de console worden uitgevoerd](#ff7e5e)'
+ error_in_game_command_only: 'Error: Dat command kan alleen in-game worden gebruikt.'
+ error_no_data_to_display: '[Error:](#ff3300) [Kon geen gebruikersgegevens vinden om weer te geven.](#ff7e5e)'
+ error_invalid_version_uuid: '[Error:](#ff3300) [Kon geen gebruikersgegevens vinden voor dat versie-UUID.](#ff7e5e)'
+ husksync_command_description: 'Beheer de HuskSync plugin'
+ userdata_command_description: 'Bekijk, beheer en herstel de gebruikersgegevens van spelers'
+ inventory_command_description: 'Bekijk en bewerk de inventaris van een speler'
+ enderchest_command_description: 'Bekijk en bewerk de Enderkist van een speler'
diff --git a/common/src/main/resources/locales/pt-br.yml b/common/src/main/resources/locales/pt-br.yml
index 4e08aaca..3d3aa9f4 100644
--- a/common/src/main/resources/locales/pt-br.yml
+++ b/common/src/main/resources/locales/pt-br.yml
@@ -1,62 +1,63 @@
-synchronization_complete: '[⏵ Dados sincronizados!](#00fb9a)'
-synchronization_failed: '[⏵ Falha na sincronização de seus dados! Por favor entre em contato com um administrador.](#ff7e5e)'
-inventory_viewer_menu_title: '&0%1%''s Inventory'
-ender_chest_viewer_menu_title: '&0%1%''s Ender Chest'
-inventory_viewer_opened: '[Visualizando snapshot de](#00fb9a) [%1%](#00fb9a bold) [''s inventory a partir de ⌚ %2%](#00fb9a)'
-ender_chest_viewer_opened: '[Visualizando snapshot de](#00fb9a) [%1%](#00fb9a bold) [''s Ender Chest a partir de ⌚ %2%](#00fb9a)'
-data_update_complete: '[🔔 Seus dados foram atualizados!](#00fb9a)'
-data_update_failed: '[🔔 Falha na atualização de seus dados! Por favor entre em contato com um administrador.](#ff7e5e)'
-user_registration_complete: '[⭐ User registration complete!](#00fb9a)'
-data_manager_title: '[Visualizando snapshot dos dados do usuário](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%](#00fb9a bold show_text=&7Player UUID:\n&8%4%)[:](#00fb9a)'
-data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Version timestamp:\n&8Quando os dados foram salvos)'
-data_manager_pinned: '[※ Snapshot marcada](#d8ff2b show_text=&7Marcada:\n&8Essa snapshot de dados do usuário não será girada automaticamente.)'
-data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Causa do salvamento:\n&8O motivo para que os dados fossem salvos)'
-data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name of the server the data was saved on)'
-data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:\n&8Estimated file size of the snapshot (in KiB))\n'
-data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Pontos de Vida) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Pontos de vida) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7XP level) [🏹 %5%](dark_aqua show_text=&7Game mode)'
-data_manager_advancements_statistics: '[⭐ Progressos: %1%](color=#ffc43b-#f5c962 show_text=&7Progressos que você tem realizado em:\n&8%2%) [⌛ Tempo de jogo: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7Tempo de jogo dentro do jogo\n&8⚠ Com base em estatísticas dentro do jogo)\n'
-data_manager_item_buttons: '[View:](gray) [[🪣 Inventory…]](color=#a17b5f-#f5b98c show_text=&7Clique para ver run_command=/inventory %1% %2%) [[⌀ Ender Chest…]](#b649c4-#d254ff show_text=&7Clique para ver run_command=/enderchest %1% %2%)'
-data_manager_management_buttons: '[Gerenciar:](gray) [[❌ Deletar…]](#ff3300 show_text=&7Clique para deletar esta snapshot de dados do usuário\n&8Isto não afetará os dados atuais do usuário.\nff3300&⚠ Isto não pode ser desfeito! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Restaurar…]](#00fb9a show_text=&7Clique para restaurar estes dados do usuário.\n&8Isto substituirá os dados atuais do usuário para os da snapshot.\nff3300&⚠ %1%''s os dados atuais serão substituídos! suggest_command=/husksync:userdata restore %1% %2%) [[※ Marcar/Desmarcar…]](#d8ff2b show_text=&7Clique para marcar ou desmarcar este snapshot de dados do usuário\n&8Snapshots marcadas não serão giradas automaticamente run_command=/userdata pin %1% %2%)'
-data_manager_system_buttons: '[System:](gray) [[⏷ File Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to a file.\n&8Data dumps can be found in ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ Web Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to the mc-logs service\n&8You will be provided with a URL containing the data. run_command=/husksync:userdata dump %1% %2% web)'
-data_manager_advancements_preview_remaining: 'e %1% mais…'
-data_list_title: '[%1%''s user data snapshots:](#00fb9a) [(%2%-%3% of](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
-data_list_item: '[%1%](gray show_text=&7User Data Snapshot for %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Pinned:\n&8Pinned snapshots won''t be automatically rotated. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Version timestamp:&7\n&8When the data was saved\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Save cause:\n&8What caused the data to be saved run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:&7\n&8Estimated file size of the snapshot (in KiB) run_command=/userdata view %2% %3%)'
-data_deleted: '[❌ Snapshot de dados do usuário deletada com sucesso](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
-data_restored: '[⏪ Restaurada com sucesso](#00fb9a) [%1%](#00fb9a show_text=&7Player UUID:\n&8%2%)[''s current user data from snapshot](#00fb9a) [%3%.](#00fb9a show_text=&7Version UUID:\n&8%4%)'
-data_pinned: '[※ Snapshot de dados do usuário marcada com sucesso](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
-data_unpinned: '[※ Snapshot de dados do usuário desmarcada com sucesso](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
-data_dumped: '[☂ Successfully dumped the user data snapshot %1% for %2% to:](#00fb9a) &7%3%'
-list_footer: '\n%1%[Page](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
-list_previous_page_button: '[◀](white show_text=&7View previous page run_command=%2% %1%) '
-list_next_page_button: ' [▶](white show_text=&7View next page run_command=%2% %1%)'
-list_page_jumpers: '(%1%)'
-list_page_jumper_button: '[%1%](show_text=&7Jump to page %1% run_command=%2% %1%)'
-list_page_jumper_current_page: '[%1%](#00fb9a)'
-list_page_jumper_separator: ' '
-list_page_jumper_group_separator: '…'
-save_cause_disconnect: 'disconnect'
-save_cause_world_save: 'world save'
-save_cause_death: 'death'
-save_cause_server_shutdown: 'server shutdown'
-save_cause_inventory_command: 'inventory command'
-save_cause_enderchest_command: 'enderchest command'
-save_cause_backup_restore: 'backup restore'
-save_cause_api: 'API'
-save_cause_mpdb_migration: 'MPDB migration'
-save_cause_legacy_migration: 'legacy migration'
-save_cause_converted_from_v2: 'converted from v2'
-up_to_date: '[HuskSync](#00fb9a bold) [| You are running the latest version of HuskSync (v%1%).](#00fb9a)'
-update_available: '[HuskSync](#ff7e5e bold) [| A new version of HuskSync is available: v%1% (running: v%2%).](#ff7e5e)'
-reload_complete: '[HuskSync](#00fb9a bold) [| Arquivos de configuração e mensagens recarregados.](#00fb9a)\n[⚠ Ensure config files are up-to-date on all servers!](#00fb9a)\n[A restart is needed for config changes to take effect.](#00fb9a italic)'
-system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
-error_invalid_syntax: '[Error:](#ff3300) [Sintaxe incorreta. Utilize:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
-error_invalid_player: '[Error:](#ff3300) [Não foi possível encontrar um jogador com esse nome.](#ff7e5e)'
-error_no_permission: '[Error:](#ff3300) [Você não tem permissão para executar este comando](#ff7e5e)'
-error_console_command_only: '[Error:](#ff3300) [Esse comando só pode ser executado através do console](#ff7e5e)'
-error_in_game_command_only: 'Error: Esse comando só pode ser usado dentro do jogo.'
-error_no_data_to_display: '[Error:](#ff3300) [Não encontramos nenhuma informação deste jogador para exibir.](#ff7e5e)'
-error_invalid_version_uuid: '[Error:](#ff3300) [Não foi possível encontrar nenhuma informação deste jogador para essa versão UUID.](#ff7e5e)'
-husksync_command_description: 'Manage the HuskSync plugin'
-userdata_command_description: 'View, manage & restore player userdata'
-inventory_command_description: 'View & edit a player''s inventory'
-enderchest_command_description: 'View & edit a player''s Ender Chest'
\ No newline at end of file
+locales:
+ synchronization_complete: '[⏵ Dados sincronizados!](#00fb9a)'
+ synchronization_failed: '[⏵ Falha na sincronização de seus dados! Por favor entre em contato com um administrador.](#ff7e5e)'
+ inventory_viewer_menu_title: '&0%1%''s Inventory'
+ ender_chest_viewer_menu_title: '&0%1%''s Ender Chest'
+ inventory_viewer_opened: '[Visualizando snapshot de](#00fb9a) [%1%](#00fb9a bold) [''s inventory a partir de ⌚ %2%](#00fb9a)'
+ ender_chest_viewer_opened: '[Visualizando snapshot de](#00fb9a) [%1%](#00fb9a bold) [''s Ender Chest a partir de ⌚ %2%](#00fb9a)'
+ data_update_complete: '[🔔 Seus dados foram atualizados!](#00fb9a)'
+ data_update_failed: '[🔔 Falha na atualização de seus dados! Por favor entre em contato com um administrador.](#ff7e5e)'
+ user_registration_complete: '[⭐ User registration complete!](#00fb9a)'
+ data_manager_title: '[Visualizando snapshot dos dados do usuário](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%](#00fb9a bold show_text=&7Player UUID:\n&8%4%)[:](#00fb9a)'
+ data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Version timestamp:\n&8Quando os dados foram salvos)'
+ data_manager_pinned: '[※ Snapshot marcada](#d8ff2b show_text=&7Marcada:\n&8Essa snapshot de dados do usuário não será girada automaticamente.)'
+ data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Causa do salvamento:\n&8O motivo para que os dados fossem salvos)'
+ data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name of the server the data was saved on)'
+ data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:\n&8Estimated file size of the snapshot (in KiB))\n'
+ data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Pontos de Vida) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Pontos de vida) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7XP level) [🏹 %5%](dark_aqua show_text=&7Game mode)'
+ data_manager_advancements_statistics: '[⭐ Progressos: %1%](color=#ffc43b-#f5c962 show_text=&7Progressos que você tem realizado em:\n&8%2%) [⌛ Tempo de jogo: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7Tempo de jogo dentro do jogo\n&8⚠ Com base em estatísticas dentro do jogo)\n'
+ data_manager_item_buttons: '[View:](gray) [[🪣 Inventory…]](color=#a17b5f-#f5b98c show_text=&7Clique para ver run_command=/inventory %1% %2%) [[⌀ Ender Chest…]](#b649c4-#d254ff show_text=&7Clique para ver run_command=/enderchest %1% %2%)'
+ data_manager_management_buttons: '[Gerenciar:](gray) [[❌ Deletar…]](#ff3300 show_text=&7Clique para deletar esta snapshot de dados do usuário\n&8Isto não afetará os dados atuais do usuário.\nff3300&⚠ Isto não pode ser desfeito! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Restaurar…]](#00fb9a show_text=&7Clique para restaurar estes dados do usuário.\n&8Isto substituirá os dados atuais do usuário para os da snapshot.\nff3300&⚠ %1%''s os dados atuais serão substituídos! suggest_command=/husksync:userdata restore %1% %2%) [[※ Marcar/Desmarcar…]](#d8ff2b show_text=&7Clique para marcar ou desmarcar este snapshot de dados do usuário\n&8Snapshots marcadas não serão giradas automaticamente run_command=/userdata pin %1% %2%)'
+ data_manager_system_buttons: '[System:](gray) [[⏷ File Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to a file.\n&8Data dumps can be found in ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ Web Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to the mc-logs service\n&8You will be provided with a URL containing the data. run_command=/husksync:userdata dump %1% %2% web)'
+ data_manager_advancements_preview_remaining: 'e %1% mais…'
+ data_list_title: '[%1%''s user data snapshots:](#00fb9a) [(%2%-%3% of](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
+ data_list_item: '[%1%](gray show_text=&7User Data Snapshot for %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Pinned:\n&8Pinned snapshots won''t be automatically rotated. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Version timestamp:&7\n&8When the data was saved\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Save cause:\n&8What caused the data to be saved run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:&7\n&8Estimated file size of the snapshot (in KiB) run_command=/userdata view %2% %3%)'
+ data_deleted: '[❌ Snapshot de dados do usuário deletada com sucesso](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
+ data_restored: '[⏪ Restaurada com sucesso](#00fb9a) [%1%](#00fb9a show_text=&7Player UUID:\n&8%2%)[''s current user data from snapshot](#00fb9a) [%3%.](#00fb9a show_text=&7Version UUID:\n&8%4%)'
+ data_pinned: '[※ Snapshot de dados do usuário marcada com sucesso](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
+ data_unpinned: '[※ Snapshot de dados do usuário desmarcada com sucesso](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
+ data_dumped: '[☂ Successfully dumped the user data snapshot %1% for %2% to:](#00fb9a) &7%3%'
+ list_footer: '\n%1%[Page](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
+ list_previous_page_button: '[◀](white show_text=&7View previous page run_command=%2% %1%) '
+ list_next_page_button: ' [▶](white show_text=&7View next page run_command=%2% %1%)'
+ list_page_jumpers: '(%1%)'
+ list_page_jumper_button: '[%1%](show_text=&7Jump to page %1% run_command=%2% %1%)'
+ list_page_jumper_current_page: '[%1%](#00fb9a)'
+ list_page_jumper_separator: ' '
+ list_page_jumper_group_separator: '…'
+ save_cause_disconnect: 'disconnect'
+ save_cause_world_save: 'world save'
+ save_cause_death: 'death'
+ save_cause_server_shutdown: 'server shutdown'
+ save_cause_inventory_command: 'inventory command'
+ save_cause_enderchest_command: 'enderchest command'
+ save_cause_backup_restore: 'backup restore'
+ save_cause_api: 'API'
+ save_cause_mpdb_migration: 'MPDB migration'
+ save_cause_legacy_migration: 'legacy migration'
+ save_cause_converted_from_v2: 'converted from v2'
+ up_to_date: '[HuskSync](#00fb9a bold) [| You are running the latest version of HuskSync (v%1%).](#00fb9a)'
+ update_available: '[HuskSync](#ff7e5e bold) [| A new version of HuskSync is available: v%1% (running: v%2%).](#ff7e5e)'
+ reload_complete: '[HuskSync](#00fb9a bold) [| Arquivos de configuração e mensagens recarregados.](#00fb9a)\n[⚠ Ensure config files are up-to-date on all servers!](#00fb9a)\n[A restart is needed for config changes to take effect.](#00fb9a italic)'
+ system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
+ error_invalid_syntax: '[Error:](#ff3300) [Sintaxe incorreta. Utilize:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
+ error_invalid_player: '[Error:](#ff3300) [Não foi possível encontrar um jogador com esse nome.](#ff7e5e)'
+ error_no_permission: '[Error:](#ff3300) [Você não tem permissão para executar este comando](#ff7e5e)'
+ error_console_command_only: '[Error:](#ff3300) [Esse comando só pode ser executado através do console](#ff7e5e)'
+ error_in_game_command_only: 'Error: Esse comando só pode ser usado dentro do jogo.'
+ error_no_data_to_display: '[Error:](#ff3300) [Não encontramos nenhuma informação deste jogador para exibir.](#ff7e5e)'
+ error_invalid_version_uuid: '[Error:](#ff3300) [Não foi possível encontrar nenhuma informação deste jogador para essa versão UUID.](#ff7e5e)'
+ husksync_command_description: 'Manage the HuskSync plugin'
+ userdata_command_description: 'View, manage & restore player userdata'
+ inventory_command_description: 'View & edit a player''s inventory'
+ enderchest_command_description: 'View & edit a player''s Ender Chest'
\ No newline at end of file
diff --git a/common/src/main/resources/locales/ru-ru.yml b/common/src/main/resources/locales/ru-ru.yml
index 5e5cf01e..49d1e16e 100644
--- a/common/src/main/resources/locales/ru-ru.yml
+++ b/common/src/main/resources/locales/ru-ru.yml
@@ -1,62 +1,63 @@
-synchronization_complete: '[⏵ Данные синхронизированы!](#00fb9a)'
-synchronization_failed: '[⏵ Не удалось синхронизировать данные! Пожалуйста, обратитесь к администратору.](#ff7e5e)'
-inventory_viewer_menu_title: '&0Инвентарь %1%'
-ender_chest_viewer_menu_title: '&0Эндер-сундук %1%'
-inventory_viewer_opened: '[Просмотр снимка инвентаря](#00fb9a) [%1%](#00fb9a bold) [во время ⌚ %2%](#00fb9a)'
-ender_chest_viewer_opened: '[Просмотр снимка эндер-сундука](#00fb9a) [%1%](#00fb9a bold) [во время ⌚ %2%](#00fb9a)'
-data_update_complete: '[🔔 Ваши данные обновлены!](#00fb9a)'
-data_update_failed: '[🔔 Не удалось обновить ваши данные! Пожалуйста, обратитесь к администратору.](#ff7e5e)'
-user_registration_complete: '[⭐ Регистрация пользователя завершена!](#00fb9a)'
-data_manager_title: '[Просмотр снимка данных](#00fb9a) [%1%](#00fb9a show_text=&7UUID снимка:\n&8%2%) [пользователя](#00fb9a) [%3%](#00fb9a bold show_text=&7UUID игрока:\n&8%4%)[:](#00fb9a)'
-data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Время:\n&8Когда данные были сохранены)'
-data_manager_pinned: '[※ Снимок закреплен](#d8ff2b show_text=&7Закреплен:\n&8Этот снимок данных пользователя не будет автоматически применено.)'
-data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Причина сохранения:\n&8Что привело к сохранению данных)'
-data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Сервер:\n&8Название сервера где данные были сохранены)'
-data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Размер:\n&8Предполагаемый размер снимка (в килобайтах))\n'
-data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Здоровье) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Голод) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7Уровень опыта) [🏹 %5%](dark_aqua show_text=&7Игровой режим)'
-data_manager_advancements_statistics: '[⭐ Достижения: %1%](color=#ffc43b-#f5c962 show_text=&7Полученные вами достижения:\n&8%2%) [⌛ Отыгранное время: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7Сколько времени вы отыграли\n&8⚠ Строится по внутреигровой статистике)\n'
-data_manager_item_buttons: '[Просмотр:](gray) [[🪣 Инвентарь…]](color=#a17b5f-#f5b98c show_text=&7Нажмите для просмотра run_command=/inventory %1% %2%) [[⌀ Эндер-сундук…]](#b649c4-#d254ff show_text=&7Нажмите для просмотра run_command=/enderchest %1% %2%)'
-data_manager_management_buttons: '[Управление:](gray) [[❌ Удалить…]](#ff3300 show_text=&7Нажмите для удаления этого снимка данных пользователя\n&8Не влияет на текущие данные пользователя.\nff3300&⚠ Необратимое действие! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Восстановить…]](#00fb9a show_text=&7Нажмите для восстановления данных пользователя\n&8Это восстановит данные пользователя до этого снимка.\nff3300&⚠ Текущие данные %1% будут перезаписаны! suggest_command=/husksync:userdata restore %1% %2%) [[※ Закрепить/Открепить…]](#d8ff2b show_text=&7Нажмите для закрепления или открепления снимка данных пользователя\n&8Закрепленные снимки данных не удаляются автоматически. run_command=/userdata pin %1% %2%)'
-data_manager_system_buttons: '[Система:](gray) [[⏷ Дамп в файл…]](dark_gray show_text=&7Нажмите для дампа исходного снимка данных пользователя в файл\n&8Файлы дампов данных находятся в ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ Выгрузить дамп…]](dark_gray show_text=&7Нажмите для дампа исходного снимка данных пользователя с помощью сервиса mc-logs\n&8Вы получите ссылку с дампом данных. run_command=/husksync:userdata dump %1% %2% web)'
-data_manager_advancements_preview_remaining: 'и еще %1%…'
-data_list_title: '[Снимки данных %1%:](#00fb9a) [(%2%-%3% из](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
-data_list_item: '[%1%](gray show_text=&7Снимок данных %4% пользователя %2%&8⚡ run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Закреплен:\n&8Закрепленные снимки данных не удаляются автоматически run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Время:&7\n&8Когда данные были сохранены\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Причина сохранения:\n&8Что привело к сохранению данных run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Размер:&7\n&8Предполагаемый размер снимка (в килобайтах) run_command=/userdata view %2% %3%)'
-data_deleted: '[❌ Снимок данных](#00fb9a) [%1%](#00fb9a show_text=&7UUID снимка:\n&8%2%) [пользователя](#00fb9a) [%3%](#00fb9a show_text=&7UUID игрока:\n&8%4%) [удален.](#00fb9a)'
-data_restored: '[⏪ Данные пользователя](#00fb9a) [%1%](#00fb9a show_text=&7UUID игрока:\n&8%2%) [из снимка](#00fb9a) [%3%](#00fb9a show_text=&7UUID снимка:\n&8%4%) [успешно восстановлены.](#00fb9a)'
-data_pinned: '[※ Снимок данных](#00fb9a) [%1%](#00fb9a show_text=&7UUID снимка:\n&8%2%) [пользователя](#00fb9a) [%3%](#00fb9a show_text=&7UUID игрока:\n&8%4%) [успешно закреплен.](#00fb9a)'
-data_unpinned: '[※ Снимок данных](#00fb9a) [%1%](#00fb9a show_text=&7UUID снимка:\n&8%2%) [пользователя](#00fb9a) [%3%](#00fb9a show_text=&7UUID пользователя:\n&8%4%) [успешно откреплен.](#00fb9a)'
-data_dumped: '[☂ Дамп снимка данных %1% пользователя %2% успешно выгружен:](#00fb9a) &7%3%'
-list_footer: '\n%1%[Страница](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%\n'
-list_previous_page_button: '[◀](white show_text=&7Просмотр предыдущей страницы run_command=%2% %1%) '
-list_next_page_button: ' [▶](white show_text=&7Просмотр следующей страницы run_command=%2% %1%)'
-list_page_jumpers: '(%1%)'
-list_page_jumper_button: '[%1%](show_text=&7Перейти на страницу %1% run_command=%2% %1%)'
-list_page_jumper_current_page: '[%1%](#00fb9a)'
-list_page_jumper_separator: ' '
-list_page_jumper_group_separator: '…'
-save_cause_disconnect: 'отключение с сервера'
-save_cause_world_save: 'сохранение мира'
-save_cause_death: 'смерть'
-save_cause_server_shutdown: 'отключение сервера'
-save_cause_inventory_command: 'команда inventory'
-save_cause_enderchest_command: 'команда enderchest'
-save_cause_backup_restore: 'восстановление из снимка'
-save_cause_api: 'API'
-save_cause_mpdb_migration: 'миграция из MPDB'
-save_cause_legacy_migration: 'миграция с legacy'
-save_cause_converted_from_v2: 'конвертация с v2'
-up_to_date: '[HuskSync](#00fb9a bold) [| Вы используете последнюю версию HuskSync (v%1%).](#00fb9a)'
-update_available: '[HuskSync](#ff7e5e bold) [| Доступна новая версия HuskSync: v%1% (текущая: v%2%).](#ff7e5e)'
-reload_complete: '[HuskSync](#00fb9a bold) [| Конфигурация и файлы локализации перезагружены.](#00fb9a)\n[⚠ Убедитесь, что файлы конфигурации обновлены на всех серверах!](#00fb9a)\n[Необходима перезагрузка для вступления изменений конфигурации в силу.](#00fb9a italic)'
-system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
-error_invalid_syntax: '[Ошибка:](#ff3300) [Неправильный синтаксис. Используйте:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
-error_invalid_player: '[Ошибка:](#ff3300) [Не удалось найти игрока с данным именем.](#ff7e5e)'
-error_no_permission: '[Ошибка:](#ff3300) [У вас недостаточно прав для выполнения данной команды.](#ff7e5e)'
-error_console_command_only: '[Ошибка:](#ff3300) [Данная команда может быть выполнена только из консоли.](#ff7e5e)'
-error_in_game_command_only: 'Ошибка: Данная команда может быть выполнена только в игре.'
-error_no_data_to_display: '[Ошибка:](#ff3300) [Не удалось найти никаких пользовательских данных для отображения.](#ff7e5e)'
-error_invalid_version_uuid: '[Ошибка:](#ff3300) [Не удалось найти никаких пользовательских данных с этим UUID снимка.](#ff7e5e)'
-husksync_command_description: 'Управление плагином HuskSync'
-userdata_command_description: 'Просмотр, редактирование и восстановление пользовательских данных игрока'
-inventory_command_description: 'Просмотр и редактирование инвентаря игрока'
-enderchest_command_description: 'Просмотр и редактирование эндер-сундука игрока'
\ No newline at end of file
+locales:
+ synchronization_complete: '[⏵ Данные синхронизированы!](#00fb9a)'
+ synchronization_failed: '[⏵ Не удалось синхронизировать данные! Пожалуйста, обратитесь к администратору.](#ff7e5e)'
+ inventory_viewer_menu_title: '&0Инвентарь %1%'
+ ender_chest_viewer_menu_title: '&0Эндер-сундук %1%'
+ inventory_viewer_opened: '[Просмотр снимка инвентаря](#00fb9a) [%1%](#00fb9a bold) [во время ⌚ %2%](#00fb9a)'
+ ender_chest_viewer_opened: '[Просмотр снимка эндер-сундука](#00fb9a) [%1%](#00fb9a bold) [во время ⌚ %2%](#00fb9a)'
+ data_update_complete: '[🔔 Ваши данные обновлены!](#00fb9a)'
+ data_update_failed: '[🔔 Не удалось обновить ваши данные! Пожалуйста, обратитесь к администратору.](#ff7e5e)'
+ user_registration_complete: '[⭐ Регистрация пользователя завершена!](#00fb9a)'
+ data_manager_title: '[Просмотр снимка данных](#00fb9a) [%1%](#00fb9a show_text=&7UUID снимка:\n&8%2%) [пользователя](#00fb9a) [%3%](#00fb9a bold show_text=&7UUID игрока:\n&8%4%)[:](#00fb9a)'
+ data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Время:\n&8Когда данные были сохранены)'
+ data_manager_pinned: '[※ Снимок закреплен](#d8ff2b show_text=&7Закреплен:\n&8Этот снимок данных пользователя не будет автоматически применено.)'
+ data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Причина сохранения:\n&8Что привело к сохранению данных)'
+ data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Сервер:\n&8Название сервера где данные были сохранены)'
+ data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Размер:\n&8Предполагаемый размер снимка (в килобайтах))\n'
+ data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Здоровье) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Голод) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7Уровень опыта) [🏹 %5%](dark_aqua show_text=&7Игровой режим)'
+ data_manager_advancements_statistics: '[⭐ Достижения: %1%](color=#ffc43b-#f5c962 show_text=&7Полученные вами достижения:\n&8%2%) [⌛ Отыгранное время: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7Сколько времени вы отыграли\n&8⚠ Строится по внутреигровой статистике)\n'
+ data_manager_item_buttons: '[Просмотр:](gray) [[🪣 Инвентарь…]](color=#a17b5f-#f5b98c show_text=&7Нажмите для просмотра run_command=/inventory %1% %2%) [[⌀ Эндер-сундук…]](#b649c4-#d254ff show_text=&7Нажмите для просмотра run_command=/enderchest %1% %2%)'
+ data_manager_management_buttons: '[Управление:](gray) [[❌ Удалить…]](#ff3300 show_text=&7Нажмите для удаления этого снимка данных пользователя\n&8Не влияет на текущие данные пользователя.\nff3300&⚠ Необратимое действие! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Восстановить…]](#00fb9a show_text=&7Нажмите для восстановления данных пользователя\n&8Это восстановит данные пользователя до этого снимка.\nff3300&⚠ Текущие данные %1% будут перезаписаны! suggest_command=/husksync:userdata restore %1% %2%) [[※ Закрепить/Открепить…]](#d8ff2b show_text=&7Нажмите для закрепления или открепления снимка данных пользователя\n&8Закрепленные снимки данных не удаляются автоматически. run_command=/userdata pin %1% %2%)'
+ data_manager_system_buttons: '[Система:](gray) [[⏷ Дамп в файл…]](dark_gray show_text=&7Нажмите для дампа исходного снимка данных пользователя в файл\n&8Файлы дампов данных находятся в ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ Выгрузить дамп…]](dark_gray show_text=&7Нажмите для дампа исходного снимка данных пользователя с помощью сервиса mc-logs\n&8Вы получите ссылку с дампом данных. run_command=/husksync:userdata dump %1% %2% web)'
+ data_manager_advancements_preview_remaining: 'и еще %1%…'
+ data_list_title: '[Снимки данных %1%:](#00fb9a) [(%2%-%3% из](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
+ data_list_item: '[%1%](gray show_text=&7Снимок данных %4% пользователя %2%&8⚡ run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Закреплен:\n&8Закрепленные снимки данных не удаляются автоматически run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Время:&7\n&8Когда данные были сохранены\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Причина сохранения:\n&8Что привело к сохранению данных run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Размер:&7\n&8Предполагаемый размер снимка (в килобайтах) run_command=/userdata view %2% %3%)'
+ data_deleted: '[❌ Снимок данных](#00fb9a) [%1%](#00fb9a show_text=&7UUID снимка:\n&8%2%) [пользователя](#00fb9a) [%3%](#00fb9a show_text=&7UUID игрока:\n&8%4%) [удален.](#00fb9a)'
+ data_restored: '[⏪ Данные пользователя](#00fb9a) [%1%](#00fb9a show_text=&7UUID игрока:\n&8%2%) [из снимка](#00fb9a) [%3%](#00fb9a show_text=&7UUID снимка:\n&8%4%) [успешно восстановлены.](#00fb9a)'
+ data_pinned: '[※ Снимок данных](#00fb9a) [%1%](#00fb9a show_text=&7UUID снимка:\n&8%2%) [пользователя](#00fb9a) [%3%](#00fb9a show_text=&7UUID игрока:\n&8%4%) [успешно закреплен.](#00fb9a)'
+ data_unpinned: '[※ Снимок данных](#00fb9a) [%1%](#00fb9a show_text=&7UUID снимка:\n&8%2%) [пользователя](#00fb9a) [%3%](#00fb9a show_text=&7UUID пользователя:\n&8%4%) [успешно откреплен.](#00fb9a)'
+ data_dumped: '[☂ Дамп снимка данных %1% пользователя %2% успешно выгружен:](#00fb9a) &7%3%'
+ list_footer: '\n%1%[Страница](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%\n'
+ list_previous_page_button: '[◀](white show_text=&7Просмотр предыдущей страницы run_command=%2% %1%) '
+ list_next_page_button: ' [▶](white show_text=&7Просмотр следующей страницы run_command=%2% %1%)'
+ list_page_jumpers: '(%1%)'
+ list_page_jumper_button: '[%1%](show_text=&7Перейти на страницу %1% run_command=%2% %1%)'
+ list_page_jumper_current_page: '[%1%](#00fb9a)'
+ list_page_jumper_separator: ' '
+ list_page_jumper_group_separator: '…'
+ save_cause_disconnect: 'отключение с сервера'
+ save_cause_world_save: 'сохранение мира'
+ save_cause_death: 'смерть'
+ save_cause_server_shutdown: 'отключение сервера'
+ save_cause_inventory_command: 'команда inventory'
+ save_cause_enderchest_command: 'команда enderchest'
+ save_cause_backup_restore: 'восстановление из снимка'
+ save_cause_api: 'API'
+ save_cause_mpdb_migration: 'миграция из MPDB'
+ save_cause_legacy_migration: 'миграция с legacy'
+ save_cause_converted_from_v2: 'конвертация с v2'
+ up_to_date: '[HuskSync](#00fb9a bold) [| Вы используете последнюю версию HuskSync (v%1%).](#00fb9a)'
+ update_available: '[HuskSync](#ff7e5e bold) [| Доступна новая версия HuskSync: v%1% (текущая: v%2%).](#ff7e5e)'
+ reload_complete: '[HuskSync](#00fb9a bold) [| Конфигурация и файлы локализации перезагружены.](#00fb9a)\n[⚠ Убедитесь, что файлы конфигурации обновлены на всех серверах!](#00fb9a)\n[Необходима перезагрузка для вступления изменений конфигурации в силу.](#00fb9a italic)'
+ system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
+ error_invalid_syntax: '[Ошибка:](#ff3300) [Неправильный синтаксис. Используйте:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
+ error_invalid_player: '[Ошибка:](#ff3300) [Не удалось найти игрока с данным именем.](#ff7e5e)'
+ error_no_permission: '[Ошибка:](#ff3300) [У вас недостаточно прав для выполнения данной команды.](#ff7e5e)'
+ error_console_command_only: '[Ошибка:](#ff3300) [Данная команда может быть выполнена только из консоли.](#ff7e5e)'
+ error_in_game_command_only: 'Ошибка: Данная команда может быть выполнена только в игре.'
+ error_no_data_to_display: '[Ошибка:](#ff3300) [Не удалось найти никаких пользовательских данных для отображения.](#ff7e5e)'
+ error_invalid_version_uuid: '[Ошибка:](#ff3300) [Не удалось найти никаких пользовательских данных с этим UUID снимка.](#ff7e5e)'
+ husksync_command_description: 'Управление плагином HuskSync'
+ userdata_command_description: 'Просмотр, редактирование и восстановление пользовательских данных игрока'
+ inventory_command_description: 'Просмотр и редактирование инвентаря игрока'
+ enderchest_command_description: 'Просмотр и редактирование эндер-сундука игрока'
\ No newline at end of file
diff --git a/common/src/main/resources/locales/tr-tr.yml b/common/src/main/resources/locales/tr-tr.yml
index 803b1897..0230b23b 100644
--- a/common/src/main/resources/locales/tr-tr.yml
+++ b/common/src/main/resources/locales/tr-tr.yml
@@ -1,62 +1,63 @@
-synchronization_complete: '[⏵ Veri senkronize edildi!](#00fb9a)'
-synchronization_failed: '[⏵ Veriler senkronize edilemedi! Lütfen bir yönetici ile iletişime geçin.](#ff7e5e)'
-inventory_viewer_menu_title: '&0%1%''ın Envanteri'
-ender_chest_viewer_menu_title: '&0%1%''ın Ender Sandığı'
-inventory_viewer_opened: '[Görüntülenen anlık](#00fb9a) [%1%](#00fb9a bold)[''ın envanteri ⌚ %2% tarihine kadar](#00fb9a)'
-ender_chest_viewer_opened: '[Görüntülenen anlık](#00fb9a) [%1%](#00fb9a bold)[''ın Ender Sandığı ⌚ %2% tarihine kadar](#00fb9a)'
-data_update_complete: '[🔔 Verileriniz güncellendi!](#00fb9a)'
-data_update_failed: '[🔔 Verileriniz güncellenirken bir hata oluştu! Lütfen bir yönetici ile iletişime geçin.](#ff7e5e)'
-user_registration_complete: '[⭐ Kullanıcı kaydı tamamlandı!](#00fb9a)'
-data_manager_title: '[Kullanıcı veri anlık görünümü](#00fb9a) [%1%](#00fb9a show_text=&7Versiyon UUID:\n&8%2%) [için](#00fb9a) [%3%](#00fb9a bold show_text=&7Oyuncu UUID:\n&8%4%)[:](#00fb9a)'
-data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Versiyon zaman damgası:\n&8Verinin ne zaman kaydedildiği)'
-data_manager_pinned: '[※ Anlık sabitlendi](#d8ff2b show_text=&7Sabitlendi:\n&8Bu kullanıcı veri anlığı otomatik olarak döndürülmeyecek.)'
-data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Kaydetme sebebi:\n&8Verinin kaydedilme nedeni)'
-data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Sunucu:\n&8Verinin kaydedildiği sunucu adı)'
-data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Anlık boyutu:\n&8Anlının tahmini dosya boyutu (KiB cinsinden))\n'
-data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Can puanı) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Açlık puanı) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7XP seviyesi) [🏹 %5%](dark_aqua show_text=&7Oyun modu)'
-data_manager_advancements_statistics: '[⭐ Gelişmeler: %1%](color=#ffc43b-#f5c962 show_text=&7Gelişmelerdeki ilerlemeniz:\n&8%2%) [⌛ Oynama Süresi: %3%s](color=#62a9f5-#7ab8fa show_text=&7Oyunda geçen süre\n&8⚠ Oyun içi istatistiklere dayanır)\n'
-data_manager_item_buttons: '[Görünüm:](gray) [[🪣 Envanter…]](color=#a17b5f-#f5b98c show_text=&7Görüntülemek için tıklayın run_command=/inventory %1% %2%) [[⌀ Ender Sandığı…]](#b649c4-#d254ff show_text=&7Görüntülemek için tıklayın run_command=/enderchest %1% %2%)'
-data_manager_management_buttons: '[Yönet:](gray) [[❌ Sil…]](#ff3300 show_text=&7Bu kullanıcı veri anlığını silmek için tıklayın.\n&8Bu, kullanıcının mevcut verilerini etkilemez.\nff3300&⚠ Geri alınamaz! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Geri Yükle…]](#00fb9a show_text=&7Bu kullanıcı verisini geri yüklemek için tıklayın.\n&8Bu, kullanıcının verisini bu anlığa ayarlar.\nff3300&⚠ %1%''nın mevcut verisi üzerine yazılacak! suggest_command=/husksync:userdata restore %1% %2%) [[※ Sabitle/Çöz…]](#d8ff2b show_text=&7Bu kullanıcı veri anlığını sabitlemek veya çözmek için tıklayın\n&8Sabitlenmiş anlıklar otomatik olarak döndürülmez run_command=/userdata pin %1% %2%)'
-data_manager_system_buttons: '[Sistem:](gray) [[⏷ Dosya Dök…]](dark_gray show_text=&7Bu ham kullanıcı veri anlığını bir dosyaya dökmek için tıklayın.\n&8Veri dökümleri ~/plugins/HuskSync/dumps/ klasöründe bulunabilir. run_command=/husksync:userdata dump %1% %2% file) [[☂ Web Dök…]](dark_gray show_text=&7Bu ham kullanıcı veri anlığını mc-logs servisine dökme için tıklayın\n&8Verileri içeren bir URL ile sağlanacaksınız. run_command=/husksync:userdata dump %1% %2% web)'
-data_manager_advancements_preview_remaining: 've %1% daha fazla…'
-data_list_title: '[%1%''ın kullanıcı veri anlıkları:](#00fb9a) [(%2%-%3% /](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
-data_list_item: '[%1%](gray show_text=&7Oyuncu Veri Anlığı %2% için %3%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Sabitlendi:\n&8Sabitlenmiş anlıklar otomatik olarak döndürülmez. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Versiyon zaman damgası:&7\n&8Verinin ne zaman kaydedildiği\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Kaydetme sebebi:\n&8Verinin kaydedilme nedeni run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Anlık boyutu:&7\n&8Anlının tahmini dosya boyutu (KiB cinsinden) run_command=/userdata view %2% %3%)'
-data_deleted: '[❌ Kullanıcı veri anlığı başarıyla silindi](#00fb9a) [%1%](#00fb9a show_text=&7Versiyon UUID:\n&8%2%) [için](#00fb9a) [%3%.](#00fb9a show_text=&7Oyuncu UUID:\n&8%4%)'
-data_restored: '[⏪ Başarıyla geri yüklendi](#00fb9a) [%1%](#00fb9a show_text=&7Oyuncu UUID:\n&8%2%)[''ın mevcut kullanıcı verisi anlığından](#00fb9a) [%3%.](#00fb9a show_text=&7Versiyon UUID:\n&8%4%)'
-data_pinned: '[※ Kullanıcı veri anlığı başarıyla sabitlendi](#00fb9a) [%1%](#00fb9a show_text=&7Versiyon UUID:\n&8%2%) [için](#00fb9a) [%3%.](#00fb9a show_text=&7Oyuncu UUID:\n&8%4%)'
-data_unpinned: '[※ Kullanıcı veri anlığı başarıyla çözüldü](#00fb9a) [%1%](#00fb9a show_text=&7Versiyon UUID:\n&8%2%) [için](#00fb9a) [%3%.](#00fb9a show_text=&7Oyuncu UUID:\n&8%4%)'
-data_dumped: '[☂ Kullanıcı veri anlığı başarıyla döküldü %1% için %2%:](#00fb9a) &7%3%'
-list_footer: '\n%1%[Sayfa](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
-list_previous_page_button: '[◀](white show_text=&7Önceki sayfayı görüntüle run_command=%2% %1%) '
-list_next_page_button: ' [▶](white show_text=&7Sonraki sayfayı görüntüle run_command=%2% %1%)'
-list_page_jumpers: '(%1%)'
-list_page_jumper_button: '[%1%](show_text=&7Sayfaya git %1% run_command=%2% %1%)'
-list_page_jumper_current_page: '[%1%](#00fb9a)'
-list_page_jumper_separator: ' '
-list_page_jumper_group_separator: '…'
-save_cause_disconnect: 'bağlantı kesilmesi'
-save_cause_world_save: 'dünya kaydı'
-save_cause_death: 'ölüm'
-save_cause_server_shutdown: 'sunucu kapatma'
-save_cause_inventory_command: 'envanter komutu'
-save_cause_enderchest_command: 'ender sandığı komutu'
-save_cause_backup_restore: 'yedek geri yükleme'
-save_cause_api: 'API'
-save_cause_mpdb_migration: 'MPDB migration'
-save_cause_legacy_migration: 'legacy migration'
-save_cause_converted_from_v2: 'v2 den dönüştürüldü'
-up_to_date: '[HuskSync](#00fb9a bold) [| HuskSync\''in en son sürümünü kullanıyorsunuz (v%1%).](#00fb9a)'
-update_available: '[HuskSync](#ff7e5e bold) [| HuskSync\''in yeni bir sürümü mevcut: v%1% (kullanılan sürüm: v%2%).](#ff7e5e)'
-reload_complete: '[HuskSync](#00fb9a bold) [| Yapılandırma ve mesaj dosyaları yeniden yüklendi.](#00fb9a)\n[⚠ Lütfen yapılandırma dosyalarının tüm sunucularda güncel olduğundan emin olun!](#00fb9a)\n[Yapılandırma değişikliklerinin etkili olabilmesi için bir yeniden başlatma gereklidir.](#00fb9a italic)'
-system_status_header: '[HuskSync](#00fb9a bold) [| Sistem durumu raporu:](#00fb9a)'
-error_invalid_syntax: '[Hata:](#ff3300) [Yanlış sözdizimi. Kullanım:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Öneri için tıklayın Suggest_command=%1%)'
-error_invalid_player: '[Hata:](#ff3300) [Bu isimde bir oyuncu bulunamadı.](#ff7e5e)'
-error_no_permission: '[Hata:](#ff3300) [Bu komutu gerçekleştirmek için izniniz yok](#ff7e5e)'
-error_console_command_only: '[Hata:](#ff3300) [Bu komut yalnızca konsoldan çalıştırılabilir](#ff7e5e)'
-error_in_game_command_only: 'Hata: Bu komut yalnızca oyun içinde kullanılabilir.'
-error_no_data_to_display: '[Hata:](#ff3300) [Görüntülenecek kullanıcı verisi bulunamadı.](#ff7e5e)'
-error_invalid_version_uuid: '[Hata:](#ff3300) [Bu sürüm UUID''si için kullanıcı verisi bulunamadı.](#ff7e5e)'
-husksync_command_description: 'HuskSync eklentisini yönet'
-userdata_command_description: 'Oyuncu verilerini görüntüle, yönet ve geri yükle'
-inventory_command_description: 'Oyuncunun envanterini görüntüle ve düzenle'
-enderchest_command_description: 'Oyuncunun Ender Chest''ini görüntüle ve düzenle'
+locales:
+ synchronization_complete: '[⏵ Veri senkronize edildi!](#00fb9a)'
+ synchronization_failed: '[⏵ Veriler senkronize edilemedi! Lütfen bir yönetici ile iletişime geçin.](#ff7e5e)'
+ inventory_viewer_menu_title: '&0%1%''ın Envanteri'
+ ender_chest_viewer_menu_title: '&0%1%''ın Ender Sandığı'
+ inventory_viewer_opened: '[Görüntülenen anlık](#00fb9a) [%1%](#00fb9a bold)[''ın envanteri ⌚ %2% tarihine kadar](#00fb9a)'
+ ender_chest_viewer_opened: '[Görüntülenen anlık](#00fb9a) [%1%](#00fb9a bold)[''ın Ender Sandığı ⌚ %2% tarihine kadar](#00fb9a)'
+ data_update_complete: '[🔔 Verileriniz güncellendi!](#00fb9a)'
+ data_update_failed: '[🔔 Verileriniz güncellenirken bir hata oluştu! Lütfen bir yönetici ile iletişime geçin.](#ff7e5e)'
+ user_registration_complete: '[⭐ Kullanıcı kaydı tamamlandı!](#00fb9a)'
+ data_manager_title: '[Kullanıcı veri anlık görünümü](#00fb9a) [%1%](#00fb9a show_text=&7Versiyon UUID:\n&8%2%) [için](#00fb9a) [%3%](#00fb9a bold show_text=&7Oyuncu UUID:\n&8%4%)[:](#00fb9a)'
+ data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Versiyon zaman damgası:\n&8Verinin ne zaman kaydedildiği)'
+ data_manager_pinned: '[※ Anlık sabitlendi](#d8ff2b show_text=&7Sabitlendi:\n&8Bu kullanıcı veri anlığı otomatik olarak döndürülmeyecek.)'
+ data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Kaydetme sebebi:\n&8Verinin kaydedilme nedeni)'
+ data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Sunucu:\n&8Verinin kaydedildiği sunucu adı)'
+ data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Anlık boyutu:\n&8Anlının tahmini dosya boyutu (KiB cinsinden))\n'
+ data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Can puanı) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Açlık puanı) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7XP seviyesi) [🏹 %5%](dark_aqua show_text=&7Oyun modu)'
+ data_manager_advancements_statistics: '[⭐ Gelişmeler: %1%](color=#ffc43b-#f5c962 show_text=&7Gelişmelerdeki ilerlemeniz:\n&8%2%) [⌛ Oynama Süresi: %3%s](color=#62a9f5-#7ab8fa show_text=&7Oyunda geçen süre\n&8⚠ Oyun içi istatistiklere dayanır)\n'
+ data_manager_item_buttons: '[Görünüm:](gray) [[🪣 Envanter…]](color=#a17b5f-#f5b98c show_text=&7Görüntülemek için tıklayın run_command=/inventory %1% %2%) [[⌀ Ender Sandığı…]](#b649c4-#d254ff show_text=&7Görüntülemek için tıklayın run_command=/enderchest %1% %2%)'
+ data_manager_management_buttons: '[Yönet:](gray) [[❌ Sil…]](#ff3300 show_text=&7Bu kullanıcı veri anlığını silmek için tıklayın.\n&8Bu, kullanıcının mevcut verilerini etkilemez.\nff3300&⚠ Geri alınamaz! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Geri Yükle…]](#00fb9a show_text=&7Bu kullanıcı verisini geri yüklemek için tıklayın.\n&8Bu, kullanıcının verisini bu anlığa ayarlar.\nff3300&⚠ %1%''nın mevcut verisi üzerine yazılacak! suggest_command=/husksync:userdata restore %1% %2%) [[※ Sabitle/Çöz…]](#d8ff2b show_text=&7Bu kullanıcı veri anlığını sabitlemek veya çözmek için tıklayın\n&8Sabitlenmiş anlıklar otomatik olarak döndürülmez run_command=/userdata pin %1% %2%)'
+ data_manager_system_buttons: '[Sistem:](gray) [[⏷ Dosya Dök…]](dark_gray show_text=&7Bu ham kullanıcı veri anlığını bir dosyaya dökmek için tıklayın.\n&8Veri dökümleri ~/plugins/HuskSync/dumps/ klasöründe bulunabilir. run_command=/husksync:userdata dump %1% %2% file) [[☂ Web Dök…]](dark_gray show_text=&7Bu ham kullanıcı veri anlığını mc-logs servisine dökme için tıklayın\n&8Verileri içeren bir URL ile sağlanacaksınız. run_command=/husksync:userdata dump %1% %2% web)'
+ data_manager_advancements_preview_remaining: 've %1% daha fazla…'
+ data_list_title: '[%1%''ın kullanıcı veri anlıkları:](#00fb9a) [(%2%-%3% /](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
+ data_list_item: '[%1%](gray show_text=&7Oyuncu Veri Anlığı %2% için %3%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Sabitlendi:\n&8Sabitlenmiş anlıklar otomatik olarak döndürülmez. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Versiyon zaman damgası:&7\n&8Verinin ne zaman kaydedildiği\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Kaydetme sebebi:\n&8Verinin kaydedilme nedeni run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Anlık boyutu:&7\n&8Anlının tahmini dosya boyutu (KiB cinsinden) run_command=/userdata view %2% %3%)'
+ data_deleted: '[❌ Kullanıcı veri anlığı başarıyla silindi](#00fb9a) [%1%](#00fb9a show_text=&7Versiyon UUID:\n&8%2%) [için](#00fb9a) [%3%.](#00fb9a show_text=&7Oyuncu UUID:\n&8%4%)'
+ data_restored: '[⏪ Başarıyla geri yüklendi](#00fb9a) [%1%](#00fb9a show_text=&7Oyuncu UUID:\n&8%2%)[''ın mevcut kullanıcı verisi anlığından](#00fb9a) [%3%.](#00fb9a show_text=&7Versiyon UUID:\n&8%4%)'
+ data_pinned: '[※ Kullanıcı veri anlığı başarıyla sabitlendi](#00fb9a) [%1%](#00fb9a show_text=&7Versiyon UUID:\n&8%2%) [için](#00fb9a) [%3%.](#00fb9a show_text=&7Oyuncu UUID:\n&8%4%)'
+ data_unpinned: '[※ Kullanıcı veri anlığı başarıyla çözüldü](#00fb9a) [%1%](#00fb9a show_text=&7Versiyon UUID:\n&8%2%) [için](#00fb9a) [%3%.](#00fb9a show_text=&7Oyuncu UUID:\n&8%4%)'
+ data_dumped: '[☂ Kullanıcı veri anlığı başarıyla döküldü %1% için %2%:](#00fb9a) &7%3%'
+ list_footer: '\n%1%[Sayfa](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
+ list_previous_page_button: '[◀](white show_text=&7Önceki sayfayı görüntüle run_command=%2% %1%) '
+ list_next_page_button: ' [▶](white show_text=&7Sonraki sayfayı görüntüle run_command=%2% %1%)'
+ list_page_jumpers: '(%1%)'
+ list_page_jumper_button: '[%1%](show_text=&7Sayfaya git %1% run_command=%2% %1%)'
+ list_page_jumper_current_page: '[%1%](#00fb9a)'
+ list_page_jumper_separator: ' '
+ list_page_jumper_group_separator: '…'
+ save_cause_disconnect: 'bağlantı kesilmesi'
+ save_cause_world_save: 'dünya kaydı'
+ save_cause_death: 'ölüm'
+ save_cause_server_shutdown: 'sunucu kapatma'
+ save_cause_inventory_command: 'envanter komutu'
+ save_cause_enderchest_command: 'ender sandığı komutu'
+ save_cause_backup_restore: 'yedek geri yükleme'
+ save_cause_api: 'API'
+ save_cause_mpdb_migration: 'MPDB migration'
+ save_cause_legacy_migration: 'legacy migration'
+ save_cause_converted_from_v2: 'v2 den dönüştürüldü'
+ up_to_date: '[HuskSync](#00fb9a bold) [| HuskSync\''in en son sürümünü kullanıyorsunuz (v%1%).](#00fb9a)'
+ update_available: '[HuskSync](#ff7e5e bold) [| HuskSync\''in yeni bir sürümü mevcut: v%1% (kullanılan sürüm: v%2%).](#ff7e5e)'
+ reload_complete: '[HuskSync](#00fb9a bold) [| Yapılandırma ve mesaj dosyaları yeniden yüklendi.](#00fb9a)\n[⚠ Lütfen yapılandırma dosyalarının tüm sunucularda güncel olduğundan emin olun!](#00fb9a)\n[Yapılandırma değişikliklerinin etkili olabilmesi için bir yeniden başlatma gereklidir.](#00fb9a italic)'
+ system_status_header: '[HuskSync](#00fb9a bold) [| Sistem durumu raporu:](#00fb9a)'
+ error_invalid_syntax: '[Hata:](#ff3300) [Yanlış sözdizimi. Kullanım:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Öneri için tıklayın Suggest_command=%1%)'
+ error_invalid_player: '[Hata:](#ff3300) [Bu isimde bir oyuncu bulunamadı.](#ff7e5e)'
+ error_no_permission: '[Hata:](#ff3300) [Bu komutu gerçekleştirmek için izniniz yok](#ff7e5e)'
+ error_console_command_only: '[Hata:](#ff3300) [Bu komut yalnızca konsoldan çalıştırılabilir](#ff7e5e)'
+ error_in_game_command_only: 'Hata: Bu komut yalnızca oyun içinde kullanılabilir.'
+ error_no_data_to_display: '[Hata:](#ff3300) [Görüntülenecek kullanıcı verisi bulunamadı.](#ff7e5e)'
+ error_invalid_version_uuid: '[Hata:](#ff3300) [Bu sürüm UUID''si için kullanıcı verisi bulunamadı.](#ff7e5e)'
+ husksync_command_description: 'HuskSync eklentisini yönet'
+ userdata_command_description: 'Oyuncu verilerini görüntüle, yönet ve geri yükle'
+ inventory_command_description: 'Oyuncunun envanterini görüntüle ve düzenle'
+ enderchest_command_description: 'Oyuncunun Ender Chest''ini görüntüle ve düzenle'
diff --git a/common/src/main/resources/locales/uk-ua.yml b/common/src/main/resources/locales/uk-ua.yml
index 00eeb76b..a13307ee 100644
--- a/common/src/main/resources/locales/uk-ua.yml
+++ b/common/src/main/resources/locales/uk-ua.yml
@@ -1,62 +1,63 @@
-synchronization_complete: '[⏵ Дані синхронізовано!](#00fb9a)'
-synchronization_failed: '[⏵ Failed to synchronize your data! Please contact an administrator.](#ff7e5e)'
-inventory_viewer_menu_title: '&0%1%''s Inventory'
-ender_chest_viewer_menu_title: '&0%1%''s Ender Chest'
-inventory_viewer_opened: '[Viewing snapshot of](#00fb9a) [%1%](#00fb9a bold)[''s inventory as of ⌚ %2%](#00fb9a)'
-ender_chest_viewer_opened: '[Viewing snapshot of](#00fb9a) [%1%](#00fb9a bold)[''s Ender Chest as of ⌚ %2%](#00fb9a)'
-data_update_complete: '[🔔 Your data has been updated!](#00fb9a)'
-data_update_failed: '[🔔 Failed to update your data! Please contact an administrator.](#ff7e5e)'
-user_registration_complete: '[⭐ User registration complete!](#00fb9a)'
-data_manager_title: '[Viewing user data snapshot](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%](#00fb9a bold show_text=&7Player UUID:\n&8%4%)[:](#00fb9a)'
-data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Version timestamp:\n&8When the data was saved)'
-data_manager_pinned: '[※ Snapshot pinned](#d8ff2b show_text=&7Pinned:\n&8This user data snapshot won''t be automatically rotated.)'
-data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Save cause:\n&8What caused the data to be saved)'
-data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name of the server the data was saved on)'
-data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:\n&8Estimated file size of the snapshot (in KiB))\n'
-data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Health points) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Hunger points) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7XP level) [🏹 %5%](dark_aqua show_text=&7Game mode)'
-data_manager_advancements_statistics: '[⭐ Advancements: %1%](color=#ffc43b-#f5c962 show_text=&7Advancements you have progress in:\n&8%2%) [⌛ Play Time: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7In-game play time\n&8⚠ Based on in-game statistics)\n'
-data_manager_item_buttons: '[View:](gray) [[🪣 Inventory…]](color=#a17b5f-#f5b98c show_text=&7Click to view run_command=/inventory %1% %2%) [[⌀ Ender Chest…]](#b649c4-#d254ff show_text=&7Click to view run_command=/enderchest %1% %2%)'
-data_manager_management_buttons: '[Manage:](gray) [[❌ Delete…]](#ff3300 show_text=&7Click to delete this snapshot of user data.\n&8This will not affect the user''s current data.\nff3300&⚠ This cannot be undone! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Restore…]](#00fb9a show_text=&7Click to restore this user data.\n&8This will set the user''s data to this snapshot.\nff3300&⚠ %1%''s current data will be overwritten! suggest_command=/husksync:userdata restore %1% %2%) [[※ Pin/Unpin…]](#d8ff2b show_text=&7Click to pin or unpin this user data snapshot\n&8Pinned snapshots won''t be automatically rotated run_command=/userdata pin %1% %2%)'
-data_manager_system_buttons: '[System:](gray) [[⏷ File Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to a file.\n&8Data dumps can be found in ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ Web Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to the mc-logs service\n&8You will be provided with a URL containing the data. run_command=/husksync:userdata dump %1% %2% web)'
-data_manager_advancements_preview_remaining: 'and %1% more…'
-data_list_title: '[%1%''s user data snapshots:](#00fb9a) [(%2%-%3% of](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
-data_list_item: '[%1%](gray show_text=&7User Data Snapshot for %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Pinned:\n&8Pinned snapshots won''t be automatically rotated. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Version timestamp:&7\n&8When the data was saved\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Save cause:\n&8What caused the data to be saved run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:&7\n&8Estimated file size of the snapshot (in KiB) run_command=/userdata view %2% %3%)'
-data_deleted: '[❌ Successfully deleted user data snapshot](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
-data_restored: '[⏪ Successfully restored](#00fb9a) [%1%](#00fb9a show_text=&7Player UUID:\n&8%2%)[''s current user data from snapshot](#00fb9a) [%3%.](#00fb9a show_text=&7Version UUID:\n&8%4%)'
-data_pinned: '[※ Successfully pinned user data snapshot](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
-data_unpinned: '[※ Successfully unpinned user data snapshot](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
-data_dumped: '[☂ Successfully dumped the user data snapshot %1% for %2% to:](#00fb9a) &7%3%'
-list_footer: '\n%1%[Page](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
-list_previous_page_button: '[◀](white show_text=&7View previous page run_command=%2% %1%) '
-list_next_page_button: ' [▶](white show_text=&7View next page run_command=%2% %1%)'
-list_page_jumpers: '(%1%)'
-list_page_jumper_button: '[%1%](show_text=&7Jump to page %1% run_command=%2% %1%)'
-list_page_jumper_current_page: '[%1%](#00fb9a)'
-list_page_jumper_separator: ' '
-list_page_jumper_group_separator: '…'
-save_cause_disconnect: 'disconnect'
-save_cause_world_save: 'world save'
-save_cause_death: 'death'
-save_cause_server_shutdown: 'server shutdown'
-save_cause_inventory_command: 'inventory command'
-save_cause_enderchest_command: 'enderchest command'
-save_cause_backup_restore: 'backup restore'
-save_cause_api: 'API'
-save_cause_mpdb_migration: 'MPDB migration'
-save_cause_legacy_migration: 'legacy migration'
-save_cause_converted_from_v2: 'converted from v2'
-up_to_date: '[HuskSync](#00fb9a bold) [| You are running the latest version of HuskSync (v%1%).](#00fb9a)'
-update_available: '[HuskSync](#ff7e5e bold) [| A new version of HuskSync is available: v%1% (running: v%2%).](#ff7e5e)'
-reload_complete: '[HuskSync](#00fb9a bold) [| Перезавантажено конфіґ та файли повідомлень.](#00fb9a)\n[⚠ Ensure config files are up-to-date on all servers!](#00fb9a)\n[A restart is needed for config changes to take effect.](#00fb9a italic)'
-system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
-error_invalid_syntax: '[Помилка:](#ff3300) [Неправильний синтакс. Використання:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
-error_invalid_player: '[Помилка:](#ff3300) [Гравця не знайдено](#ff7e5e)'
-error_no_permission: '[Помилка:](#ff3300) [Ввас немає дозволу на використання цієї команди](#ff7e5e)'
-error_console_command_only: '[Помилка:](#ff3300) [Ця команда може бути використана лише з допомогою %1% консолі](#ff7e5e)'
-error_in_game_command_only: 'Error: That command can only be used in-game.'
-error_no_data_to_display: '[Error:](#ff3300) [Could not find any user data to display.](#ff7e5e)'
-error_invalid_version_uuid: '[Error:](#ff3300) [Could not find any user data for that version UUID.](#ff7e5e)'
-husksync_command_description: 'Manage the HuskSync plugin'
-userdata_command_description: 'View, manage & restore player userdata'
-inventory_command_description: 'View & edit a player''s inventory'
-enderchest_command_description: 'View & edit a player''s Ender Chest'
\ No newline at end of file
+locales:
+ synchronization_complete: '[⏵ Дані синхронізовано!](#00fb9a)'
+ synchronization_failed: '[⏵ Failed to synchronize your data! Please contact an administrator.](#ff7e5e)'
+ inventory_viewer_menu_title: '&0%1%''s Inventory'
+ ender_chest_viewer_menu_title: '&0%1%''s Ender Chest'
+ inventory_viewer_opened: '[Viewing snapshot of](#00fb9a) [%1%](#00fb9a bold)[''s inventory as of ⌚ %2%](#00fb9a)'
+ ender_chest_viewer_opened: '[Viewing snapshot of](#00fb9a) [%1%](#00fb9a bold)[''s Ender Chest as of ⌚ %2%](#00fb9a)'
+ data_update_complete: '[🔔 Your data has been updated!](#00fb9a)'
+ data_update_failed: '[🔔 Failed to update your data! Please contact an administrator.](#ff7e5e)'
+ user_registration_complete: '[⭐ User registration complete!](#00fb9a)'
+ data_manager_title: '[Viewing user data snapshot](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%](#00fb9a bold show_text=&7Player UUID:\n&8%4%)[:](#00fb9a)'
+ data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7Version timestamp:\n&8When the data was saved)'
+ data_manager_pinned: '[※ Snapshot pinned](#d8ff2b show_text=&7Pinned:\n&8This user data snapshot won''t be automatically rotated.)'
+ data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7Save cause:\n&8What caused the data to be saved)'
+ data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name of the server the data was saved on)'
+ data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:\n&8Estimated file size of the snapshot (in KiB))\n'
+ data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7Health points) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7Hunger points) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7XP level) [🏹 %5%](dark_aqua show_text=&7Game mode)'
+ data_manager_advancements_statistics: '[⭐ Advancements: %1%](color=#ffc43b-#f5c962 show_text=&7Advancements you have progress in:\n&8%2%) [⌛ Play Time: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7In-game play time\n&8⚠ Based on in-game statistics)\n'
+ data_manager_item_buttons: '[View:](gray) [[🪣 Inventory…]](color=#a17b5f-#f5b98c show_text=&7Click to view run_command=/inventory %1% %2%) [[⌀ Ender Chest…]](#b649c4-#d254ff show_text=&7Click to view run_command=/enderchest %1% %2%)'
+ data_manager_management_buttons: '[Manage:](gray) [[❌ Delete…]](#ff3300 show_text=&7Click to delete this snapshot of user data.\n&8This will not affect the user''s current data.\nff3300&⚠ This cannot be undone! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ Restore…]](#00fb9a show_text=&7Click to restore this user data.\n&8This will set the user''s data to this snapshot.\nff3300&⚠ %1%''s current data will be overwritten! suggest_command=/husksync:userdata restore %1% %2%) [[※ Pin/Unpin…]](#d8ff2b show_text=&7Click to pin or unpin this user data snapshot\n&8Pinned snapshots won''t be automatically rotated run_command=/userdata pin %1% %2%)'
+ data_manager_system_buttons: '[System:](gray) [[⏷ File Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to a file.\n&8Data dumps can be found in ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ Web Dump…]](dark_gray show_text=&7Click to dump this raw user data snapshot to the mc-logs service\n&8You will be provided with a URL containing the data. run_command=/husksync:userdata dump %1% %2% web)'
+ data_manager_advancements_preview_remaining: 'and %1% more…'
+ data_list_title: '[%1%''s user data snapshots:](#00fb9a) [(%2%-%3% of](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
+ data_list_item: '[%1%](gray show_text=&7User Data Snapshot for %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Pinned:\n&8Pinned snapshots won''t be automatically rotated. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Version timestamp:&7\n&8When the data was saved\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Save cause:\n&8What caused the data to be saved run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:&7\n&8Estimated file size of the snapshot (in KiB) run_command=/userdata view %2% %3%)'
+ data_deleted: '[❌ Successfully deleted user data snapshot](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
+ data_restored: '[⏪ Successfully restored](#00fb9a) [%1%](#00fb9a show_text=&7Player UUID:\n&8%2%)[''s current user data from snapshot](#00fb9a) [%3%.](#00fb9a show_text=&7Version UUID:\n&8%4%)'
+ data_pinned: '[※ Successfully pinned user data snapshot](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
+ data_unpinned: '[※ Successfully unpinned user data snapshot](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [for](#00fb9a) [%3%.](#00fb9a show_text=&7Player UUID:\n&8%4%)'
+ data_dumped: '[☂ Successfully dumped the user data snapshot %1% for %2% to:](#00fb9a) &7%3%'
+ list_footer: '\n%1%[Page](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
+ list_previous_page_button: '[◀](white show_text=&7View previous page run_command=%2% %1%) '
+ list_next_page_button: ' [▶](white show_text=&7View next page run_command=%2% %1%)'
+ list_page_jumpers: '(%1%)'
+ list_page_jumper_button: '[%1%](show_text=&7Jump to page %1% run_command=%2% %1%)'
+ list_page_jumper_current_page: '[%1%](#00fb9a)'
+ list_page_jumper_separator: ' '
+ list_page_jumper_group_separator: '…'
+ save_cause_disconnect: 'disconnect'
+ save_cause_world_save: 'world save'
+ save_cause_death: 'death'
+ save_cause_server_shutdown: 'server shutdown'
+ save_cause_inventory_command: 'inventory command'
+ save_cause_enderchest_command: 'enderchest command'
+ save_cause_backup_restore: 'backup restore'
+ save_cause_api: 'API'
+ save_cause_mpdb_migration: 'MPDB migration'
+ save_cause_legacy_migration: 'legacy migration'
+ save_cause_converted_from_v2: 'converted from v2'
+ up_to_date: '[HuskSync](#00fb9a bold) [| You are running the latest version of HuskSync (v%1%).](#00fb9a)'
+ update_available: '[HuskSync](#ff7e5e bold) [| A new version of HuskSync is available: v%1% (running: v%2%).](#ff7e5e)'
+ reload_complete: '[HuskSync](#00fb9a bold) [| Перезавантажено конфіґ та файли повідомлень.](#00fb9a)\n[⚠ Ensure config files are up-to-date on all servers!](#00fb9a)\n[A restart is needed for config changes to take effect.](#00fb9a italic)'
+ system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
+ error_invalid_syntax: '[Помилка:](#ff3300) [Неправильний синтакс. Використання:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
+ error_invalid_player: '[Помилка:](#ff3300) [Гравця не знайдено](#ff7e5e)'
+ error_no_permission: '[Помилка:](#ff3300) [Ввас немає дозволу на використання цієї команди](#ff7e5e)'
+ error_console_command_only: '[Помилка:](#ff3300) [Ця команда може бути використана лише з допомогою %1% консолі](#ff7e5e)'
+ error_in_game_command_only: 'Error: That command can only be used in-game.'
+ error_no_data_to_display: '[Error:](#ff3300) [Could not find any user data to display.](#ff7e5e)'
+ error_invalid_version_uuid: '[Error:](#ff3300) [Could not find any user data for that version UUID.](#ff7e5e)'
+ husksync_command_description: 'Manage the HuskSync plugin'
+ userdata_command_description: 'View, manage & restore player userdata'
+ inventory_command_description: 'View & edit a player''s inventory'
+ enderchest_command_description: 'View & edit a player''s Ender Chest'
\ No newline at end of file
diff --git a/common/src/main/resources/locales/zh-cn.yml b/common/src/main/resources/locales/zh-cn.yml
index e5b98bf4..f51eab08 100644
--- a/common/src/main/resources/locales/zh-cn.yml
+++ b/common/src/main/resources/locales/zh-cn.yml
@@ -1,62 +1,63 @@
-synchronization_complete: '[⏵ 数据同步完成!](#00fb9a)'
-synchronization_failed: '[⏵ 无法同步你的数据! 请联系管理员.](#ff7e5e)'
-inventory_viewer_menu_title: '&0%1% 的背包'
-ender_chest_viewer_menu_title: '&0%1% 的末影箱'
-inventory_viewer_opened: '[查看备份](#00fb9a) [%1%](#00fb9a bold) [于 ⌚ %2% 的背包备份](#00fb9a)'
-ender_chest_viewer_opened: '[查看备份](#00fb9a) [%1%](#00fb9a bold) [于 ⌚ %2% 的末影箱备份](#00fb9a)'
-data_update_complete: '[🔔 你的数据已更新!](#00fb9a)'
-data_update_failed: '[🔔 无法更新你的数据! 请联系管理员.](#ff7e5e)'
-user_registration_complete: '[⭐ 用户注册完成!](#00fb9a)'
-data_manager_title: '[正在查看玩家](#00fb9a) [%3%](#00fb9a bold show_text=&7玩家UUID:\n&8%4%) [的数据备份](#00fb9a) [%1%](#00fb9a show_text=&7备份版本UUID:\n&8%2%)[:](#00fb9a)'
-data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7备份时间:\n&8数据保存时间)'
-data_manager_pinned: '[※ 置顶备份](#d8ff2b show_text=&7已置顶:\n&8此玩家数据备份不会按照备份时间自动排序.)'
-data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7保存原因:\n&8导致数据保存的原因)'
-data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7服务器:\n&8数据保存所在服务器的名称)'
-data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7备份大小:\n&8预计备份的文件大小(以KiB为单位))\n'
-data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7生命值) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7饥饿值) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7经验等级) [🏹 %5%](dark_aqua show_text=&7游戏模式)'
-data_manager_advancements_statistics: '[⭐ 进度: %1%](color=#ffc43b-#f5c962 show_text=&7你已经取得的进度:\n&8%2%) [⌛ 游玩时间: %3%小时](color=#62a9f5-#7ab8fa show_text=&7在游戏内游玩的时间\n&8⚠ 基于游戏内的统计信息)\n'
-data_manager_item_buttons: '[查看:](gray) [[🪣 背包…]](color=#a17b5f-#f5b98c show_text=&7点击查看 run_command=/inventory %1% %2%) [[⌀ 末影箱…]](#b649c4-#d254ff show_text=&7点击查看 run_command=/enderchest %1% %2%)'
-data_manager_management_buttons: '[管理:](gray) [[❌ 删除…]](#ff3300 show_text=&7点击删除此玩家数据备份.\n&8这不会影响用户的当前数据.\nff3300&⚠ 此操作无法撤消! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ 恢复…]](#00fb9a show_text=&7点击还原此玩家数据.\n&8这将使用户的数据恢复到此备份.\nff3300&⚠ %1%当前数据将被覆盖! suggest_command=/husksync:userdata restore %1% %2%) [[※ 置顶/取消置顶…]](#d8ff2b show_text=&7点击置顶或取消置顶此玩家数据备份\n&8已置顶的备份不会按照备份时间自动排序 run_command=/userdata pin %1% %2%)'
-data_manager_system_buttons: '[系统:](gray) [[⏷ 文件转储…]](dark_gray show_text=&7点击将此原始玩家数据备份转储到文件中.\n&8数据转储可以在~/plugins/HuskSync/dumps/中找到 run_command=/husksync:userdata dump %1% %2% file) [[☂ 网络转储…]](dark_gray show_text=&7点击将此原始玩家数据备份转储到mc-logs服务中\n&8你将获得包含数据的网址. run_command=/husksync:userdata dump %1% %2% web)'
-data_manager_advancements_preview_remaining: '以及其他 %1%…'
-data_list_title: '[%1%的玩家数据备份:](#00fb9a) [(%2%-%3% of](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
-data_list_item: '[%1%](gray show_text=&7玩家数据备份 %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7已置顶:\n&8已置顶的备份不会按照备份时间自动排序 run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7备份时间:&7\n&8数据保存时间\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7保存原因:\n&8导致数据保存的原因 run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7备份大小:&7\n&8预计备份文件大小(以KiB为单位) run_command=/userdata view %2% %3%)'
-data_deleted: '[❌ 成功删除玩家](#00fb9a) [%3%](#00fb9a show_text=&7玩家 UUID:\n&7%4%) [的数据备份](#00fb9a) [%1%.](#00fb9a show_text=&7备份版本UUID:\n&7%2%)'
-data_restored: '[⏪ 成功恢复玩家](#00fb9a) [%1%](#00fb9a show_text=&7玩家 UUID:\n&7%2%)[的数据备份](#00fb9a) [%3%.](#00fb9a show_text=&7备份版本UUID:\n&7%4%)'
-data_pinned: '[※ 成功置顶玩家](#00fb9a) [%3%](#00fb9a show_text=&7玩家 UUID:\n&8%4%) [的数据备份](#00fb9a) [%1%.](#00fb9a show_text=&7备份版本UUID:\n&8%2%)'
-data_unpinned: '[※ 成功取消置顶玩家](#00fb9a) [%3%](#00fb9a show_text=&7玩家 UUID:\n&8%4%) [的数据备份](#00fb9a) [%1%.](#00fb9a show_text=&7备份版本UUID:\n&8%2%)'
-data_dumped: '[☂ 已成功将 %1% 的玩家数据快照 %2% 转储到:](#00fb9a) &7%3%'
-list_footer: '\n%1%[页数](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
-list_previous_page_button: '[◀](white show_text=&7查看上一页 run_command=%2% %1%) '
-list_next_page_button: ' [▶](white show_text=&7查看下一页 run_command=%2% %1%)'
-list_page_jumpers: '(%1%)'
-list_page_jumper_button: '[%1%](show_text=&7跳转至第 %1% 页 run_command=%2% %1%)'
-list_page_jumper_current_page: '[%1%](#00fb9a)'
-list_page_jumper_separator: ' '
-list_page_jumper_group_separator: '…'
-save_cause_disconnect: '断开连接'
-save_cause_world_save: '保存世界'
-save_cause_death: '死亡'
-save_cause_server_shutdown: '服务器关闭'
-save_cause_inventory_command: '背包命令'
-save_cause_enderchest_command: '末影箱命令'
-save_cause_backup_restore: '备份还原'
-save_cause_api: 'API'
-save_cause_mpdb_migration: 'MPDB迁移'
-save_cause_legacy_migration: '旧版迁移'
-save_cause_converted_from_v2: '从v2转换'
-up_to_date: '[HuskSync](#00fb9a bold) [| 你正在运行最新版本的HuskSync(v%1%).](#00fb9a)'
-update_available: '[HuskSync](#ff7e5e bold) [| 检测到HuskSync有新版本可以更新了:v%1%(当前版本:v%2%).](#ff7e5e)'
-reload_complete: '[HuskSync](#00fb9a bold) [| 重新加载配置和消息文件完成.](#00fb9a)\n[⚠ 确保在所有服务器上更新配置文件!](#00fb9a)\n[需要重新启动才能使配置更改生效.](#00fb9a italic)'
-system_status_header: '[HuskSync](#00fb9a bold) [| 系统状态报告:](#00fb9a)'
-error_invalid_syntax: '[错误:](#ff3300) [语法错误.用法:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&点击建议 suggest_command=%1%)'
-error_invalid_player: '[错误:](#ff3300) [找不到这个名称的玩家.](#ff7e5e)'
-error_no_permission: '[错误:](#ff3300) [你没有执行此命令的权限](#ff7e5e)'
-error_console_command_only: '[错误:](#ff3300) [该命令只能在控制台中运行](#ff7e5e)'
-error_in_game_command_only: '错误: 该命令只能在游戏中使用.'
-error_no_data_to_display: '[错误:](#ff3300) [找不到要显示的任何玩家数据.](#ff7e5e)'
-error_invalid_version_uuid: '[错误:](#ff3300) [找不到该版本UUID的任何玩家数据.](#ff7e5e)'
-husksync_command_description: '管理HuskSync插件'
-userdata_command_description: '查看、管理和还原玩家玩家数据'
-inventory_command_description: '查看和编辑玩家的背包'
-enderchest_command_description: '查看和编辑玩家的末影箱'
+locales:
+ synchronization_complete: '[⏵ 数据同步完成!](#00fb9a)'
+ synchronization_failed: '[⏵ 无法同步你的数据! 请联系管理员.](#ff7e5e)'
+ inventory_viewer_menu_title: '&0%1% 的背包'
+ ender_chest_viewer_menu_title: '&0%1% 的末影箱'
+ inventory_viewer_opened: '[查看备份](#00fb9a) [%1%](#00fb9a bold) [于 ⌚ %2% 的背包备份](#00fb9a)'
+ ender_chest_viewer_opened: '[查看备份](#00fb9a) [%1%](#00fb9a bold) [于 ⌚ %2% 的末影箱备份](#00fb9a)'
+ data_update_complete: '[🔔 你的数据已更新!](#00fb9a)'
+ data_update_failed: '[🔔 无法更新你的数据! 请联系管理员.](#ff7e5e)'
+ user_registration_complete: '[⭐ 用户注册完成!](#00fb9a)'
+ data_manager_title: '[正在查看玩家](#00fb9a) [%3%](#00fb9a bold show_text=&7玩家UUID:\n&8%4%) [的数据备份](#00fb9a) [%1%](#00fb9a show_text=&7备份版本UUID:\n&8%2%)[:](#00fb9a)'
+ data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7备份时间:\n&8数据保存时间)'
+ data_manager_pinned: '[※ 置顶备份](#d8ff2b show_text=&7已置顶:\n&8此玩家数据备份不会按照备份时间自动排序.)'
+ data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7保存原因:\n&8导致数据保存的原因)'
+ data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7服务器:\n&8数据保存所在服务器的名称)'
+ data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7备份大小:\n&8预计备份的文件大小(以KiB为单位))\n'
+ data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7生命值) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7饥饿值) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7经验等级) [🏹 %5%](dark_aqua show_text=&7游戏模式)'
+ data_manager_advancements_statistics: '[⭐ 进度: %1%](color=#ffc43b-#f5c962 show_text=&7你已经取得的进度:\n&8%2%) [⌛ 游玩时间: %3%小时](color=#62a9f5-#7ab8fa show_text=&7在游戏内游玩的时间\n&8⚠ 基于游戏内的统计信息)\n'
+ data_manager_item_buttons: '[查看:](gray) [[🪣 背包…]](color=#a17b5f-#f5b98c show_text=&7点击查看 run_command=/inventory %1% %2%) [[⌀ 末影箱…]](#b649c4-#d254ff show_text=&7点击查看 run_command=/enderchest %1% %2%)'
+ data_manager_management_buttons: '[管理:](gray) [[❌ 删除…]](#ff3300 show_text=&7点击删除此玩家数据备份.\n&8这不会影响用户的当前数据.\nff3300&⚠ 此操作无法撤消! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ 恢复…]](#00fb9a show_text=&7点击还原此玩家数据.\n&8这将使用户的数据恢复到此备份.\nff3300&⚠ %1%当前数据将被覆盖! suggest_command=/husksync:userdata restore %1% %2%) [[※ 置顶/取消置顶…]](#d8ff2b show_text=&7点击置顶或取消置顶此玩家数据备份\n&8已置顶的备份不会按照备份时间自动排序 run_command=/userdata pin %1% %2%)'
+ data_manager_system_buttons: '[系统:](gray) [[⏷ 文件转储…]](dark_gray show_text=&7点击将此原始玩家数据备份转储到文件中.\n&8数据转储可以在~/plugins/HuskSync/dumps/中找到 run_command=/husksync:userdata dump %1% %2% file) [[☂ 网络转储…]](dark_gray show_text=&7点击将此原始玩家数据备份转储到mc-logs服务中\n&8你将获得包含数据的网址. run_command=/husksync:userdata dump %1% %2% web)'
+ data_manager_advancements_preview_remaining: '以及其他 %1%…'
+ data_list_title: '[%1%的玩家数据备份:](#00fb9a) [(%2%-%3% of](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
+ data_list_item: '[%1%](gray show_text=&7玩家数据备份 %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7已置顶:\n&8已置顶的备份不会按照备份时间自动排序 run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7备份时间:&7\n&8数据保存时间\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7保存原因:\n&8导致数据保存的原因 run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7备份大小:&7\n&8预计备份文件大小(以KiB为单位) run_command=/userdata view %2% %3%)'
+ data_deleted: '[❌ 成功删除玩家](#00fb9a) [%3%](#00fb9a show_text=&7玩家 UUID:\n&7%4%) [的数据备份](#00fb9a) [%1%.](#00fb9a show_text=&7备份版本UUID:\n&7%2%)'
+ data_restored: '[⏪ 成功恢复玩家](#00fb9a) [%1%](#00fb9a show_text=&7玩家 UUID:\n&7%2%)[的数据备份](#00fb9a) [%3%.](#00fb9a show_text=&7备份版本UUID:\n&7%4%)'
+ data_pinned: '[※ 成功置顶玩家](#00fb9a) [%3%](#00fb9a show_text=&7玩家 UUID:\n&8%4%) [的数据备份](#00fb9a) [%1%.](#00fb9a show_text=&7备份版本UUID:\n&8%2%)'
+ data_unpinned: '[※ 成功取消置顶玩家](#00fb9a) [%3%](#00fb9a show_text=&7玩家 UUID:\n&8%4%) [的数据备份](#00fb9a) [%1%.](#00fb9a show_text=&7备份版本UUID:\n&8%2%)'
+ data_dumped: '[☂ 已成功将 %1% 的玩家数据快照 %2% 转储到:](#00fb9a) &7%3%'
+ list_footer: '\n%1%[页数](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
+ list_previous_page_button: '[◀](white show_text=&7查看上一页 run_command=%2% %1%) '
+ list_next_page_button: ' [▶](white show_text=&7查看下一页 run_command=%2% %1%)'
+ list_page_jumpers: '(%1%)'
+ list_page_jumper_button: '[%1%](show_text=&7跳转至第 %1% 页 run_command=%2% %1%)'
+ list_page_jumper_current_page: '[%1%](#00fb9a)'
+ list_page_jumper_separator: ' '
+ list_page_jumper_group_separator: '…'
+ save_cause_disconnect: '断开连接'
+ save_cause_world_save: '保存世界'
+ save_cause_death: '死亡'
+ save_cause_server_shutdown: '服务器关闭'
+ save_cause_inventory_command: '背包命令'
+ save_cause_enderchest_command: '末影箱命令'
+ save_cause_backup_restore: '备份还原'
+ save_cause_api: 'API'
+ save_cause_mpdb_migration: 'MPDB迁移'
+ save_cause_legacy_migration: '旧版迁移'
+ save_cause_converted_from_v2: '从v2转换'
+ up_to_date: '[HuskSync](#00fb9a bold) [| 你正在运行最新版本的HuskSync(v%1%).](#00fb9a)'
+ update_available: '[HuskSync](#ff7e5e bold) [| 检测到HuskSync有新版本可以更新了:v%1%(当前版本:v%2%).](#ff7e5e)'
+ reload_complete: '[HuskSync](#00fb9a bold) [| 重新加载配置和消息文件完成.](#00fb9a)\n[⚠ 确保在所有服务器上更新配置文件!](#00fb9a)\n[需要重新启动才能使配置更改生效.](#00fb9a italic)'
+ system_status_header: '[HuskSync](#00fb9a bold) [| 系统状态报告:](#00fb9a)'
+ error_invalid_syntax: '[错误:](#ff3300) [语法错误.用法:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&点击建议 suggest_command=%1%)'
+ error_invalid_player: '[错误:](#ff3300) [找不到这个名称的玩家.](#ff7e5e)'
+ error_no_permission: '[错误:](#ff3300) [你没有执行此命令的权限](#ff7e5e)'
+ error_console_command_only: '[错误:](#ff3300) [该命令只能在控制台中运行](#ff7e5e)'
+ error_in_game_command_only: '错误: 该命令只能在游戏中使用.'
+ error_no_data_to_display: '[错误:](#ff3300) [找不到要显示的任何玩家数据.](#ff7e5e)'
+ error_invalid_version_uuid: '[错误:](#ff3300) [找不到该版本UUID的任何玩家数据.](#ff7e5e)'
+ husksync_command_description: '管理HuskSync插件'
+ userdata_command_description: '查看、管理和还原玩家玩家数据'
+ inventory_command_description: '查看和编辑玩家的背包'
+ enderchest_command_description: '查看和编辑玩家的末影箱'
\ No newline at end of file
diff --git a/common/src/main/resources/locales/zh-tw.yml b/common/src/main/resources/locales/zh-tw.yml
index 54f0956f..97401afa 100644
--- a/common/src/main/resources/locales/zh-tw.yml
+++ b/common/src/main/resources/locales/zh-tw.yml
@@ -1,62 +1,63 @@
-synchronization_complete: '[⏵資料已同步!](#00fb9a)'
-synchronization_failed: '[⏵ 無法同步您的資料! 請聯繫管理員](#ff7e5e)'
-inventory_viewer_menu_title: '&0%1% 的背包'
-ender_chest_viewer_menu_title: '&0%1% 的終界箱'
-inventory_viewer_opened: '[查看](#00fb9a) [%1%](#00fb9a bold) [於 ⌚ %2% 的背包快照資料](#00fb9a)'
-ender_chest_viewer_opened: '[查看](#00fb9a) [%1%](#00fb9a bold) [於 ⌚ %2% 的終界箱快照資料](#00fb9a)'
-data_update_complete: '[🔔 你的資料已更新!](#00fb9a)'
-data_update_failed: '[🔔 無法更新您的資料! 請聯繫管理員](#ff7e5e)'
-user_registration_complete: '[⭐ User registration complete!](#00fb9a)'
-data_manager_title: '[查看](#00fb9a) [%3%](#00fb9a bold show_text=&7玩家 UUID:\n&8%4%) [的快照:](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [:](#00fb9a)'
-data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7快照時間:\n&8何時保存的資料)'
-data_manager_pinned: '[※ 被標記的快照](#d8ff2b show_text=&7標記:\n&8此快照資料不會自動輪換更新)'
-data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7保存原因:\n&8保存此快照的原因)'
-data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name of the server the data was saved on)'
-data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:\n&8Estimated file size of the snapshot (in KiB))\n'
-data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7血量) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7飽食度) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7經驗等級) [🏹 %5%](dark_aqua show_text=&7遊戲模式)'
-data_manager_advancements_statistics: '[⭐ 成就: %1%](color=#ffc43b-#f5c962 show_text=&7已獲得的成就:\n&8%2%) [⌛ 遊戲時間: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7遊戲內的遊玩時間\n&8⚠ 根據遊戲內統計)\n'
-data_manager_item_buttons: '[查看:](gray) [[🪣 背包…]](color=#a17b5f-#f5b98c show_text=&7點擊查看 run_command=/inventory %1% %2%) [[⌀ 終界箱…]](#b649c4-#d254ff show_text=&7點擊查看 run_command=/enderchest %1% %2%)'
-data_manager_management_buttons: '[管理:](gray) [[❌ 刪除…]](#ff3300 show_text=&7點擊刪除這個快照\n&8這不會影像目前玩家的資料\nff3300&⚠ 此操作不能取消! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ 恢復…]](#00fb9a show_text=&7點擊將玩家資料覆蓋為此快照\n&8這將導致玩家的資料會被此快照覆蓋\nff3300&⚠ %1% 當前的資料將被覆蓋! suggest_command=/husksync:userdata restore %1% %2%) [[※ 標記…]](#d8ff2b show_text=&7點擊切換標記狀態\n&8被標記的快照將不會自動輪換更新 run_command=/userdata pin %1% %2%)'
-data_manager_system_buttons: '[系統:](gray) [[⏷ 本地轉存…]](dark_gray show_text=&7點擊將此玩家資料快照轉存到本地文件中\n&8轉存的資料可以在以下路徑找到 ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ 雲端轉存…]](dark_gray show_text=&7點擊將此玩家資料快照轉存到 mc-logs 服務\n&8您將獲得一個包含資料的 URL. run_command=/husksync:userdata dump %1% %2% web)'
-data_manager_advancements_preview_remaining: '還有 %1% …'
-data_list_title: '[%1% 的玩家資料快照:](#00fb9a) [(%2%-%3% 共](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
-data_list_item: '[%1%](gray show_text=&7User Data Snapshot for %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Pinned:\n&8Pinned snapshots won''t be automatically rotated. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Version timestamp:&7\n&8When the data was saved\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Save cause:\n&8What caused the data to be saved run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:&7\n&8Estimated file size of the snapshot (in KiB) run_command=/userdata view %2% %3%)'
-data_deleted: '[❌ 成功刪除:](#00fb9a) [%3%](#00fb9a show_text=&7玩家 UUID:\n&8%4%) [的快照:](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%)'
-data_restored: '[⏪ 成功將玩家](#00fb9a) [%1%](#00fb9a show_text=&7玩家 UUID:\n&8%2%)[的資料恢復為 快照:](#00fb9a) [%3%.](#00fb9a show_text=&7Version UUID:\n&8%4%)'
-data_pinned: '[※ 成功標記](#00fb9a) [%3%](#00fb9a show_text=&7玩家 UUID:\n&8%4%) [的快照:](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%)'
-data_unpinned: '[※ 成功解除](#00fb9a) [%3%](#00fb9a show_text=&7玩家 UUID:\n&8%4%) [快照:](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [的標記](#00fb9a)'
-data_dumped: '[☂ 成功將 %2% 資料快照 %1% 儲存至:](#00fb9a) &7%3%'
-list_footer: '\n%1%[頁面](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
-list_previous_page_button: '[◀](white show_text=&7查看上一頁 run_command=%2% %1%) '
-list_next_page_button: ' [▶](white show_text=&7查看下一頁 run_command=%2% %1%)'
-list_page_jumpers: '(%1%)'
-list_page_jumper_button: '[%1%](show_text=&7跳至第 %1% 頁 run_command=%2% %1%)'
-list_page_jumper_current_page: '[%1%](#00fb9a)'
-list_page_jumper_separator: ' '
-list_page_jumper_group_separator: '…'
-save_cause_disconnect: 'disconnect'
-save_cause_world_save: 'world save'
-save_cause_death: 'death'
-save_cause_server_shutdown: 'server shutdown'
-save_cause_inventory_command: 'inventory command'
-save_cause_enderchest_command: 'enderchest command'
-save_cause_backup_restore: 'backup restore'
-save_cause_api: 'API'
-save_cause_mpdb_migration: 'MPDB migration'
-save_cause_legacy_migration: 'legacy migration'
-save_cause_converted_from_v2: 'converted from v2'
-up_to_date: '[HuskSync](#00fb9a bold) [| 您運行的是最新版本的 HuskSync (v%1%).](#00fb9a)'
-update_available: '[HuskSync](#ff7e5e bold) [| 發現可用的新版本: v%1% (running: v%2%).](#ff7e5e)'
-reload_complete: '[HuskSync](#00fb9a bold) [| 已重新載入配置和訊息文件](#00fb9a)\n[⚠ Ensure config files are up-to-date on all servers!](#00fb9a)\n[A restart is needed for config changes to take effect.](#00fb9a italic)'
-system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
-error_invalid_syntax: '[錯誤:](#ff3300) [語法不正確,用法:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
-error_invalid_player: '[錯誤:](#ff3300) [找不到這位玩家](#ff7e5e)'
-error_no_permission: '[錯誤:](#ff3300) [您沒有權限執行這個指令](#ff7e5e)'
-error_console_command_only: '[錯誤:](#ff3300) [該指令只能透過 控制台 執行](#ff7e5e)'
-error_in_game_command_only: '[錯誤:](#ff3300) [該指令只能在遊戲內執行](#ff7e5e)'
-error_no_data_to_display: '[錯誤:](#ff3300) [找不到任何可顯示的用戶資訊.](#ff7e5e)'
-error_invalid_version_uuid: '[錯誤:](#ff3300) [找不到正確的 Version UUID.](#ff7e5e)'
-husksync_command_description: 'Manage the HuskSync plugin'
-userdata_command_description: 'View, manage & restore player userdata'
-inventory_command_description: 'View & edit a player''s inventory'
-enderchest_command_description: 'View & edit a player''s Ender Chest'
\ No newline at end of file
+locales:
+ synchronization_complete: '[⏵資料已同步!](#00fb9a)'
+ synchronization_failed: '[⏵ 無法同步您的資料! 請聯繫管理員](#ff7e5e)'
+ inventory_viewer_menu_title: '&0%1% 的背包'
+ ender_chest_viewer_menu_title: '&0%1% 的終界箱'
+ inventory_viewer_opened: '[查看](#00fb9a) [%1%](#00fb9a bold) [於 ⌚ %2% 的背包快照資料](#00fb9a)'
+ ender_chest_viewer_opened: '[查看](#00fb9a) [%1%](#00fb9a bold) [於 ⌚ %2% 的終界箱快照資料](#00fb9a)'
+ data_update_complete: '[🔔 你的資料已更新!](#00fb9a)'
+ data_update_failed: '[🔔 無法更新您的資料! 請聯繫管理員](#ff7e5e)'
+ user_registration_complete: '[⭐ User registration complete!](#00fb9a)'
+ data_manager_title: '[查看](#00fb9a) [%3%](#00fb9a bold show_text=&7玩家 UUID:\n&8%4%) [的快照:](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [:](#00fb9a)'
+ data_manager_timestamp: '[⌚ %1%](#ffc43b-#f5c962 show_text=&7快照時間:\n&8何時保存的資料)'
+ data_manager_pinned: '[※ 被標記的快照](#d8ff2b show_text=&7標記:\n&8此快照資料不會自動輪換更新)'
+ data_manager_cause: '[⚑ %1%](#23a825-#36f539 show_text=&7保存原因:\n&8保存此快照的原因)'
+ data_manager_server: '[☁ %1%](#ff87b3-#f5538e show_text=&7Server:\n&8Name of the server the data was saved on)'
+ data_manager_size: '[⏏ %1%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:\n&8Estimated file size of the snapshot (in KiB))\n'
+ data_manger_status: '[%1%](red)[/](gray)[%2%](red)[×](gray)[❤](red show_text=&7血量) [%3%](yellow)[×](gray)[🍖](yellow show_text=&7飽食度) [ʟᴠ](green)[.](gray)[%4%](green show_text=&7經驗等級) [🏹 %5%](dark_aqua show_text=&7遊戲模式)'
+ data_manager_advancements_statistics: '[⭐ 成就: %1%](color=#ffc43b-#f5c962 show_text=&7已獲得的成就:\n&8%2%) [⌛ 遊戲時間: %3%ʜʀs](color=#62a9f5-#7ab8fa show_text=&7遊戲內的遊玩時間\n&8⚠ 根據遊戲內統計)\n'
+ data_manager_item_buttons: '[查看:](gray) [[🪣 背包…]](color=#a17b5f-#f5b98c show_text=&7點擊查看 run_command=/inventory %1% %2%) [[⌀ 終界箱…]](#b649c4-#d254ff show_text=&7點擊查看 run_command=/enderchest %1% %2%)'
+ data_manager_management_buttons: '[管理:](gray) [[❌ 刪除…]](#ff3300 show_text=&7點擊刪除這個快照\n&8這不會影像目前玩家的資料\nff3300&⚠ 此操作不能取消! suggest_command=/husksync:userdata delete %1% %2%) [[⏪ 恢復…]](#00fb9a show_text=&7點擊將玩家資料覆蓋為此快照\n&8這將導致玩家的資料會被此快照覆蓋\nff3300&⚠ %1% 當前的資料將被覆蓋! suggest_command=/husksync:userdata restore %1% %2%) [[※ 標記…]](#d8ff2b show_text=&7點擊切換標記狀態\n&8被標記的快照將不會自動輪換更新 run_command=/userdata pin %1% %2%)'
+ data_manager_system_buttons: '[系統:](gray) [[⏷ 本地轉存…]](dark_gray show_text=&7點擊將此玩家資料快照轉存到本地文件中\n&8轉存的資料可以在以下路徑找到 ~/plugins/HuskSync/dumps/ run_command=/husksync:userdata dump %1% %2% file) [[☂ 雲端轉存…]](dark_gray show_text=&7點擊將此玩家資料快照轉存到 mc-logs 服務\n&8您將獲得一個包含資料的 URL. run_command=/husksync:userdata dump %1% %2% web)'
+ data_manager_advancements_preview_remaining: '還有 %1% …'
+ data_list_title: '[%1% 的玩家資料快照:](#00fb9a) [(%2%-%3% 共](#00fb9a) [%4%](#00fb9a bold)[)](#00fb9a)\n'
+ data_list_item: '[%1%](gray show_text=&7User Data Snapshot for %2%&8⚡ %4% run_command=/userdata view %2% %3%) [%5%](#d8ff2b show_text=&7Pinned:\n&8Pinned snapshots won''t be automatically rotated. run_command=/userdata view %2% %3%) [%6%](color=#ffc43b-#f5c962 show_text=&7Version timestamp:&7\n&8When the data was saved\n&8%7% run_command=/userdata view %2% %3%) [⚑ %8%](#23a825-#36f539 show_text=&7Save cause:\n&8What caused the data to be saved run_command=/userdata view %2% %3%) [⏏ %9%](color=#62a9f5-#7ab8fa show_text=&7Snapshot size:&7\n&8Estimated file size of the snapshot (in KiB) run_command=/userdata view %2% %3%)'
+ data_deleted: '[❌ 成功刪除:](#00fb9a) [%3%](#00fb9a show_text=&7玩家 UUID:\n&8%4%) [的快照:](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%)'
+ data_restored: '[⏪ 成功將玩家](#00fb9a) [%1%](#00fb9a show_text=&7玩家 UUID:\n&8%2%)[的資料恢復為 快照:](#00fb9a) [%3%.](#00fb9a show_text=&7Version UUID:\n&8%4%)'
+ data_pinned: '[※ 成功標記](#00fb9a) [%3%](#00fb9a show_text=&7玩家 UUID:\n&8%4%) [的快照:](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%)'
+ data_unpinned: '[※ 成功解除](#00fb9a) [%3%](#00fb9a show_text=&7玩家 UUID:\n&8%4%) [快照:](#00fb9a) [%1%](#00fb9a show_text=&7Version UUID:\n&8%2%) [的標記](#00fb9a)'
+ data_dumped: '[☂ 成功將 %2% 資料快照 %1% 儲存至:](#00fb9a) &7%3%'
+ list_footer: '\n%1%[頁面](#00fb9a) [%2%](#00fb9a)/[%3%](#00fb9a)%4% %5%'
+ list_previous_page_button: '[◀](white show_text=&7查看上一頁 run_command=%2% %1%) '
+ list_next_page_button: ' [▶](white show_text=&7查看下一頁 run_command=%2% %1%)'
+ list_page_jumpers: '(%1%)'
+ list_page_jumper_button: '[%1%](show_text=&7跳至第 %1% 頁 run_command=%2% %1%)'
+ list_page_jumper_current_page: '[%1%](#00fb9a)'
+ list_page_jumper_separator: ' '
+ list_page_jumper_group_separator: '…'
+ save_cause_disconnect: 'disconnect'
+ save_cause_world_save: 'world save'
+ save_cause_death: 'death'
+ save_cause_server_shutdown: 'server shutdown'
+ save_cause_inventory_command: 'inventory command'
+ save_cause_enderchest_command: 'enderchest command'
+ save_cause_backup_restore: 'backup restore'
+ save_cause_api: 'API'
+ save_cause_mpdb_migration: 'MPDB migration'
+ save_cause_legacy_migration: 'legacy migration'
+ save_cause_converted_from_v2: 'converted from v2'
+ up_to_date: '[HuskSync](#00fb9a bold) [| 您運行的是最新版本的 HuskSync (v%1%).](#00fb9a)'
+ update_available: '[HuskSync](#ff7e5e bold) [| 發現可用的新版本: v%1% (running: v%2%).](#ff7e5e)'
+ reload_complete: '[HuskSync](#00fb9a bold) [| 已重新載入配置和訊息文件](#00fb9a)\n[⚠ Ensure config files are up-to-date on all servers!](#00fb9a)\n[A restart is needed for config changes to take effect.](#00fb9a italic)'
+ system_status_header: '[HuskSync](#00fb9a bold) [| System status report:](#00fb9a)'
+ error_invalid_syntax: '[錯誤:](#ff3300) [語法不正確,用法:](#ff7e5e) [%1%](#ff7e5e italic show_text=ff7e5e&Click to suggest suggest_command=%1%)'
+ error_invalid_player: '[錯誤:](#ff3300) [找不到這位玩家](#ff7e5e)'
+ error_no_permission: '[錯誤:](#ff3300) [您沒有權限執行這個指令](#ff7e5e)'
+ error_console_command_only: '[錯誤:](#ff3300) [該指令只能透過 控制台 執行](#ff7e5e)'
+ error_in_game_command_only: '[錯誤:](#ff3300) [該指令只能在遊戲內執行](#ff7e5e)'
+ error_no_data_to_display: '[錯誤:](#ff3300) [找不到任何可顯示的用戶資訊.](#ff7e5e)'
+ error_invalid_version_uuid: '[錯誤:](#ff3300) [找不到正確的 Version UUID.](#ff7e5e)'
+ husksync_command_description: 'Manage the HuskSync plugin'
+ userdata_command_description: 'View, manage & restore player userdata'
+ inventory_command_description: 'View & edit a player''s inventory'
+ enderchest_command_description: 'View & edit a player''s Ender Chest'
\ No newline at end of file
diff --git a/common/src/test/java/net/william278/husksync/config/LocalesTests.java b/common/src/test/java/net/william278/husksync/config/LocalesTests.java
index cb5ab5ca..2a2682b8 100644
--- a/common/src/test/java/net/william278/husksync/config/LocalesTests.java
+++ b/common/src/test/java/net/william278/husksync/config/LocalesTests.java
@@ -19,9 +19,8 @@
package net.william278.husksync.config;
-import net.william278.annotaml.Annotaml;
+import de.exlll.configlib.YamlConfigurations;
import org.jetbrains.annotations.NotNull;
-import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -30,14 +29,14 @@ import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.io.File;
-import java.io.IOException;
import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Stream;
+import static org.junit.jupiter.api.Assertions.*;
+
@DisplayName("Locales Tests")
public class LocalesTests {
@@ -48,10 +47,10 @@ public class LocalesTests {
@Test
public void testLoadEnglishLocales() {
try (InputStream locales = LocalesTests.class.getClassLoader().getResourceAsStream("locales/en-gb.yml")) {
- Assertions.assertNotNull(locales, "en-gb.yml is missing from the locales folder");
- englishLocales = Annotaml.create(Locales.class, locales).get();
- } catch (IOException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
- throw new RuntimeException(e);
+ assertNotNull(locales, "en-gb.yml is missing from the locales folder");
+ englishLocales = YamlConfigurations.read(locales, Locales.class);
+ } catch (Throwable e) {
+ fail("Failed to load en-gb.yml", e);
}
}
@@ -59,23 +58,20 @@ public class LocalesTests {
@DisplayName("Test All Locale Keys Present")
@MethodSource("provideLocaleFiles")
public void testAllLocaleKeysPresent(@NotNull File file, @SuppressWarnings("unused") @NotNull String keyName) {
- try {
- final Set fileKeys = Annotaml.create(file, Locales.class).get().rawLocales.keySet();
- englishLocales.rawLocales.keySet()
- .forEach(key -> Assertions.assertTrue(fileKeys.contains(key),
- "Locale key " + key + " is missing from " + file.getName()));
- } catch (IOException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
- throw new RuntimeException(e);
- }
+ final Set fileKeys = YamlConfigurations.load(file.toPath(), Locales.class).locales.keySet();
+ englishLocales.locales.keySet().forEach(key -> assertTrue(
+ fileKeys.contains(key), "Locale key " + key + " is missing from " + file.getName()
+ ));
}
@NotNull
private static Stream provideLocaleFiles() {
- URL url = LocalesTests.class.getClassLoader().getResource("locales");
- Assertions.assertNotNull(url, "locales folder is missing");
- return Stream.of(Objects.requireNonNull(new File(url.getPath())
- .listFiles(file -> file.getName().endsWith("yml") && !file.getName().equals("en-gb.yml"))))
- .map(file -> Arguments.of(file, file.getName().replace(".yml", "")));
+ final URL url = LocalesTests.class.getClassLoader().getResource("locales");
+ assertNotNull(url, "locales folder is missing");
+
+ return Stream.of(Objects.requireNonNull(new File(url.getPath()).listFiles(
+ file -> file.getName().endsWith("yml") && !file.getName().equals("en-gb.yml")
+ ))).map(file -> Arguments.of(file, file.getName().replace(".yml", "")));
}
}
\ No newline at end of file
diff --git a/common/src/test/java/net/william278/husksync/hook/PlanDataExtensionTests.java b/common/src/test/java/net/william278/husksync/hook/PlanHookTests.java
similarity index 88%
rename from common/src/test/java/net/william278/husksync/hook/PlanDataExtensionTests.java
rename to common/src/test/java/net/william278/husksync/hook/PlanHookTests.java
index 000e59a3..f1a08e0e 100644
--- a/common/src/test/java/net/william278/husksync/hook/PlanDataExtensionTests.java
+++ b/common/src/test/java/net/william278/husksync/hook/PlanHookTests.java
@@ -24,11 +24,11 @@ import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@DisplayName("Plan Hook Tests")
-public class PlanDataExtensionTests {
+public class PlanHookTests {
@Test
- @DisplayName("Test Plan Hook Implementation")
- public void testPlanHookImplementation() {
+ @DisplayName("Test Plan Data Extension")
+ public void testPlanDataExtension() {
new ExtensionExtractor(new PlanHook.PlanDataExtension()).validateAnnotations();
}
diff --git a/paper/build.gradle b/paper/build.gradle
index 49c2edab..2ea9aa78 100644
--- a/paper/build.gradle
+++ b/paper/build.gradle
@@ -3,6 +3,10 @@ dependencies {
compileOnly project(':common')
compileOnly 'io.papermc.paper:paper-api:1.19.4-R0.1-SNAPSHOT'
+ compileOnly 'org.jetbrains:annotations:24.1.0'
+ compileOnly 'org.projectlombok:lombok:1.18.30'
+
+ annotationProcessor 'org.projectlombok:lombok:1.18.30'
}
shadowJar {
@@ -14,27 +18,24 @@ shadowJar {
relocate 'org.apache.commons.text', 'net.william278.husksync.libraries.commons.text'
relocate 'org.apache.commons.lang3', 'net.william278.husksync.libraries.commons.lang3'
relocate 'com.google.gson', 'net.william278.husksync.libraries.gson'
- relocate 'org.json', 'net.william278.husksync.libraries.json'
relocate 'com.fatboyindustrial', 'net.william278.husksync.libraries'
relocate 'de.themoep', 'net.william278.husksync.libraries'
relocate 'org.jetbrains', 'net.william278.husksync.libraries'
relocate 'org.intellij', 'net.william278.husksync.libraries'
relocate 'com.zaxxer', 'net.william278.husksync.libraries'
- relocate 'dev.dejvokep', 'net.william278.husksync.libraries'
+ relocate 'de.exlll', 'net.william278.huskclaims.libraries'
relocate 'net.william278.desertwell', 'net.william278.husksync.libraries.desertwell'
relocate 'net.william278.paginedown', 'net.william278.husksync.libraries.paginedown'
relocate 'net.william278.mapdataapi', 'net.william278.husksync.libraries.mapdataapi'
relocate 'net.william278.andjam', 'net.william278.husksync.libraries.andjam'
- relocate 'net.querz', 'net.william278.husksync.libraries.nbtparser'
- relocate 'net.roxeez', 'net.william278.husksync.libraries'
-
- relocate 'me.lucko.commodore', 'net.william278.husksync.libraries.commodore'
- relocate 'net.byteflux.libby', 'net.william278.husksync.libraries.libby'
- relocate 'org.bstats', 'net.william278.husksync.libraries.bstats'
- relocate 'dev.triumphteam.gui', 'net.william278.husksync.libraries.triumphgui'
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'
+ relocate 'org.json', 'net.william278.husksync.libraries.json'
+ relocate 'net.querz', 'net.william278.husksync.libraries.nbtparser'
+ relocate 'net.roxeez', 'net.william278.husksync.libraries'
+ relocate 'me.lucko.commodore', 'net.william278.husksync.libraries.commodore'
+ relocate 'org.bstats', 'net.william278.husksync.libraries.bstats'
+ relocate 'dev.triumphteam.gui', 'net.william278.husksync.libraries.triumphgui'
relocate 'space.arim.morepaperlib', 'net.william278.husksync.libraries.paperlib'
relocate 'de.tr7zw.changeme.nbtapi', 'net.william278.husksync.libraries.nbtapi'
diff --git a/paper/src/main/java/net/william278/husksync/PaperHuskSyncLoader.java b/paper/src/main/java/net/william278/husksync/PaperHuskSyncLoader.java
index 117e879a..9637453c 100644
--- a/paper/src/main/java/net/william278/husksync/PaperHuskSyncLoader.java
+++ b/paper/src/main/java/net/william278/husksync/PaperHuskSyncLoader.java
@@ -19,12 +19,12 @@
package net.william278.husksync;
+import de.exlll.configlib.Configuration;
+import de.exlll.configlib.YamlConfigurations;
import io.papermc.paper.plugin.loader.PluginClasspathBuilder;
import io.papermc.paper.plugin.loader.PluginLoader;
import io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver;
-import net.william278.annotaml.Annotaml;
-import net.william278.annotaml.YamlFile;
-import net.william278.annotaml.YamlKey;
+import lombok.NoArgsConstructor;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.repository.RemoteRepository;
@@ -35,12 +35,13 @@ import java.io.InputStream;
import java.util.List;
import java.util.Objects;
-@SuppressWarnings({"UnstableApiUsage", "unused"})
+@NoArgsConstructor
+@SuppressWarnings("UnstableApiUsage")
public class PaperHuskSyncLoader implements PluginLoader {
@Override
public void classloader(@NotNull PluginClasspathBuilder classpathBuilder) {
- MavenLibraryResolver resolver = new MavenLibraryResolver();
+ final MavenLibraryResolver resolver = new MavenLibraryResolver();
resolveLibraries(classpathBuilder).stream()
.map(DefaultArtifact::new)
@@ -55,8 +56,11 @@ public class PaperHuskSyncLoader implements PluginLoader {
@NotNull
private static List resolveLibraries(@NotNull PluginClasspathBuilder classpathBuilder) {
try (InputStream input = getLibraryListFile()) {
- return Annotaml.create(PaperLibraries.class, Objects.requireNonNull(input)).get().libraries;
- } catch (Exception e) {
+ return YamlConfigurations.read(
+ Objects.requireNonNull(input, "Failed to read libraries file"),
+ PaperLibraries.class
+ ).libraries;
+ } catch (Throwable e) {
classpathBuilder.getContext().getLogger().error("Failed to resolve libraries", e);
}
return List.of();
@@ -67,16 +71,12 @@ public class PaperHuskSyncLoader implements PluginLoader {
return PaperHuskSyncLoader.class.getClassLoader().getResourceAsStream("paper-libraries.yml");
}
- @YamlFile(header = "Dependencies for HuskSync on Paper")
+ @Configuration
+ @NoArgsConstructor
public static class PaperLibraries {
- @YamlKey("libraries")
private List libraries;
- @SuppressWarnings("unused")
- private PaperLibraries() {
- }
-
}
}
\ No newline at end of file
diff --git a/paper/src/main/java/net/william278/husksync/listener/PaperEventListener.java b/paper/src/main/java/net/william278/husksync/listener/PaperEventListener.java
index 9259c0db..a91ad92b 100644
--- a/paper/src/main/java/net/william278/husksync/listener/PaperEventListener.java
+++ b/paper/src/main/java/net/william278/husksync/listener/PaperEventListener.java
@@ -29,6 +29,8 @@ import org.jetbrains.annotations.NotNull;
import java.util.List;
+import static net.william278.husksync.config.Settings.SynchronizationSettings.SaveOnDeathSettings;
+
public class PaperEventListener extends BukkitEventListener {
public PaperEventListener(@NotNull BukkitHuskSync plugin) {
@@ -46,13 +48,14 @@ public class PaperEventListener extends BukkitEventListener {
}
// Handle saving player data snapshots on death
- if (!plugin.getSettings().doSaveOnDeath()) {
+ final SaveOnDeathSettings settings = plugin.getSettings().getSynchronization().getSaveOnDeath();
+ if (!settings.isEnabled()) {
return;
}
// Paper - support saving the player's items to keep if enabled
final int maxInventorySize = BukkitData.Items.Inventory.INVENTORY_SLOT_COUNT;
- final List itemsToSave = switch (plugin.getSettings().getDeathItemsMode()) {
+ final List itemsToSave = switch (settings.getItemsToSave()) {
case DROPS -> event.getDrops();
case ITEMS_TO_KEEP -> event.getItemsToKeep();
};