From 16122b3092d027a2fd24ec5fb25ae6a04d029c55 Mon Sep 17 00:00:00 2001 From: Noah Ross Date: Sun, 17 May 2026 09:08:10 -0400 Subject: [PATCH 1/3] multilingual support, with 14 languages --- .../dev/noah/perplayerkit/ConfigManager.java | 17 + .../dev/noah/perplayerkit/ConfigMigrator.java | 224 ++++++++++++ .../dev/noah/perplayerkit/KitManager.java | 52 +-- .../noah/perplayerkit/KitShareManager.java | 65 ++-- .../dev/noah/perplayerkit/PerPlayerKit.java | 4 + .../dev/noah/perplayerkit/UpdateChecker.java | 4 +- .../commands/admin/AboutCommandListener.java | 17 +- .../commands/admin/KitRoomCommand.java | 10 +- .../commands/admin/PerPlayerKitCommand.java | 47 +-- .../commands/admin/SavePublicKitCommand.java | 14 +- .../commands/core/CommandGuards.java | 17 +- .../commands/features/RegearCommand.java | 65 ++-- .../inspect/AbstractInspectCommand.java | 24 +- .../commands/inspect/InspectCommandUtil.java | 9 +- .../commands/inspect/InspectEcCommand.java | 8 +- .../commands/inspect/InspectKitCommand.java | 8 +- .../commands/kits/DeleteKitCommand.java | 16 +- .../commands/kits/EnderchestCommand.java | 3 +- .../commands/kits/SwapKitCommand.java | 16 +- .../share/AbstractShareSlotCommand.java | 14 +- .../commands/share/CopyKitCommand.java | 4 +- .../commands/share/ShareECKitCommand.java | 2 +- .../commands/share/ShareKitCommand.java | 2 +- .../shortcuts/AbstractShortSlotCommand.java | 5 +- .../java/dev/noah/perplayerkit/gui/GUI.java | 116 +++--- .../noah/perplayerkit/gui/GuiMenuFactory.java | 31 +- .../perplayerkit/listeners/JoinListener.java | 3 +- .../listeners/KitMenuCloseListener.java | 336 +++++++++--------- .../perplayerkit/util/BroadcastManager.java | 77 ++-- .../perplayerkit/util/DisabledCommand.java | 6 +- .../java/dev/noah/perplayerkit/util/Lang.java | 310 ++++++++++++++++ .../noah/perplayerkit/util/PlayerUtil.java | 5 +- src/main/resources/config.yml | 50 ++- src/main/resources/lang/da.yml | 204 +++++++++++ src/main/resources/lang/de.yml | 204 +++++++++++ src/main/resources/lang/en.yml | 208 +++++++++++ src/main/resources/lang/es.yml | 204 +++++++++++ src/main/resources/lang/fi.yml | 204 +++++++++++ src/main/resources/lang/fr.yml | 204 +++++++++++ src/main/resources/lang/it.yml | 204 +++++++++++ src/main/resources/lang/nl.yml | 204 +++++++++++ src/main/resources/lang/pl.yml | 204 +++++++++++ src/main/resources/lang/pt.yml | 204 +++++++++++ src/main/resources/lang/ro.yml | 204 +++++++++++ src/main/resources/lang/sv.yml | 204 +++++++++++ src/main/resources/lang/uk.yml | 204 +++++++++++ src/main/resources/lang/zh.yml | 204 +++++++++++ .../noah/perplayerkit/ConfigMigratorTest.java | 117 ++++++ .../AbstractShareSlotCommandTest.java | 17 +- .../AbstractShortSlotCommandTest.java | 18 +- .../dev/noah/perplayerkit/util/LangTest.java | 59 +++ 51 files changed, 4173 insertions(+), 479 deletions(-) create mode 100644 src/main/java/dev/noah/perplayerkit/ConfigMigrator.java create mode 100644 src/main/java/dev/noah/perplayerkit/util/Lang.java create mode 100644 src/main/resources/lang/da.yml create mode 100644 src/main/resources/lang/de.yml create mode 100644 src/main/resources/lang/en.yml create mode 100644 src/main/resources/lang/es.yml create mode 100644 src/main/resources/lang/fi.yml create mode 100644 src/main/resources/lang/fr.yml create mode 100644 src/main/resources/lang/it.yml create mode 100644 src/main/resources/lang/nl.yml create mode 100644 src/main/resources/lang/pl.yml create mode 100644 src/main/resources/lang/pt.yml create mode 100644 src/main/resources/lang/ro.yml create mode 100644 src/main/resources/lang/sv.yml create mode 100644 src/main/resources/lang/uk.yml create mode 100644 src/main/resources/lang/zh.yml create mode 100644 src/test/java/dev/noah/perplayerkit/ConfigMigratorTest.java create mode 100644 src/test/java/dev/noah/perplayerkit/util/LangTest.java diff --git a/src/main/java/dev/noah/perplayerkit/ConfigManager.java b/src/main/java/dev/noah/perplayerkit/ConfigManager.java index 65d95ea..c981c21 100644 --- a/src/main/java/dev/noah/perplayerkit/ConfigManager.java +++ b/src/main/java/dev/noah/perplayerkit/ConfigManager.java @@ -25,8 +25,20 @@ import java.io.File; import java.io.InputStream; import java.io.InputStreamReader; +import java.util.Set; public class ConfigManager { + + /** + * Keys that were moved out of config.yml into lang files in v2. ConfigManager must not + * re-add them when merging missing keys, or migrated installs would gain stale duplicates. + */ + private static final Set LANG_KEYS = Set.of( + "prefix", + "disabled-command-message", + "motd.message", + "scheduled-broadcast.messages" + ); private final File configFile; private final FileConfiguration config; private final Plugin plugin; @@ -71,6 +83,11 @@ private void mergeMissingKeys() { continue; } + // Strings that live in lang files no longer belong in config.yml + if (LANG_KEYS.contains(key) || key.endsWith(".message") && key.startsWith("messages.")) { + continue; + } + // Add missing keys for everything else if (!config.contains(key)) { config.set(key, defaultConfig.get(key)); diff --git a/src/main/java/dev/noah/perplayerkit/ConfigMigrator.java b/src/main/java/dev/noah/perplayerkit/ConfigMigrator.java new file mode 100644 index 0000000..a7b0d57 --- /dev/null +++ b/src/main/java/dev/noah/perplayerkit/ConfigMigrator.java @@ -0,0 +1,224 @@ +/* + * Copyright 2022-2025 Noah Ross + * + * This file is part of PerPlayerKit. + * + * PerPlayerKit is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * PerPlayerKit is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with PerPlayerKit. If not, see . + */ +package dev.noah.perplayerkit; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.Plugin; + +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * Migrates legacy config.yml (config-version 1) to the new layout (config-version 2). + * + * v1 stored translatable strings (prefix, motd.message, scheduled-broadcast.messages, + * messages.*.message, disabled-command-message) directly in config.yml. v2 moves them + * to lang files. If the user customized any of those values, this migrator writes them + * into plugins/PerPlayerKit/lang/en.yml so their changes survive the upgrade. + * + * Runs before Lang is initialized. + */ +public class ConfigMigrator { + + public static final int CURRENT_VERSION = 2; + + private final Plugin plugin; + + public ConfigMigrator(Plugin plugin) { + this.plugin = plugin; + } + + public void migrate() { + File configFile = new File(plugin.getDataFolder(), "config.yml"); + if (!configFile.exists()) { + return; + } + + FileConfiguration userConfig = YamlConfiguration.loadConfiguration(configFile); + int version = userConfig.getInt("config-version", 1); + if (version >= CURRENT_VERSION) { + return; + } + + plugin.getLogger().info("Migrating config from v" + version + " to v" + CURRENT_VERSION); + + Map savedCustomizations = extractCustomizedStrings(userConfig); + if (!savedCustomizations.isEmpty()) { + writeCustomizationsToLangFile(savedCustomizations); + plugin.getLogger().info("Preserved " + savedCustomizations.size() + + " customized string(s) from config.yml into lang/en.yml"); + } + + userConfig.set("prefix", null); + userConfig.set("disabled-command-message", null); + if (userConfig.isConfigurationSection("motd")) { + userConfig.set("motd.message", null); + } + if (userConfig.isConfigurationSection("scheduled-broadcast")) { + userConfig.set("scheduled-broadcast.messages", null); + } + if (userConfig.isConfigurationSection("messages")) { + for (String key : userConfig.getConfigurationSection("messages").getKeys(false)) { + if (userConfig.isConfigurationSection("messages." + key)) { + userConfig.set("messages." + key + ".message", null); + } + } + } + + userConfig.set("config-version", CURRENT_VERSION); + if (!userConfig.contains("language")) { + userConfig.set("language", "en"); + } + + try { + userConfig.save(configFile); + plugin.getLogger().info("config.yml migrated to v" + CURRENT_VERSION); + } catch (IOException e) { + plugin.getLogger().severe("Failed to save migrated config.yml: " + e.getMessage()); + } + } + + private Map extractCustomizedStrings(FileConfiguration userConfig) { + FileConfiguration defaults = loadBundledDefaults(); + Map diffs = new LinkedHashMap<>(); + + copyIfCustomized(userConfig, defaults, "prefix", diffs); + + if (userConfig.contains("motd.message")) { + List current = userConfig.getStringList("motd.message"); + List defaultsList = bundledMotdDefault(); + if (!current.equals(defaultsList) && !current.isEmpty()) { + diffs.put("motd.message", new ArrayList<>(current)); + } + } + + if (userConfig.contains("scheduled-broadcast.messages")) { + List current = userConfig.getStringList("scheduled-broadcast.messages"); + List defaultsList = bundledBroadcastDefault(); + if (!current.equals(defaultsList) && !current.isEmpty()) { + diffs.put("scheduled-broadcast.messages", new ArrayList<>(current)); + } + } + + if (userConfig.contains("disabled-command-message")) { + String current = userConfig.getString("disabled-command-message"); + String defaultValue = "Kits are disabled here!"; + if (current != null && !current.equals(defaultValue)) { + diffs.put("error.disabled-in-world", current); + } + } + + Map broadcastKeyMap = Map.of( + "messages.player-repaired.message", "broadcast-messages.player-repaired", + "messages.player-healed.message", "broadcast-messages.player-healed", + "messages.player-opened-kit-room.message", "broadcast-messages.player-opened-kit-room", + "messages.player-loaded-private-kit.message", "broadcast-messages.player-loaded-private-kit", + "messages.player-loaded-public-kit.message", "broadcast-messages.player-loaded-public-kit", + "messages.player-loaded-enderchest.message", "broadcast-messages.player-loaded-enderchest", + "messages.player-copied-kit.message", "broadcast-messages.player-copied-kit", + "messages.player-copied-ec.message", "broadcast-messages.player-copied-ec", + "messages.player-regeared.message", "broadcast-messages.player-regeared" + ); + + for (Map.Entry entry : broadcastKeyMap.entrySet()) { + String oldPath = entry.getKey(); + String newKey = entry.getValue(); + if (!userConfig.contains(oldPath)) { + continue; + } + String current = userConfig.getString(oldPath); + String defaultValue = defaults.getString(oldPath); + if (current != null && !current.equals(defaultValue)) { + diffs.put(newKey, current); + } + } + + return diffs; + } + + private void copyIfCustomized(FileConfiguration user, FileConfiguration defaults, String path, + Map out) { + Object current = user.get(path); + Object defaultValue = defaults.get(path); + if (current == null) { + return; + } + if (defaultValue != null && defaultValue.equals(current)) { + return; + } + out.put(path, current); + } + + private void writeCustomizationsToLangFile(Map customizations) { + File langDir = new File(plugin.getDataFolder(), "lang"); + if (!langDir.exists() && !langDir.mkdirs()) { + plugin.getLogger().warning("Failed to create lang directory"); + return; + } + File langFile = new File(langDir, "en.yml"); + + if (!langFile.exists()) { + try (java.io.InputStream in = plugin.getResource("lang/en.yml")) { + if (in != null) { + Files.copy(in, langFile.toPath()); + } + } catch (IOException e) { + plugin.getLogger().warning("Failed to copy bundled lang/en.yml: " + e.getMessage()); + return; + } + } + + YamlConfiguration langConfig = YamlConfiguration.loadConfiguration(langFile); + for (Map.Entry e : customizations.entrySet()) { + langConfig.set(e.getKey(), e.getValue()); + } + try { + langConfig.save(langFile); + } catch (IOException ex) { + plugin.getLogger().severe("Failed to save customizations to lang/en.yml: " + ex.getMessage()); + } + } + + private FileConfiguration loadBundledDefaults() { + try (java.io.InputStream in = plugin.getResource("lang/en.yml")) { + if (in == null) { + return new YamlConfiguration(); + } + return YamlConfiguration.loadConfiguration(new InputStreamReader(in, StandardCharsets.UTF_8)); + } catch (IOException e) { + return new YamlConfiguration(); + } + } + + private List bundledMotdDefault() { + return loadBundledDefaults().getStringList("motd.message"); + } + + private List bundledBroadcastDefault() { + return loadBundledDefaults().getStringList("scheduled-broadcast.messages"); + } +} diff --git a/src/main/java/dev/noah/perplayerkit/KitManager.java b/src/main/java/dev/noah/perplayerkit/KitManager.java index 85e58aa..40191c6 100644 --- a/src/main/java/dev/noah/perplayerkit/KitManager.java +++ b/src/main/java/dev/noah/perplayerkit/KitManager.java @@ -20,9 +20,9 @@ import dev.noah.perplayerkit.util.BroadcastManager; import dev.noah.perplayerkit.util.IDUtil; +import dev.noah.perplayerkit.util.Lang; import dev.noah.perplayerkit.util.Serializer; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.block.Container; import org.bukkit.entity.Player; import dev.noah.perplayerkit.util.SoundManager; @@ -115,12 +115,12 @@ public boolean savekit(UUID uuid, int slot, ItemStack[] kit) { } cacheKit(IDUtil.getPlayerKitId(uuid, slot), kit); - player.sendMessage(ChatColor.GREEN + "Kit " + slot + " saved!"); + Lang.get().send(player, "success.kit-saved", "slot", String.valueOf(slot)); Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> savePlayerKitToDB(uuid, slot)); return true; } else { - player.sendMessage(ChatColor.RED + "You cant save an empty kit!"); + Lang.get().send(player, "error.empty-kit"); } } } @@ -160,12 +160,12 @@ public boolean savePublicKit(Player player, String publickit, ItemStack[] kit) { } cacheKit(IDUtil.getPublicKitId(publickit), kit); - player.sendMessage(ChatColor.GREEN + "Public Kit " + publickit + " saved!"); + Lang.get().send(player, "success.public-kit-saved", "kitname", publickit); Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> savePublicKitToDB(publickit)); return true; } else { - player.sendMessage(ChatColor.RED + "You cant save an empty kit!"); + Lang.get().send(player, "error.empty-kit"); } return false; } @@ -223,11 +223,11 @@ public boolean saveEC(UUID uuid, int slot, ItemStack[] kit) { if (notEmpty) { cacheKit(IDUtil.getECId(uuid, slot), kit); - player.sendMessage(ChatColor.GREEN + "Enderchest " + slot + " saved!"); + Lang.get().send(player, "success.ec-saved", "slot", String.valueOf(slot)); Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> saveEnderchestToDB(uuid, slot)); return true; } else { - player.sendMessage(ChatColor.RED + "You cant save an empty enderchest!"); + Lang.get().send(player, "error.empty-ec"); } } } @@ -341,7 +341,7 @@ public boolean regearKit(Player player, int slot) { return true; } - private boolean loadKitInternal(Player player, String kitId, String notFoundMessage, boolean isEnderChest, Runnable afterLoad) { + private boolean loadKitInternal(Player player, String kitId, Runnable notFoundMessage, boolean isEnderChest, Runnable afterLoad) { if (player == null) { return false; } @@ -349,7 +349,7 @@ private boolean loadKitInternal(Player player, String kitId, String notFoundMess ItemStack[] kit = kitByKitIDMap.get(kitId); if (kit == null) { if (notFoundMessage != null) { - player.sendMessage(ChatColor.RED + notFoundMessage); + notFoundMessage.run(); SoundManager.playFailure(player); } return false; @@ -370,11 +370,13 @@ private boolean loadKitInternal(Player player, String kitId, String notFoundMess } public boolean loadKit(Player player, int slot) { - return loadKitInternal(player, IDUtil.getPlayerKitId(player.getUniqueId(), slot), "Kit " + slot + " does not exist!", false, () -> { - BroadcastManager.get().broadcastPlayerLoadedPrivateKit(player, "Kit " + slot); - player.sendMessage(ChatColor.GREEN + "Kit " + slot + " loaded!"); - lastKitUsedByPlayer.put(player.getUniqueId(), slot); - }); + return loadKitInternal(player, IDUtil.getPlayerKitId(player.getUniqueId(), slot), + () -> Lang.get().send(player, "error.kit-slot-not-found", "slot", String.valueOf(slot)), + false, () -> { + BroadcastManager.get().broadcastPlayerLoadedPrivateKit(player, "Kit " + slot); + Lang.get().send(player, "success.kit-loaded", "slot", String.valueOf(slot)); + lastKitUsedByPlayer.put(player.getUniqueId(), slot); + }); } public boolean loadKitSilent(Player player, int slot) { @@ -387,11 +389,13 @@ public boolean loadPublicKit(Player player, String id) { .map(k -> k.name) .findFirst() .orElse(id); - return loadKitInternal(player, IDUtil.getPublicKitId(id), "Kit does not exist!", false, () -> { - BroadcastManager.get().broadcastPlayerLoadedPublicKit(player, kitDisplayName); - player.sendMessage(ChatColor.GREEN + "Public Kit loaded!"); - player.sendMessage(ChatColor.GRAY + "You can save a custom version this kit by importing into the kit editor"); - }); + return loadKitInternal(player, IDUtil.getPublicKitId(id), + () -> Lang.get().send(player, "error.kit-not-found"), + false, () -> { + BroadcastManager.get().broadcastPlayerLoadedPublicKit(player, kitDisplayName); + Lang.get().send(player, "success.public-kit-loaded"); + Lang.get().send(player, "info.custom-version-available"); + }); } public boolean loadPublicKitSilent(Player player, String id) { @@ -399,10 +403,12 @@ public boolean loadPublicKitSilent(Player player, String id) { } public boolean loadEnderchest(Player player, int slot) { - return loadKitInternal(player, IDUtil.getECId(player.getUniqueId(), slot), "Enderchest " + slot + " does not exist!", true, () -> { - BroadcastManager.get().broadcastPlayerLoadedEnderChest(player); - player.sendMessage(ChatColor.GREEN + "Enderchest " + slot + " loaded!"); - }); + return loadKitInternal(player, IDUtil.getECId(player.getUniqueId(), slot), + () -> Lang.get().send(player, "error.kit-slot-not-found", "slot", String.valueOf(slot)), + true, () -> { + BroadcastManager.get().broadcastPlayerLoadedEnderChest(player); + Lang.get().send(player, "success.ec-loaded", "slot", String.valueOf(slot)); + }); } public boolean loadEnderchestSilent(Player player, int slot) { diff --git a/src/main/java/dev/noah/perplayerkit/KitShareManager.java b/src/main/java/dev/noah/perplayerkit/KitShareManager.java index 4ec978b..a3fcccc 100644 --- a/src/main/java/dev/noah/perplayerkit/KitShareManager.java +++ b/src/main/java/dev/noah/perplayerkit/KitShareManager.java @@ -19,11 +19,11 @@ package dev.noah.perplayerkit; import dev.noah.perplayerkit.util.BroadcastManager; +import dev.noah.perplayerkit.util.Lang; +import dev.noah.perplayerkit.util.SoundManager; import org.apache.commons.lang3.RandomStringUtils; -import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import dev.noah.perplayerkit.util.SoundManager; import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitRunnable; @@ -79,31 +79,26 @@ public void shareKit(Player p, int slot) { String id = RandomStringUtils.randomAlphanumeric(6).toUpperCase(); if (kitShareMap.putIfAbsent(id, kitManager.getPlayerKit(uuid, slot).clone()) == null) { - p.sendMessage(ChatColor.GREEN + "Use /copykit " + id + " to copy this kit"); - p.sendMessage(ChatColor.GREEN + "Code expires in 15 minutes"); + Lang.get().send(p, "info.share-kit-code", "code", id); + Lang.get().send(p, "info.share-code-expiry"); SoundManager.playSuccess(p); - new BukkitRunnable() { - @Override public void run() { kitShareMap.remove(id); } - }.runTaskLater(plugin, 15 * 60 * 20); - } else { - p.sendMessage(ChatColor.RED + "Unexpected error occurred, please try again."); + Lang.get().send(p, "error.unexpected"); SoundManager.playFailure(p); } } else { - p.sendMessage(ChatColor.RED + "Error, that kit does not exist"); + Lang.get().send(p, "error.kit-not-found"); SoundManager.playFailure(p); } - } @@ -114,31 +109,26 @@ public void shareEC(Player p, int slot) { String id = RandomStringUtils.randomAlphanumeric(6).toUpperCase(); if (kitShareMap.putIfAbsent(id, kitManager.getPlayerEC(uuid, slot).clone()) == null) { - p.sendMessage(ChatColor.GREEN + "Use /copyEC " + id + " to copy this enderchest"); - p.sendMessage(ChatColor.GREEN + "Code expires in 15 minutes"); + Lang.get().send(p, "info.share-ec-code", "code", id); + Lang.get().send(p, "info.share-code-expiry"); SoundManager.playSuccess(p); - new BukkitRunnable() { - @Override public void run() { kitShareMap.remove(id); } - }.runTaskLater(plugin, 15 * 60 * 20); - } else { - p.sendMessage(ChatColor.RED + "Unexpected error occurred, please try again."); + Lang.get().send(p, "error.unexpected"); SoundManager.playFailure(p); } } else { - p.sendMessage(ChatColor.RED + "Error, that EC does not exist"); + Lang.get().send(p, "error.ec-not-found"); SoundManager.playFailure(p); } - } @@ -146,32 +136,25 @@ public void copyKit(Player p, String str) { String id = str.toUpperCase(); if (!kitShareMap.containsKey(id)) { - p.sendMessage(ChatColor.RED + "Error, kit does not exist or has expired"); + Lang.get().send(p, "error.kit-expired"); SoundManager.playFailure(p); return; } - ItemStack[] data = kitShareMap.get(id); - - if (data.length == 27) { - // enderchest - p.getEnderChest().setContents(kitShareMap.get(id)); - BroadcastManager.get().broadcastPlayerCopiedEC(p); - SoundManager.playSuccess(p); - - } else if (data.length == 41) { - // inventory - - p.getInventory().setContents(kitShareMap.get(id)); - BroadcastManager.get().broadcastPlayerCopiedKit(p); - SoundManager.playSuccess(p); - } else { - p.sendMessage(ChatColor.RED + "Unexpected error occurred, please try again."); - SoundManager.playFailure(p); - } + ItemStack[] data = kitShareMap.get(id); + if (data.length == 27) { + p.getEnderChest().setContents(kitShareMap.get(id)); + BroadcastManager.get().broadcastPlayerCopiedEC(p); + SoundManager.playSuccess(p); + } else if (data.length == 41) { + p.getInventory().setContents(kitShareMap.get(id)); + BroadcastManager.get().broadcastPlayerCopiedKit(p); + SoundManager.playSuccess(p); + } else { + Lang.get().send(p, "error.unexpected"); + SoundManager.playFailure(p); + } } - - } diff --git a/src/main/java/dev/noah/perplayerkit/PerPlayerKit.java b/src/main/java/dev/noah/perplayerkit/PerPlayerKit.java index 73a08e3..6342c40 100644 --- a/src/main/java/dev/noah/perplayerkit/PerPlayerKit.java +++ b/src/main/java/dev/noah/perplayerkit/PerPlayerKit.java @@ -49,6 +49,7 @@ import dev.noah.perplayerkit.storage.exceptions.StorageOperationException; import dev.noah.perplayerkit.util.BackupManager; import dev.noah.perplayerkit.util.BroadcastManager; +import dev.noah.perplayerkit.util.Lang; import dev.noah.perplayerkit.util.StyleManager; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; @@ -76,9 +77,12 @@ public void onEnable() { Metrics metrics = new Metrics(this, bstatsId); plugin = this; + new ConfigMigrator(this).migrate(); ConfigManager configManager = new ConfigManager(this); configManager.loadConfig(); + reloadConfig(); + new Lang(this); new StyleManager(this); new ItemFilter(this); diff --git a/src/main/java/dev/noah/perplayerkit/UpdateChecker.java b/src/main/java/dev/noah/perplayerkit/UpdateChecker.java index c482096..d064f0d 100644 --- a/src/main/java/dev/noah/perplayerkit/UpdateChecker.java +++ b/src/main/java/dev/noah/perplayerkit/UpdateChecker.java @@ -22,6 +22,7 @@ import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; import com.squareup.okhttp.Response; +import dev.noah.perplayerkit.util.Lang; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; @@ -109,7 +110,8 @@ public void sendUpdateMessage(Player player) { String currentVersion = getCurrentVersion(); String latestVersion = getLatestVersion(); - player.sendMessage("A new version of PerPlayerKit is available! You are running version " + currentVersion + " and the latest version is " + latestVersion); + Lang.get().send(player, "update.new-version-available", + "current", currentVersion, "latest", latestVersion); } } diff --git a/src/main/java/dev/noah/perplayerkit/commands/admin/AboutCommandListener.java b/src/main/java/dev/noah/perplayerkit/commands/admin/AboutCommandListener.java index 3d0d51f..f426caf 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/admin/AboutCommandListener.java +++ b/src/main/java/dev/noah/perplayerkit/commands/admin/AboutCommandListener.java @@ -18,6 +18,7 @@ */ package dev.noah.perplayerkit.commands.admin; +import dev.noah.perplayerkit.util.Lang; import org.bukkit.command.CommandSender; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -50,14 +51,14 @@ private void sendAboutMessage(CommandSender sender) { String pluginVersion = buildProperties.getProperty("plugin.version", "Unknown"); - sender.sendMessage("==========[About]=========="); - sender.sendMessage("PerPlayerKit"); - sender.sendMessage("Author: " + author); - sender.sendMessage("License: " + license); - sender.sendMessage("Source Code: " + source); - sender.sendMessage("Version: " + pluginVersion); - sender.sendMessage("Build Time: " + buildTimestamp); - sender.sendMessage("==========================="); + Lang.get().sendNoPrefix(sender, "about.header-start"); + Lang.get().sendNoPrefix(sender, "about.title"); + Lang.get().sendNoPrefix(sender, "about.author", "author", author); + Lang.get().sendNoPrefix(sender, "about.license", "license", license); + Lang.get().sendNoPrefix(sender, "about.source-code", "source", source); + Lang.get().sendNoPrefix(sender, "about.version", "version", pluginVersion); + Lang.get().sendNoPrefix(sender, "about.build-time", "time", buildTimestamp); + Lang.get().sendNoPrefix(sender, "about.header-end"); } @EventHandler diff --git a/src/main/java/dev/noah/perplayerkit/commands/admin/KitRoomCommand.java b/src/main/java/dev/noah/perplayerkit/commands/admin/KitRoomCommand.java index ec12c3f..3b4a19c 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/admin/KitRoomCommand.java +++ b/src/main/java/dev/noah/perplayerkit/commands/admin/KitRoomCommand.java @@ -19,7 +19,7 @@ package dev.noah.perplayerkit.commands.admin; import dev.noah.perplayerkit.KitRoomDataManager; -import org.bukkit.ChatColor; +import dev.noah.perplayerkit.util.Lang; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -45,14 +45,14 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command if (args[0].equalsIgnoreCase(LOAD)) { KitRoomDataManager.get().loadFromDB(); - sender.sendMessage(ChatColor.GREEN + "Kit Room loaded from SQL"); + Lang.get().send(sender, "success.kitroom-loaded"); if (sender instanceof Player p) SoundManager.playSuccess(p); return true; } if (args[0].equalsIgnoreCase(SAVE)) { KitRoomDataManager.get().saveToDBAsync(); - sender.sendMessage(ChatColor.GREEN + "Kit Room saved to SQL"); + Lang.get().send(sender, "success.kitroom-saved"); if (sender instanceof Player p) SoundManager.playSuccess(p); return true; } @@ -73,8 +73,8 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command } private void sendUsageError(CommandSender sender) { - sender.sendMessage(ChatColor.RED + "Incorrect Usage!"); - sender.sendMessage("/kitroom "); + Lang.get().send(sender, "error.incorrect-usage"); + Lang.get().sendNoPrefix(sender, "command.kitroom-usage-hint"); if (sender instanceof Player p) { SoundManager.playFailure(p); } diff --git a/src/main/java/dev/noah/perplayerkit/commands/admin/PerPlayerKitCommand.java b/src/main/java/dev/noah/perplayerkit/commands/admin/PerPlayerKitCommand.java index 74a7223..2ad7c69 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/admin/PerPlayerKitCommand.java +++ b/src/main/java/dev/noah/perplayerkit/commands/admin/PerPlayerKitCommand.java @@ -19,9 +19,9 @@ package dev.noah.perplayerkit.commands.admin; import dev.noah.perplayerkit.storage.StorageMigrator; +import dev.noah.perplayerkit.util.Lang; import dev.noah.perplayerkit.util.importutil.KitsXImporter; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -47,20 +47,20 @@ public PerPlayerKitCommand(Plugin plugin) { @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { if (args.length == 0) { - sender.sendMessage(ChatColor.RED + "Missing arguments!"); + Lang.get().send(sender, "error.missing-arguments"); return true; } switch (args[0].toLowerCase()) { case "about": - sender.sendMessage(ChatColor.GREEN + "PerPlayerKit is a plugin that allows players to have their own kits."); + Lang.get().send(sender, "command.perplayerkit-about"); return true; case "import": return handleImport(sender, args); case "migrate": return handleMigrate(sender, args); default: - sender.sendMessage(ChatColor.RED + "Invalid subcommand!"); + Lang.get().send(sender, "error.invalid-subcommand"); return true; } @@ -68,25 +68,25 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command private boolean handleImport(CommandSender sender, String[] args) { if (args.length < 2) { - sender.sendMessage(ChatColor.RED + "Missing import type!"); + Lang.get().send(sender, "error.missing-import-type"); return true; } if (!args[1].equalsIgnoreCase("kitsx")) { - sender.sendMessage(ChatColor.RED + "Invalid import type!"); + Lang.get().send(sender, "error.invalid-import-type"); return true; } - sender.sendMessage(ChatColor.GREEN + "Starting import..."); + Lang.get().send(sender, "success.import-starting"); KitsXImporter importer = new KitsXImporter(plugin, sender); if (!importer.checkForFiles()) { - sender.sendMessage(ChatColor.RED + "Missing files to import"); - sender.sendMessage(ChatColor.RED + "Copy data folder from KitsX into the PerPlayerKit folder"); + Lang.get().send(sender, "error.import-files-missing"); + Lang.get().send(sender, "info.import-instructions"); return true; } importer.importFiles(); - sender.sendMessage(ChatColor.GREEN + "Attempted import of KitsX data!"); + Lang.get().send(sender, "success.import-attempted"); return true; } @@ -106,20 +106,20 @@ private boolean handleMigrate(CommandSender sender, String[] args) { return true; } if (sourceType.equals(destinationType)) { - sender.sendMessage(ChatColor.RED + "Source and destination cannot be the same!"); + Lang.get().send(sender, "error.storage-same"); return true; } - sender.sendMessage(ChatColor.YELLOW + "Starting migration from " + sourceType + " to " + destinationType + "..."); - sender.sendMessage(ChatColor.GRAY + "This may take a while for large datasets. Check console for progress."); + Lang.get().send(sender, "info.migration-starting", "source", sourceType, "destination", destinationType); + Lang.get().send(sender, "info.migration-large-dataset"); Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> runMigration(sender, sourceType, destinationType)); return true; } private void sendMigrateUsage(CommandSender sender) { - sender.sendMessage(ChatColor.RED + "Usage: /perplayerkit migrate "); - sender.sendMessage(ChatColor.GRAY + "Available storage types: sqlite, mysql, redis, yml"); + Lang.get().send(sender, "command.perplayerkit-migrate-usage"); + Lang.get().send(sender, "info.available-storage-types"); } private boolean validateStorageType(CommandSender sender, String storageType, String role) { @@ -127,8 +127,8 @@ private boolean validateStorageType(CommandSender sender, String storageType, St return true; } - sender.sendMessage(ChatColor.RED + "Invalid " + role + " storage type: " + storageType); - sender.sendMessage(ChatColor.GRAY + "Available types: sqlite, mysql, redis, yml"); + Lang.get().send(sender, "error.invalid-storage-type", "role", role, "type", storageType); + Lang.get().send(sender, "info.available-storage-types"); return false; } @@ -137,7 +137,8 @@ private void runMigration(CommandSender sender, String sourceType, String destin StorageMigrator.MigrationResult result = migrator.migrate( sourceType, destinationType, - message -> Bukkit.getScheduler().runTask(plugin, () -> sender.sendMessage(ChatColor.GRAY + message)) + message -> Bukkit.getScheduler().runTask(plugin, + () -> Lang.get().send(sender, "info.migration-progress", "message", message)) ); Bukkit.getScheduler().runTask(plugin, () -> sendMigrationResult(sender, destinationType, result)); @@ -145,16 +146,16 @@ private void runMigration(CommandSender sender, String sourceType, String destin private void sendMigrationResult(CommandSender sender, String destinationType, StorageMigrator.MigrationResult result) { if (result.isSuccess()) { - sender.sendMessage(ChatColor.GREEN + "Migration completed successfully!"); - sender.sendMessage(ChatColor.GREEN + "Migrated: " + result.getMigratedCount() + " entries"); + Lang.get().send(sender, "success.migration-completed"); + Lang.get().send(sender, "success.migration-count", "count", String.valueOf(result.getMigratedCount())); if (result.getFailedCount() > 0) { - sender.sendMessage(ChatColor.YELLOW + "Failed: " + result.getFailedCount() + " entries"); + Lang.get().send(sender, "info.migration-failed-count", "count", String.valueOf(result.getFailedCount())); } - sender.sendMessage(ChatColor.YELLOW + "Remember to update your config.yml storage.type to '" + destinationType + "' and restart the server."); + Lang.get().send(sender, "info.update-config-storage", "type", destinationType); return; } - sender.sendMessage(ChatColor.RED + "Migration failed: " + result.getErrorMessage()); + Lang.get().send(sender, "error.migration-failed", "error", result.getErrorMessage()); } diff --git a/src/main/java/dev/noah/perplayerkit/commands/admin/SavePublicKitCommand.java b/src/main/java/dev/noah/perplayerkit/commands/admin/SavePublicKitCommand.java index 5c7cbd3..9b83b34 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/admin/SavePublicKitCommand.java +++ b/src/main/java/dev/noah/perplayerkit/commands/admin/SavePublicKitCommand.java @@ -21,7 +21,7 @@ import dev.noah.perplayerkit.ItemFilter; import dev.noah.perplayerkit.KitManager; import dev.noah.perplayerkit.commands.core.CommandGuards; -import org.bukkit.ChatColor; +import dev.noah.perplayerkit.util.Lang; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -44,16 +44,16 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command } if (args.length < 1) { - player.sendMessage(ChatColor.RED + "You need to specify a kit id"); - player.sendMessage(ChatColor.RED + "Usage: /" + label + " "); + Lang.get().send(player, "error.missing-kit-id"); + Lang.get().send(player, "command.savepublickit-usage", "command", label); return true; } String kitId = args[0]; if (KitManager.get().getPublicKitList().stream().noneMatch(kit -> kit.id.equals(kitId))) { - player.sendMessage(ChatColor.RED + "Public kit " + kitId + " does not exist"); - player.sendMessage(ChatColor.RED + "You may need to add a public kit in the config"); + Lang.get().send(player, "error.public-kit-not-found", "kitid", kitId); + Lang.get().send(player, "error.add-public-kit-config"); return true; } @@ -76,10 +76,10 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command boolean success = kitManager.savePublicKit(kitId, data); if (success) { kitManager.savePublicKitToDB(kitId); - player.sendMessage("Saved kit " + kitId); + Lang.get().send(player, "success.public-kit-saved-admin", "kitid", kitId); SoundManager.playSuccess(player); } else { - player.sendMessage("Error saving kit " + kitId); + Lang.get().send(player, "error.public-kit-save-failed", "kitid", kitId); SoundManager.playFailure(player); } diff --git a/src/main/java/dev/noah/perplayerkit/commands/core/CommandGuards.java b/src/main/java/dev/noah/perplayerkit/commands/core/CommandGuards.java index c6c0b02..c21e204 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/core/CommandGuards.java +++ b/src/main/java/dev/noah/perplayerkit/commands/core/CommandGuards.java @@ -19,18 +19,22 @@ package dev.noah.perplayerkit.commands.core; import dev.noah.perplayerkit.util.DisabledCommand; +import dev.noah.perplayerkit.util.Lang; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.Nullable; public final class CommandGuards { - private static final String DEFAULT_ONLY_PLAYERS_MESSAGE = "Only players can use this command"; private CommandGuards() { } public static @Nullable Player requirePlayer(CommandSender sender) { - return requirePlayer(sender, DEFAULT_ONLY_PLAYERS_MESSAGE); + if (sender instanceof Player player) { + return player; + } + Lang.get().sendNoPrefix(sender, "error.players-only"); + return null; } public static @Nullable Player requirePlayer(CommandSender sender, String onlyPlayersMessage) { @@ -42,7 +46,14 @@ private CommandGuards() { } public static @Nullable Player requirePlayerInEnabledWorld(CommandSender sender) { - return requirePlayerInEnabledWorld(sender, DEFAULT_ONLY_PLAYERS_MESSAGE); + Player player = requirePlayer(sender); + if (player == null) { + return null; + } + if (DisabledCommand.isBlockedInWorld(player)) { + return null; + } + return player; } public static @Nullable Player requirePlayerInEnabledWorld(CommandSender sender, String onlyPlayersMessage) { diff --git a/src/main/java/dev/noah/perplayerkit/commands/features/RegearCommand.java b/src/main/java/dev/noah/perplayerkit/commands/features/RegearCommand.java index 2ee441a..cef0b94 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/features/RegearCommand.java +++ b/src/main/java/dev/noah/perplayerkit/commands/features/RegearCommand.java @@ -5,8 +5,8 @@ import dev.noah.perplayerkit.gui.ItemUtil; import dev.noah.perplayerkit.util.BroadcastManager; import dev.noah.perplayerkit.util.CooldownManager; +import dev.noah.perplayerkit.util.Lang; import dev.noah.perplayerkit.util.StyleManager; -import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.command.Command; @@ -26,15 +26,13 @@ public class RegearCommand implements CommandExecutor, Listener { - public static final ItemStack REGEAR_SHULKER_ITEM = ItemUtil.createItem(Material.WHITE_SHULKER_BOX, 1, StyleManager.get().getPrimaryColorTag() + "Regear Shulker", "● Restocks Your Kit", "● Use " + StyleManager.get().getPrimaryColorTag() + "/rg to get another regear shulker"); - public static final ItemStack REGEAR_SHELL_ITEM = ItemUtil.createItem(Material.SHULKER_SHELL, 1, StyleManager.get().getPrimaryColorTag() + "Regear Shell", "● Restocks Your Kit", "● Click to use!"); - private static final MiniMessage MM = MiniMessage.miniMessage(); - private final Plugin plugin; private final CooldownManager commandCooldownManager; private final CooldownManager damageCooldownManager; private final boolean allowRegearWhileUsingElytra; private final boolean preventPuttingItemsInRegearInventory; + private final ItemStack regearShulkerItem; + private final ItemStack regearShellItem; public RegearCommand(Plugin plugin) { this.plugin = plugin; @@ -44,6 +42,22 @@ public RegearCommand(Plugin plugin) { this.damageCooldownManager = new CooldownManager(damageCooldownInSeconds); this.allowRegearWhileUsingElytra = plugin.getConfig().getBoolean("regear.allow-while-using-elytra", true); this.preventPuttingItemsInRegearInventory = plugin.getConfig().getBoolean("regear.prevent-putting-items-in-regear-inventory", false); + + String primaryTag = StyleManager.get().getPrimaryColorTag(); + this.regearShulkerItem = ItemUtil.createItem( + Material.WHITE_SHULKER_BOX, + 1, + primaryTag + Lang.get().raw("gui.regear-shulker-name"), + Lang.get().raw("gui.lore-regear-restocks"), + Lang.get().raw("gui.lore-regear-shulker-use", "primary", primaryTag) + ); + this.regearShellItem = ItemUtil.createItem( + Material.SHULKER_SHELL, + 1, + primaryTag + Lang.get().raw("gui.regear-shell-name"), + Lang.get().raw("gui.lore-regear-restocks"), + Lang.get().raw("gui.lore-regear-shell-click") + ); } @EventHandler @@ -56,7 +70,7 @@ public void onPlayerTakesDamage(EntityDamageEvent event) { @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - Player player = CommandGuards.requirePlayerInEnabledWorld(sender, "Only players can use this command!"); + Player player = CommandGuards.requirePlayerInEnabledWorld(sender); if (player == null) { return true; } @@ -72,13 +86,13 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command return true; } - sendMessage(player, "This command is not configured correctly, please contact an administrator."); + Lang.get().send(player, "error.regear-misconfigured"); return true; } @EventHandler public void onShulkerPlace(BlockPlaceEvent event) { - if (!event.getItemInHand().equals(REGEAR_SHULKER_ITEM)) { + if (!event.getItemInHand().equals(regearShulkerItem)) { return; } event.setCancelled(true); @@ -96,7 +110,7 @@ public void onShulkerPlace(BlockPlaceEvent event) { player.getInventory().setItem(event.getHand(), null); RegearInventoryHolder holder = new RegearInventoryHolder(player); - Inventory inventory = holder.getInventory(); + Inventory inventory = createRegearInventory(holder); player.openInventory(inventory); } @@ -112,7 +126,7 @@ public void onShulkerShellClick(InventoryClickEvent event) { } - if (!currentItem.equals(REGEAR_SHELL_ITEM)) { + if (!currentItem.equals(regearShellItem)) { if (preventPuttingItemsInRegearInventory) { event.setCancelled(true); } @@ -151,12 +165,12 @@ private String getEffectiveMode(String label) { private void handleShulkerMode(Player player) { int slot = player.getInventory().firstEmpty(); if (slot == -1) { - sendMessage(player, "Your inventory is full, can't give you a regear shulker!"); + Lang.get().send(player, "error.inventory-full"); return; } - player.getInventory().setItem(slot, REGEAR_SHULKER_ITEM); - sendMessage(player, "Regear Shulker given!"); + player.getInventory().setItem(slot, regearShulkerItem); + Lang.get().send(player, "success.shulker-given"); } private void handleCommandMode(Player player) { @@ -185,7 +199,7 @@ private Integer getLastLoadedKitSlot(Player player) { return slot; } - sendMessage(player, "You have not loaded a kit yet!"); + Lang.get().send(player, "error.no-kit-loaded"); return null; } @@ -200,7 +214,7 @@ private boolean isElytraBlocked(Player player) { return false; } - sendMessage(player, "You cannot regear while using an elytra!"); + Lang.get().send(player, "error.regear-elytra-blocked"); return true; } @@ -210,7 +224,7 @@ private boolean isDamageCooldownBlocked(Player player) { } int secondsLeft = damageCooldownManager.getTimeLeft(player); - sendMessage(player, "You must be out of combat for " + secondsLeft + " more seconds before regearing!"); + Lang.get().send(player, "error.regear-combat-cooldown", "seconds", String.valueOf(secondsLeft)); return true; } @@ -220,17 +234,21 @@ private boolean isCommandCooldownBlocked(Player player) { } int secondsLeft = commandCooldownManager.getTimeLeft(player); - sendMessage(player, "You must wait " + secondsLeft + " seconds before using this command again!"); + Lang.get().send(player, "error.regear-command-cooldown", "seconds", String.valueOf(secondsLeft)); return true; } private void announceRegearSuccess(Player player) { - sendMessage(player, "Regeared!"); + Lang.get().send(player, "success.regeared"); BroadcastManager.get().broadcastPlayerRegeared(player); } - private void sendMessage(Player player, String message) { - BroadcastManager.get().sendComponentMessage(player, MM.deserialize(message)); + + private Inventory createRegearInventory(RegearInventoryHolder holder) { + Inventory inventory = Bukkit.createInventory(holder, 27, + StyleManager.get().getPrimaryColor() + Lang.get().legacy("gui.regear-shulker-title")); + inventory.setItem(13, regearShellItem); + return inventory; } @@ -239,9 +257,10 @@ public record RegearInventoryHolder( @Override public @NotNull Inventory getInventory() { - Inventory inventory = Bukkit.createInventory(this, 27, StyleManager.get().getPrimaryColor() + "Regear Shulker"); - inventory.setItem(13, REGEAR_SHELL_ITEM); - return inventory; + // Inventory is created externally via RegearCommand#createRegearInventory. + // This method is required by InventoryHolder but not used at runtime — the + // inventory is opened through createRegearInventory which assigns the holder. + throw new UnsupportedOperationException("Use RegearCommand#createRegearInventory"); } } } diff --git a/src/main/java/dev/noah/perplayerkit/commands/inspect/AbstractInspectCommand.java b/src/main/java/dev/noah/perplayerkit/commands/inspect/AbstractInspectCommand.java index 3b320df..796f918 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/inspect/AbstractInspectCommand.java +++ b/src/main/java/dev/noah/perplayerkit/commands/inspect/AbstractInspectCommand.java @@ -20,6 +20,7 @@ import dev.noah.perplayerkit.KitManager; import dev.noah.perplayerkit.util.BroadcastManager; +import dev.noah.perplayerkit.util.Lang; import dev.noah.perplayerkit.util.SoundManager; import org.bukkit.Bukkit; import org.bukkit.command.Command; @@ -38,10 +39,9 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -import static dev.noah.perplayerkit.commands.inspect.InspectCommandUtil.ERROR_PREFIX; import static dev.noah.perplayerkit.commands.inspect.InspectCommandUtil.MAX_SLOT; import static dev.noah.perplayerkit.commands.inspect.InspectCommandUtil.MIN_SLOT; -import static dev.noah.perplayerkit.commands.inspect.InspectCommandUtil.mm; +import static dev.noah.perplayerkit.commands.inspect.InspectCommandUtil.errorPrefix; import static dev.noah.perplayerkit.commands.inspect.InspectCommandUtil.resolvePlayerIdentifierAsync; import static dev.noah.perplayerkit.commands.inspect.InspectCommandUtil.showUsage; import static dev.noah.perplayerkit.util.PlayerUtil.getPlayerName; @@ -59,18 +59,17 @@ protected AbstractInspectCommand(Plugin plugin) { protected abstract void openInspectGui(Player inspector, UUID targetUuid, int slot); - protected abstract String missingDataMessage(String targetName, int slot); + protected abstract String missingDataKey(); protected abstract String loadErrorLogMessage(); - protected abstract String loadErrorUserMessage(); + protected abstract String loadErrorUserKey(); @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { if (!(sender instanceof Player player)) { - sender.sendMessage(ERROR_PREFIX.append( - mm.deserialize("This command can only be executed by players.")).toString()); + Lang.get().send(sender, "error.players-only-inspect"); return true; } @@ -128,7 +127,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command } BroadcastManager.get().sendComponentMessage(currentSender, - ERROR_PREFIX.append(mm.deserialize(loadErrorUserMessage()))); + errorPrefix().append(Lang.get().component(loadErrorUserKey()))); SoundManager.playFailure(currentSender); }); return null; @@ -181,9 +180,8 @@ private int parseSlot(String slotArg, Player player) { return slot; } catch (NumberFormatException e) { BroadcastManager.get().sendComponentMessage(player, - ERROR_PREFIX.append( - mm.deserialize("Slot must be a number between " + - MIN_SLOT + " and " + MAX_SLOT + "."))); + errorPrefix().append(Lang.get().component("error.invalid-slot-range", + "min", String.valueOf(MIN_SLOT), "max", String.valueOf(MAX_SLOT)))); SoundManager.playFailure(player); return -1; } @@ -200,14 +198,14 @@ private void showInspectResult(Player inspector, @Nullable Player targetPlayer, targetName = targetUuid.toString(); } BroadcastManager.get().sendComponentMessage(inspector, - ERROR_PREFIX.append(mm.deserialize(missingDataMessage(targetName, slot)))); + errorPrefix().append(Lang.get().component(missingDataKey(), + "player", targetName, "slot", String.valueOf(slot)))); SoundManager.playFailure(inspector); } private void showPlayerNotFound(Player player) { BroadcastManager.get().sendComponentMessage(player, - ERROR_PREFIX.append( - mm.deserialize("Could not find a player with that name or UUID."))); + errorPrefix().append(Lang.get().component("error.player-not-found"))); SoundManager.playFailure(player); } } diff --git a/src/main/java/dev/noah/perplayerkit/commands/inspect/InspectCommandUtil.java b/src/main/java/dev/noah/perplayerkit/commands/inspect/InspectCommandUtil.java index b801904..dc0e358 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/inspect/InspectCommandUtil.java +++ b/src/main/java/dev/noah/perplayerkit/commands/inspect/InspectCommandUtil.java @@ -22,6 +22,7 @@ import com.squareup.okhttp.Request; import com.squareup.okhttp.Response; import dev.noah.perplayerkit.util.BroadcastManager; +import dev.noah.perplayerkit.util.Lang; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.Bukkit; @@ -40,12 +41,15 @@ public class InspectCommandUtil { public static final int MIN_SLOT = 1; public static final int MAX_SLOT = 9; public static final MiniMessage mm = MiniMessage.miniMessage(); - public static final Component ERROR_PREFIX = mm.deserialize("Error: "); private InspectCommandUtil() { // Utility class } + public static Component errorPrefix() { + return Lang.get().component("error.prefix-tag"); + } + /** * Attempts to resolve a player identifier (name or UUID) to a UUID asynchronously. * This method first tries to parse as UUID, then checks online players synchronously, @@ -85,8 +89,7 @@ private InspectCommandUtil() { */ public static void showUsage(@NotNull Player player, @NotNull String commandName) { BroadcastManager.get().sendComponentMessage(player, - ERROR_PREFIX.append( - mm.deserialize("Usage: /" + commandName + " "))); + errorPrefix().append(Lang.get().component("command.inspect-usage", "command", commandName))); } private static @Nullable UUID findCachedOfflinePlayerUuid(@NotNull String identifier) { diff --git a/src/main/java/dev/noah/perplayerkit/commands/inspect/InspectEcCommand.java b/src/main/java/dev/noah/perplayerkit/commands/inspect/InspectEcCommand.java index f85d127..ea79723 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/inspect/InspectEcCommand.java +++ b/src/main/java/dev/noah/perplayerkit/commands/inspect/InspectEcCommand.java @@ -46,8 +46,8 @@ protected void openInspectGui(Player inspector, UUID targetUuid, int slot) { } @Override - protected String missingDataMessage(String targetName, int slot) { - return "" + targetName + " does not have an enderchest in slot " + slot + ""; + protected String missingDataKey() { + return "error.inspect-ec-missing"; } @Override @@ -56,7 +56,7 @@ protected String loadErrorLogMessage() { } @Override - protected String loadErrorUserMessage() { - return "An error occurred while loading enderchest data. See console for details."; + protected String loadErrorUserKey() { + return "error.inspect-ec-load-error"; } } diff --git a/src/main/java/dev/noah/perplayerkit/commands/inspect/InspectKitCommand.java b/src/main/java/dev/noah/perplayerkit/commands/inspect/InspectKitCommand.java index 810d631..159c1d9 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/inspect/InspectKitCommand.java +++ b/src/main/java/dev/noah/perplayerkit/commands/inspect/InspectKitCommand.java @@ -46,8 +46,8 @@ protected void openInspectGui(Player inspector, UUID targetUuid, int slot) { } @Override - protected String missingDataMessage(String targetName, int slot) { - return "" + targetName + " does not have a kit in slot " + slot + ""; + protected String missingDataKey() { + return "error.inspect-kit-missing"; } @Override @@ -56,7 +56,7 @@ protected String loadErrorLogMessage() { } @Override - protected String loadErrorUserMessage() { - return "An error occurred while loading kit data. See console for details."; + protected String loadErrorUserKey() { + return "error.inspect-kit-load-error"; } } diff --git a/src/main/java/dev/noah/perplayerkit/commands/kits/DeleteKitCommand.java b/src/main/java/dev/noah/perplayerkit/commands/kits/DeleteKitCommand.java index 6e9a33c..c5f6adf 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/kits/DeleteKitCommand.java +++ b/src/main/java/dev/noah/perplayerkit/commands/kits/DeleteKitCommand.java @@ -21,7 +21,7 @@ import dev.noah.perplayerkit.KitManager; import dev.noah.perplayerkit.commands.core.CommandGuards; import dev.noah.perplayerkit.commands.core.SlotArgumentParser; -import org.bukkit.ChatColor; +import dev.noah.perplayerkit.util.Lang; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -34,14 +34,14 @@ public class DeleteKitCommand implements CommandExecutor { @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - Player player = CommandGuards.requirePlayer(sender, ChatColor.RED + "Only Players can use this!"); + Player player = CommandGuards.requirePlayer(sender); if (player == null) { return true; } UUID uuid = player.getUniqueId(); if (args.length != 1) { - player.sendMessage(ChatColor.RED + "Usage: /deletekit "); + Lang.get().send(player, "command.deletekit-usage"); SoundManager.playFailure(player); return true; } @@ -49,23 +49,23 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command Integer slot = SlotArgumentParser.parseSlotInRange(args[0], 1, 9); KitManager kitManager = KitManager.get(); if (slot == null) { - player.sendMessage(ChatColor.RED + "Usage: /deletekit "); - player.sendMessage(ChatColor.RED + "Select a real number"); + Lang.get().send(player, "command.deletekit-usage"); + Lang.get().send(player, "error.invalid-number"); SoundManager.playFailure(player); return true; } if (!kitManager.hasKit(uuid, slot)) { - player.sendMessage(ChatColor.RED + "Kit " + slot + " doesnt exist!"); + Lang.get().send(player, "error.kit-slot-not-found", "slot", String.valueOf(slot)); SoundManager.playFailure(player); return true; } if (kitManager.deleteKit(uuid, slot)) { - player.sendMessage(ChatColor.GREEN + "Kit " + slot + " deleted!"); + Lang.get().send(player, "success.kit-deleted", "slot", String.valueOf(slot)); SoundManager.playSuccess(player); } else { - player.sendMessage(ChatColor.RED + "Kit deletion failed!"); + Lang.get().send(player, "error.kit-deletion-failed"); SoundManager.playFailure(player); } diff --git a/src/main/java/dev/noah/perplayerkit/commands/kits/EnderchestCommand.java b/src/main/java/dev/noah/perplayerkit/commands/kits/EnderchestCommand.java index 49bf713..1091bf9 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/kits/EnderchestCommand.java +++ b/src/main/java/dev/noah/perplayerkit/commands/kits/EnderchestCommand.java @@ -20,6 +20,7 @@ import dev.noah.perplayerkit.commands.core.CommandGuards; import dev.noah.perplayerkit.gui.ItemUtil; +import dev.noah.perplayerkit.util.Lang; import dev.noah.perplayerkit.util.StyleManager; import dev.noah.perplayerkit.util.SoundManager; import org.bukkit.command.Command; @@ -47,7 +48,7 @@ public void viewOnlyEC(Player player) { ItemStack fill = ItemUtil.createGlassPane(); - Menu menu = ChestMenu.builder(5).title(StyleManager.get().getPrimaryColor() + "View Only Enderchest").build(); + Menu menu = ChestMenu.builder(5).title(StyleManager.get().getPrimaryColor() + Lang.get().legacy("gui.enderchest-view-title")).build(); for (int i = 0; i < 9; i++) { diff --git a/src/main/java/dev/noah/perplayerkit/commands/kits/SwapKitCommand.java b/src/main/java/dev/noah/perplayerkit/commands/kits/SwapKitCommand.java index 3fc02da..09d9750 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/kits/SwapKitCommand.java +++ b/src/main/java/dev/noah/perplayerkit/commands/kits/SwapKitCommand.java @@ -21,7 +21,7 @@ import dev.noah.perplayerkit.KitManager; import dev.noah.perplayerkit.commands.core.CommandGuards; import dev.noah.perplayerkit.commands.core.SlotArgumentParser; -import org.bukkit.ChatColor; +import dev.noah.perplayerkit.util.Lang; import dev.noah.perplayerkit.util.SoundManager; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -35,13 +35,13 @@ public class SwapKitCommand implements CommandExecutor { @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - Player player = CommandGuards.requirePlayer(sender, ChatColor.RED + "Only Players can use this!"); + Player player = CommandGuards.requirePlayer(sender); if (player == null) { return true; } if (args.length != 2) { - player.sendMessage(ChatColor.RED + "Usage: /swapkit "); + Lang.get().send(player, "command.swapkit-usage"); SoundManager.playFailure(player); return true; } @@ -50,8 +50,8 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command Integer slot2 = SlotArgumentParser.parseSlotInRange(args[1], 1, 9); if (slot1 == null || slot2 == null) { - player.sendMessage(ChatColor.RED + "Usage: /swapkit "); - player.sendMessage(ChatColor.RED + "Select real numbers"); + Lang.get().send(player, "command.swapkit-usage"); + Lang.get().send(player, "error.invalid-numbers"); SoundManager.playFailure(player); return true; } @@ -60,13 +60,13 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command UUID uuid = player.getUniqueId(); if (!kitManager.hasKit(uuid, slot1)) { - player.sendMessage(ChatColor.RED + "Kit " + slot1 + " doesn't exist!"); + Lang.get().send(player, "error.kit-slot-not-found", "slot", String.valueOf(slot1)); SoundManager.playFailure(player); return true; } if (!kitManager.hasKit(uuid, slot2)) { - player.sendMessage(ChatColor.RED + "Kit " + slot2 + " doesn't exist!"); + Lang.get().send(player, "error.kit-slot-not-found", "slot", String.valueOf(slot2)); SoundManager.playFailure(player); return true; } @@ -77,7 +77,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command kitManager.saveEnderchestToDB(uuid, slot1); kitManager.saveEnderchestToDB(uuid, slot2); - player.sendMessage(ChatColor.GREEN + "Kits " + slot1 + " and " + slot2 + " have been swapped!"); + Lang.get().send(player, "success.kits-swapped", "slot1", String.valueOf(slot1), "slot2", String.valueOf(slot2)); SoundManager.playSuccess(player); return true; } diff --git a/src/main/java/dev/noah/perplayerkit/commands/share/AbstractShareSlotCommand.java b/src/main/java/dev/noah/perplayerkit/commands/share/AbstractShareSlotCommand.java index 96e7c4a..8fb8c44 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/share/AbstractShareSlotCommand.java +++ b/src/main/java/dev/noah/perplayerkit/commands/share/AbstractShareSlotCommand.java @@ -21,8 +21,8 @@ import dev.noah.perplayerkit.commands.core.CommandGuards; import dev.noah.perplayerkit.commands.core.SlotArgumentParser; import dev.noah.perplayerkit.util.CooldownManager; +import dev.noah.perplayerkit.util.Lang; import dev.noah.perplayerkit.util.SoundManager; -import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -35,11 +35,11 @@ public abstract class AbstractShareSlotCommand implements CommandExecutor { private static final int COOLDOWN_SECONDS = 5; private final CooldownManager cooldownManager = new CooldownManager(COOLDOWN_SECONDS); - private final String missingSlotMessage; + private final String missingSlotMessageKey; private final BiConsumer shareAction; - protected AbstractShareSlotCommand(String missingSlotMessage, BiConsumer shareAction) { - this.missingSlotMessage = missingSlotMessage; + protected AbstractShareSlotCommand(String missingSlotMessageKey, BiConsumer shareAction) { + this.missingSlotMessageKey = missingSlotMessageKey; this.shareAction = shareAction; } @@ -51,20 +51,20 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command } if (args.length < 1) { - player.sendMessage(ChatColor.RED + missingSlotMessage); + Lang.get().send(player, missingSlotMessageKey); SoundManager.playFailure(player); return true; } if (cooldownManager.isOnCooldown(player)) { - player.sendMessage(ChatColor.RED + "Please don't spam the command (5 second cooldown)"); + Lang.get().send(player, "error.command-cooldown"); SoundManager.playFailure(player); return true; } Integer slot = SlotArgumentParser.parseSlotInRange(args[0], 1, 9); if (slot == null) { - player.sendMessage(ChatColor.RED + "Select a valid kit slot"); + Lang.get().send(player, "error.invalid-kit-slot"); SoundManager.playFailure(player); return true; } diff --git a/src/main/java/dev/noah/perplayerkit/commands/share/CopyKitCommand.java b/src/main/java/dev/noah/perplayerkit/commands/share/CopyKitCommand.java index e171378..6fd192e 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/share/CopyKitCommand.java +++ b/src/main/java/dev/noah/perplayerkit/commands/share/CopyKitCommand.java @@ -20,7 +20,7 @@ import dev.noah.perplayerkit.KitShareManager; import dev.noah.perplayerkit.commands.core.CommandGuards; -import org.bukkit.ChatColor; +import dev.noah.perplayerkit.util.Lang; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -39,7 +39,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command if (args.length > 0) { KitShareManager.get().copyKit(player, args[0]); } else { - player.sendMessage(ChatColor.RED + "Error, you must enter a kit code to copy"); + Lang.get().send(player, "error.missing-kit-code"); SoundManager.playFailure(player); } diff --git a/src/main/java/dev/noah/perplayerkit/commands/share/ShareECKitCommand.java b/src/main/java/dev/noah/perplayerkit/commands/share/ShareECKitCommand.java index 6951e73..bed3901 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/share/ShareECKitCommand.java +++ b/src/main/java/dev/noah/perplayerkit/commands/share/ShareECKitCommand.java @@ -23,6 +23,6 @@ public class ShareECKitCommand extends AbstractShareSlotCommand { public ShareECKitCommand() { - super("Error, you must select an EC slot to share", (player, slot) -> KitShareManager.get().shareEC(player, slot)); + super("error.missing-ec-slot-share", (player, slot) -> KitShareManager.get().shareEC(player, slot)); } } diff --git a/src/main/java/dev/noah/perplayerkit/commands/share/ShareKitCommand.java b/src/main/java/dev/noah/perplayerkit/commands/share/ShareKitCommand.java index 7dc567b..e33854d 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/share/ShareKitCommand.java +++ b/src/main/java/dev/noah/perplayerkit/commands/share/ShareKitCommand.java @@ -23,6 +23,6 @@ public class ShareKitCommand extends AbstractShareSlotCommand { public ShareKitCommand() { - super("Error, you must select a kit slot to share", (player, slot) -> KitShareManager.get().shareKit(player, slot)); + super("error.missing-kit-slot-share", (player, slot) -> KitShareManager.get().shareKit(player, slot)); } } diff --git a/src/main/java/dev/noah/perplayerkit/commands/shortcuts/AbstractShortSlotCommand.java b/src/main/java/dev/noah/perplayerkit/commands/shortcuts/AbstractShortSlotCommand.java index ad0a027..f0f0cea 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/shortcuts/AbstractShortSlotCommand.java +++ b/src/main/java/dev/noah/perplayerkit/commands/shortcuts/AbstractShortSlotCommand.java @@ -19,6 +19,7 @@ package dev.noah.perplayerkit.commands.shortcuts; import dev.noah.perplayerkit.util.DisabledCommand; +import dev.noah.perplayerkit.util.Lang; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -40,7 +41,7 @@ protected AbstractShortSlotCommand(String shortPrefix, String longPrefix) { @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { if (!(sender instanceof Player player)) { - sender.sendMessage("Only players can use this command."); + Lang.get().sendNoPrefix(sender, "error.players-only"); return true; } @@ -50,7 +51,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command Integer slot = parseSlot(label); if (slot == null) { - player.sendMessage("Invalid command label."); + Lang.get().send(player, "error.invalid-command-label"); return true; } diff --git a/src/main/java/dev/noah/perplayerkit/gui/GUI.java b/src/main/java/dev/noah/perplayerkit/gui/GUI.java index 52a5afe..c87baec 100644 --- a/src/main/java/dev/noah/perplayerkit/gui/GUI.java +++ b/src/main/java/dev/noah/perplayerkit/gui/GUI.java @@ -76,6 +76,14 @@ public static boolean removeKitDeletionFlag(Player player) { return kitDeletionFlag.remove(player.getUniqueId()); } + private static String lang(String key) { + return Lang.get().raw(key); + } + + private static String lang(String key, String... pairs) { + return Lang.get().raw(key, pairs); + } + public void OpenKitMenu(Player p, int slot) { Menu menu = GuiMenuFactory.createKitMenu(slot); @@ -89,9 +97,9 @@ public void OpenKitMenu(Player p, int slot) { setGlassPaneRange(menu, KIT_CONTENT_END, MENU_SIZE); setArmorAndOffhandIndicators(menu); - menu.getSlot(IMPORT_SLOT).setItem(createItem(Material.CHEST, 1, "IMPORT", "● Import from inventory")); - menu.getSlot(CLEAR_SLOT).setItem(createItem(Material.BARRIER, 1, "CLEAR KIT", "● Shift click to clear")); - menu.getSlot(BACK_SLOT).setItem(createItem(Material.OAK_DOOR, 1, "BACK")); + menu.getSlot(IMPORT_SLOT).setItem(createItem(Material.CHEST, 1, lang("gui.import-button"), lang("gui.lore-import-inventory"))); + menu.getSlot(CLEAR_SLOT).setItem(createItem(Material.BARRIER, 1, lang("gui.clear-kit-button"), lang("gui.lore-shift-clear"))); + menu.getSlot(BACK_SLOT).setItem(createItem(Material.OAK_DOOR, 1, lang("gui.back-button"))); addMainButton(menu.getSlot(BACK_SLOT)); addClear(menu.getSlot(CLEAR_SLOT)); addImport(menu.getSlot(IMPORT_SLOT)); @@ -113,9 +121,9 @@ public void OpenPublicKitEditor(Player p, String kitId) { setGlassPaneRange(menu, KIT_CONTENT_END, MENU_SIZE); setArmorAndOffhandIndicators(menu); - menu.getSlot(IMPORT_SLOT).setItem(createItem(Material.CHEST, 1, "IMPORT", "● Import from inventory")); - menu.getSlot(CLEAR_SLOT).setItem(createItem(Material.BARRIER, 1, "CLEAR KIT", "● Shift click to clear")); - menu.getSlot(BACK_SLOT).setItem(createItem(Material.OAK_DOOR, 1, "BACK")); + menu.getSlot(IMPORT_SLOT).setItem(createItem(Material.CHEST, 1, lang("gui.import-button"), lang("gui.lore-import-inventory"))); + menu.getSlot(CLEAR_SLOT).setItem(createItem(Material.BARRIER, 1, lang("gui.clear-kit-button"), lang("gui.lore-shift-clear"))); + menu.getSlot(BACK_SLOT).setItem(createItem(Material.OAK_DOOR, 1, lang("gui.back-button"))); addMainButton(menu.getSlot(BACK_SLOT)); addClear(menu.getSlot(CLEAR_SLOT)); addImport(menu.getSlot(IMPORT_SLOT)); @@ -137,9 +145,9 @@ public void OpenECKitKenu(Player p, int slot) { } } allowModificationRange(menu, EC_CONTENT_START, EC_CONTENT_END); - menu.getSlot(IMPORT_SLOT).setItem(createItem(Material.ENDER_CHEST, 1, "IMPORT", "● Import from enderchest")); - menu.getSlot(CLEAR_SLOT).setItem(createItem(Material.BARRIER, 1, "CLEAR KIT", "● Shift click to clear")); - menu.getSlot(BACK_SLOT).setItem(createItem(Material.OAK_DOOR, 1, "BACK")); + menu.getSlot(IMPORT_SLOT).setItem(createItem(Material.ENDER_CHEST, 1, lang("gui.import-button"), lang("gui.lore-import-ec"))); + menu.getSlot(CLEAR_SLOT).setItem(createItem(Material.BARRIER, 1, lang("gui.clear-kit-button"), lang("gui.lore-shift-clear"))); + menu.getSlot(BACK_SLOT).setItem(createItem(Material.OAK_DOOR, 1, lang("gui.back-button"))); addMainButton(menu.getSlot(BACK_SLOT)); addClear(menu.getSlot(CLEAR_SLOT), EC_CONTENT_START, EC_CONTENT_END); addImportEC(menu.getSlot(IMPORT_SLOT)); @@ -161,7 +169,7 @@ public void InspectKit(Player p, UUID target, int slot) { setGlassPaneRange(menu, KIT_CONTENT_END, MENU_SIZE); setArmorAndOffhandIndicators(menu); - menu.getSlot(BACK_SLOT).setItem(createItem(Material.OAK_DOOR, 1, "CLOSE")); + menu.getSlot(BACK_SLOT).setItem(createItem(Material.OAK_DOOR, 1, lang("gui.close-button"))); menu.getSlot(BACK_SLOT).setClickHandler((player, info) -> { SoundManager.playClick(player); info.getClickedMenu().close(); @@ -170,7 +178,7 @@ public void InspectKit(Player p, UUID target, int slot) { if (p.hasPermission("perplayerkit.admin")) { allowModificationRange(menu, 0, KIT_CONTENT_END); - menu.getSlot(CLEAR_SLOT).setItem(createItem(Material.BARRIER, 1, "CLEAR KIT", "● Shift click to delete kit")); + menu.getSlot(CLEAR_SLOT).setItem(createItem(Material.BARRIER, 1, lang("gui.clear-kit-button"), lang("gui.lore-shift-delete-kit"))); addClearKit(menu.getSlot(CLEAR_SLOT), target, slot); } @@ -197,7 +205,7 @@ public void InspectEc(Player p, UUID target, int slot) { } } - menu.getSlot(BACK_SLOT).setItem(createItem(Material.OAK_DOOR, 1, "CLOSE")); + menu.getSlot(BACK_SLOT).setItem(createItem(Material.OAK_DOOR, 1, lang("gui.close-button"))); menu.getSlot(BACK_SLOT).setClickHandler((player, info) -> { SoundManager.playClick(player); info.getClickedMenu().close(); @@ -206,7 +214,7 @@ public void InspectEc(Player p, UUID target, int slot) { if (p.hasPermission("perplayerkit.admin")) { allowModificationRange(menu, EC_CONTENT_START, EC_CONTENT_END); - menu.getSlot(CLEAR_SLOT).setItem(createItem(Material.BARRIER, 1, "CLEAR ENDERCHEST", "● Shift click to delete enderchest")); + menu.getSlot(CLEAR_SLOT).setItem(createItem(Material.BARRIER, 1, lang("gui.clear-ec-button"), lang("gui.lore-shift-delete-ec"))); addClearEnderchest(menu.getSlot(CLEAR_SLOT), target, slot); } @@ -221,23 +229,31 @@ public void OpenMainMenu(Player p) { menu.getSlot(i).setItem(createGlassPane()); } for (int i = 9; i < 18; i++) { - menu.getSlot(i).setItem(createItem(Material.CHEST, 1, "Kit " + (i - 8) + "", "● Left click to load kit", "● Right click to edit kit")); - addEditLoad(menu.getSlot(i), i - 8); + int slotNum = i - 8; + menu.getSlot(i).setItem(createItem(Material.CHEST, 1, + lang("gui.kit-slot-name", "slot", String.valueOf(slotNum)), + lang("gui.lore-left-load"), lang("gui.lore-right-edit"))); + addEditLoad(menu.getSlot(i), slotNum); } for (int i = 18; i < 27; i++) { - if (KitManager.get().getItemStackArrayById(p.getUniqueId() + "ec" + (i - 17)) != null) { - menu.getSlot(i).setItem(createItem(Material.ENDER_CHEST, 1, "Enderchest " + (i - 17) + "", "● Left click to load kit", "● Right click to edit kit")); - addEditLoadEC(menu.getSlot(i), i - 17); + int slotNum = i - 17; + if (KitManager.get().getItemStackArrayById(p.getUniqueId() + "ec" + slotNum) != null) { + menu.getSlot(i).setItem(createItem(Material.ENDER_CHEST, 1, + lang("gui.enderchest-slot-name", "slot", String.valueOf(slotNum)), + lang("gui.lore-left-load"), lang("gui.lore-right-edit"))); + addEditLoadEC(menu.getSlot(i), slotNum); } else { - menu.getSlot(i).setItem(createItem(Material.ENDER_EYE, 1, "Enderchest " + (i - 17) + "", "● Click to create")); - addEditEC(menu.getSlot(i), i - 17); + menu.getSlot(i).setItem(createItem(Material.ENDER_EYE, 1, + lang("gui.enderchest-slot-name", "slot", String.valueOf(slotNum)), + lang("gui.lore-click-create"))); + addEditEC(menu.getSlot(i), slotNum); } } for (int i = 27; i < 36; i++) { if (KitManager.get().getItemStackArrayById(p.getUniqueId().toString() + (i - 26)) != null) { - menu.getSlot(i).setItem(createItem(Material.KNOWLEDGE_BOOK, 1, "KIT EXISTS", "● Click to edit")); + menu.getSlot(i).setItem(createItem(Material.KNOWLEDGE_BOOK, 1, lang("gui.kit-exists"), lang("gui.lore-click-edit"))); } else { - menu.getSlot(i).setItem(createItem(Material.BOOK, 1, "KIT NOT FOUND", "● Click to create")); + menu.getSlot(i).setItem(createItem(Material.BOOK, 1, lang("gui.kit-not-found"), lang("gui.lore-click-create"))); } addEdit(menu.getSlot(i), i - 26); } @@ -246,12 +262,13 @@ public void OpenMainMenu(Player p) { menu.getSlot(i).setItem(createGlassPane()); } - menu.getSlot(37).setItem(createItem(Material.NETHER_STAR, 1, "KIT ROOM")); - menu.getSlot(38).setItem(createItem(Material.BOOKSHELF, 1, "PREMADE KITS")); - menu.getSlot(39).setItem(createItem(Material.OAK_SIGN, 1, "INFO", "● Click a kit slot to load your kit", "● Right click or click the book to edit", "● Share kits with /sharekit ")); - menu.getSlot(41).setItem(createItem(Material.REDSTONE_BLOCK, 1, "CLEAR INVENTORY", "● Shift click")); - menu.getSlot(42).setItem(createItem(Material.COMPASS, 1, "SHARE KITS", "● /sharekit ")); - menu.getSlot(43).setItem(createItem(Material.EXPERIENCE_BOTTLE, 1, "REPAIR ITEMS")); + menu.getSlot(37).setItem(createItem(Material.NETHER_STAR, 1, lang("gui.kit-room-button"))); + menu.getSlot(38).setItem(createItem(Material.BOOKSHELF, 1, lang("gui.premade-kits-button"))); + menu.getSlot(39).setItem(createItem(Material.OAK_SIGN, 1, lang("gui.info-button"), + lang("gui.lore-info-load"), lang("gui.lore-info-edit"), lang("gui.lore-info-share"))); + menu.getSlot(41).setItem(createItem(Material.REDSTONE_BLOCK, 1, lang("gui.clear-inventory-button"), lang("gui.lore-shift-click"))); + menu.getSlot(42).setItem(createItem(Material.COMPASS, 1, lang("gui.share-kits-button"), lang("gui.lore-share-kits"))); + menu.getSlot(43).setItem(createItem(Material.EXPERIENCE_BOTTLE, 1, lang("gui.repair-items-button"))); addRepairButton(menu.getSlot(43)); addKitRoom(menu.getSlot(37)); addPublicKitMenu(menu.getSlot(38)); @@ -275,14 +292,14 @@ public void OpenKitRoom(Player p, int page) { } } - menu.getSlot(45).setItem(createItem(Material.BEACON, 1, "REFILL")); + menu.getSlot(45).setItem(createItem(Material.BEACON, 1, lang("gui.refill-button"))); addKitRoom(menu.getSlot(45), page); if (!p.hasPermission("perplayerkit.editkitroom")) { - menu.getSlot(53).setItem(createItem(Material.OAK_DOOR, 1, "BACK")); + menu.getSlot(53).setItem(createItem(Material.OAK_DOOR, 1, lang("gui.back-button"))); addMainButton(menu.getSlot(53)); } else { - menu.getSlot(53).setItem(createItem(Material.BARRIER, page + 1, "EDIT MENU", "SHIFT RIGHT CLICK TO SAVE")); + menu.getSlot(53).setItem(createItem(Material.BARRIER, page + 1, lang("gui.edit-menu-button"), lang("gui.edit-menu-lore"))); } addKitRoom(menu.getSlot(47), 0); addKitRoom(menu.getSlot(48), 1); @@ -304,9 +321,9 @@ public Menu ViewPublicKitMenu(Player p, String id) { ItemStack[] kit = KitManager.get().getPublicKit(id); if (kit == null) { - p.sendMessage(ChatColor.RED + "Kit not found"); + Lang.get().send(p, "error.kit-not-found-display"); if (p.hasPermission("perplayerkit.admin")) { - p.sendMessage(ChatColor.RED + "To assign a kit to this publickit use /savepublickit "); + Lang.get().send(p, "info.assign-publickit-instruction"); } return null; } @@ -327,8 +344,8 @@ public Menu ViewPublicKitMenu(Player p, String id) { } setArmorAndOffhandIndicators(menu); - menu.getSlot(LOAD_PUBLIC_KIT_SLOT).setItem(createItem(Material.APPLE, 1, "LOAD KIT")); - menu.getSlot(BACK_SLOT).setItem(createItem(Material.OAK_DOOR, 1, "BACK")); + menu.getSlot(LOAD_PUBLIC_KIT_SLOT).setItem(createItem(Material.APPLE, 1, lang("gui.load-kit-button"))); + menu.getSlot(BACK_SLOT).setItem(createItem(Material.OAK_DOOR, 1, lang("gui.back-button"))); addPublicKitMenu(menu.getSlot(BACK_SLOT)); addLoadPublicKit(menu.getSlot(LOAD_PUBLIC_KIT_SLOT), id); @@ -344,34 +361,37 @@ public void OpenPublicKitMenu(Player player) { } for (int i = 18; i < 36; i++) { - menu.getSlot(i).setItem(ItemUtil.createItem(Material.BOOK, 1, "MORE KITS COMING SOON")); + menu.getSlot(i).setItem(ItemUtil.createItem(Material.BOOK, 1, lang("gui.more-kits-coming"))); } List publicKitList = KitManager.get().getPublicKitList(); for (int i = 0; i < publicKitList.size(); i++) { - if (KitManager.get().hasPublicKit(publicKitList.get(i).id)) { + PublicKit kit = publicKitList.get(i); + if (KitManager.get().hasPublicKit(kit.id)) { if (player.hasPermission("perplayerkit.admin")) { - menu.getSlot(i + 18).setItem(createItem(publicKitList.get(i).icon, 1, ChatColor.RESET + publicKitList.get(i).name, "● [ADMIN] Shift click to edit")); + menu.getSlot(i + 18).setItem(createItem(kit.icon, 1, ChatColor.RESET + kit.name, lang("gui.lore-admin-shift-edit"))); } else { - menu.getSlot(i + 18).setItem(createItem(publicKitList.get(i).icon, 1, ChatColor.RESET + publicKitList.get(i).name)); + menu.getSlot(i + 18).setItem(createItem(kit.icon, 1, ChatColor.RESET + kit.name)); } - addPublicKitButton(menu.getSlot(i + 18), publicKitList.get(i).id); + addPublicKitButton(menu.getSlot(i + 18), kit.id); } else { + String unassignedName = ChatColor.RESET + kit.name + " " + lang("gui.unassigned-tag"); if (player.hasPermission("perplayerkit.admin")) { - menu.getSlot(i + 18).setItem(createItem(publicKitList.get(i).icon, 1, ChatColor.RESET + publicKitList.get(i).name + " [UNASSIGNED]", "● Admins have not yet setup this kit yet", "● [ADMIN] Shift click to edit")); + menu.getSlot(i + 18).setItem(createItem(kit.icon, 1, unassignedName, + lang("gui.lore-unassigned-info"), lang("gui.lore-admin-shift-edit"))); } else { - menu.getSlot(i + 18).setItem(createItem(publicKitList.get(i).icon, 1, ChatColor.RESET + publicKitList.get(i).name + " [UNASSIGNED]", "● Admins have not yet setup this kit yet")); + menu.getSlot(i + 18).setItem(createItem(kit.icon, 1, unassignedName, lang("gui.lore-unassigned-info"))); } } if (player.hasPermission("perplayerkit.admin")) { - addAdminPublicKitButton(menu.getSlot(i + 18), publicKitList.get(i).id); + addAdminPublicKitButton(menu.getSlot(i + 18), kit.id); } } addMainButton(menu.getSlot(BACK_SLOT)); - menu.getSlot(BACK_SLOT).setItem(createItem(Material.OAK_DOOR, 1, "BACK")); + menu.getSlot(BACK_SLOT).setItem(createItem(Material.OAK_DOOR, 1, lang("gui.back-button"))); menu.open(player); } @@ -404,7 +424,7 @@ public void addClearKit(Slot slot, UUID target, int slotNum) { SoundManager.playClick(player); if (info.getClickType().isShiftClick()) { KitManager.get().deleteKit(target, slotNum); - player.sendMessage(ChatColor.GREEN + "Kit " + slotNum + " deleted for player!"); + Lang.get().send(player, "success.admin-kit-deleted", "slot", String.valueOf(slotNum)); SoundManager.playSuccess(player); kitDeletionFlag.add(player.getUniqueId()); info.getClickedMenu().close(); @@ -418,7 +438,7 @@ public void addClearEnderchest(Slot slot, UUID target, int slotNum) { SoundManager.playClick(player); if (info.getClickType().isShiftClick()) { KitManager.get().deleteEnderchest(target, slotNum); - player.sendMessage(ChatColor.GREEN + "Enderchest " + slotNum + " deleted for player!"); + Lang.get().send(player, "success.admin-ec-deleted", "slot", String.valueOf(slotNum)); SoundManager.playSuccess(player); kitDeletionFlag.add(player.getUniqueId()); info.getClickedMenu().close(); @@ -498,7 +518,7 @@ public void addKitRoomSaveButton(Slot slot, int page) { data[i] = player.getInventory().getContents()[i]; } KitRoomDataManager.get().setKitRoom(page, data); - player.sendMessage("saved menu"); + Lang.get().send(player, "success.kitroom-menu-saved"); SoundManager.playSuccess(player); } }); @@ -519,7 +539,7 @@ public void addClearButton(Slot slot) { SoundManager.playClick(player); if (info.getClickType().isShiftClick()) { player.getInventory().clear(); - player.sendMessage(ChatColor.GREEN + "Inventory cleared"); + Lang.get().send(player, "success.inventory-cleared"); SoundManager.playSuccess(player); } }); diff --git a/src/main/java/dev/noah/perplayerkit/gui/GuiMenuFactory.java b/src/main/java/dev/noah/perplayerkit/gui/GuiMenuFactory.java index 36d894b..28ec45e 100644 --- a/src/main/java/dev/noah/perplayerkit/gui/GuiMenuFactory.java +++ b/src/main/java/dev/noah/perplayerkit/gui/GuiMenuFactory.java @@ -18,7 +18,10 @@ */ package dev.noah.perplayerkit.gui; +import dev.noah.perplayerkit.util.Lang; import dev.noah.perplayerkit.util.StyleManager; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.entity.Player; import org.ipvp.canvas.Menu; import org.ipvp.canvas.type.ChestMenu; @@ -27,39 +30,49 @@ public final class GuiMenuFactory { private GuiMenuFactory() { } + private static String title(String key) { + return StyleManager.get().getPrimaryColor() + + LegacyComponentSerializer.legacySection().serialize(MiniMessage.miniMessage().deserialize(Lang.get().raw(key))); + } + + private static String title(String key, String... pairs) { + return StyleManager.get().getPrimaryColor() + + LegacyComponentSerializer.legacySection().serialize(MiniMessage.miniMessage().deserialize(Lang.get().raw(key, pairs))); + } + public static Menu createPublicKitRoomMenu() { - return ChestMenu.builder(6).title(StyleManager.get().getPrimaryColor() + "Public Kit Room").redraw(true).build(); + return ChestMenu.builder(6).title(title("gui.public-kit-room-title")).redraw(true).build(); } public static Menu createKitMenu(int slot) { - return ChestMenu.builder(6).title(StyleManager.get().getPrimaryColor() + "Kit: " + slot).build(); + return ChestMenu.builder(6).title(title("gui.kit-editor-title", "slot", String.valueOf(slot))).build(); } public static Menu createPublicKitMenu(String id) { - return ChestMenu.builder(6).title(StyleManager.get().getPrimaryColor() + "Public Kit: " + id).build(); + return ChestMenu.builder(6).title(title("gui.public-kit-editor-title", "id", id)).build(); } public static Menu createECMenu(int slot) { - return ChestMenu.builder(6).title(StyleManager.get().getPrimaryColor() + "Enderchest: " + slot).build(); + return ChestMenu.builder(6).title(title("gui.enderchest-editor-title", "slot", String.valueOf(slot))).build(); } public static Menu createInspectMenu(int slot, String playerName) { - return ChestMenu.builder(6).title(StyleManager.get().getPrimaryColor() + "Inspecting " + playerName + "'s kit " + slot).build(); + return ChestMenu.builder(6).title(title("gui.inspect-kit-title", "player", playerName, "slot", String.valueOf(slot))).build(); } public static Menu createInspectEcMenu(int slot, String playerName) { - return ChestMenu.builder(6).title(StyleManager.get().getPrimaryColor() + "Inspecting " + playerName + "'s enderchest " + slot).build(); + return ChestMenu.builder(6).title(title("gui.inspect-ec-title", "player", playerName, "slot", String.valueOf(slot))).build(); } public static Menu createMainMenu(Player player) { - return ChestMenu.builder(6).title(StyleManager.get().getPrimaryColor() + player.getName() + "'s Kits").build(); + return ChestMenu.builder(6).title(title("gui.main-menu-title", "player", player.getName())).build(); } public static Menu createKitRoomMenu() { - return ChestMenu.builder(6).title(StyleManager.get().getPrimaryColor() + "Kit Room").redraw(true).build(); + return ChestMenu.builder(6).title(title("gui.kit-room-title")).redraw(true).build(); } public static Menu createViewPublicKitMenu(String id) { - return ChestMenu.builder(6).title(StyleManager.get().getPrimaryColor() + "Viewing Public Kit: " + id).redraw(true).build(); + return ChestMenu.builder(6).title(title("gui.view-public-kit-title", "id", id)).redraw(true).build(); } } diff --git a/src/main/java/dev/noah/perplayerkit/listeners/JoinListener.java b/src/main/java/dev/noah/perplayerkit/listeners/JoinListener.java index 8590589..deab0f5 100644 --- a/src/main/java/dev/noah/perplayerkit/listeners/JoinListener.java +++ b/src/main/java/dev/noah/perplayerkit/listeners/JoinListener.java @@ -21,6 +21,7 @@ import dev.noah.perplayerkit.KitManager; import dev.noah.perplayerkit.UpdateChecker; import dev.noah.perplayerkit.util.BroadcastManager; +import dev.noah.perplayerkit.util.Lang; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.Bukkit; @@ -71,7 +72,7 @@ public void run() { // Check if MOTD is enabled and send MOTD messages if (plugin.getConfig().getBoolean("motd.enabled")) { List motdMessages = new ArrayList<>(); - plugin.getConfig().getStringList("motd.message").forEach(message -> motdMessages.add(MiniMessage.miniMessage().deserialize(message))); + Lang.get().rawList("motd.message").forEach(message -> motdMessages.add(MiniMessage.miniMessage().deserialize(message))); // Delay for sending the MOTD Bukkit.getScheduler().runTaskLater(plugin, () -> motdMessages.forEach(message -> BroadcastManager.get().sendComponentMessage(player,message)), plugin.getConfig().getLong("motd.delay") * 20L); diff --git a/src/main/java/dev/noah/perplayerkit/listeners/KitMenuCloseListener.java b/src/main/java/dev/noah/perplayerkit/listeners/KitMenuCloseListener.java index 5049800..7c6584d 100644 --- a/src/main/java/dev/noah/perplayerkit/listeners/KitMenuCloseListener.java +++ b/src/main/java/dev/noah/perplayerkit/listeners/KitMenuCloseListener.java @@ -20,8 +20,10 @@ import dev.noah.perplayerkit.KitManager; import dev.noah.perplayerkit.gui.GUI; +import dev.noah.perplayerkit.util.Lang; import dev.noah.perplayerkit.util.StyleManager; -import net.md_5.bungee.api.ChatColor; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -34,190 +36,206 @@ public class KitMenuCloseListener implements Listener { + /** + * Parse a rendered inventory title back into placeholder values, using the + * localized template. Returns the placeholder values in order, or null if + * the title doesn't match the template. + * + * If {@code second} is null, the template is treated as containing only one + * placeholder and the returned array has length 1. + */ + private static String[] parseTitle(String title, String key, String first, String second) { + String template = Lang.get().raw(key); + String firstToken = "{" + first + "}"; + int firstIdx = template.indexOf(firstToken); + if (firstIdx < 0) { + return null; + } + + String fullPrefix = StyleManager.get().getPrimaryColor() + legacyConvert(template.substring(0, firstIdx)); + if (!title.startsWith(fullPrefix)) { + return null; + } + String remainder = title.substring(fullPrefix.length()); + + if (second == null) { + String suffix = legacyConvert(template.substring(firstIdx + firstToken.length())); + if (!remainder.endsWith(suffix)) { + return null; + } + return new String[]{remainder.substring(0, remainder.length() - suffix.length())}; + } + + String secondToken = "{" + second + "}"; + int secondIdx = template.indexOf(secondToken); + if (secondIdx < firstIdx + firstToken.length()) { + return null; + } + String infix = legacyConvert(template.substring(firstIdx + firstToken.length(), secondIdx)); + String suffix = legacyConvert(template.substring(secondIdx + secondToken.length())); + + if (!remainder.endsWith(suffix)) { + return null; + } + String body = remainder.substring(0, remainder.length() - suffix.length()); + int infixIdx = body.lastIndexOf(infix); + if (infixIdx < 0) { + return null; + } + return new String[]{body.substring(0, infixIdx), body.substring(infixIdx + infix.length())}; + } + + private static String legacyConvert(String miniMessage) { + return LegacyComponentSerializer.legacySection().serialize(MiniMessage.miniMessage().deserialize(miniMessage)); + } + @EventHandler public void onKitEditorClose(InventoryCloseEvent e) { Inventory inv = e.getInventory(); - if (inv.getSize() == 54) { - if (inv.getLocation() == null) { - InventoryView view = e.getView(); - if (view.getTitle().contains(StyleManager.get().getPrimaryColor() + "Kit: ")) { - Player p = (Player) e.getPlayer(); - UUID uuid = p.getUniqueId(); - int slot = Integer.parseInt(view.getTitle().replace(StyleManager.get().getPrimaryColor() + "Kit: ", "")); - ItemStack[] kit = new ItemStack[41]; - ItemStack[] chestitems = e.getInventory().getContents(); - - for (int i = 0; i < 41; i++) { - if (chestitems[i] == null) { - kit[i] = null; - } else { - kit[i] = chestitems[i].clone(); - } - } - KitManager.get().savekit(uuid, slot, kit); - } - } + if (inv.getSize() != 54 || inv.getLocation() != null) { + return; + } + InventoryView view = e.getView(); + Integer slot = parseSingleSlot(view.getTitle(), "gui.kit-editor-title", "slot"); + if (slot == null) { + return; } + Player p = (Player) e.getPlayer(); + ItemStack[] kit = copyContents(e.getInventory().getContents(), 41); + KitManager.get().savekit(p.getUniqueId(), slot, kit); } @EventHandler public void onPublicKitEditorClose(InventoryCloseEvent e) { Inventory inv = e.getInventory(); - if (inv.getSize() == 54) { - if (inv.getLocation() == null) { - InventoryView view = e.getView(); - if (view.getTitle().contains(StyleManager.get().getPrimaryColor() + "Public Kit: ")) { - Player player = (Player) e.getPlayer(); - String publickit = view.getTitle().replace(StyleManager.get().getPrimaryColor() + "Public Kit: ", ""); - ItemStack[] kit = new ItemStack[41]; - ItemStack[] chestitems = e.getInventory().getContents(); - - for (int i = 0; i < 41; i++) { - if (chestitems[i] == null) { - kit[i] = null; - } else { - kit[i] = chestitems[i].clone(); - } - } - KitManager.get().savePublicKit(player, publickit, kit); - } - } + if (inv.getSize() != 54 || inv.getLocation() != null) { + return; } + InventoryView view = e.getView(); + String[] parsed = parseTitle(view.getTitle(), "gui.public-kit-editor-title", "id", null); + if (parsed == null || parsed.length != 1 || parsed[0].isEmpty()) { + return; + } + Player player = (Player) e.getPlayer(); + ItemStack[] kit = copyContents(e.getInventory().getContents(), 41); + KitManager.get().savePublicKit(player, parsed[0], kit); } @EventHandler public void onEnderchestEditorClose(InventoryCloseEvent e) { Inventory inv = e.getInventory(); - if (inv.getSize() == 54) { - if (inv.getLocation() == null) { - InventoryView view = e.getView(); - if (view.getTitle().contains(StyleManager.get().getPrimaryColor() + "Enderchest: ")) { - Player p = (Player) e.getPlayer(); - UUID uuid = p.getUniqueId(); - int slot = Integer.parseInt(view.getTitle().replace(StyleManager.get().getPrimaryColor() + "Enderchest: ", "")); - ItemStack[] kit = new ItemStack[27]; - ItemStack[] chestitems = e.getInventory().getContents(); - - for (int i = 0; i < 27; i++) { - if (chestitems[i + 9] == null) { - kit[i] = null; - } else { - kit[i] = chestitems[i + 9].clone(); - } - } - KitManager.get().saveEC(uuid, slot, kit); - } - } + if (inv.getSize() != 54 || inv.getLocation() != null) { + return; + } + InventoryView view = e.getView(); + Integer slot = parseSingleSlot(view.getTitle(), "gui.enderchest-editor-title", "slot"); + if (slot == null) { + return; } + Player p = (Player) e.getPlayer(); + ItemStack[] ec = copyContentsFromOffset(e.getInventory().getContents(), 9, 27); + KitManager.get().saveEC(p.getUniqueId(), slot, ec); } @EventHandler public void onInspectKitEditorClose(InventoryCloseEvent e) { Inventory inv = e.getInventory(); - if (inv.getSize() == 54) { - if (inv.getLocation() == null) { - InventoryView view = e.getView(); - if (view.getTitle().contains(StyleManager.get().getPrimaryColor() + "Inspecting ") && view.getTitle().contains("'s kit ")) { - Player p = (Player) e.getPlayer(); - if (!p.hasPermission("perplayerkit.admin")) { - return; - } - - UUID targetUuid = GUI.getAndRemoveInspectTarget(p.getUniqueId()); - if (targetUuid == null) { - return; - } - - String title = view.getTitle(); - String[] parts = title.replace(StyleManager.get().getPrimaryColor() + "Inspecting ", "").split("'s kit "); - if (parts.length != 2) { - return; - } - String playerName = parts[0]; - int slot; - try { - slot = Integer.parseInt(parts[1]); - } catch (NumberFormatException ex) { - return; - } - - if (GUI.removeKitDeletionFlag(p)) { - return; - } - - ItemStack[] kit = new ItemStack[41]; - ItemStack[] chestitems = e.getInventory().getContents(); - - for (int i = 0; i < 41; i++) { - if (chestitems[i] == null) { - kit[i] = null; - } else { - kit[i] = chestitems[i].clone(); - } - } - - if (KitManager.get().savekit(targetUuid, slot, kit, true)) { - p.sendMessage(ChatColor.GREEN + "Kit " + slot + " updated for player " + playerName + "!"); - } else { - p.sendMessage(ChatColor.RED + "Failed to update kit for player " + playerName + "!"); - } - } - } + if (inv.getSize() != 54 || inv.getLocation() != null) { + return; + } + InventoryView view = e.getView(); + String[] parsed = parseTitle(view.getTitle(), "gui.inspect-kit-title", "player", "slot"); + if (parsed == null) { + return; + } + Player p = (Player) e.getPlayer(); + if (!p.hasPermission("perplayerkit.admin")) { + return; + } + UUID targetUuid = GUI.getAndRemoveInspectTarget(p.getUniqueId()); + if (targetUuid == null) { + return; + } + String playerName = parsed[0]; + int slot; + try { + slot = Integer.parseInt(parsed[1]); + } catch (NumberFormatException ex) { + return; + } + if (GUI.removeKitDeletionFlag(p)) { + return; + } + ItemStack[] kit = copyContents(e.getInventory().getContents(), 41); + if (KitManager.get().savekit(targetUuid, slot, kit, true)) { + Lang.get().send(p, "success.admin-kit-updated", "slot", String.valueOf(slot), "player", playerName); + } else { + Lang.get().send(p, "error.failed-to-update-kit", "player", playerName); } } @EventHandler public void onInspectEnderchestEditorClose(InventoryCloseEvent e) { Inventory inv = e.getInventory(); - if (inv.getSize() == 54) { - if (inv.getLocation() == null) { - InventoryView view = e.getView(); - if (view.getTitle().contains(StyleManager.get().getPrimaryColor() + "Inspecting ") && view.getTitle().contains("'s enderchest ")) { - Player p = (Player) e.getPlayer(); - if (!p.hasPermission("perplayerkit.admin")) { - return; - } - - UUID targetUuid = GUI.getAndRemoveInspectTarget(p.getUniqueId()); - if (targetUuid == null) { - return; - } - - String title = view.getTitle(); - String[] parts = title.replace(StyleManager.get().getPrimaryColor() + "Inspecting ", "").split("'s enderchest "); - if (parts.length != 2) { - return; - } - String playerName = parts[0]; - int slot; - try { - slot = Integer.parseInt(parts[1]); - } catch (NumberFormatException ex) { - return; - } - - if (GUI.removeKitDeletionFlag(p)) { - return; - } - - ItemStack[] kit = new ItemStack[27]; - ItemStack[] chestitems = e.getInventory().getContents(); - - for (int i = 0; i < 27; i++) { - if (chestitems[i + 9] == null) { - kit[i] = null; - } else { - kit[i] = chestitems[i + 9].clone(); - } - } - - if (KitManager.get().saveECSilent(targetUuid, slot, kit)) { - p.sendMessage(ChatColor.GREEN + "Enderchest " + slot + " updated for player " + playerName + "!"); - } else { - p.sendMessage(ChatColor.RED + "Failed to update enderchest for player " + playerName + "!"); - } - } - } + if (inv.getSize() != 54 || inv.getLocation() != null) { + return; + } + InventoryView view = e.getView(); + String[] parsed = parseTitle(view.getTitle(), "gui.inspect-ec-title", "player", "slot"); + if (parsed == null) { + return; + } + Player p = (Player) e.getPlayer(); + if (!p.hasPermission("perplayerkit.admin")) { + return; + } + UUID targetUuid = GUI.getAndRemoveInspectTarget(p.getUniqueId()); + if (targetUuid == null) { + return; + } + String playerName = parsed[0]; + int slot; + try { + slot = Integer.parseInt(parsed[1]); + } catch (NumberFormatException ex) { + return; + } + if (GUI.removeKitDeletionFlag(p)) { + return; + } + ItemStack[] ec = copyContentsFromOffset(e.getInventory().getContents(), 9, 27); + if (KitManager.get().saveECSilent(targetUuid, slot, ec)) { + Lang.get().send(p, "success.admin-ec-updated", "slot", String.valueOf(slot), "player", playerName); + } else { + Lang.get().send(p, "error.failed-to-update-ec", "player", playerName); + } + } + + private static Integer parseSingleSlot(String title, String key, String placeholder) { + String[] parsed = parseTitle(title, key, placeholder, null); + if (parsed == null || parsed.length != 1) { + return null; + } + try { + return Integer.parseInt(parsed[0].trim()); + } catch (NumberFormatException ex) { + return null; + } + } + + private static ItemStack[] copyContents(ItemStack[] source, int count) { + ItemStack[] out = new ItemStack[count]; + for (int i = 0; i < count; i++) { + out[i] = source[i] == null ? null : source[i].clone(); + } + return out; + } + + private static ItemStack[] copyContentsFromOffset(ItemStack[] source, int offset, int count) { + ItemStack[] out = new ItemStack[count]; + for (int i = 0; i < count; i++) { + out[i] = source[i + offset] == null ? null : source[i + offset].clone(); } + return out; } -} \ No newline at end of file +} diff --git a/src/main/java/dev/noah/perplayerkit/util/BroadcastManager.java b/src/main/java/dev/noah/perplayerkit/util/BroadcastManager.java index 137b7ba..37b2466 100644 --- a/src/main/java/dev/noah/perplayerkit/util/BroadcastManager.java +++ b/src/main/java/dev/noah/perplayerkit/util/BroadcastManager.java @@ -29,23 +29,22 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; public class BroadcastManager { private static final int LINE_LENGTH = 60; // Length of the strikethrough line - private static final String FIGURE_SPACE = "\u2007"; // A whitespace character of consistent width + private static final String FIGURE_SPACE = " "; // A whitespace character of consistent width private static BroadcastManager instance; private final int broadcastDistance = 200; private final Plugin plugin; private final CooldownManager repairBroadcastCooldown = new CooldownManager(5); private final CooldownManager kitroomBroadcastCooldown = new CooldownManager(15); private final BukkitAudiences audience; - private final Component prefix; public BroadcastManager(Plugin plugin) { this.plugin = plugin; audience = BukkitAudiences.create(plugin); - prefix = MiniMessage.miniMessage().deserialize(plugin.getConfig().getString("prefix", "[Kits] ")); instance = this; } @@ -70,42 +69,42 @@ public static Component generateBroadcastComponent(String message) { private boolean isKitLoadingMessage(MessageKey key) { return key == MessageKey.PLAYER_LOADED_PRIVATE_KIT || - key == MessageKey.PLAYER_LOADED_PUBLIC_KIT || - key == MessageKey.PLAYER_LOADED_ENDER_CHEST; + key == MessageKey.PLAYER_LOADED_PUBLIC_KIT || + key == MessageKey.PLAYER_LOADED_ENDER_CHEST; } private void broadcastMessage(Player player, String message, String permission) { World world = player.getWorld(); - if(Bukkit.getPluginManager().getPlugin("PlaceholderAPI")!=null) { + if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { message = PlaceholderAPI.setPlaceholders(player, message); } + Component prefix = Lang.get().prefix(); + Component body = MiniMessage.miniMessage().deserialize(message); for (Player broadcastPlayer : world.getPlayers()) { if (broadcastPlayer.getLocation().distance(player.getLocation()) < broadcastDistance) { - // Check if the broadcast player has permission to see this message if (broadcastPlayer.hasPermission(permission)) { - audience.player(broadcastPlayer).sendMessage(prefix.append(MiniMessage.miniMessage().deserialize(message))); + audience.player(broadcastPlayer).sendMessage(prefix.append(body)); } } } } - private void broadcastMessage(Player player, BroadcastManager.MessageKey key, CooldownManager cooldownManager) { + private void broadcastMessage(Player player, MessageKey key, CooldownManager cooldownManager) { broadcastMessage(player, key, cooldownManager, null); } - private void broadcastMessage(Player player, BroadcastManager.MessageKey key, CooldownManager cooldownManager, String kitName) { + private void broadcastMessage(Player player, MessageKey key, CooldownManager cooldownManager, String kitName) { - if(!plugin.getConfig().getBoolean("feature.broadcast-on-player-action",true)){ + if (!plugin.getConfig().getBoolean("feature.broadcast-on-player-action", true)) { return; } - if(plugin.getConfig().getBoolean("messages.disable-kit-messages", false)){ + if (plugin.getConfig().getBoolean("messages.disable-kit-messages", false)) { return; } - // Check if this is a kit loading message and if kit message broadcasts are disabled if (isKitLoadingMessage(key) && !plugin.getConfig().getBoolean("feature.broadcast-kit-messages", true)) { return; } @@ -114,18 +113,14 @@ private void broadcastMessage(Player player, BroadcastManager.MessageKey key, Co return; } - String messageConfigPath = key.getKey(); - String enabledPath = messageConfigPath + ".enabled"; - String messagePath = messageConfigPath + ".message"; - String permissionPath = messageConfigPath + ".permission"; + String configBase = key.getConfigKey(); + String enabledPath = configBase + ".enabled"; + String permissionPath = configBase + ".permission"; - // Check if message is enabled if (!plugin.getConfig().getBoolean(enabledPath, true)) { return; } - String message = plugin.getConfig().getString(messagePath, "%player% " + - "performed an action."); String permission = plugin.getConfig().getString(permissionPath, "perplayerkit.kitnotify"); String playerName; @@ -135,11 +130,10 @@ private void broadcastMessage(Player player, BroadcastManager.MessageKey key, Co playerName = player.getName(); } - message = message.replace("%player%", playerName); - - if (kitName != null) { - message = message.replace("%kitname%", kitName); - } + String message = Lang.get().raw(key.getLangKey(), Map.of( + "player", playerName, + "kitname", kitName == null ? "" : kitName + )); broadcastMessage(player, message, permission); @@ -183,13 +177,14 @@ public void broadcastPlayerCopiedEC(Player player) { public void broadcastPlayerRegeared(Player player) { broadcastMessage(player, MessageKey.PLAYER_REGEARED, null); } + public void startScheduledBroadcast() { List messages = new ArrayList<>(); - plugin.getConfig().getStringList("scheduled-broadcast.messages").forEach(message -> messages.add(generateBroadcastComponent(message))); + Lang.get().rawList("scheduled-broadcast.messages").forEach(message -> messages.add(generateBroadcastComponent(message))); int[] index = {0}; - if (plugin.getConfig().getBoolean("scheduled-broadcast.enabled")) { + if (plugin.getConfig().getBoolean("scheduled-broadcast.enabled") && !messages.isEmpty()) { Bukkit.getScheduler().runTaskTimer(plugin, () -> { for (Player player : Bukkit.getOnlinePlayers()) { audience.player(player).sendMessage(messages.get(index[0])); @@ -204,16 +199,30 @@ public void sendComponentMessage(Player player, Component message) { } public enum MessageKey { - PLAYER_REPAIRED("messages.player-repaired"), PLAYER_HEALED("messages.player-healed"), PLAYER_OPENED_KIT_ROOM("messages.player-opened-kit-room"), PLAYER_LOADED_PRIVATE_KIT("messages.player-loaded-private-kit"), PLAYER_LOADED_PUBLIC_KIT("messages.player-loaded-public-kit"), PLAYER_LOADED_ENDER_CHEST("messages.player-loaded-enderchest"), PLAYER_COPIED_KIT("messages.player-copied-kit"),PLAYER_COPIED_EC("messages.player-copied-ec"), PLAYER_REGEARED("messages.player-regeared"); - - private final String key; + PLAYER_REPAIRED("messages.player-repaired", "broadcast-messages.player-repaired"), + PLAYER_HEALED("messages.player-healed", "broadcast-messages.player-healed"), + PLAYER_OPENED_KIT_ROOM("messages.player-opened-kit-room", "broadcast-messages.player-opened-kit-room"), + PLAYER_LOADED_PRIVATE_KIT("messages.player-loaded-private-kit", "broadcast-messages.player-loaded-private-kit"), + PLAYER_LOADED_PUBLIC_KIT("messages.player-loaded-public-kit", "broadcast-messages.player-loaded-public-kit"), + PLAYER_LOADED_ENDER_CHEST("messages.player-loaded-enderchest", "broadcast-messages.player-loaded-enderchest"), + PLAYER_COPIED_KIT("messages.player-copied-kit", "broadcast-messages.player-copied-kit"), + PLAYER_COPIED_EC("messages.player-copied-ec", "broadcast-messages.player-copied-ec"), + PLAYER_REGEARED("messages.player-regeared", "broadcast-messages.player-regeared"); + + private final String configKey; + private final String langKey; + + MessageKey(String configKey, String langKey) { + this.configKey = configKey; + this.langKey = langKey; + } - MessageKey(String key) { - this.key = key; + public String getConfigKey() { + return configKey; } - public String getKey() { - return key; + public String getLangKey() { + return langKey; } } } diff --git a/src/main/java/dev/noah/perplayerkit/util/DisabledCommand.java b/src/main/java/dev/noah/perplayerkit/util/DisabledCommand.java index 3a51337..663821a 100644 --- a/src/main/java/dev/noah/perplayerkit/util/DisabledCommand.java +++ b/src/main/java/dev/noah/perplayerkit/util/DisabledCommand.java @@ -19,15 +19,11 @@ package dev.noah.perplayerkit.util; import dev.noah.perplayerkit.PerPlayerKit; -import org.bukkit.ChatColor; import org.bukkit.World; import org.bukkit.entity.Player; public class DisabledCommand { - - - private static boolean isBlockedInWorld(World world) { return PerPlayerKit.getPlugin().getConfig().getStringList("disabled-command-worlds").contains(world.getName()); } @@ -35,7 +31,7 @@ private static boolean isBlockedInWorld(World world) { public static boolean isBlockedInWorld(Player player) { if (isBlockedInWorld(player.getWorld())) { - player.sendMessage(ChatColor.translateAlternateColorCodes('&', PerPlayerKit.getPlugin().getConfig().getString("disabled-command-message"))); + Lang.get().sendNoPrefix(player, "error.disabled-in-world"); SoundManager.playFailure(player); return true; } diff --git a/src/main/java/dev/noah/perplayerkit/util/Lang.java b/src/main/java/dev/noah/perplayerkit/util/Lang.java new file mode 100644 index 0000000..a29d6a6 --- /dev/null +++ b/src/main/java/dev/noah/perplayerkit/util/Lang.java @@ -0,0 +1,310 @@ +/* + * Copyright 2022-2025 Noah Ross + * + * This file is part of PerPlayerKit. + * + * PerPlayerKit is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * PerPlayerKit is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with PerPlayerKit. If not, see . + */ +package dev.noah.perplayerkit.util; + +import net.kyori.adventure.platform.bukkit.BukkitAudiences; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class Lang { + + public static final List BUNDLED_LANGS = Arrays.asList("en", "zh", "es", "pt", "fr", "uk", "de", "sv", "da", "fi", "it", "pl", "ro", "nl"); + private static final String DEFAULT_LANG = "en"; + + private static Lang instance; + + private final Plugin plugin; + private final MiniMessage mm = MiniMessage.miniMessage(); + private final BukkitAudiences audience; + private final YamlConfiguration lang; + private final YamlConfiguration fallback; + private final String activeLang; + + public Lang(Plugin plugin) { + this.plugin = plugin; + this.audience = BukkitAudiences.create(plugin); + extractBundledLangFiles(); + + String configured = plugin.getConfig().getString("language", DEFAULT_LANG); + if (configured == null || configured.isBlank()) { + configured = DEFAULT_LANG; + } + this.activeLang = configured.toLowerCase(); + + this.fallback = loadFromJar(DEFAULT_LANG); + this.lang = loadActive(activeLang); + + instance = this; + plugin.getLogger().info("Loaded language: " + activeLang); + } + + /** + * Test-only constructor: skips file extraction and Bukkit audience setup. + * Sends fall back to {@link CommandSender#sendMessage(String)} with legacy + * color codes so tests can verify with simple Mockito matchers. + */ + Lang(YamlConfiguration langConfig) { + this.plugin = null; + this.audience = null; + this.activeLang = DEFAULT_LANG; + this.fallback = langConfig; + this.lang = langConfig; + } + + public static Lang get() { + if (instance == null) { + throw new IllegalStateException("Lang has not been initialized"); + } + return instance; + } + + /** + * Install a test-mode Lang instance backed by the bundled en.yml jar resource. + * Intended for unit tests; should not be called from production code. + */ + public static void installForTesting() { + try (InputStream in = Lang.class.getResourceAsStream("/lang/en.yml")) { + YamlConfiguration cfg = (in == null) + ? new YamlConfiguration() + : YamlConfiguration.loadConfiguration(new InputStreamReader(in, StandardCharsets.UTF_8)); + instance = new Lang(cfg); + } catch (IOException e) { + instance = new Lang(new YamlConfiguration()); + } + } + + /** Reset for test isolation. */ + public static void resetForTesting() { + instance = null; + } + + public String getActiveLanguage() { + return activeLang; + } + + private void extractBundledLangFiles() { + File langDir = new File(plugin.getDataFolder(), "lang"); + if (!langDir.exists() && !langDir.mkdirs()) { + plugin.getLogger().warning("Failed to create lang directory"); + } + for (String code : BUNDLED_LANGS) { + String name = code + ".yml"; + File outFile = new File(langDir, name); + if (outFile.exists()) { + continue; + } + try (InputStream in = plugin.getResource("lang/" + name)) { + if (in == null) { + continue; + } + java.nio.file.Files.copy(in, outFile.toPath()); + } catch (IOException e) { + plugin.getLogger().warning("Failed to extract lang file " + name + ": " + e.getMessage()); + } + } + } + + private YamlConfiguration loadActive(String code) { + File file = new File(plugin.getDataFolder(), "lang/" + code + ".yml"); + if (!file.exists()) { + plugin.getLogger().warning("Language file lang/" + code + ".yml not found; falling back to " + DEFAULT_LANG); + return loadFromJar(DEFAULT_LANG); + } + YamlConfiguration cfg = YamlConfiguration.loadConfiguration(file); + cfg.setDefaults(loadFromJar(DEFAULT_LANG)); + return cfg; + } + + private YamlConfiguration loadFromJar(String code) { + InputStream in = plugin.getResource("lang/" + code + ".yml"); + if (in == null) { + plugin.getLogger().severe("Bundled lang file lang/" + code + ".yml is missing from the jar"); + return new YamlConfiguration(); + } + try (InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_8)) { + return YamlConfiguration.loadConfiguration(reader); + } catch (IOException e) { + plugin.getLogger().severe("Failed to read bundled lang file " + code + ".yml: " + e.getMessage()); + return new YamlConfiguration(); + } + } + + public String raw(String key) { + String value = lang.getString(key); + if (value == null) { + value = fallback.getString(key); + } + if (value == null) { + if (plugin != null) { + plugin.getLogger().warning("Missing language key: " + key); + } + return key; + } + return value; + } + + public String raw(String key, Map placeholders) { + return applyPlaceholders(raw(key), placeholders); + } + + public String raw(String key, String... pairs) { + return applyPlaceholders(raw(key), pairsToMap(pairs)); + } + + public List rawList(String key) { + List value = lang.getStringList(key); + if (value == null || value.isEmpty()) { + value = fallback.getStringList(key); + } + return value; + } + + public Component component(String key) { + return mm.deserialize(raw(key)); + } + + public Component component(String key, Map placeholders) { + return mm.deserialize(raw(key, placeholders)); + } + + public Component component(String key, String... pairs) { + return mm.deserialize(raw(key, pairs)); + } + + public Component prefix() { + return mm.deserialize(raw("prefix")); + } + + public void send(CommandSender sender, String key) { + send(sender, key, (Map) null); + } + + public void send(CommandSender sender, String key, Map placeholders) { + Component msg = prefix().append(component(key, placeholders == null ? Map.of() : placeholders)); + deliver(sender, msg); + } + + public void send(CommandSender sender, String key, String... pairs) { + send(sender, key, pairsToMap(pairs)); + } + + public void sendNoPrefix(CommandSender sender, String key) { + sendNoPrefix(sender, key, (Map) null); + } + + public void sendNoPrefix(CommandSender sender, String key, Map placeholders) { + Component msg = component(key, placeholders == null ? Map.of() : placeholders); + deliver(sender, msg); + } + + private void deliver(CommandSender sender, Component msg) { + if (audience != null) { + if (sender instanceof Player p) { + audience.player(p).sendMessage(msg); + } else { + audience.sender(sender).sendMessage(msg); + } + } else { + sender.sendMessage(LegacyComponentSerializer.legacySection().serialize(msg)); + } + } + + public void sendNoPrefix(CommandSender sender, String key, String... pairs) { + sendNoPrefix(sender, key, pairsToMap(pairs)); + } + + public String legacy(String key) { + return LegacyComponentSerializer.legacySection().serialize(component(key)); + } + + public String legacy(String key, String... pairs) { + return LegacyComponentSerializer.legacySection().serialize(component(key, pairs)); + } + + /** + * Splits a template like "Kit: {slot}" around the named placeholder. Returns + * {@code [prefix, suffix]} — useful for both rendering the template and parsing + * back the placeholder value from a rendered title. + */ + public String[] splitTemplate(String key, String placeholder) { + String tmpl = raw(key); + String token = "{" + placeholder + "}"; + int idx = tmpl.indexOf(token); + if (idx < 0) { + return new String[]{tmpl, ""}; + } + return new String[]{tmpl.substring(0, idx), tmpl.substring(idx + token.length())}; + } + + private static String applyPlaceholders(String input, Map placeholders) { + if (placeholders == null || placeholders.isEmpty()) { + return input; + } + String out = input; + for (Map.Entry e : placeholders.entrySet()) { + out = out.replace("{" + e.getKey() + "}", e.getValue() == null ? "" : e.getValue()); + } + return out; + } + + private static Map pairsToMap(String... pairs) { + if (pairs == null || pairs.length == 0) { + return Map.of(); + } + if (pairs.length % 2 != 0) { + throw new IllegalArgumentException("placeholder pairs must be key,value pairs"); + } + Map map = new LinkedHashMap<>(); + for (int i = 0; i < pairs.length; i += 2) { + map.put(pairs[i], pairs[i + 1]); + } + return map; + } + + public static Map placeholders(String... pairs) { + return pairsToMap(pairs); + } + + public Map ph(String... pairs) { + return pairsToMap(pairs); + } + + static Map applyPlaceholdersForTest(String input, String... pairs) { + Map map = pairsToMap(pairs); + Map out = new HashMap<>(map); + out.put("__result__", applyPlaceholders(input, map)); + return out; + } +} diff --git a/src/main/java/dev/noah/perplayerkit/util/PlayerUtil.java b/src/main/java/dev/noah/perplayerkit/util/PlayerUtil.java index 26159aa..325df24 100644 --- a/src/main/java/dev/noah/perplayerkit/util/PlayerUtil.java +++ b/src/main/java/dev/noah/perplayerkit/util/PlayerUtil.java @@ -21,7 +21,6 @@ import dev.noah.perplayerkit.PerPlayerKit; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; -import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.Damageable; @@ -49,7 +48,7 @@ public static void repairAll(Player p) { for (ItemStack i : p.getInventory().getContents()) { repairItem(i); } - p.sendMessage(ChatColor.GREEN + "All items repaired!"); + Lang.get().send(p, "success.all-repaired"); } public static void healPlayer(Player p) { @@ -62,7 +61,7 @@ public static void healPlayer(Player p) { p.getActivePotionEffects().forEach(potionEffect -> p.removePotionEffect(potionEffect.getType())); } - p.sendMessage(ChatColor.GREEN + "You have been healed!"); + Lang.get().send(p, "success.healed"); } public static void healPlayerSilent(Player p) { diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index f7c8949..3c2b6c3 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,5 +1,16 @@ -config-version: 1 #do not change this value +config-version: 2 #do not change this value + +# Language file selection. +# Built-in choices: +# en - English zh - Chinese (中文) es - Spanish (Español) +# pt - Portuguese fr - French (Français) uk - Ukrainian (Українська) +# de - German (Deutsch) sv - Swedish (Svenska) da - Danish (Dansk) +# fi - Finnish (Suomi) it - Italian (Italiano) pl - Polish (Polski) +# ro - Romanian (Română) nl - Dutch (Nederlands) +# Lang files live in plugins/PerPlayerKit/lang/.yml — copy & edit any file to translate further. +# Set to a custom code to use plugins/PerPlayerKit/lang/.yml. +language: "en" #Database credentials are only required if you are using MySQL or Redis @@ -28,7 +39,7 @@ backup: enabled: true # Enable automatic backups for file-based storage methods # Retention policy: # - 1 backup per hour for the last 24 hours - # - 1 backup per day for the last 7 days + # - 1 backup per day for the last 7 days # - 1 backup per week for the last 30 days # - 1 backup per month for the last 365 days # Backups are stored in the plugins/PerPlayerKit/backups/ directory @@ -36,22 +47,12 @@ backup: motd: enabled: true delay: 5 - message: #join messages using mini message format - - "" - - " Per Player Kits " - - "" - - " Type /kit, /k or /pk to get started!" - - "" - - " " - - "" - -scheduled-broadcast: #uses mini message format + # MOTD message text lives in the active lang file under motd.message + +scheduled-broadcast: enabled: true period: 90 #in seconds - messages: - - "Check out public kits with the /pk command!" - - "Want to share a kit? Use the /sharekit command!" - - "Type /kit, /k or /pk to get started!" + # Broadcast message text lives in the active lang file under scheduled-broadcast.messages interface: glass-material: BLUE_STAINED_GLASS_PANE @@ -77,8 +78,8 @@ kitroom: disabled-command-worlds: - "example_world" - -disabled-command-message: "Kits are disabled here!" +# Message shown when a player tries to use a kit command in a disabled world +# lives in the active lang file under error.disabled-in-world publickits: @@ -86,47 +87,40 @@ publickits: name: "Kit 1" icon: "DIAMOND_SWORD" -prefix: "[Kits] " +# Plugin message prefix lives in the active lang file under `prefix` use-display-name: false #For example, set to true if you want to display nicknames set by other plugins. messages: disable-kit-messages: false # Set to true to disable all kit action messages (e.g. player loaded a kit, player repaired gear, etc.) + # Each broadcast below has an enabled flag and a permission required to see it. + # The actual message text lives in the active lang file under broadcast-messages.* player-repaired: enabled: true - message: "%player% repaired their gear" permission: "perplayerkit.kitnotify" player-healed: enabled: true - message: "%player% healed themselves" permission: "perplayerkit.kitnotify" player-opened-kit-room: enabled: true - message: "%player% opened the Kit Room" permission: "perplayerkit.kitnotify" player-loaded-private-kit: enabled: true - message: "%player% loaded a kit" permission: "perplayerkit.kitnotify" player-loaded-public-kit: enabled: true - message: "%player% loaded a public kit" permission: "perplayerkit.kitnotify" player-loaded-enderchest: enabled: true - message: "%player% loaded an ender chest." permission: "perplayerkit.kitnotify" player-copied-kit: enabled: true - message: "%player% copied a kit" permission: "perplayerkit.kitnotify" player-copied-ec: enabled: true - message: "%player% copied an ender chest" permission: "perplayerkit.kitnotify" player-regeared: enabled: true - message: "%player% regeared" permission: "perplayerkit.kitnotify" diff --git a/src/main/resources/lang/da.yml b/src/main/resources/lang/da.yml new file mode 100644 index 0000000..94c2b55 --- /dev/null +++ b/src/main/resources/lang/da.yml @@ -0,0 +1,204 @@ +# PerPlayerKit Language File - Danish (Dansk) +# Uses MiniMessage format: https://docs.advntr.dev/minimessage/format.html +# Placeholders use {name} syntax (e.g. {player}, {slot}). +# To use this file, set `language: da` in config.yml. + +prefix: "[Kits] " + +motd: + message: + - "" + - " Per Spiller Kits " + - "" + - " Skriv /kit, /k eller /pk for at komme i gang!" + - "" + - " " + - "" + +scheduled-broadcast: + messages: + - "Tjek offentlige kits med /pk-kommandoen!" + - "Vil du dele et kit? Brug /sharekit ." + - "Skriv /kit, /k eller /pk for at komme i gang!" + +broadcast-messages: + player-repaired: "{player} reparerede sit udstyr" + player-healed: "{player} helede sig selv" + player-opened-kit-room: "{player} åbnede kitrummet" + player-loaded-private-kit: "{player} indlæste et kit" + player-loaded-public-kit: "{player} indlæste et offentligt kit" + player-loaded-enderchest: "{player} indlæste en enderkiste." + player-copied-kit: "{player} kopierede et kit" + player-copied-ec: "{player} kopierede en enderkiste" + player-regeared: "{player} udrustede sig igen" + generic: "{player} udførte en handling." + +error: + disabled-in-world: "Kits er deaktiveret her!" + unexpected: "Der opstod en uventet fejl, prøv igen." + kit-not-found: "Fejl, det kit findes ikke" + kit-expired: "Fejl, kit findes ikke eller er udløbet" + ec-not-found: "Fejl, den enderkiste findes ikke" + empty-kit: "Du kan ikke gemme et tomt kit!" + empty-ec: "Du kan ikke gemme en tom enderkiste!" + kit-slot-not-found: "Kit {slot} findes ikke!" + kit-deletion-failed: "Sletning af kit mislykkedes!" + invalid-number: "Vælg et gyldigt tal" + invalid-numbers: "Vælg gyldige tal" + invalid-kit-slot: "Vælg en gyldig kit-slot" + missing-kit-code: "Fejl, du skal indtaste en kit-kode for at kopiere" + missing-kit-slot-share: "Fejl, du skal vælge en kit-slot at dele" + missing-ec-slot-share: "Fejl, du skal vælge en enderkiste-slot at dele" + command-cooldown: "Spam ikke kommandoen (5 sekunders nedkøling)" + regear-misconfigured: "Denne kommando er ikke konfigureret korrekt, kontakt en administrator." + inventory-full: "Dit inventar er fyldt, kan ikke give dig en regear-shulker!" + no-kit-loaded: "Du har ikke indlæst et kit endnu!" + regear-elytra-blocked: "Du kan ikke regear mens du bruger elytra!" + regear-combat-cooldown: "Du skal være uden for kamp i {seconds} sekunder mere før du kan regear!" + regear-command-cooldown: "Du skal vente {seconds} sekunder før du kan bruge denne kommando igen!" + missing-arguments: "Manglende argumenter!" + invalid-subcommand: "Ugyldig underkommando!" + missing-import-type: "Manglende importtype!" + invalid-import-type: "Ugyldig importtype!" + import-files-missing: "Filer til import mangler" + invalid-storage-type: "Ugyldig {role}-lagertype: {type}" + storage-same: "Kilde og destination må ikke være den samme!" + migration-failed: "Migrering mislykkedes: {error}" + missing-kit-id: "Du skal angive et kit-id" + public-kit-not-found: "Offentligt kit {kitid} findes ikke" + add-public-kit-config: "Du skal måske tilføje et offentligt kit i konfigurationen" + public-kit-save-failed: "Fejl ved gemning af kit {kitid}" + incorrect-usage: "Forkert brug!" + players-only: "Kun spillere kan bruge denne kommando" + players-only-inspect: "Denne kommando kan kun udføres af spillere." + invalid-slot-range: "Slot skal være et tal mellem {min} og {max}." + player-not-found: "Kunne ikke finde en spiller med det navn eller UUID." + kit-not-found-display: "Kit ikke fundet" + inspect-kit-missing: "{player} har ikke et kit i slot {slot}" + inspect-ec-missing: "{player} har ikke en enderkiste i slot {slot}" + inspect-kit-load-error: "Der opstod en fejl ved indlæsning af kit-data. Se konsollen for detaljer." + inspect-ec-load-error: "Der opstod en fejl ved indlæsning af enderkiste-data. Se konsollen for detaljer." + failed-to-update-kit: "Kunne ikke opdatere kit for spiller {player}!" + failed-to-update-ec: "Kunne ikke opdatere enderkiste for spiller {player}!" + invalid-command-label: "Ugyldig kommandoetiket." + prefix-tag: "Fejl: " + +success: + kit-saved: "Kit {slot} gemt!" + kit-loaded: "Kit {slot} indlæst!" + kit-deleted: "Kit {slot} slettet!" + kits-swapped: "Kits {slot1} og {slot2} er blevet byttet!" + ec-saved: "Enderkiste {slot} gemt!" + ec-loaded: "Enderkiste {slot} indlæst!" + public-kit-saved: "Offentligt kit {kitname} gemt!" + public-kit-loaded: "Offentligt kit indlæst!" + public-kit-saved-admin: "Gemte kit {kitid}" + kitroom-loaded: "Kitrum indlæst fra SQL" + kitroom-saved: "Kitrum gemt til SQL" + kitroom-menu-saved: "Kitrum-menu gemt" + all-repaired: "Alle genstande repareret!" + healed: "Du er blevet helet!" + shulker-given: "Regear-shulker givet!" + regeared: "Udrustet igen!" + inventory-cleared: "Inventar ryddet" + admin-kit-deleted: "Kit {slot} slettet for spiller!" + admin-ec-deleted: "Enderkiste {slot} slettet for spiller!" + admin-kit-updated: "Kit {slot} opdateret for spiller {player}!" + admin-ec-updated: "Enderkiste {slot} opdateret for spiller {player}!" + migration-completed: "Migrering fuldført!" + migration-count: "Migreret: {count} indtastninger" + import-attempted: "Forsøgte import af KitsX-data!" + import-starting: "Starter import..." + +info: + custom-version-available: "Du kan gemme en brugerdefineret version af dette kit ved at importere til kit-editoren" + assign-publickit-instruction: "For at tildele et kit til denne publickit brug /savepublickit " + share-kit-code: "Brug /copykit {code} for at kopiere dette kit" + share-ec-code: "Brug /copyEC {code} for at kopiere denne enderkiste" + share-code-expiry: "Koden udløber om 15 minutter" + import-instructions: "Kopier datamappen fra KitsX til PerPlayerKit-mappen" + migration-starting: "Starter migrering fra {source} til {destination}..." + migration-large-dataset: "Dette kan tage et stykke tid for store datasæt. Tjek konsollen for fremgang." + available-storage-types: "Tilgængelige lagertyper: sqlite, mysql, redis, yml" + update-config-storage: "Husk at opdatere din config.yml storage.type til '{type}' og genstart serveren." + migration-failed-count: "Mislykkedes: {count} indtastninger" + migration-progress: "{message}" + +command: + perplayerkit-about: "PerPlayerKit er et plugin, der lader spillere have deres egne kits." + deletekit-usage: "Brug: /deletekit " + swapkit-usage: "Brug: /swapkit " + savepublickit-usage: "Brug: /{command} " + perplayerkit-migrate-usage: "Brug: /perplayerkit migrate " + kitroom-usage-hint: "/kitroom " + inspect-usage: "Brug: /{command} " + +update: + new-version-available: "En ny version af PerPlayerKit er tilgængelig! Du kører version {current} og den nyeste version er {latest}" + +about: + header-start: "==========[Om]==========" + title: "PerPlayerKit" + author: "Forfatter: {author}" + license: "Licens: {license}" + source-code: "Kildekode: {source}" + version: "Version: {version}" + build-time: "Byggetid: {time}" + header-end: "========================" + +gui: + main-menu-title: "{player}s Kits" + kit-editor-title: "Kit: {slot}" + public-kit-editor-title: "Offentligt Kit: {id}" + enderchest-editor-title: "Enderkiste: {slot}" + inspect-kit-title: "Inspicerer {player}s kit {slot}" + inspect-ec-title: "Inspicerer {player}s enderkiste {slot}" + kit-room-title: "Kitrum" + public-kit-room-title: "Offentligt Kitrum" + view-public-kit-title: "Viser Offentligt Kit: {id}" + enderchest-view-title: "Kun Vis Enderkiste" + regear-shulker-title: "Regear-Shulker" + + kit-slot-name: "Kit {slot}" + enderchest-slot-name: "Enderkiste {slot}" + kit-exists: "KIT FINDES" + kit-not-found: "KIT IKKE FUNDET" + more-kits-coming: "FLERE KITS KOMMER SNART" + unassigned-tag: "[IKKE TILDELT]" + import-button: "IMPORTER" + clear-kit-button: "RYD KIT" + clear-ec-button: "RYD ENDERKISTE" + back-button: "TILBAGE" + close-button: "LUK" + load-kit-button: "INDLÆS KIT" + refill-button: "GENOPFYLD" + kit-room-button: "KITRUM" + premade-kits-button: "FÆRDIGE KITS" + info-button: "INFO" + clear-inventory-button: "RYD INVENTAR" + share-kits-button: "DEL KITS" + repair-items-button: "REPARER GENSTANDE" + edit-menu-button: "REDIGER MENU" + edit-menu-lore: "SHIFT HØJREKLIK FOR AT GEMME" + regear-shulker-name: "Regear-Shulker" + regear-shell-name: "Regear-Skal" + + lore-click-edit: "● Klik for at redigere" + lore-click-create: "● Klik for at oprette" + lore-shift-clear: "● Shift-klik for at rydde" + lore-shift-delete-kit: "● Shift-klik for at slette kit" + lore-shift-delete-ec: "● Shift-klik for at slette enderkiste" + lore-shift-click: "● Shift-klik" + lore-import-inventory: "● Importer fra inventar" + lore-import-ec: "● Importer fra enderkiste" + lore-left-load: "● Venstreklik for at indlæse kit" + lore-right-edit: "● Højreklik for at redigere kit" + lore-share-kits: "● /sharekit " + lore-info-load: "● Klik på en kit-slot for at indlæse dit kit" + lore-info-edit: "● Højreklik eller klik på bogen for at redigere" + lore-info-share: "● Del kits med /sharekit " + lore-admin-shift-edit: "● [ADMIN] Shift-klik for at redigere" + lore-unassigned-info: "● Admins har ikke konfigureret dette kit endnu" + lore-regear-restocks: "● Genopfylder dit kit" + lore-regear-shulker-use: "● Brug {primary}/rg for at få en anden regear-shulker" + lore-regear-shell-click: "● Klik for at bruge!" diff --git a/src/main/resources/lang/de.yml b/src/main/resources/lang/de.yml new file mode 100644 index 0000000..ef466e9 --- /dev/null +++ b/src/main/resources/lang/de.yml @@ -0,0 +1,204 @@ +# PerPlayerKit Language File - German (Deutsch) +# Uses MiniMessage format: https://docs.advntr.dev/minimessage/format.html +# Placeholders use {name} syntax (e.g. {player}, {slot}). +# To use this file, set `language: de` in config.yml. + +prefix: "[Kits] " + +motd: + message: + - "" + - " Per-Spieler-Kits " + - "" + - " Tippe /kit, /k oder /pk, um zu beginnen!" + - "" + - " " + - "" + +scheduled-broadcast: + messages: + - "Schau dir öffentliche Kits mit dem Befehl /pk an!" + - "Möchtest du ein Kit teilen? Verwende /sharekit ." + - "Tippe /kit, /k oder /pk, um zu beginnen!" + +broadcast-messages: + player-repaired: "{player} hat seine Ausrüstung repariert" + player-healed: "{player} hat sich geheilt" + player-opened-kit-room: "{player} hat den Kit-Raum geöffnet" + player-loaded-private-kit: "{player} hat ein Kit geladen" + player-loaded-public-kit: "{player} hat ein öffentliches Kit geladen" + player-loaded-enderchest: "{player} hat eine Endertruhe geladen." + player-copied-kit: "{player} hat ein Kit kopiert" + player-copied-ec: "{player} hat eine Endertruhe kopiert" + player-regeared: "{player} hat sich neu ausgerüstet" + generic: "{player} hat eine Aktion ausgeführt." + +error: + disabled-in-world: "Kits sind hier deaktiviert!" + unexpected: "Ein unerwarteter Fehler ist aufgetreten, bitte erneut versuchen." + kit-not-found: "Fehler, dieses Kit existiert nicht" + kit-expired: "Fehler, Kit existiert nicht oder ist abgelaufen" + ec-not-found: "Fehler, diese Endertruhe existiert nicht" + empty-kit: "Du kannst kein leeres Kit speichern!" + empty-ec: "Du kannst keine leere Endertruhe speichern!" + kit-slot-not-found: "Kit {slot} existiert nicht!" + kit-deletion-failed: "Kit-Löschung fehlgeschlagen!" + invalid-number: "Wähle eine gültige Zahl" + invalid-numbers: "Wähle gültige Zahlen" + invalid-kit-slot: "Wähle einen gültigen Kit-Slot" + missing-kit-code: "Fehler, du musst einen Kit-Code zum Kopieren eingeben" + missing-kit-slot-share: "Fehler, du musst einen Kit-Slot zum Teilen auswählen" + missing-ec-slot-share: "Fehler, du musst einen Endertruhen-Slot zum Teilen auswählen" + command-cooldown: "Bitte spamme den Befehl nicht (5 Sekunden Wartezeit)" + regear-misconfigured: "Dieser Befehl ist nicht korrekt konfiguriert, bitte kontaktiere einen Administrator." + inventory-full: "Dein Inventar ist voll, ich kann dir keinen Regear-Shulker geben!" + no-kit-loaded: "Du hast noch kein Kit geladen!" + regear-elytra-blocked: "Du kannst dich nicht neu ausrüsten, während du Elytren benutzt!" + regear-combat-cooldown: "Du musst noch {seconds} Sekunden außerhalb des Kampfes sein, bevor du dich neu ausrüsten kannst!" + regear-command-cooldown: "Du musst {seconds} Sekunden warten, bevor du diesen Befehl erneut benutzen kannst!" + missing-arguments: "Fehlende Argumente!" + invalid-subcommand: "Ungültiger Unterbefehl!" + missing-import-type: "Fehlender Import-Typ!" + invalid-import-type: "Ungültiger Import-Typ!" + import-files-missing: "Dateien zum Importieren fehlen" + invalid-storage-type: "Ungültiger {role}-Speichertyp: {type}" + storage-same: "Quelle und Ziel dürfen nicht identisch sein!" + migration-failed: "Migration fehlgeschlagen: {error}" + missing-kit-id: "Du musst eine Kit-ID angeben" + public-kit-not-found: "Öffentliches Kit {kitid} existiert nicht" + add-public-kit-config: "Möglicherweise musst du ein öffentliches Kit in der Konfiguration hinzufügen" + public-kit-save-failed: "Fehler beim Speichern von Kit {kitid}" + incorrect-usage: "Falsche Verwendung!" + players-only: "Nur Spieler können diesen Befehl benutzen" + players-only-inspect: "Dieser Befehl kann nur von Spielern ausgeführt werden." + invalid-slot-range: "Der Slot muss eine Zahl zwischen {min} und {max} sein." + player-not-found: "Konnte keinen Spieler mit diesem Namen oder dieser UUID finden." + kit-not-found-display: "Kit nicht gefunden" + inspect-kit-missing: "{player} hat kein Kit in Slot {slot}" + inspect-ec-missing: "{player} hat keine Endertruhe in Slot {slot}" + inspect-kit-load-error: "Beim Laden der Kit-Daten ist ein Fehler aufgetreten. Siehe Konsole für Details." + inspect-ec-load-error: "Beim Laden der Endertruhen-Daten ist ein Fehler aufgetreten. Siehe Konsole für Details." + failed-to-update-kit: "Aktualisierung des Kits für Spieler {player} fehlgeschlagen!" + failed-to-update-ec: "Aktualisierung der Endertruhe für Spieler {player} fehlgeschlagen!" + invalid-command-label: "Ungültiges Befehls-Label." + prefix-tag: "Fehler: " + +success: + kit-saved: "Kit {slot} gespeichert!" + kit-loaded: "Kit {slot} geladen!" + kit-deleted: "Kit {slot} gelöscht!" + kits-swapped: "Kits {slot1} und {slot2} wurden getauscht!" + ec-saved: "Endertruhe {slot} gespeichert!" + ec-loaded: "Endertruhe {slot} geladen!" + public-kit-saved: "Öffentliches Kit {kitname} gespeichert!" + public-kit-loaded: "Öffentliches Kit geladen!" + public-kit-saved-admin: "Kit {kitid} gespeichert" + kitroom-loaded: "Kit-Raum aus SQL geladen" + kitroom-saved: "Kit-Raum in SQL gespeichert" + kitroom-menu-saved: "Kit-Raum-Menü gespeichert" + all-repaired: "Alle Gegenstände repariert!" + healed: "Du wurdest geheilt!" + shulker-given: "Regear-Shulker übergeben!" + regeared: "Neu ausgerüstet!" + inventory-cleared: "Inventar geleert" + admin-kit-deleted: "Kit {slot} für Spieler gelöscht!" + admin-ec-deleted: "Endertruhe {slot} für Spieler gelöscht!" + admin-kit-updated: "Kit {slot} für Spieler {player} aktualisiert!" + admin-ec-updated: "Endertruhe {slot} für Spieler {player} aktualisiert!" + migration-completed: "Migration erfolgreich abgeschlossen!" + migration-count: "Migriert: {count} Einträge" + import-attempted: "Import der KitsX-Daten versucht!" + import-starting: "Starte Import..." + +info: + custom-version-available: "Du kannst eine eigene Version dieses Kits speichern, indem du es in den Kit-Editor importierst" + assign-publickit-instruction: "Um diesem publickit ein Kit zuzuweisen, benutze /savepublickit " + share-kit-code: "Verwende /copykit {code}, um dieses Kit zu kopieren" + share-ec-code: "Verwende /copyEC {code}, um diese Endertruhe zu kopieren" + share-code-expiry: "Code läuft in 15 Minuten ab" + import-instructions: "Kopiere den Datenordner von KitsX in den PerPlayerKit-Ordner" + migration-starting: "Starte Migration von {source} nach {destination}..." + migration-large-dataset: "Dies kann bei großen Datensätzen eine Weile dauern. Siehe Konsole für Fortschritt." + available-storage-types: "Verfügbare Speichertypen: sqlite, mysql, redis, yml" + update-config-storage: "Denke daran, deine config.yml storage.type auf '{type}' zu aktualisieren und den Server neu zu starten." + migration-failed-count: "Fehlgeschlagen: {count} Einträge" + migration-progress: "{message}" + +command: + perplayerkit-about: "PerPlayerKit ist ein Plugin, das Spielern erlaubt, eigene Kits zu haben." + deletekit-usage: "Verwendung: /deletekit " + swapkit-usage: "Verwendung: /swapkit " + savepublickit-usage: "Verwendung: /{command} " + perplayerkit-migrate-usage: "Verwendung: /perplayerkit migrate " + kitroom-usage-hint: "/kitroom " + inspect-usage: "Verwendung: /{command} " + +update: + new-version-available: "Eine neue Version von PerPlayerKit ist verfügbar! Du verwendest Version {current}, die neueste Version ist {latest}" + +about: + header-start: "==========[Über]==========" + title: "PerPlayerKit" + author: "Autor: {author}" + license: "Lizenz: {license}" + source-code: "Quellcode: {source}" + version: "Version: {version}" + build-time: "Build-Zeit: {time}" + header-end: "==========================" + +gui: + main-menu-title: "{player}s Kits" + kit-editor-title: "Kit: {slot}" + public-kit-editor-title: "Öffentliches Kit: {id}" + enderchest-editor-title: "Endertruhe: {slot}" + inspect-kit-title: "Untersuche {player}s Kit {slot}" + inspect-ec-title: "Untersuche {player}s Endertruhe {slot}" + kit-room-title: "Kit-Raum" + public-kit-room-title: "Öffentlicher Kit-Raum" + view-public-kit-title: "Öffentliches Kit ansehen: {id}" + enderchest-view-title: "Endertruhe (nur Ansicht)" + regear-shulker-title: "Regear-Shulker" + + kit-slot-name: "Kit {slot}" + enderchest-slot-name: "Endertruhe {slot}" + kit-exists: "KIT VORHANDEN" + kit-not-found: "KIT NICHT GEFUNDEN" + more-kits-coming: "WEITERE KITS FOLGEN" + unassigned-tag: "[NICHT ZUGEWIESEN]" + import-button: "IMPORTIEREN" + clear-kit-button: "KIT LEEREN" + clear-ec-button: "ENDERTRUHE LEEREN" + back-button: "ZURÜCK" + close-button: "SCHLIESSEN" + load-kit-button: "KIT LADEN" + refill-button: "AUFFÜLLEN" + kit-room-button: "KIT-RAUM" + premade-kits-button: "VORGEFERTIGTE KITS" + info-button: "INFO" + clear-inventory-button: "INVENTAR LEEREN" + share-kits-button: "KITS TEILEN" + repair-items-button: "GEGENSTÄNDE REPARIEREN" + edit-menu-button: "MENÜ BEARBEITEN" + edit-menu-lore: "SHIFT RECHTSKLICK ZUM SPEICHERN" + regear-shulker-name: "Regear-Shulker" + regear-shell-name: "Regear-Hülle" + + lore-click-edit: "● Klicken zum Bearbeiten" + lore-click-create: "● Klicken zum Erstellen" + lore-shift-clear: "● Shift-Klick zum Leeren" + lore-shift-delete-kit: "● Shift-Klick zum Löschen des Kits" + lore-shift-delete-ec: "● Shift-Klick zum Löschen der Endertruhe" + lore-shift-click: "● Shift-Klick" + lore-import-inventory: "● Aus Inventar importieren" + lore-import-ec: "● Aus Endertruhe importieren" + lore-left-load: "● Linksklick zum Laden des Kits" + lore-right-edit: "● Rechtsklick zum Bearbeiten des Kits" + lore-share-kits: "● /sharekit " + lore-info-load: "● Klicke einen Kit-Slot an, um dein Kit zu laden" + lore-info-edit: "● Rechtsklick oder Klick auf das Buch zum Bearbeiten" + lore-info-share: "● Teile Kits mit /sharekit " + lore-admin-shift-edit: "● [ADMIN] Shift-Klick zum Bearbeiten" + lore-unassigned-info: "● Admins haben dieses Kit noch nicht eingerichtet" + lore-regear-restocks: "● Füllt dein Kit auf" + lore-regear-shulker-use: "● Verwende {primary}/rg um einen weiteren Regear-Shulker zu erhalten" + lore-regear-shell-click: "● Klicken zum Benutzen!" diff --git a/src/main/resources/lang/en.yml b/src/main/resources/lang/en.yml new file mode 100644 index 0000000..091927f --- /dev/null +++ b/src/main/resources/lang/en.yml @@ -0,0 +1,208 @@ +# PerPlayerKit Language File - English +# Uses MiniMessage format: https://docs.advntr.dev/minimessage/format.html +# Placeholders use {name} syntax (e.g. {player}, {slot}). +# To use this file, set `language: en` in config.yml. + +prefix: "[Kits] " + +motd: + message: + - "" + - " Per Player Kits " + - "" + - " Type /kit, /k or /pk to get started!" + - "" + - " " + - "" + +scheduled-broadcast: + messages: + - "Check out public kits with the /pk command!" + - "Want to share a kit? Use the /sharekit command!" + - "Type /kit, /k or /pk to get started!" + +# Broadcast messages shown when a player performs an action (configured in config.yml messages.*). +broadcast-messages: + player-repaired: "{player} repaired their gear" + player-healed: "{player} healed themselves" + player-opened-kit-room: "{player} opened the Kit Room" + player-loaded-private-kit: "{player} loaded a kit" + player-loaded-public-kit: "{player} loaded a public kit" + player-loaded-enderchest: "{player} loaded an ender chest." + player-copied-kit: "{player} copied a kit" + player-copied-ec: "{player} copied an ender chest" + player-regeared: "{player} regeared" + generic: "{player} performed an action." + +error: + disabled-in-world: "Kits are disabled here!" + unexpected: "Unexpected error occurred, please try again." + kit-not-found: "Error, that kit does not exist" + kit-expired: "Error, kit does not exist or has expired" + ec-not-found: "Error, that EC does not exist" + empty-kit: "You cant save an empty kit!" + empty-ec: "You cant save an empty enderchest!" + kit-slot-not-found: "Kit {slot} doesnt exist!" + kit-deletion-failed: "Kit deletion failed!" + invalid-number: "Select a real number" + invalid-numbers: "Select real numbers" + invalid-kit-slot: "Select a valid kit slot" + missing-kit-code: "Error, you must enter a kit code to copy" + missing-kit-slot-share: "Error, you must select a kit slot to share" + missing-ec-slot-share: "Error, you must select an EC slot to share" + command-cooldown: "Please don't spam the command (5 second cooldown)" + regear-misconfigured: "This command is not configured correctly, please contact an administrator." + inventory-full: "Your inventory is full, can't give you a regear shulker!" + no-kit-loaded: "You have not loaded a kit yet!" + regear-elytra-blocked: "You cannot regear while using an elytra!" + regear-combat-cooldown: "You must be out of combat for {seconds} more seconds before regearing!" + regear-command-cooldown: "You must wait {seconds} seconds before using this command again!" + missing-arguments: "Missing arguments!" + invalid-subcommand: "Invalid subcommand!" + missing-import-type: "Missing import type!" + invalid-import-type: "Invalid import type!" + import-files-missing: "Missing files to import" + invalid-storage-type: "Invalid {role} storage type: {type}" + storage-same: "Source and destination cannot be the same!" + migration-failed: "Migration failed: {error}" + missing-kit-id: "You need to specify a kit id" + public-kit-not-found: "Public kit {kitid} does not exist" + add-public-kit-config: "You may need to add a public kit in the config" + public-kit-save-failed: "Error saving kit {kitid}" + incorrect-usage: "Incorrect Usage!" + players-only: "Only players can use this command" + players-only-inspect: "This command can only be executed by players." + invalid-slot-range: "Slot must be a number between {min} and {max}." + player-not-found: "Could not find a player with that name or UUID." + kit-not-found-display: "Kit not found" + inspect-kit-missing: "{player} does not have a kit in slot {slot}" + inspect-ec-missing: "{player} does not have an enderchest in slot {slot}" + inspect-kit-load-error: "An error occurred while loading kit data. See console for details." + inspect-ec-load-error: "An error occurred while loading enderchest data. See console for details." + failed-to-update-kit: "Failed to update kit for player {player}!" + failed-to-update-ec: "Failed to update enderchest for player {player}!" + invalid-command-label: "Invalid command label." + prefix-tag: "Error: " + +success: + kit-saved: "Kit {slot} saved!" + kit-loaded: "Kit {slot} loaded!" + kit-deleted: "Kit {slot} deleted!" + kits-swapped: "Kits {slot1} and {slot2} have been swapped!" + ec-saved: "Enderchest {slot} saved!" + ec-loaded: "Enderchest {slot} loaded!" + public-kit-saved: "Public Kit {kitname} saved!" + public-kit-loaded: "Public Kit loaded!" + public-kit-saved-admin: "Saved kit {kitid}" + kitroom-loaded: "Kit Room loaded from SQL" + kitroom-saved: "Kit Room saved to SQL" + kitroom-menu-saved: "Kit room menu saved" + all-repaired: "All items repaired!" + healed: "You have been healed!" + shulker-given: "Regear Shulker given!" + regeared: "Regeared!" + inventory-cleared: "Inventory cleared" + admin-kit-deleted: "Kit {slot} deleted for player!" + admin-ec-deleted: "Enderchest {slot} deleted for player!" + admin-kit-updated: "Kit {slot} updated for player {player}!" + admin-ec-updated: "Enderchest {slot} updated for player {player}!" + migration-completed: "Migration completed successfully!" + migration-count: "Migrated: {count} entries" + import-attempted: "Attempted import of KitsX data!" + import-starting: "Starting import..." + +info: + custom-version-available: "You can save a custom version of this kit by importing into the kit editor" + assign-publickit-instruction: "To assign a kit to this publickit use /savepublickit " + share-kit-code: "Use /copykit {code} to copy this kit" + share-ec-code: "Use /copyEC {code} to copy this enderchest" + share-code-expiry: "Code expires in 15 minutes" + import-instructions: "Copy data folder from KitsX into the PerPlayerKit folder" + migration-starting: "Starting migration from {source} to {destination}..." + migration-large-dataset: "This may take a while for large datasets. Check console for progress." + available-storage-types: "Available storage types: sqlite, mysql, redis, yml" + update-config-storage: "Remember to update your config.yml storage.type to '{type}' and restart the server." + migration-failed-count: "Failed: {count} entries" + migration-progress: "{message}" + +command: + perplayerkit-about: "PerPlayerKit is a plugin that allows players to have their own kits." + deletekit-usage: "Usage: /deletekit " + swapkit-usage: "Usage: /swapkit " + savepublickit-usage: "Usage: /{command} " + perplayerkit-migrate-usage: "Usage: /perplayerkit migrate " + kitroom-usage-hint: "/kitroom " + inspect-usage: "Usage: /{command} " + +update: + new-version-available: "A new version of PerPlayerKit is available! You are running version {current} and the latest version is {latest}" + +about: + header-start: "==========[About]==========" + title: "PerPlayerKit" + author: "Author: {author}" + license: "License: {license}" + source-code: "Source Code: {source}" + version: "Version: {version}" + build-time: "Build Time: {time}" + header-end: "===========================" + +gui: + # Inventory titles + main-menu-title: "{player}'s Kits" + kit-editor-title: "Kit: {slot}" + public-kit-editor-title: "Public Kit: {id}" + enderchest-editor-title: "Enderchest: {slot}" + inspect-kit-title: "Inspecting {player}'s kit {slot}" + inspect-ec-title: "Inspecting {player}'s enderchest {slot}" + kit-room-title: "Kit Room" + public-kit-room-title: "Public Kit Room" + view-public-kit-title: "Viewing Public Kit: {id}" + enderchest-view-title: "View Only Enderchest" + regear-shulker-title: "Regear Shulker" + + # Item display names + kit-slot-name: "Kit {slot}" + enderchest-slot-name: "Enderchest {slot}" + kit-exists: "KIT EXISTS" + kit-not-found: "KIT NOT FOUND" + more-kits-coming: "MORE KITS COMING SOON" + unassigned-tag: "[UNASSIGNED]" + import-button: "IMPORT" + clear-kit-button: "CLEAR KIT" + clear-ec-button: "CLEAR ENDERCHEST" + back-button: "BACK" + close-button: "CLOSE" + load-kit-button: "LOAD KIT" + refill-button: "REFILL" + kit-room-button: "KIT ROOM" + premade-kits-button: "PREMADE KITS" + info-button: "INFO" + clear-inventory-button: "CLEAR INVENTORY" + share-kits-button: "SHARE KITS" + repair-items-button: "REPAIR ITEMS" + edit-menu-button: "EDIT MENU" + edit-menu-lore: "SHIFT RIGHT CLICK TO SAVE" + regear-shulker-name: "Regear Shulker" + regear-shell-name: "Regear Shell" + + # Lores (item tooltip lines) + lore-click-edit: "● Click to edit" + lore-click-create: "● Click to create" + lore-shift-clear: "● Shift click to clear" + lore-shift-delete-kit: "● Shift click to delete kit" + lore-shift-delete-ec: "● Shift click to delete enderchest" + lore-shift-click: "● Shift click" + lore-import-inventory: "● Import from inventory" + lore-import-ec: "● Import from enderchest" + lore-left-load: "● Left click to load kit" + lore-right-edit: "● Right click to edit kit" + lore-share-kits: "● /sharekit " + lore-info-load: "● Click a kit slot to load your kit" + lore-info-edit: "● Right click or click the book to edit" + lore-info-share: "● Share kits with /sharekit " + lore-admin-shift-edit: "● [ADMIN] Shift click to edit" + lore-unassigned-info: "● Admins have not yet setup this kit yet" + lore-regear-restocks: "● Restocks Your Kit" + lore-regear-shulker-use: "● Use {primary}/rg to get another regear shulker" + lore-regear-shell-click: "● Click to use!" diff --git a/src/main/resources/lang/es.yml b/src/main/resources/lang/es.yml new file mode 100644 index 0000000..178d2f9 --- /dev/null +++ b/src/main/resources/lang/es.yml @@ -0,0 +1,204 @@ +# PerPlayerKit Language File - Spanish (Español) +# Uses MiniMessage format: https://docs.advntr.dev/minimessage/format.html +# Placeholders use {name} syntax (e.g. {player}, {slot}). +# To use this file, set `language: es` in config.yml. + +prefix: "[Kits] " + +motd: + message: + - "" + - " Kits Por Jugador " + - "" + - " Escribe /kit, /k o /pk para comenzar." + - "" + - " " + - "" + +scheduled-broadcast: + messages: + - "¡Mira los kits públicos con el comando /pk!" + - "¿Quieres compartir un kit? Usa /sharekit ." + - "Escribe /kit, /k o /pk para comenzar." + +broadcast-messages: + player-repaired: "{player} reparó su equipo" + player-healed: "{player} se curó" + player-opened-kit-room: "{player} abrió la Sala de Kits" + player-loaded-private-kit: "{player} cargó un kit" + player-loaded-public-kit: "{player} cargó un kit público" + player-loaded-enderchest: "{player} cargó un cofre de ender." + player-copied-kit: "{player} copió un kit" + player-copied-ec: "{player} copió un cofre de ender" + player-regeared: "{player} reequipó" + generic: "{player} realizó una acción." + +error: + disabled-in-world: "¡Los kits están deshabilitados aquí!" + unexpected: "Ocurrió un error inesperado, inténtalo de nuevo." + kit-not-found: "Error, ese kit no existe" + kit-expired: "Error, el kit no existe o ha expirado" + ec-not-found: "Error, ese cofre de ender no existe" + empty-kit: "¡No puedes guardar un kit vacío!" + empty-ec: "¡No puedes guardar un cofre de ender vacío!" + kit-slot-not-found: "¡El kit {slot} no existe!" + kit-deletion-failed: "¡Error al eliminar el kit!" + invalid-number: "Selecciona un número válido" + invalid-numbers: "Selecciona números válidos" + invalid-kit-slot: "Selecciona una ranura de kit válida" + missing-kit-code: "Error, debes ingresar un código de kit para copiar" + missing-kit-slot-share: "Error, debes seleccionar una ranura de kit para compartir" + missing-ec-slot-share: "Error, debes seleccionar una ranura de cofre de ender para compartir" + command-cooldown: "Por favor no envíes spam con el comando (5 segundos de espera)" + regear-misconfigured: "Este comando no está configurado correctamente, contacta a un administrador." + inventory-full: "¡Tu inventario está lleno, no se puede entregar un shulker de reequipo!" + no-kit-loaded: "¡Aún no has cargado un kit!" + regear-elytra-blocked: "¡No puedes reequiparte mientras usas una élitra!" + regear-combat-cooldown: "¡Debes estar fuera de combate por {seconds} segundos más antes de reequiparte!" + regear-command-cooldown: "¡Debes esperar {seconds} segundos antes de usar este comando otra vez!" + missing-arguments: "¡Faltan argumentos!" + invalid-subcommand: "¡Subcomando inválido!" + missing-import-type: "¡Falta el tipo de importación!" + invalid-import-type: "¡Tipo de importación inválido!" + import-files-missing: "Faltan archivos para importar" + invalid-storage-type: "Tipo de almacenamiento {role} inválido: {type}" + storage-same: "¡El origen y el destino no pueden ser iguales!" + migration-failed: "Migración fallida: {error}" + missing-kit-id: "Debes especificar un id de kit" + public-kit-not-found: "El kit público {kitid} no existe" + add-public-kit-config: "Puede que necesites añadir un kit público en la configuración" + public-kit-save-failed: "Error guardando el kit {kitid}" + incorrect-usage: "¡Uso incorrecto!" + players-only: "Solo los jugadores pueden usar este comando" + players-only-inspect: "Este comando solo puede ser ejecutado por jugadores." + invalid-slot-range: "La ranura debe ser un número entre {min} y {max}." + player-not-found: "No se encontró un jugador con ese nombre o UUID." + kit-not-found-display: "Kit no encontrado" + inspect-kit-missing: "{player} no tiene un kit en la ranura {slot}" + inspect-ec-missing: "{player} no tiene un cofre de ender en la ranura {slot}" + inspect-kit-load-error: "Ocurrió un error al cargar los datos del kit. Mira la consola para más detalles." + inspect-ec-load-error: "Ocurrió un error al cargar los datos del cofre de ender. Mira la consola para más detalles." + failed-to-update-kit: "¡Error al actualizar el kit del jugador {player}!" + failed-to-update-ec: "¡Error al actualizar el cofre de ender del jugador {player}!" + invalid-command-label: "Etiqueta de comando inválida." + prefix-tag: "Error: " + +success: + kit-saved: "¡Kit {slot} guardado!" + kit-loaded: "¡Kit {slot} cargado!" + kit-deleted: "¡Kit {slot} eliminado!" + kits-swapped: "¡Los kits {slot1} y {slot2} han sido intercambiados!" + ec-saved: "¡Cofre de ender {slot} guardado!" + ec-loaded: "¡Cofre de ender {slot} cargado!" + public-kit-saved: "¡Kit público {kitname} guardado!" + public-kit-loaded: "¡Kit público cargado!" + public-kit-saved-admin: "Kit {kitid} guardado" + kitroom-loaded: "Sala de kits cargada desde SQL" + kitroom-saved: "Sala de kits guardada en SQL" + kitroom-menu-saved: "Menú de la sala de kits guardado" + all-repaired: "¡Todos los objetos reparados!" + healed: "¡Has sido curado!" + shulker-given: "¡Shulker de reequipo entregado!" + regeared: "¡Reequipado!" + inventory-cleared: "Inventario vaciado" + admin-kit-deleted: "¡Kit {slot} eliminado para el jugador!" + admin-ec-deleted: "¡Cofre de ender {slot} eliminado para el jugador!" + admin-kit-updated: "¡Kit {slot} actualizado para el jugador {player}!" + admin-ec-updated: "¡Cofre de ender {slot} actualizado para el jugador {player}!" + migration-completed: "¡Migración completada con éxito!" + migration-count: "Migrados: {count} registros" + import-attempted: "¡Importación de datos KitsX intentada!" + import-starting: "Iniciando importación..." + +info: + custom-version-available: "Puedes guardar una versión personalizada de este kit importándolo en el editor" + assign-publickit-instruction: "Para asignar un kit a este publickit usa /savepublickit " + share-kit-code: "Usa /copykit {code} para copiar este kit" + share-ec-code: "Usa /copyEC {code} para copiar este cofre de ender" + share-code-expiry: "El código expira en 15 minutos" + import-instructions: "Copia la carpeta de datos de KitsX a la carpeta PerPlayerKit" + migration-starting: "Iniciando migración de {source} a {destination}..." + migration-large-dataset: "Esto puede tardar para conjuntos de datos grandes. Mira la consola para el progreso." + available-storage-types: "Tipos de almacenamiento disponibles: sqlite, mysql, redis, yml" + update-config-storage: "Recuerda actualizar tu config.yml storage.type a '{type}' y reiniciar el servidor." + migration-failed-count: "Fallidos: {count} registros" + migration-progress: "{message}" + +command: + perplayerkit-about: "PerPlayerKit es un plugin que permite a los jugadores tener sus propios kits." + deletekit-usage: "Uso: /deletekit " + swapkit-usage: "Uso: /swapkit " + savepublickit-usage: "Uso: /{command} " + perplayerkit-migrate-usage: "Uso: /perplayerkit migrate " + kitroom-usage-hint: "/kitroom " + inspect-usage: "Uso: /{command} " + +update: + new-version-available: "¡Hay una nueva versión de PerPlayerKit disponible! Estás usando la versión {current} y la última es {latest}" + +about: + header-start: "==========[Acerca de]==========" + title: "PerPlayerKit" + author: "Autor: {author}" + license: "Licencia: {license}" + source-code: "Código fuente: {source}" + version: "Versión: {version}" + build-time: "Compilado: {time}" + header-end: "===============================" + +gui: + main-menu-title: "Kits de {player}" + kit-editor-title: "Kit: {slot}" + public-kit-editor-title: "Kit Público: {id}" + enderchest-editor-title: "Cofre de Ender: {slot}" + inspect-kit-title: "Inspeccionando kit {slot} de {player}" + inspect-ec-title: "Inspeccionando cofre de ender {slot} de {player}" + kit-room-title: "Sala de Kits" + public-kit-room-title: "Sala de Kits Públicos" + view-public-kit-title: "Viendo Kit Público: {id}" + enderchest-view-title: "Cofre de Ender (Solo Vista)" + regear-shulker-title: "Shulker de Reequipo" + + kit-slot-name: "Kit {slot}" + enderchest-slot-name: "Cofre de Ender {slot}" + kit-exists: "KIT EXISTE" + kit-not-found: "KIT NO ENCONTRADO" + more-kits-coming: "MÁS KITS PRONTO" + unassigned-tag: "[SIN ASIGNAR]" + import-button: "IMPORTAR" + clear-kit-button: "LIMPIAR KIT" + clear-ec-button: "LIMPIAR COFRE ENDER" + back-button: "ATRÁS" + close-button: "CERRAR" + load-kit-button: "CARGAR KIT" + refill-button: "RELLENAR" + kit-room-button: "SALA DE KITS" + premade-kits-button: "KITS PREDEFINIDOS" + info-button: "INFO" + clear-inventory-button: "VACIAR INVENTARIO" + share-kits-button: "COMPARTIR KITS" + repair-items-button: "REPARAR OBJETOS" + edit-menu-button: "EDITAR MENÚ" + edit-menu-lore: "SHIFT CLIC DERECHO PARA GUARDAR" + regear-shulker-name: "Shulker de Reequipo" + regear-shell-name: "Concha de Reequipo" + + lore-click-edit: "● Clic para editar" + lore-click-create: "● Clic para crear" + lore-shift-clear: "● Shift clic para limpiar" + lore-shift-delete-kit: "● Shift clic para eliminar kit" + lore-shift-delete-ec: "● Shift clic para eliminar cofre de ender" + lore-shift-click: "● Shift clic" + lore-import-inventory: "● Importar desde inventario" + lore-import-ec: "● Importar desde cofre de ender" + lore-left-load: "● Clic izquierdo para cargar kit" + lore-right-edit: "● Clic derecho para editar kit" + lore-share-kits: "● /sharekit " + lore-info-load: "● Clic en una ranura para cargar tu kit" + lore-info-edit: "● Clic derecho o en el libro para editar" + lore-info-share: "● Comparte kits con /sharekit " + lore-admin-shift-edit: "● [ADMIN] Shift clic para editar" + lore-unassigned-info: "● Los admins aún no han configurado este kit" + lore-regear-restocks: "● Reabastece tu kit" + lore-regear-shulker-use: "● Usa {primary}/rg para obtener otro shulker de reequipo" + lore-regear-shell-click: "● ¡Clic para usar!" diff --git a/src/main/resources/lang/fi.yml b/src/main/resources/lang/fi.yml new file mode 100644 index 0000000..36030da --- /dev/null +++ b/src/main/resources/lang/fi.yml @@ -0,0 +1,204 @@ +# PerPlayerKit Language File - Finnish (Suomi) +# Uses MiniMessage format: https://docs.advntr.dev/minimessage/format.html +# Placeholders use {name} syntax (e.g. {player}, {slot}). +# To use this file, set `language: fi` in config.yml. + +prefix: "[Kitit] " + +motd: + message: + - "" + - " Pelaajakohtaiset Kitit " + - "" + - " Kirjoita /kit, /k tai /pk aloittaaksesi!" + - "" + - " " + - "" + +scheduled-broadcast: + messages: + - "Katso julkiset kitit komennolla /pk!" + - "Haluatko jakaa kitin? Käytä /sharekit ." + - "Kirjoita /kit, /k tai /pk aloittaaksesi!" + +broadcast-messages: + player-repaired: "{player} korjasi varusteensa" + player-healed: "{player} paransi itsensä" + player-opened-kit-room: "{player} avasi kittihuoneen" + player-loaded-private-kit: "{player} latasi kitin" + player-loaded-public-kit: "{player} latasi julkisen kitin" + player-loaded-enderchest: "{player} latasi ender-arkun." + player-copied-kit: "{player} kopioi kitin" + player-copied-ec: "{player} kopioi ender-arkun" + player-regeared: "{player} varusti itsensä uudelleen" + generic: "{player} suoritti toiminnon." + +error: + disabled-in-world: "Kitit on poistettu käytöstä täällä!" + unexpected: "Tapahtui odottamaton virhe, yritä uudelleen." + kit-not-found: "Virhe, kittiä ei ole olemassa" + kit-expired: "Virhe, kittiä ei ole olemassa tai se on vanhentunut" + ec-not-found: "Virhe, ender-arkkua ei ole olemassa" + empty-kit: "Et voi tallentaa tyhjää kittiä!" + empty-ec: "Et voi tallentaa tyhjää ender-arkkua!" + kit-slot-not-found: "Kittiä {slot} ei ole olemassa!" + kit-deletion-failed: "Kitin poisto epäonnistui!" + invalid-number: "Valitse kelvollinen numero" + invalid-numbers: "Valitse kelvolliset numerot" + invalid-kit-slot: "Valitse kelvollinen kitti-paikka" + missing-kit-code: "Virhe, sinun täytyy syöttää kittikoodi kopioidaksesi" + missing-kit-slot-share: "Virhe, sinun täytyy valita kitti-paikka jaettavaksi" + missing-ec-slot-share: "Virhe, sinun täytyy valita ender-arkun paikka jaettavaksi" + command-cooldown: "Älä spämmää komentoa (5 sekunnin jäähy)" + regear-misconfigured: "Tätä komentoa ei ole asetettu oikein, ota yhteyttä ylläpitäjään." + inventory-full: "Tavaraluettelosi on täynnä, ei voida antaa regear-shulkeria!" + no-kit-loaded: "Et ole ladannut kittiä vielä!" + regear-elytra-blocked: "Et voi varustaa uudelleen käyttäessäsi elytraa!" + regear-combat-cooldown: "Sinun on oltava taistelun ulkopuolella vielä {seconds} sekuntia ennen uudelleenvarustusta!" + regear-command-cooldown: "Sinun on odotettava {seconds} sekuntia ennen tämän komennon uudelleenkäyttöä!" + missing-arguments: "Argumentteja puuttuu!" + invalid-subcommand: "Virheellinen alikomento!" + missing-import-type: "Tuontityyppi puuttuu!" + invalid-import-type: "Virheellinen tuontityyppi!" + import-files-missing: "Tuotavia tiedostoja puuttuu" + invalid-storage-type: "Virheellinen {role}-tallennustyyppi: {type}" + storage-same: "Lähde ja kohde eivät voi olla samat!" + migration-failed: "Migraatio epäonnistui: {error}" + missing-kit-id: "Sinun on määritettävä kitti-id" + public-kit-not-found: "Julkista kittiä {kitid} ei ole olemassa" + add-public-kit-config: "Saatat joutua lisäämään julkisen kitin asetuksiin" + public-kit-save-failed: "Virhe tallennettaessa kittiä {kitid}" + incorrect-usage: "Virheellinen käyttö!" + players-only: "Vain pelaajat voivat käyttää tätä komentoa" + players-only-inspect: "Vain pelaajat voivat suorittaa tämän komennon." + invalid-slot-range: "Paikan on oltava luku väliltä {min} ja {max}." + player-not-found: "Pelaajaa tällä nimellä tai UUID:llä ei löytynyt." + kit-not-found-display: "Kittiä ei löytynyt" + inspect-kit-missing: "Pelaajalla {player} ei ole kittiä paikassa {slot}" + inspect-ec-missing: "Pelaajalla {player} ei ole ender-arkkua paikassa {slot}" + inspect-kit-load-error: "Virhe ladattaessa kitti-tietoja. Katso lisätietoja konsolista." + inspect-ec-load-error: "Virhe ladattaessa ender-arkun tietoja. Katso lisätietoja konsolista." + failed-to-update-kit: "Pelaajan {player} kitin päivitys epäonnistui!" + failed-to-update-ec: "Pelaajan {player} ender-arkun päivitys epäonnistui!" + invalid-command-label: "Virheellinen komentolappu." + prefix-tag: "Virhe: " + +success: + kit-saved: "Kitti {slot} tallennettu!" + kit-loaded: "Kitti {slot} ladattu!" + kit-deleted: "Kitti {slot} poistettu!" + kits-swapped: "Kitit {slot1} ja {slot2} on vaihdettu!" + ec-saved: "Ender-arkku {slot} tallennettu!" + ec-loaded: "Ender-arkku {slot} ladattu!" + public-kit-saved: "Julkinen kitti {kitname} tallennettu!" + public-kit-loaded: "Julkinen kitti ladattu!" + public-kit-saved-admin: "Tallennettu kitti {kitid}" + kitroom-loaded: "Kittihuone ladattu SQL:stä" + kitroom-saved: "Kittihuone tallennettu SQL:ään" + kitroom-menu-saved: "Kittihuoneen valikko tallennettu" + all-repaired: "Kaikki esineet korjattu!" + healed: "Sinut on parannettu!" + shulker-given: "Regear-shulker annettu!" + regeared: "Uudelleenvarustettu!" + inventory-cleared: "Tavaraluettelo tyhjennetty" + admin-kit-deleted: "Kitti {slot} poistettu pelaajalta!" + admin-ec-deleted: "Ender-arkku {slot} poistettu pelaajalta!" + admin-kit-updated: "Kitti {slot} päivitetty pelaajalle {player}!" + admin-ec-updated: "Ender-arkku {slot} päivitetty pelaajalle {player}!" + migration-completed: "Migraatio valmistui onnistuneesti!" + migration-count: "Siirretty: {count} merkintää" + import-attempted: "Yritettiin KitsX-datan tuontia!" + import-starting: "Aloitetaan tuonti..." + +info: + custom-version-available: "Voit tallentaa oman version tästä kitistä tuomalla sen kittieditoriin" + assign-publickit-instruction: "Asettaaksesi kitin tälle publickitille käytä /savepublickit " + share-kit-code: "Käytä /copykit {code} kopioidaksesi tämän kitin" + share-ec-code: "Käytä /copyEC {code} kopioidaksesi tämän ender-arkun" + share-code-expiry: "Koodi vanhenee 15 minuutissa" + import-instructions: "Kopioi datakansio KitsX:stä PerPlayerKit-kansioon" + migration-starting: "Aloitetaan migraatio lähteestä {source} kohteeseen {destination}..." + migration-large-dataset: "Tämä voi kestää hetken suurille tietoaineistoille. Tarkista konsolista edistyminen." + available-storage-types: "Käytettävissä olevat tallennustyypit: sqlite, mysql, redis, yml" + update-config-storage: "Muista päivittää config.yml storage.type arvoon '{type}' ja käynnistää palvelin uudelleen." + migration-failed-count: "Epäonnistui: {count} merkintää" + migration-progress: "{message}" + +command: + perplayerkit-about: "PerPlayerKit on lisäosa, joka antaa pelaajille omat kitit." + deletekit-usage: "Käyttö: /deletekit " + swapkit-usage: "Käyttö: /swapkit " + savepublickit-usage: "Käyttö: /{command} " + perplayerkit-migrate-usage: "Käyttö: /perplayerkit migrate " + kitroom-usage-hint: "/kitroom " + inspect-usage: "Käyttö: /{command} " + +update: + new-version-available: "PerPlayerKitistä on saatavilla uusi versio! Käytät versiota {current} ja uusin versio on {latest}" + +about: + header-start: "==========[Tietoja]==========" + title: "PerPlayerKit" + author: "Tekijä: {author}" + license: "Lisenssi: {license}" + source-code: "Lähdekoodi: {source}" + version: "Versio: {version}" + build-time: "Käännösaika: {time}" + header-end: "=============================" + +gui: + main-menu-title: "Pelaajan {player} Kitit" + kit-editor-title: "Kitti: {slot}" + public-kit-editor-title: "Julkinen Kitti: {id}" + enderchest-editor-title: "Ender-arkku: {slot}" + inspect-kit-title: "Tarkastellaan pelaajan {player} kittiä {slot}" + inspect-ec-title: "Tarkastellaan pelaajan {player} ender-arkkua {slot}" + kit-room-title: "Kittihuone" + public-kit-room-title: "Julkinen Kittihuone" + view-public-kit-title: "Tarkastellaan julkista kittiä: {id}" + enderchest-view-title: "Vain Katselu Ender-arkku" + regear-shulker-title: "Regear-Shulker" + + kit-slot-name: "Kitti {slot}" + enderchest-slot-name: "Ender-arkku {slot}" + kit-exists: "KITTI ON OLEMASSA" + kit-not-found: "KITTIÄ EI LÖYTYNYT" + more-kits-coming: "LISÄÄ KITTEJÄ TULOSSA" + unassigned-tag: "[EI MÄÄRITETTY]" + import-button: "TUO" + clear-kit-button: "TYHJENNÄ KITTI" + clear-ec-button: "TYHJENNÄ ENDER-ARKKU" + back-button: "TAKAISIN" + close-button: "SULJE" + load-kit-button: "LATAA KITTI" + refill-button: "TÄYTÄ UUDELLEEN" + kit-room-button: "KITTIHUONE" + premade-kits-button: "VALMIIT KITIT" + info-button: "TIETOJA" + clear-inventory-button: "TYHJENNÄ TAVARALUETTELO" + share-kits-button: "JAA KITIT" + repair-items-button: "KORJAA ESINEET" + edit-menu-button: "MUOKKAA VALIKKOA" + edit-menu-lore: "SHIFT OIKEA KLIKKAUS TALLENTAAKSESI" + regear-shulker-name: "Regear-Shulker" + regear-shell-name: "Regear-Kuori" + + lore-click-edit: "● Klikkaa muokataksesi" + lore-click-create: "● Klikkaa luodaksesi" + lore-shift-clear: "● Shift-klikkaus tyhjentääksesi" + lore-shift-delete-kit: "● Shift-klikkaus poistaaksesi kitin" + lore-shift-delete-ec: "● Shift-klikkaus poistaaksesi ender-arkun" + lore-shift-click: "● Shift-klikkaus" + lore-import-inventory: "● Tuo tavaraluettelosta" + lore-import-ec: "● Tuo ender-arkusta" + lore-left-load: "● Vasen klikkaus ladataksesi kitin" + lore-right-edit: "● Oikea klikkaus muokataksesi kittiä" + lore-share-kits: "● /sharekit " + lore-info-load: "● Klikkaa kitin paikkaa ladataksesi kittisi" + lore-info-edit: "● Oikea klikkaus tai kirjan klikkaus muokataksesi" + lore-info-share: "● Jaa kittejä komennolla /sharekit " + lore-admin-shift-edit: "● [ADMIN] Shift-klikkaus muokataksesi" + lore-unassigned-info: "● Ylläpitäjät eivät ole vielä asettaneet tätä kittiä" + lore-regear-restocks: "● Täydentää kittisi" + lore-regear-shulker-use: "● Käytä {primary}/rg saadaksesi toisen regear-shulkerin" + lore-regear-shell-click: "● Klikkaa käyttääksesi!" diff --git a/src/main/resources/lang/fr.yml b/src/main/resources/lang/fr.yml new file mode 100644 index 0000000..9dad8c3 --- /dev/null +++ b/src/main/resources/lang/fr.yml @@ -0,0 +1,204 @@ +# PerPlayerKit Language File - French (Français) +# Uses MiniMessage format: https://docs.advntr.dev/minimessage/format.html +# Placeholders use {name} syntax (e.g. {player}, {slot}). +# To use this file, set `language: fr` in config.yml. + +prefix: "[Kits] " + +motd: + message: + - "" + - " Kits Par Joueur " + - "" + - " Tapez /kit, /k ou /pk pour commencer !" + - "" + - " " + - "" + +scheduled-broadcast: + messages: + - "Découvrez les kits publics avec la commande /pk !" + - "Vous voulez partager un kit ? Utilisez /sharekit ." + - "Tapez /kit, /k ou /pk pour commencer !" + +broadcast-messages: + player-repaired: "{player} a réparé son équipement" + player-healed: "{player} s'est soigné" + player-opened-kit-room: "{player} a ouvert la Salle des Kits" + player-loaded-private-kit: "{player} a chargé un kit" + player-loaded-public-kit: "{player} a chargé un kit public" + player-loaded-enderchest: "{player} a chargé un ender chest." + player-copied-kit: "{player} a copié un kit" + player-copied-ec: "{player} a copié un ender chest" + player-regeared: "{player} s'est rééquipé" + generic: "{player} a effectué une action." + +error: + disabled-in-world: "Les kits sont désactivés ici !" + unexpected: "Une erreur inattendue s'est produite, veuillez réessayer." + kit-not-found: "Erreur, ce kit n'existe pas" + kit-expired: "Erreur, le kit n'existe pas ou a expiré" + ec-not-found: "Erreur, cet ender chest n'existe pas" + empty-kit: "Vous ne pouvez pas sauvegarder un kit vide !" + empty-ec: "Vous ne pouvez pas sauvegarder un ender chest vide !" + kit-slot-not-found: "Le kit {slot} n'existe pas !" + kit-deletion-failed: "Échec de la suppression du kit !" + invalid-number: "Choisissez un nombre valide" + invalid-numbers: "Choisissez des nombres valides" + invalid-kit-slot: "Choisissez un emplacement de kit valide" + missing-kit-code: "Erreur, vous devez entrer un code de kit à copier" + missing-kit-slot-share: "Erreur, vous devez sélectionner un emplacement de kit à partager" + missing-ec-slot-share: "Erreur, vous devez sélectionner un emplacement EC à partager" + command-cooldown: "Ne spammez pas la commande (5 secondes de délai)" + regear-misconfigured: "Cette commande n'est pas configurée correctement, contactez un administrateur." + inventory-full: "Votre inventaire est plein, impossible de vous donner un shulker de rééquipement !" + no-kit-loaded: "Vous n'avez pas encore chargé de kit !" + regear-elytra-blocked: "Vous ne pouvez pas vous rééquiper en utilisant une élytre !" + regear-combat-cooldown: "Vous devez être hors combat pendant {seconds} secondes supplémentaires avant de vous rééquiper !" + regear-command-cooldown: "Vous devez attendre {seconds} secondes avant de réutiliser cette commande !" + missing-arguments: "Arguments manquants !" + invalid-subcommand: "Sous-commande invalide !" + missing-import-type: "Type d'importation manquant !" + invalid-import-type: "Type d'importation invalide !" + import-files-missing: "Fichiers à importer manquants" + invalid-storage-type: "Type de stockage {role} invalide : {type}" + storage-same: "La source et la destination ne peuvent pas être identiques !" + migration-failed: "Migration échouée : {error}" + missing-kit-id: "Vous devez spécifier un identifiant de kit" + public-kit-not-found: "Le kit public {kitid} n'existe pas" + add-public-kit-config: "Vous devrez peut-être ajouter un kit public dans la configuration" + public-kit-save-failed: "Erreur lors de la sauvegarde du kit {kitid}" + incorrect-usage: "Utilisation incorrecte !" + players-only: "Seuls les joueurs peuvent utiliser cette commande" + players-only-inspect: "Cette commande ne peut être exécutée que par des joueurs." + invalid-slot-range: "L'emplacement doit être un nombre entre {min} et {max}." + player-not-found: "Impossible de trouver un joueur avec ce nom ou UUID." + kit-not-found-display: "Kit introuvable" + inspect-kit-missing: "{player} n'a pas de kit dans l'emplacement {slot}" + inspect-ec-missing: "{player} n'a pas d'ender chest dans l'emplacement {slot}" + inspect-kit-load-error: "Une erreur s'est produite lors du chargement des données du kit. Voir la console pour les détails." + inspect-ec-load-error: "Une erreur s'est produite lors du chargement des données de l'ender chest. Voir la console pour les détails." + failed-to-update-kit: "Échec de la mise à jour du kit du joueur {player} !" + failed-to-update-ec: "Échec de la mise à jour de l'ender chest du joueur {player} !" + invalid-command-label: "Étiquette de commande invalide." + prefix-tag: "Erreur : " + +success: + kit-saved: "Kit {slot} sauvegardé !" + kit-loaded: "Kit {slot} chargé !" + kit-deleted: "Kit {slot} supprimé !" + kits-swapped: "Les kits {slot1} et {slot2} ont été échangés !" + ec-saved: "Ender chest {slot} sauvegardé !" + ec-loaded: "Ender chest {slot} chargé !" + public-kit-saved: "Kit Public {kitname} sauvegardé !" + public-kit-loaded: "Kit public chargé !" + public-kit-saved-admin: "Kit {kitid} sauvegardé" + kitroom-loaded: "Salle des Kits chargée depuis SQL" + kitroom-saved: "Salle des Kits sauvegardée dans SQL" + kitroom-menu-saved: "Menu de la salle des kits sauvegardé" + all-repaired: "Tous les objets ont été réparés !" + healed: "Vous avez été soigné !" + shulker-given: "Shulker de rééquipement donné !" + regeared: "Rééquipé !" + inventory-cleared: "Inventaire vidé" + admin-kit-deleted: "Kit {slot} supprimé pour le joueur !" + admin-ec-deleted: "Ender chest {slot} supprimé pour le joueur !" + admin-kit-updated: "Kit {slot} mis à jour pour le joueur {player} !" + admin-ec-updated: "Ender chest {slot} mis à jour pour le joueur {player} !" + migration-completed: "Migration terminée avec succès !" + migration-count: "Migrés : {count} entrées" + import-attempted: "Importation des données KitsX tentée !" + import-starting: "Démarrage de l'importation..." + +info: + custom-version-available: "Vous pouvez sauvegarder une version personnalisée de ce kit en l'important dans l'éditeur" + assign-publickit-instruction: "Pour assigner un kit à ce publickit utilisez /savepublickit " + share-kit-code: "Utilisez /copykit {code} pour copier ce kit" + share-ec-code: "Utilisez /copyEC {code} pour copier cet ender chest" + share-code-expiry: "Le code expire dans 15 minutes" + import-instructions: "Copiez le dossier de données de KitsX dans le dossier PerPlayerKit" + migration-starting: "Démarrage de la migration de {source} vers {destination}..." + migration-large-dataset: "Cela peut prendre du temps pour les grands ensembles de données. Consultez la console pour la progression." + available-storage-types: "Types de stockage disponibles : sqlite, mysql, redis, yml" + update-config-storage: "N'oubliez pas de mettre à jour storage.type dans config.yml à '{type}' et de redémarrer le serveur." + migration-failed-count: "Échecs : {count} entrées" + migration-progress: "{message}" + +command: + perplayerkit-about: "PerPlayerKit est un plugin qui permet aux joueurs d'avoir leurs propres kits." + deletekit-usage: "Utilisation : /deletekit " + swapkit-usage: "Utilisation : /swapkit " + savepublickit-usage: "Utilisation : /{command} " + perplayerkit-migrate-usage: "Utilisation : /perplayerkit migrate " + kitroom-usage-hint: "/kitroom " + inspect-usage: "Utilisation : /{command} " + +update: + new-version-available: "Une nouvelle version de PerPlayerKit est disponible ! Vous utilisez la version {current} et la dernière est {latest}" + +about: + header-start: "==========[À propos]==========" + title: "PerPlayerKit" + author: "Auteur : {author}" + license: "Licence : {license}" + source-code: "Code source : {source}" + version: "Version : {version}" + build-time: "Compilé le : {time}" + header-end: "==============================" + +gui: + main-menu-title: "Kits de {player}" + kit-editor-title: "Kit : {slot}" + public-kit-editor-title: "Kit Public : {id}" + enderchest-editor-title: "Ender Chest : {slot}" + inspect-kit-title: "Inspection du kit {slot} de {player}" + inspect-ec-title: "Inspection de l'ender chest {slot} de {player}" + kit-room-title: "Salle des Kits" + public-kit-room-title: "Salle des Kits Publics" + view-public-kit-title: "Voir le Kit Public : {id}" + enderchest-view-title: "Ender Chest (Lecture Seule)" + regear-shulker-title: "Shulker de Rééquipement" + + kit-slot-name: "Kit {slot}" + enderchest-slot-name: "Ender Chest {slot}" + kit-exists: "KIT EXISTE" + kit-not-found: "KIT INTROUVABLE" + more-kits-coming: "PLUS DE KITS À VENIR" + unassigned-tag: "[NON ASSIGNÉ]" + import-button: "IMPORTER" + clear-kit-button: "EFFACER LE KIT" + clear-ec-button: "EFFACER L'ENDER CHEST" + back-button: "RETOUR" + close-button: "FERMER" + load-kit-button: "CHARGER LE KIT" + refill-button: "REMPLIR" + kit-room-button: "SALLE DES KITS" + premade-kits-button: "KITS PRÉDÉFINIS" + info-button: "INFO" + clear-inventory-button: "VIDER L'INVENTAIRE" + share-kits-button: "PARTAGER LES KITS" + repair-items-button: "RÉPARER LES OBJETS" + edit-menu-button: "MENU D'ÉDITION" + edit-menu-lore: "SHIFT CLIC DROIT POUR SAUVEGARDER" + regear-shulker-name: "Shulker de Rééquipement" + regear-shell-name: "Coquille de Rééquipement" + + lore-click-edit: "● Cliquer pour éditer" + lore-click-create: "● Cliquer pour créer" + lore-shift-clear: "● Shift clic pour effacer" + lore-shift-delete-kit: "● Shift clic pour supprimer le kit" + lore-shift-delete-ec: "● Shift clic pour supprimer l'ender chest" + lore-shift-click: "● Shift clic" + lore-import-inventory: "● Importer depuis l'inventaire" + lore-import-ec: "● Importer depuis l'ender chest" + lore-left-load: "● Clic gauche pour charger le kit" + lore-right-edit: "● Clic droit pour éditer le kit" + lore-share-kits: "● /sharekit " + lore-info-load: "● Cliquez sur un emplacement pour charger votre kit" + lore-info-edit: "● Clic droit ou sur le livre pour éditer" + lore-info-share: "● Partagez les kits avec /sharekit " + lore-admin-shift-edit: "● [ADMIN] Shift clic pour éditer" + lore-unassigned-info: "● Les admins n'ont pas encore configuré ce kit" + lore-regear-restocks: "● Réapprovisionne votre kit" + lore-regear-shulker-use: "● Utilisez {primary}/rg pour obtenir un autre shulker de rééquipement" + lore-regear-shell-click: "● Cliquez pour utiliser !" diff --git a/src/main/resources/lang/it.yml b/src/main/resources/lang/it.yml new file mode 100644 index 0000000..79f03d4 --- /dev/null +++ b/src/main/resources/lang/it.yml @@ -0,0 +1,204 @@ +# PerPlayerKit Language File - Italian (Italiano) +# Uses MiniMessage format: https://docs.advntr.dev/minimessage/format.html +# Placeholders use {name} syntax (e.g. {player}, {slot}). +# To use this file, set `language: it` in config.yml. + +prefix: "[Kit] " + +motd: + message: + - "" + - " Kit Per Giocatore " + - "" + - " Digita /kit, /k o /pk per iniziare!" + - "" + - " " + - "" + +scheduled-broadcast: + messages: + - "Controlla i kit pubblici con il comando /pk!" + - "Vuoi condividere un kit? Usa /sharekit ." + - "Digita /kit, /k o /pk per iniziare!" + +broadcast-messages: + player-repaired: "{player} ha riparato il proprio equipaggiamento" + player-healed: "{player} si è curato" + player-opened-kit-room: "{player} ha aperto la stanza dei kit" + player-loaded-private-kit: "{player} ha caricato un kit" + player-loaded-public-kit: "{player} ha caricato un kit pubblico" + player-loaded-enderchest: "{player} ha caricato un baule di Ender." + player-copied-kit: "{player} ha copiato un kit" + player-copied-ec: "{player} ha copiato un baule di Ender" + player-regeared: "{player} si è riequipaggiato" + generic: "{player} ha eseguito un'azione." + +error: + disabled-in-world: "I kit sono disabilitati qui!" + unexpected: "Si è verificato un errore inaspettato, riprova." + kit-not-found: "Errore, quel kit non esiste" + kit-expired: "Errore, il kit non esiste o è scaduto" + ec-not-found: "Errore, quel baule di Ender non esiste" + empty-kit: "Non puoi salvare un kit vuoto!" + empty-ec: "Non puoi salvare un baule di Ender vuoto!" + kit-slot-not-found: "Il kit {slot} non esiste!" + kit-deletion-failed: "Eliminazione del kit fallita!" + invalid-number: "Inserisci un numero valido" + invalid-numbers: "Inserisci numeri validi" + invalid-kit-slot: "Seleziona uno slot kit valido" + missing-kit-code: "Errore, devi inserire un codice kit per copiare" + missing-kit-slot-share: "Errore, devi selezionare uno slot kit da condividere" + missing-ec-slot-share: "Errore, devi selezionare uno slot baule di Ender da condividere" + command-cooldown: "Non spammare il comando (5 secondi di attesa)" + regear-misconfigured: "Questo comando non è configurato correttamente, contatta un amministratore." + inventory-full: "Il tuo inventario è pieno, impossibile darti uno shulker di riequipaggiamento!" + no-kit-loaded: "Non hai ancora caricato un kit!" + regear-elytra-blocked: "Non puoi riequipaggiarti mentre usi un'elytra!" + regear-combat-cooldown: "Devi rimanere fuori dal combattimento per altri {seconds} secondi prima di riequipaggiarti!" + regear-command-cooldown: "Devi attendere {seconds} secondi prima di usare di nuovo questo comando!" + missing-arguments: "Argomenti mancanti!" + invalid-subcommand: "Sottocomando non valido!" + missing-import-type: "Tipo di importazione mancante!" + invalid-import-type: "Tipo di importazione non valido!" + import-files-missing: "File da importare mancanti" + invalid-storage-type: "Tipo di archiviazione {role} non valido: {type}" + storage-same: "Origine e destinazione non possono essere uguali!" + migration-failed: "Migrazione fallita: {error}" + missing-kit-id: "Devi specificare un id kit" + public-kit-not-found: "Il kit pubblico {kitid} non esiste" + add-public-kit-config: "Potresti dover aggiungere un kit pubblico nella configurazione" + public-kit-save-failed: "Errore nel salvare il kit {kitid}" + incorrect-usage: "Utilizzo errato!" + players-only: "Solo i giocatori possono usare questo comando" + players-only-inspect: "Questo comando può essere eseguito solo dai giocatori." + invalid-slot-range: "Lo slot deve essere un numero tra {min} e {max}." + player-not-found: "Impossibile trovare un giocatore con quel nome o UUID." + kit-not-found-display: "Kit non trovato" + inspect-kit-missing: "{player} non ha un kit nello slot {slot}" + inspect-ec-missing: "{player} non ha un baule di Ender nello slot {slot}" + inspect-kit-load-error: "Si è verificato un errore durante il caricamento dei dati del kit. Consulta la console per i dettagli." + inspect-ec-load-error: "Si è verificato un errore durante il caricamento dei dati del baule di Ender. Consulta la console per i dettagli." + failed-to-update-kit: "Impossibile aggiornare il kit per il giocatore {player}!" + failed-to-update-ec: "Impossibile aggiornare il baule di Ender per il giocatore {player}!" + invalid-command-label: "Etichetta del comando non valida." + prefix-tag: "Errore: " + +success: + kit-saved: "Kit {slot} salvato!" + kit-loaded: "Kit {slot} caricato!" + kit-deleted: "Kit {slot} eliminato!" + kits-swapped: "I kit {slot1} e {slot2} sono stati scambiati!" + ec-saved: "Baule di Ender {slot} salvato!" + ec-loaded: "Baule di Ender {slot} caricato!" + public-kit-saved: "Kit pubblico {kitname} salvato!" + public-kit-loaded: "Kit pubblico caricato!" + public-kit-saved-admin: "Salvato kit {kitid}" + kitroom-loaded: "Stanza dei kit caricata da SQL" + kitroom-saved: "Stanza dei kit salvata su SQL" + kitroom-menu-saved: "Menu della stanza dei kit salvato" + all-repaired: "Tutti gli oggetti riparati!" + healed: "Sei stato curato!" + shulker-given: "Shulker di riequipaggiamento consegnato!" + regeared: "Riequipaggiato!" + inventory-cleared: "Inventario svuotato" + admin-kit-deleted: "Kit {slot} eliminato per il giocatore!" + admin-ec-deleted: "Baule di Ender {slot} eliminato per il giocatore!" + admin-kit-updated: "Kit {slot} aggiornato per il giocatore {player}!" + admin-ec-updated: "Baule di Ender {slot} aggiornato per il giocatore {player}!" + migration-completed: "Migrazione completata con successo!" + migration-count: "Migrati: {count} elementi" + import-attempted: "Tentata l'importazione dei dati KitsX!" + import-starting: "Avvio importazione..." + +info: + custom-version-available: "Puoi salvare una versione personalizzata di questo kit importandola nell'editor" + assign-publickit-instruction: "Per assegnare un kit a questo publickit usa /savepublickit " + share-kit-code: "Usa /copykit {code} per copiare questo kit" + share-ec-code: "Usa /copyEC {code} per copiare questo baule di Ender" + share-code-expiry: "Il codice scade tra 15 minuti" + import-instructions: "Copia la cartella dei dati da KitsX nella cartella PerPlayerKit" + migration-starting: "Avvio della migrazione da {source} a {destination}..." + migration-large-dataset: "Questo potrebbe richiedere tempo per grandi set di dati. Consulta la console per i progressi." + available-storage-types: "Tipi di archiviazione disponibili: sqlite, mysql, redis, yml" + update-config-storage: "Ricorda di aggiornare config.yml storage.type a '{type}' e riavvia il server." + migration-failed-count: "Falliti: {count} elementi" + migration-progress: "{message}" + +command: + perplayerkit-about: "PerPlayerKit è un plugin che permette ai giocatori di avere i propri kit." + deletekit-usage: "Utilizzo: /deletekit " + swapkit-usage: "Utilizzo: /swapkit " + savepublickit-usage: "Utilizzo: /{command} " + perplayerkit-migrate-usage: "Utilizzo: /perplayerkit migrate " + kitroom-usage-hint: "/kitroom " + inspect-usage: "Utilizzo: /{command} " + +update: + new-version-available: "È disponibile una nuova versione di PerPlayerKit! Stai usando la versione {current} e la più recente è {latest}" + +about: + header-start: "==========[Info]==========" + title: "PerPlayerKit" + author: "Autore: {author}" + license: "Licenza: {license}" + source-code: "Codice sorgente: {source}" + version: "Versione: {version}" + build-time: "Compilato il: {time}" + header-end: "==========================" + +gui: + main-menu-title: "Kit di {player}" + kit-editor-title: "Kit: {slot}" + public-kit-editor-title: "Kit Pubblico: {id}" + enderchest-editor-title: "Baule di Ender: {slot}" + inspect-kit-title: "Ispezione del kit {slot} di {player}" + inspect-ec-title: "Ispezione del baule di Ender {slot} di {player}" + kit-room-title: "Stanza dei Kit" + public-kit-room-title: "Stanza dei Kit Pubblici" + view-public-kit-title: "Visualizza Kit Pubblico: {id}" + enderchest-view-title: "Baule di Ender Solo Visualizzazione" + regear-shulker-title: "Shulker di Riequipaggiamento" + + kit-slot-name: "Kit {slot}" + enderchest-slot-name: "Baule di Ender {slot}" + kit-exists: "KIT ESISTENTE" + kit-not-found: "KIT NON TROVATO" + more-kits-coming: "ALTRI KIT IN ARRIVO" + unassigned-tag: "[NON ASSEGNATO]" + import-button: "IMPORTA" + clear-kit-button: "SVUOTA KIT" + clear-ec-button: "SVUOTA BAULE DI ENDER" + back-button: "INDIETRO" + close-button: "CHIUDI" + load-kit-button: "CARICA KIT" + refill-button: "RIFORNISCI" + kit-room-button: "STANZA DEI KIT" + premade-kits-button: "KIT PREIMPOSTATI" + info-button: "INFO" + clear-inventory-button: "SVUOTA INVENTARIO" + share-kits-button: "CONDIVIDI KIT" + repair-items-button: "RIPARA OGGETTI" + edit-menu-button: "MODIFICA MENU" + edit-menu-lore: "SHIFT TASTO DESTRO PER SALVARE" + regear-shulker-name: "Shulker di Riequipaggiamento" + regear-shell-name: "Guscio di Riequipaggiamento" + + lore-click-edit: "● Clicca per modificare" + lore-click-create: "● Clicca per creare" + lore-shift-clear: "● Shift+click per svuotare" + lore-shift-delete-kit: "● Shift+click per eliminare il kit" + lore-shift-delete-ec: "● Shift+click per eliminare il baule di Ender" + lore-shift-click: "● Shift+click" + lore-import-inventory: "● Importa dall'inventario" + lore-import-ec: "● Importa dal baule di Ender" + lore-left-load: "● Click sinistro per caricare il kit" + lore-right-edit: "● Click destro per modificare il kit" + lore-share-kits: "● /sharekit " + lore-info-load: "● Clicca uno slot kit per caricare il tuo kit" + lore-info-edit: "● Click destro o clicca sul libro per modificare" + lore-info-share: "● Condividi kit con /sharekit " + lore-admin-shift-edit: "● [ADMIN] Shift+click per modificare" + lore-unassigned-info: "● Gli amministratori non hanno ancora configurato questo kit" + lore-regear-restocks: "● Rifornisce il tuo kit" + lore-regear-shulker-use: "● Usa {primary}/rg per ottenere un altro shulker di riequipaggiamento" + lore-regear-shell-click: "● Clicca per usare!" diff --git a/src/main/resources/lang/nl.yml b/src/main/resources/lang/nl.yml new file mode 100644 index 0000000..a20d0a4 --- /dev/null +++ b/src/main/resources/lang/nl.yml @@ -0,0 +1,204 @@ +# PerPlayerKit Language File - Dutch (Nederlands) +# Uses MiniMessage format: https://docs.advntr.dev/minimessage/format.html +# Placeholders use {name} syntax (e.g. {player}, {slot}). +# To use this file, set `language: nl` in config.yml. + +prefix: "[Kits] " + +motd: + message: + - "" + - " Per Speler Kits " + - "" + - " Typ /kit, /k of /pk om te beginnen!" + - "" + - " " + - "" + +scheduled-broadcast: + messages: + - "Bekijk openbare kits met het commando /pk!" + - "Wil je een kit delen? Gebruik /sharekit ." + - "Typ /kit, /k of /pk om te beginnen!" + +broadcast-messages: + player-repaired: "{player} heeft zijn uitrusting gerepareerd" + player-healed: "{player} heeft zichzelf genezen" + player-opened-kit-room: "{player} heeft de Kitkamer geopend" + player-loaded-private-kit: "{player} heeft een kit geladen" + player-loaded-public-kit: "{player} heeft een openbare kit geladen" + player-loaded-enderchest: "{player} heeft een Enderkist geladen." + player-copied-kit: "{player} heeft een kit gekopieerd" + player-copied-ec: "{player} heeft een Enderkist gekopieerd" + player-regeared: "{player} heeft zich opnieuw uitgerust" + generic: "{player} heeft een actie uitgevoerd." + +error: + disabled-in-world: "Kits zijn hier uitgeschakeld!" + unexpected: "Er is een onverwachte fout opgetreden, probeer het opnieuw." + kit-not-found: "Fout, die kit bestaat niet" + kit-expired: "Fout, kit bestaat niet of is verlopen" + ec-not-found: "Fout, die Enderkist bestaat niet" + empty-kit: "Je kunt geen lege kit opslaan!" + empty-ec: "Je kunt geen lege Enderkist opslaan!" + kit-slot-not-found: "Kit {slot} bestaat niet!" + kit-deletion-failed: "Verwijderen van kit mislukt!" + invalid-number: "Kies een geldig nummer" + invalid-numbers: "Kies geldige nummers" + invalid-kit-slot: "Kies een geldig kit-slot" + missing-kit-code: "Fout, je moet een kit-code invoeren om te kopiëren" + missing-kit-slot-share: "Fout, je moet een kit-slot kiezen om te delen" + missing-ec-slot-share: "Fout, je moet een Enderkist-slot kiezen om te delen" + command-cooldown: "Spam het commando niet (5 seconden afkoeltijd)" + regear-misconfigured: "Dit commando is niet correct geconfigureerd, neem contact op met een beheerder." + inventory-full: "Je inventaris is vol, kan je geen regear-shulker geven!" + no-kit-loaded: "Je hebt nog geen kit geladen!" + regear-elytra-blocked: "Je kunt je niet opnieuw uitrusten terwijl je een elytra gebruikt!" + regear-combat-cooldown: "Je moet nog {seconds} seconden buiten gevecht zijn voordat je je opnieuw kunt uitrusten!" + regear-command-cooldown: "Je moet {seconds} seconden wachten voordat je dit commando opnieuw kunt gebruiken!" + missing-arguments: "Ontbrekende argumenten!" + invalid-subcommand: "Ongeldig subcommando!" + missing-import-type: "Ontbrekend importtype!" + invalid-import-type: "Ongeldig importtype!" + import-files-missing: "Te importeren bestanden ontbreken" + invalid-storage-type: "Ongeldig {role}-opslagtype: {type}" + storage-same: "Bron en bestemming mogen niet hetzelfde zijn!" + migration-failed: "Migratie mislukt: {error}" + missing-kit-id: "Je moet een kit-id opgeven" + public-kit-not-found: "Openbare kit {kitid} bestaat niet" + add-public-kit-config: "Je moet misschien een openbare kit toevoegen in de configuratie" + public-kit-save-failed: "Fout bij opslaan van kit {kitid}" + incorrect-usage: "Onjuist gebruik!" + players-only: "Alleen spelers kunnen dit commando gebruiken" + players-only-inspect: "Dit commando kan alleen door spelers worden uitgevoerd." + invalid-slot-range: "Slot moet een getal zijn tussen {min} en {max}." + player-not-found: "Kon geen speler vinden met die naam of UUID." + kit-not-found-display: "Kit niet gevonden" + inspect-kit-missing: "{player} heeft geen kit in slot {slot}" + inspect-ec-missing: "{player} heeft geen Enderkist in slot {slot}" + inspect-kit-load-error: "Er is een fout opgetreden bij het laden van kitgegevens. Zie console voor details." + inspect-ec-load-error: "Er is een fout opgetreden bij het laden van Enderkistgegevens. Zie console voor details." + failed-to-update-kit: "Kit bijwerken voor speler {player} mislukt!" + failed-to-update-ec: "Enderkist bijwerken voor speler {player} mislukt!" + invalid-command-label: "Ongeldig commandolabel." + prefix-tag: "Fout: " + +success: + kit-saved: "Kit {slot} opgeslagen!" + kit-loaded: "Kit {slot} geladen!" + kit-deleted: "Kit {slot} verwijderd!" + kits-swapped: "Kits {slot1} en {slot2} zijn omgewisseld!" + ec-saved: "Enderkist {slot} opgeslagen!" + ec-loaded: "Enderkist {slot} geladen!" + public-kit-saved: "Openbare kit {kitname} opgeslagen!" + public-kit-loaded: "Openbare kit geladen!" + public-kit-saved-admin: "Kit {kitid} opgeslagen" + kitroom-loaded: "Kitkamer geladen uit SQL" + kitroom-saved: "Kitkamer opgeslagen in SQL" + kitroom-menu-saved: "Kitkamer-menu opgeslagen" + all-repaired: "Alle voorwerpen gerepareerd!" + healed: "Je bent genezen!" + shulker-given: "Regear-shulker gegeven!" + regeared: "Opnieuw uitgerust!" + inventory-cleared: "Inventaris geleegd" + admin-kit-deleted: "Kit {slot} verwijderd voor speler!" + admin-ec-deleted: "Enderkist {slot} verwijderd voor speler!" + admin-kit-updated: "Kit {slot} bijgewerkt voor speler {player}!" + admin-ec-updated: "Enderkist {slot} bijgewerkt voor speler {player}!" + migration-completed: "Migratie succesvol voltooid!" + migration-count: "Gemigreerd: {count} items" + import-attempted: "Poging tot importeren van KitsX-gegevens!" + import-starting: "Import starten..." + +info: + custom-version-available: "Je kunt een aangepaste versie van deze kit opslaan door deze in de kit-editor te importeren" + assign-publickit-instruction: "Om een kit aan deze publickit toe te wijzen, gebruik /savepublickit " + share-kit-code: "Gebruik /copykit {code} om deze kit te kopiëren" + share-ec-code: "Gebruik /copyEC {code} om deze Enderkist te kopiëren" + share-code-expiry: "Code verloopt over 15 minuten" + import-instructions: "Kopieer de gegevensmap van KitsX naar de PerPlayerKit-map" + migration-starting: "Migratie starten van {source} naar {destination}..." + migration-large-dataset: "Dit kan even duren voor grote datasets. Controleer de console voor voortgang." + available-storage-types: "Beschikbare opslagtypes: sqlite, mysql, redis, yml" + update-config-storage: "Vergeet niet je config.yml storage.type bij te werken naar '{type}' en de server opnieuw te starten." + migration-failed-count: "Mislukt: {count} items" + migration-progress: "{message}" + +command: + perplayerkit-about: "PerPlayerKit is een plugin waarmee spelers hun eigen kits kunnen hebben." + deletekit-usage: "Gebruik: /deletekit " + swapkit-usage: "Gebruik: /swapkit " + savepublickit-usage: "Gebruik: /{command} " + perplayerkit-migrate-usage: "Gebruik: /perplayerkit migrate " + kitroom-usage-hint: "/kitroom " + inspect-usage: "Gebruik: /{command} " + +update: + new-version-available: "Er is een nieuwe versie van PerPlayerKit beschikbaar! Je gebruikt versie {current} en de nieuwste versie is {latest}" + +about: + header-start: "==========[Over]==========" + title: "PerPlayerKit" + author: "Auteur: {author}" + license: "Licentie: {license}" + source-code: "Broncode: {source}" + version: "Versie: {version}" + build-time: "Buildtijd: {time}" + header-end: "==========================" + +gui: + main-menu-title: "Kits van {player}" + kit-editor-title: "Kit: {slot}" + public-kit-editor-title: "Openbare Kit: {id}" + enderchest-editor-title: "Enderkist: {slot}" + inspect-kit-title: "Kit {slot} van {player} bekijken" + inspect-ec-title: "Enderkist {slot} van {player} bekijken" + kit-room-title: "Kitkamer" + public-kit-room-title: "Openbare Kitkamer" + view-public-kit-title: "Openbare Kit Bekijken: {id}" + enderchest-view-title: "Alleen-Lezen Enderkist" + regear-shulker-title: "Regear-Shulker" + + kit-slot-name: "Kit {slot}" + enderchest-slot-name: "Enderkist {slot}" + kit-exists: "KIT BESTAAT" + kit-not-found: "KIT NIET GEVONDEN" + more-kits-coming: "MEER KITS BINNENKORT" + unassigned-tag: "[NIET TOEGEWEZEN]" + import-button: "IMPORTEREN" + clear-kit-button: "KIT LEEGMAKEN" + clear-ec-button: "ENDERKIST LEEGMAKEN" + back-button: "TERUG" + close-button: "SLUITEN" + load-kit-button: "KIT LADEN" + refill-button: "BIJVULLEN" + kit-room-button: "KITKAMER" + premade-kits-button: "VOORGEMAAKTE KITS" + info-button: "INFO" + clear-inventory-button: "INVENTARIS LEEGMAKEN" + share-kits-button: "KITS DELEN" + repair-items-button: "VOORWERPEN REPAREREN" + edit-menu-button: "MENU BEWERKEN" + edit-menu-lore: "SHIFT RECHTSKLIK OM OP TE SLAAN" + regear-shulker-name: "Regear-Shulker" + regear-shell-name: "Regear-Schelp" + + lore-click-edit: "● Klik om te bewerken" + lore-click-create: "● Klik om te maken" + lore-shift-clear: "● Shift-klik om leeg te maken" + lore-shift-delete-kit: "● Shift-klik om kit te verwijderen" + lore-shift-delete-ec: "● Shift-klik om Enderkist te verwijderen" + lore-shift-click: "● Shift-klik" + lore-import-inventory: "● Importeer uit inventaris" + lore-import-ec: "● Importeer uit Enderkist" + lore-left-load: "● Linkermuisklik om kit te laden" + lore-right-edit: "● Rechtermuisklik om kit te bewerken" + lore-share-kits: "● /sharekit " + lore-info-load: "● Klik op een kit-slot om je kit te laden" + lore-info-edit: "● Rechtsklik of klik op het boek om te bewerken" + lore-info-share: "● Deel kits met /sharekit " + lore-admin-shift-edit: "● [ADMIN] Shift-klik om te bewerken" + lore-unassigned-info: "● Beheerders hebben deze kit nog niet ingesteld" + lore-regear-restocks: "● Vult je kit aan" + lore-regear-shulker-use: "● Gebruik {primary}/rg om een andere regear-shulker te krijgen" + lore-regear-shell-click: "● Klik om te gebruiken!" diff --git a/src/main/resources/lang/pl.yml b/src/main/resources/lang/pl.yml new file mode 100644 index 0000000..13ccff1 --- /dev/null +++ b/src/main/resources/lang/pl.yml @@ -0,0 +1,204 @@ +# PerPlayerKit Language File - Polish (Polski) +# Uses MiniMessage format: https://docs.advntr.dev/minimessage/format.html +# Placeholders use {name} syntax (e.g. {player}, {slot}). +# To use this file, set `language: pl` in config.yml. + +prefix: "[Zestawy] " + +motd: + message: + - "" + - " Zestawy Per Gracz " + - "" + - " Wpisz /kit, /k lub /pk, aby zacząć!" + - "" + - " " + - "" + +scheduled-broadcast: + messages: + - "Sprawdź zestawy publiczne komendą /pk!" + - "Chcesz udostępnić zestaw? Użyj /sharekit ." + - "Wpisz /kit, /k lub /pk, aby zacząć!" + +broadcast-messages: + player-repaired: "{player} naprawił swój ekwipunek" + player-healed: "{player} uleczył się" + player-opened-kit-room: "{player} otworzył pokój zestawów" + player-loaded-private-kit: "{player} załadował zestaw" + player-loaded-public-kit: "{player} załadował publiczny zestaw" + player-loaded-enderchest: "{player} załadował skrzynię Endera." + player-copied-kit: "{player} skopiował zestaw" + player-copied-ec: "{player} skopiował skrzynię Endera" + player-regeared: "{player} ponownie się wyposażył" + generic: "{player} wykonał akcję." + +error: + disabled-in-world: "Zestawy są tutaj wyłączone!" + unexpected: "Wystąpił nieoczekiwany błąd, spróbuj ponownie." + kit-not-found: "Błąd, ten zestaw nie istnieje" + kit-expired: "Błąd, zestaw nie istnieje lub wygasł" + ec-not-found: "Błąd, ta skrzynia Endera nie istnieje" + empty-kit: "Nie możesz zapisać pustego zestawu!" + empty-ec: "Nie możesz zapisać pustej skrzyni Endera!" + kit-slot-not-found: "Zestaw {slot} nie istnieje!" + kit-deletion-failed: "Usuwanie zestawu nie powiodło się!" + invalid-number: "Wybierz prawidłową liczbę" + invalid-numbers: "Wybierz prawidłowe liczby" + invalid-kit-slot: "Wybierz prawidłowy slot zestawu" + missing-kit-code: "Błąd, musisz wpisać kod zestawu, aby skopiować" + missing-kit-slot-share: "Błąd, musisz wybrać slot zestawu do udostępnienia" + missing-ec-slot-share: "Błąd, musisz wybrać slot skrzyni Endera do udostępnienia" + command-cooldown: "Nie spamuj komendą (5 sekund opóźnienia)" + regear-misconfigured: "Ta komenda nie jest skonfigurowana poprawnie, skontaktuj się z administratorem." + inventory-full: "Twój ekwipunek jest pełny, nie mogę dać ci shulkera ponownego wyposażenia!" + no-kit-loaded: "Jeszcze nie załadowałeś zestawu!" + regear-elytra-blocked: "Nie możesz ponownie się wyposażyć podczas używania elytry!" + regear-combat-cooldown: "Musisz być poza walką jeszcze {seconds} sekund, aby ponownie się wyposażyć!" + regear-command-cooldown: "Musisz poczekać {seconds} sekund przed ponownym użyciem tej komendy!" + missing-arguments: "Brakujące argumenty!" + invalid-subcommand: "Nieprawidłowa podkomenda!" + missing-import-type: "Brakujący typ importu!" + invalid-import-type: "Nieprawidłowy typ importu!" + import-files-missing: "Brakujące pliki do importu" + invalid-storage-type: "Nieprawidłowy typ przechowywania {role}: {type}" + storage-same: "Źródło i miejsce docelowe nie mogą być takie same!" + migration-failed: "Migracja nie powiodła się: {error}" + missing-kit-id: "Musisz określić id zestawu" + public-kit-not-found: "Publiczny zestaw {kitid} nie istnieje" + add-public-kit-config: "Możesz potrzebować dodać publiczny zestaw w konfiguracji" + public-kit-save-failed: "Błąd zapisu zestawu {kitid}" + incorrect-usage: "Nieprawidłowe użycie!" + players-only: "Tylko gracze mogą używać tej komendy" + players-only-inspect: "Tę komendę mogą wykonywać tylko gracze." + invalid-slot-range: "Slot musi być liczbą między {min} a {max}." + player-not-found: "Nie można znaleźć gracza o tej nazwie lub UUID." + kit-not-found-display: "Nie znaleziono zestawu" + inspect-kit-missing: "{player} nie ma zestawu w slocie {slot}" + inspect-ec-missing: "{player} nie ma skrzyni Endera w slocie {slot}" + inspect-kit-load-error: "Wystąpił błąd podczas ładowania danych zestawu. Sprawdź konsolę po szczegóły." + inspect-ec-load-error: "Wystąpił błąd podczas ładowania danych skrzyni Endera. Sprawdź konsolę po szczegóły." + failed-to-update-kit: "Nie udało się zaktualizować zestawu gracza {player}!" + failed-to-update-ec: "Nie udało się zaktualizować skrzyni Endera gracza {player}!" + invalid-command-label: "Nieprawidłowa etykieta komendy." + prefix-tag: "Błąd: " + +success: + kit-saved: "Zestaw {slot} zapisany!" + kit-loaded: "Zestaw {slot} załadowany!" + kit-deleted: "Zestaw {slot} usunięty!" + kits-swapped: "Zestawy {slot1} i {slot2} zostały zamienione!" + ec-saved: "Skrzynia Endera {slot} zapisana!" + ec-loaded: "Skrzynia Endera {slot} załadowana!" + public-kit-saved: "Publiczny zestaw {kitname} zapisany!" + public-kit-loaded: "Publiczny zestaw załadowany!" + public-kit-saved-admin: "Zapisano zestaw {kitid}" + kitroom-loaded: "Pokój zestawów załadowany z SQL" + kitroom-saved: "Pokój zestawów zapisany do SQL" + kitroom-menu-saved: "Menu pokoju zestawów zapisane" + all-repaired: "Wszystkie przedmioty naprawione!" + healed: "Zostałeś uleczony!" + shulker-given: "Shulker ponownego wyposażenia wydany!" + regeared: "Ponownie wyposażony!" + inventory-cleared: "Ekwipunek wyczyszczony" + admin-kit-deleted: "Zestaw {slot} usunięty u gracza!" + admin-ec-deleted: "Skrzynia Endera {slot} usunięta u gracza!" + admin-kit-updated: "Zestaw {slot} zaktualizowany dla gracza {player}!" + admin-ec-updated: "Skrzynia Endera {slot} zaktualizowana dla gracza {player}!" + migration-completed: "Migracja zakończona pomyślnie!" + migration-count: "Zmigrowano: {count} wpisów" + import-attempted: "Próba importu danych KitsX wykonana!" + import-starting: "Rozpoczynanie importu..." + +info: + custom-version-available: "Możesz zapisać własną wersję tego zestawu, importując ją do edytora" + assign-publickit-instruction: "Aby przypisać zestaw do tego publickit, użyj /savepublickit " + share-kit-code: "Użyj /copykit {code}, aby skopiować ten zestaw" + share-ec-code: "Użyj /copyEC {code}, aby skopiować tę skrzynię Endera" + share-code-expiry: "Kod wygaśnie za 15 minut" + import-instructions: "Skopiuj folder danych z KitsX do folderu PerPlayerKit" + migration-starting: "Rozpoczynanie migracji z {source} do {destination}..." + migration-large-dataset: "Może to potrwać dla dużych zestawów danych. Sprawdź konsolę po postęp." + available-storage-types: "Dostępne typy przechowywania: sqlite, mysql, redis, yml" + update-config-storage: "Pamiętaj zaktualizować config.yml storage.type na '{type}' i zrestartować serwer." + migration-failed-count: "Nieudane: {count} wpisów" + migration-progress: "{message}" + +command: + perplayerkit-about: "PerPlayerKit to plugin pozwalający graczom mieć własne zestawy." + deletekit-usage: "Użycie: /deletekit " + swapkit-usage: "Użycie: /swapkit " + savepublickit-usage: "Użycie: /{command} " + perplayerkit-migrate-usage: "Użycie: /perplayerkit migrate <źródło> " + kitroom-usage-hint: "/kitroom " + inspect-usage: "Użycie: /{command} " + +update: + new-version-available: "Dostępna jest nowa wersja PerPlayerKit! Używasz wersji {current}, a najnowsza to {latest}" + +about: + header-start: "==========[O Pluginie]==========" + title: "PerPlayerKit" + author: "Autor: {author}" + license: "Licencja: {license}" + source-code: "Kod źródłowy: {source}" + version: "Wersja: {version}" + build-time: "Czas kompilacji: {time}" + header-end: "================================" + +gui: + main-menu-title: "Zestawy {player}" + kit-editor-title: "Zestaw: {slot}" + public-kit-editor-title: "Publiczny Zestaw: {id}" + enderchest-editor-title: "Skrzynia Endera: {slot}" + inspect-kit-title: "Podgląd zestawu {slot} gracza {player}" + inspect-ec-title: "Podgląd skrzyni Endera {slot} gracza {player}" + kit-room-title: "Pokój Zestawów" + public-kit-room-title: "Pokój Publicznych Zestawów" + view-public-kit-title: "Podgląd Publicznego Zestawu: {id}" + enderchest-view-title: "Skrzynia Endera (tylko podgląd)" + regear-shulker-title: "Shulker Ponownego Wyposażenia" + + kit-slot-name: "Zestaw {slot}" + enderchest-slot-name: "Skrzynia Endera {slot}" + kit-exists: "ZESTAW ISTNIEJE" + kit-not-found: "NIE ZNALEZIONO ZESTAWU" + more-kits-coming: "WIĘCEJ ZESTAWÓW WKRÓTCE" + unassigned-tag: "[NIEPRZYPISANY]" + import-button: "IMPORTUJ" + clear-kit-button: "WYCZYŚĆ ZESTAW" + clear-ec-button: "WYCZYŚĆ SKRZYNIĘ ENDERA" + back-button: "WSTECZ" + close-button: "ZAMKNIJ" + load-kit-button: "ZAŁADUJ ZESTAW" + refill-button: "UZUPEŁNIJ" + kit-room-button: "POKÓJ ZESTAWÓW" + premade-kits-button: "GOTOWE ZESTAWY" + info-button: "INFO" + clear-inventory-button: "WYCZYŚĆ EKWIPUNEK" + share-kits-button: "UDOSTĘPNIJ ZESTAWY" + repair-items-button: "NAPRAW PRZEDMIOTY" + edit-menu-button: "EDYTUJ MENU" + edit-menu-lore: "SHIFT PRAWY KLIK ABY ZAPISAĆ" + regear-shulker-name: "Shulker Ponownego Wyposażenia" + regear-shell-name: "Skorupa Ponownego Wyposażenia" + + lore-click-edit: "● Kliknij, aby edytować" + lore-click-create: "● Kliknij, aby utworzyć" + lore-shift-clear: "● Shift+klik, aby wyczyścić" + lore-shift-delete-kit: "● Shift+klik, aby usunąć zestaw" + lore-shift-delete-ec: "● Shift+klik, aby usunąć skrzynię Endera" + lore-shift-click: "● Shift+klik" + lore-import-inventory: "● Importuj z ekwipunku" + lore-import-ec: "● Importuj ze skrzyni Endera" + lore-left-load: "● Lewy klik, aby załadować zestaw" + lore-right-edit: "● Prawy klik, aby edytować zestaw" + lore-share-kits: "● /sharekit " + lore-info-load: "● Kliknij slot zestawu, aby załadować swój zestaw" + lore-info-edit: "● Prawy klik lub klik księgi, aby edytować" + lore-info-share: "● Udostępniaj zestawy komendą /sharekit " + lore-admin-shift-edit: "● [ADMIN] Shift+klik, aby edytować" + lore-unassigned-info: "● Administratorzy jeszcze nie skonfigurowali tego zestawu" + lore-regear-restocks: "● Uzupełnia twój zestaw" + lore-regear-shulker-use: "● Użyj {primary}/rg aby zdobyć kolejnego shulkera ponownego wyposażenia" + lore-regear-shell-click: "● Kliknij, aby użyć!" diff --git a/src/main/resources/lang/pt.yml b/src/main/resources/lang/pt.yml new file mode 100644 index 0000000..483df47 --- /dev/null +++ b/src/main/resources/lang/pt.yml @@ -0,0 +1,204 @@ +# PerPlayerKit Language File - Portuguese (Português) +# Uses MiniMessage format: https://docs.advntr.dev/minimessage/format.html +# Placeholders use {name} syntax (e.g. {player}, {slot}). +# To use this file, set `language: pt` in config.yml. + +prefix: "[Kits] " + +motd: + message: + - "" + - " Kits Por Jogador " + - "" + - " Digite /kit, /k ou /pk para começar!" + - "" + - " " + - "" + +scheduled-broadcast: + messages: + - "Confira os kits públicos com o comando /pk!" + - "Quer compartilhar um kit? Use /sharekit ." + - "Digite /kit, /k ou /pk para começar!" + +broadcast-messages: + player-repaired: "{player} reparou o equipamento" + player-healed: "{player} se curou" + player-opened-kit-room: "{player} abriu a Sala de Kits" + player-loaded-private-kit: "{player} carregou um kit" + player-loaded-public-kit: "{player} carregou um kit público" + player-loaded-enderchest: "{player} carregou um ender chest." + player-copied-kit: "{player} copiou um kit" + player-copied-ec: "{player} copiou um ender chest" + player-regeared: "{player} se reequipou" + generic: "{player} realizou uma ação." + +error: + disabled-in-world: "Os kits estão desativados aqui!" + unexpected: "Ocorreu um erro inesperado, tente novamente." + kit-not-found: "Erro, esse kit não existe" + kit-expired: "Erro, o kit não existe ou expirou" + ec-not-found: "Erro, esse EC não existe" + empty-kit: "Você não pode salvar um kit vazio!" + empty-ec: "Você não pode salvar um ender chest vazio!" + kit-slot-not-found: "O kit {slot} não existe!" + kit-deletion-failed: "Falha ao excluir o kit!" + invalid-number: "Selecione um número válido" + invalid-numbers: "Selecione números válidos" + invalid-kit-slot: "Selecione um slot de kit válido" + missing-kit-code: "Erro, você precisa inserir um código de kit para copiar" + missing-kit-slot-share: "Erro, você precisa selecionar um slot de kit para compartilhar" + missing-ec-slot-share: "Erro, você precisa selecionar um slot de EC para compartilhar" + command-cooldown: "Por favor, não spame o comando (espera de 5 segundos)" + regear-misconfigured: "Este comando não está configurado corretamente, contate um administrador." + inventory-full: "Seu inventário está cheio, não é possível dar um shulker de reequipar!" + no-kit-loaded: "Você ainda não carregou um kit!" + regear-elytra-blocked: "Você não pode se reequipar usando uma elytra!" + regear-combat-cooldown: "Você precisa estar fora de combate por mais {seconds} segundos antes de se reequipar!" + regear-command-cooldown: "Você precisa esperar {seconds} segundos antes de usar este comando novamente!" + missing-arguments: "Argumentos faltando!" + invalid-subcommand: "Subcomando inválido!" + missing-import-type: "Tipo de importação faltando!" + invalid-import-type: "Tipo de importação inválido!" + import-files-missing: "Arquivos para importar não encontrados" + invalid-storage-type: "Tipo de armazenamento {role} inválido: {type}" + storage-same: "Origem e destino não podem ser iguais!" + migration-failed: "Migração falhou: {error}" + missing-kit-id: "Você precisa especificar um id de kit" + public-kit-not-found: "O kit público {kitid} não existe" + add-public-kit-config: "Você pode precisar adicionar um kit público no config" + public-kit-save-failed: "Erro ao salvar o kit {kitid}" + incorrect-usage: "Uso incorreto!" + players-only: "Apenas jogadores podem usar este comando" + players-only-inspect: "Este comando só pode ser executado por jogadores." + invalid-slot-range: "O slot deve ser um número entre {min} e {max}." + player-not-found: "Não foi possível encontrar um jogador com esse nome ou UUID." + kit-not-found-display: "Kit não encontrado" + inspect-kit-missing: "{player} não tem um kit no slot {slot}" + inspect-ec-missing: "{player} não tem um ender chest no slot {slot}" + inspect-kit-load-error: "Ocorreu um erro ao carregar os dados do kit. Veja o console para detalhes." + inspect-ec-load-error: "Ocorreu um erro ao carregar os dados do ender chest. Veja o console para detalhes." + failed-to-update-kit: "Falha ao atualizar o kit do jogador {player}!" + failed-to-update-ec: "Falha ao atualizar o ender chest do jogador {player}!" + invalid-command-label: "Rótulo de comando inválido." + prefix-tag: "Erro: " + +success: + kit-saved: "Kit {slot} salvo!" + kit-loaded: "Kit {slot} carregado!" + kit-deleted: "Kit {slot} excluído!" + kits-swapped: "Os kits {slot1} e {slot2} foram trocados!" + ec-saved: "Ender chest {slot} salvo!" + ec-loaded: "Ender chest {slot} carregado!" + public-kit-saved: "Kit Público {kitname} salvo!" + public-kit-loaded: "Kit público carregado!" + public-kit-saved-admin: "Kit {kitid} salvo" + kitroom-loaded: "Sala de Kits carregada do SQL" + kitroom-saved: "Sala de Kits salva no SQL" + kitroom-menu-saved: "Menu da sala de kits salvo" + all-repaired: "Todos os itens reparados!" + healed: "Você foi curado!" + shulker-given: "Shulker de reequipar entregue!" + regeared: "Reequipado!" + inventory-cleared: "Inventário limpo" + admin-kit-deleted: "Kit {slot} excluído para o jogador!" + admin-ec-deleted: "Ender chest {slot} excluído para o jogador!" + admin-kit-updated: "Kit {slot} atualizado para o jogador {player}!" + admin-ec-updated: "Ender chest {slot} atualizado para o jogador {player}!" + migration-completed: "Migração concluída com sucesso!" + migration-count: "Migrados: {count} entradas" + import-attempted: "Tentativa de importação de dados KitsX!" + import-starting: "Iniciando importação..." + +info: + custom-version-available: "Você pode salvar uma versão personalizada deste kit importando-o no editor" + assign-publickit-instruction: "Para atribuir um kit a este publickit use /savepublickit " + share-kit-code: "Use /copykit {code} para copiar este kit" + share-ec-code: "Use /copyEC {code} para copiar este ender chest" + share-code-expiry: "O código expira em 15 minutos" + import-instructions: "Copie a pasta de dados do KitsX para a pasta PerPlayerKit" + migration-starting: "Iniciando migração de {source} para {destination}..." + migration-large-dataset: "Isso pode demorar para conjuntos de dados grandes. Veja o console para o progresso." + available-storage-types: "Tipos de armazenamento disponíveis: sqlite, mysql, redis, yml" + update-config-storage: "Lembre-se de atualizar o storage.type do config.yml para '{type}' e reiniciar o servidor." + migration-failed-count: "Falharam: {count} entradas" + migration-progress: "{message}" + +command: + perplayerkit-about: "PerPlayerKit é um plugin que permite que jogadores tenham seus próprios kits." + deletekit-usage: "Uso: /deletekit " + swapkit-usage: "Uso: /swapkit " + savepublickit-usage: "Uso: /{command} " + perplayerkit-migrate-usage: "Uso: /perplayerkit migrate " + kitroom-usage-hint: "/kitroom " + inspect-usage: "Uso: /{command} " + +update: + new-version-available: "Uma nova versão do PerPlayerKit está disponível! Você está usando a versão {current} e a mais recente é {latest}" + +about: + header-start: "==========[Sobre]==========" + title: "PerPlayerKit" + author: "Autor: {author}" + license: "Licença: {license}" + source-code: "Código fonte: {source}" + version: "Versão: {version}" + build-time: "Compilado em: {time}" + header-end: "===========================" + +gui: + main-menu-title: "Kits de {player}" + kit-editor-title: "Kit: {slot}" + public-kit-editor-title: "Kit Público: {id}" + enderchest-editor-title: "Ender Chest: {slot}" + inspect-kit-title: "Inspecionando kit {slot} de {player}" + inspect-ec-title: "Inspecionando ender chest {slot} de {player}" + kit-room-title: "Sala de Kits" + public-kit-room-title: "Sala de Kits Públicos" + view-public-kit-title: "Visualizando Kit Público: {id}" + enderchest-view-title: "Ender Chest (Somente Visualização)" + regear-shulker-title: "Shulker de Reequipar" + + kit-slot-name: "Kit {slot}" + enderchest-slot-name: "Ender Chest {slot}" + kit-exists: "KIT EXISTE" + kit-not-found: "KIT NÃO ENCONTRADO" + more-kits-coming: "MAIS KITS EM BREVE" + unassigned-tag: "[NÃO ATRIBUÍDO]" + import-button: "IMPORTAR" + clear-kit-button: "LIMPAR KIT" + clear-ec-button: "LIMPAR ENDER CHEST" + back-button: "VOLTAR" + close-button: "FECHAR" + load-kit-button: "CARREGAR KIT" + refill-button: "REABASTECER" + kit-room-button: "SALA DE KITS" + premade-kits-button: "KITS PRÉ-FEITOS" + info-button: "INFO" + clear-inventory-button: "LIMPAR INVENTÁRIO" + share-kits-button: "COMPARTILHAR KITS" + repair-items-button: "REPARAR ITENS" + edit-menu-button: "EDITAR MENU" + edit-menu-lore: "SHIFT CLIQUE DIREITO PARA SALVAR" + regear-shulker-name: "Shulker de Reequipar" + regear-shell-name: "Concha de Reequipar" + + lore-click-edit: "● Clique para editar" + lore-click-create: "● Clique para criar" + lore-shift-clear: "● Shift clique para limpar" + lore-shift-delete-kit: "● Shift clique para excluir kit" + lore-shift-delete-ec: "● Shift clique para excluir ender chest" + lore-shift-click: "● Shift clique" + lore-import-inventory: "● Importar do inventário" + lore-import-ec: "● Importar do ender chest" + lore-left-load: "● Clique esquerdo para carregar kit" + lore-right-edit: "● Clique direito para editar kit" + lore-share-kits: "● /sharekit " + lore-info-load: "● Clique em um slot para carregar seu kit" + lore-info-edit: "● Clique direito ou no livro para editar" + lore-info-share: "● Compartilhe kits com /sharekit " + lore-admin-shift-edit: "● [ADMIN] Shift clique para editar" + lore-unassigned-info: "● Admins ainda não configuraram este kit" + lore-regear-restocks: "● Reabastece seu kit" + lore-regear-shulker-use: "● Use {primary}/rg para obter outro shulker de reequipar" + lore-regear-shell-click: "● Clique para usar!" diff --git a/src/main/resources/lang/ro.yml b/src/main/resources/lang/ro.yml new file mode 100644 index 0000000..87517a2 --- /dev/null +++ b/src/main/resources/lang/ro.yml @@ -0,0 +1,204 @@ +# PerPlayerKit Language File - Romanian (Română) +# Uses MiniMessage format: https://docs.advntr.dev/minimessage/format.html +# Placeholders use {name} syntax (e.g. {player}, {slot}). +# To use this file, set `language: ro` in config.yml. + +prefix: "[Kituri] " + +motd: + message: + - "" + - " Kituri Per Jucător " + - "" + - " Scrie /kit, /k sau /pk pentru a începe!" + - "" + - " " + - "" + +scheduled-broadcast: + messages: + - "Verifică kiturile publice cu comanda /pk!" + - "Vrei să partajezi un kit? Folosește /sharekit ." + - "Scrie /kit, /k sau /pk pentru a începe!" + +broadcast-messages: + player-repaired: "{player} și-a reparat echipamentul" + player-healed: "{player} s-a vindecat" + player-opened-kit-room: "{player} a deschis camera kiturilor" + player-loaded-private-kit: "{player} a încărcat un kit" + player-loaded-public-kit: "{player} a încărcat un kit public" + player-loaded-enderchest: "{player} a încărcat un cufăr Ender." + player-copied-kit: "{player} a copiat un kit" + player-copied-ec: "{player} a copiat un cufăr Ender" + player-regeared: "{player} s-a reechipat" + generic: "{player} a efectuat o acțiune." + +error: + disabled-in-world: "Kiturile sunt dezactivate aici!" + unexpected: "A apărut o eroare neașteptată, încearcă din nou." + kit-not-found: "Eroare, acel kit nu există" + kit-expired: "Eroare, kitul nu există sau a expirat" + ec-not-found: "Eroare, acel cufăr Ender nu există" + empty-kit: "Nu poți salva un kit gol!" + empty-ec: "Nu poți salva un cufăr Ender gol!" + kit-slot-not-found: "Kitul {slot} nu există!" + kit-deletion-failed: "Ștergerea kitului a eșuat!" + invalid-number: "Alege un număr valid" + invalid-numbers: "Alege numere valide" + invalid-kit-slot: "Alege un slot de kit valid" + missing-kit-code: "Eroare, trebuie să introduci un cod de kit pentru a copia" + missing-kit-slot-share: "Eroare, trebuie să selectezi un slot de kit pentru partajare" + missing-ec-slot-share: "Eroare, trebuie să selectezi un slot de cufăr Ender pentru partajare" + command-cooldown: "Nu trimite spam cu comanda (5 secunde așteptare)" + regear-misconfigured: "Această comandă nu este configurată corect, contactează un administrator." + inventory-full: "Inventarul tău este plin, nu îți pot da un shulker de reechipare!" + no-kit-loaded: "Încă nu ai încărcat un kit!" + regear-elytra-blocked: "Nu te poți reechipa în timp ce folosești elytra!" + regear-combat-cooldown: "Trebuie să fii în afara luptei încă {seconds} secunde înainte de reechipare!" + regear-command-cooldown: "Trebuie să aștepți {seconds} secunde înainte de a folosi din nou această comandă!" + missing-arguments: "Lipsesc argumente!" + invalid-subcommand: "Subcomandă invalidă!" + missing-import-type: "Lipsește tipul de import!" + invalid-import-type: "Tip de import invalid!" + import-files-missing: "Lipsesc fișierele de importat" + invalid-storage-type: "Tip de stocare {role} invalid: {type}" + storage-same: "Sursa și destinația nu pot fi identice!" + migration-failed: "Migrarea a eșuat: {error}" + missing-kit-id: "Trebuie să specifici un id de kit" + public-kit-not-found: "Kitul public {kitid} nu există" + add-public-kit-config: "Poate trebuie să adaugi un kit public în configurație" + public-kit-save-failed: "Eroare la salvarea kitului {kitid}" + incorrect-usage: "Utilizare incorectă!" + players-only: "Doar jucătorii pot folosi această comandă" + players-only-inspect: "Această comandă poate fi executată doar de jucători." + invalid-slot-range: "Slotul trebuie să fie un număr între {min} și {max}." + player-not-found: "Nu s-a putut găsi un jucător cu acel nume sau UUID." + kit-not-found-display: "Kit negăsit" + inspect-kit-missing: "{player} nu are un kit în slotul {slot}" + inspect-ec-missing: "{player} nu are un cufăr Ender în slotul {slot}" + inspect-kit-load-error: "A apărut o eroare la încărcarea datelor kitului. Vezi consola pentru detalii." + inspect-ec-load-error: "A apărut o eroare la încărcarea datelor cufărului Ender. Vezi consola pentru detalii." + failed-to-update-kit: "Nu s-a putut actualiza kitul pentru jucătorul {player}!" + failed-to-update-ec: "Nu s-a putut actualiza cufărul Ender pentru jucătorul {player}!" + invalid-command-label: "Etichetă de comandă invalidă." + prefix-tag: "Eroare: " + +success: + kit-saved: "Kitul {slot} a fost salvat!" + kit-loaded: "Kitul {slot} a fost încărcat!" + kit-deleted: "Kitul {slot} a fost șters!" + kits-swapped: "Kiturile {slot1} și {slot2} au fost schimbate!" + ec-saved: "Cufărul Ender {slot} a fost salvat!" + ec-loaded: "Cufărul Ender {slot} a fost încărcat!" + public-kit-saved: "Kitul public {kitname} a fost salvat!" + public-kit-loaded: "Kit public încărcat!" + public-kit-saved-admin: "Kit {kitid} salvat" + kitroom-loaded: "Camera kiturilor a fost încărcată din SQL" + kitroom-saved: "Camera kiturilor a fost salvată în SQL" + kitroom-menu-saved: "Meniul camerei kiturilor salvat" + all-repaired: "Toate obiectele reparate!" + healed: "Ai fost vindecat!" + shulker-given: "Shulker de reechipare dat!" + regeared: "Reechipat!" + inventory-cleared: "Inventar golit" + admin-kit-deleted: "Kitul {slot} a fost șters de la jucător!" + admin-ec-deleted: "Cufărul Ender {slot} a fost șters de la jucător!" + admin-kit-updated: "Kitul {slot} actualizat pentru jucătorul {player}!" + admin-ec-updated: "Cufărul Ender {slot} actualizat pentru jucătorul {player}!" + migration-completed: "Migrarea s-a finalizat cu succes!" + migration-count: "Migrate: {count} înregistrări" + import-attempted: "Import al datelor KitsX încercat!" + import-starting: "Pornire import..." + +info: + custom-version-available: "Poți salva o versiune personalizată a acestui kit importând-o în editor" + assign-publickit-instruction: "Pentru a atribui un kit acestui publickit folosește /savepublickit " + share-kit-code: "Folosește /copykit {code} pentru a copia acest kit" + share-ec-code: "Folosește /copyEC {code} pentru a copia acest cufăr Ender" + share-code-expiry: "Codul expiră în 15 minute" + import-instructions: "Copiază folderul de date din KitsX în folderul PerPlayerKit" + migration-starting: "Pornire migrare din {source} în {destination}..." + migration-large-dataset: "Acest lucru poate dura mult pentru seturi mari de date. Verifică consola pentru progres." + available-storage-types: "Tipuri de stocare disponibile: sqlite, mysql, redis, yml" + update-config-storage: "Nu uita să actualizezi config.yml storage.type la '{type}' și să repornești serverul." + migration-failed-count: "Eșuate: {count} înregistrări" + migration-progress: "{message}" + +command: + perplayerkit-about: "PerPlayerKit este un plugin care permite jucătorilor să aibă propriile kituri." + deletekit-usage: "Utilizare: /deletekit " + swapkit-usage: "Utilizare: /swapkit " + savepublickit-usage: "Utilizare: /{command} " + perplayerkit-migrate-usage: "Utilizare: /perplayerkit migrate " + kitroom-usage-hint: "/kitroom " + inspect-usage: "Utilizare: /{command} " + +update: + new-version-available: "Este disponibilă o nouă versiune de PerPlayerKit! Folosești versiunea {current}, iar cea mai recentă este {latest}" + +about: + header-start: "==========[Despre]==========" + title: "PerPlayerKit" + author: "Autor: {author}" + license: "Licență: {license}" + source-code: "Cod sursă: {source}" + version: "Versiune: {version}" + build-time: "Timp compilare: {time}" + header-end: "============================" + +gui: + main-menu-title: "Kiturile lui {player}" + kit-editor-title: "Kit: {slot}" + public-kit-editor-title: "Kit Public: {id}" + enderchest-editor-title: "Cufăr Ender: {slot}" + inspect-kit-title: "Inspectare kit {slot} al lui {player}" + inspect-ec-title: "Inspectare cufăr Ender {slot} al lui {player}" + kit-room-title: "Camera Kiturilor" + public-kit-room-title: "Camera Kiturilor Publice" + view-public-kit-title: "Vizualizare Kit Public: {id}" + enderchest-view-title: "Cufăr Ender (doar vizualizare)" + regear-shulker-title: "Shulker de Reechipare" + + kit-slot-name: "Kit {slot}" + enderchest-slot-name: "Cufăr Ender {slot}" + kit-exists: "KITUL EXISTĂ" + kit-not-found: "KIT NEGĂSIT" + more-kits-coming: "MAI MULTE KITURI ÎN CURÂND" + unassigned-tag: "[NEATRIBUIT]" + import-button: "IMPORTĂ" + clear-kit-button: "GOLEȘTE KITUL" + clear-ec-button: "GOLEȘTE CUFĂR ENDER" + back-button: "ÎNAPOI" + close-button: "ÎNCHIDE" + load-kit-button: "ÎNCARCĂ KIT" + refill-button: "REUMPLE" + kit-room-button: "CAMERA KITURILOR" + premade-kits-button: "KITURI PREFĂCUTE" + info-button: "INFO" + clear-inventory-button: "GOLEȘTE INVENTARUL" + share-kits-button: "PARTAJEAZĂ KITURI" + repair-items-button: "REPARĂ OBIECTE" + edit-menu-button: "EDITARE MENIU" + edit-menu-lore: "SHIFT CLICK DREAPTA PENTRU SALVARE" + regear-shulker-name: "Shulker de Reechipare" + regear-shell-name: "Cochilie de Reechipare" + + lore-click-edit: "● Click pentru editare" + lore-click-create: "● Click pentru creare" + lore-shift-clear: "● Shift+click pentru golire" + lore-shift-delete-kit: "● Shift+click pentru ștergerea kitului" + lore-shift-delete-ec: "● Shift+click pentru ștergerea cufărului Ender" + lore-shift-click: "● Shift+click" + lore-import-inventory: "● Importă din inventar" + lore-import-ec: "● Importă din cufăr Ender" + lore-left-load: "● Click stânga pentru încărcare kit" + lore-right-edit: "● Click dreapta pentru editare kit" + lore-share-kits: "● /sharekit " + lore-info-load: "● Click pe un slot pentru a încărca kitul tău" + lore-info-edit: "● Click dreapta sau pe carte pentru editare" + lore-info-share: "● Partajează kituri cu /sharekit " + lore-admin-shift-edit: "● [ADMIN] Shift+click pentru editare" + lore-unassigned-info: "● Administratorii încă nu au configurat acest kit" + lore-regear-restocks: "● Reumple kitul tău" + lore-regear-shulker-use: "● Folosește {primary}/rg pentru a primi alt shulker de reechipare" + lore-regear-shell-click: "● Click pentru utilizare!" diff --git a/src/main/resources/lang/sv.yml b/src/main/resources/lang/sv.yml new file mode 100644 index 0000000..dd8ef0b --- /dev/null +++ b/src/main/resources/lang/sv.yml @@ -0,0 +1,204 @@ +# PerPlayerKit Language File - Swedish (Svenska) +# Uses MiniMessage format: https://docs.advntr.dev/minimessage/format.html +# Placeholders use {name} syntax (e.g. {player}, {slot}). +# To use this file, set `language: sv` in config.yml. + +prefix: "[Kit] " + +motd: + message: + - "" + - " Per Spelare Kit " + - "" + - " Skriv /kit, /k eller /pk för att börja!" + - "" + - " " + - "" + +scheduled-broadcast: + messages: + - "Kolla in publika kit med kommandot /pk!" + - "Vill du dela ett kit? Använd /sharekit ." + - "Skriv /kit, /k eller /pk för att börja!" + +broadcast-messages: + player-repaired: "{player} reparerade sin utrustning" + player-healed: "{player} läkte sig själv" + player-opened-kit-room: "{player} öppnade kitrummet" + player-loaded-private-kit: "{player} laddade ett kit" + player-loaded-public-kit: "{player} laddade ett publikt kit" + player-loaded-enderchest: "{player} laddade en enderkista." + player-copied-kit: "{player} kopierade ett kit" + player-copied-ec: "{player} kopierade en enderkista" + player-regeared: "{player} utrustade om sig" + generic: "{player} utförde en handling." + +error: + disabled-in-world: "Kit är inaktiverade här!" + unexpected: "Ett oväntat fel inträffade, försök igen." + kit-not-found: "Fel, det kitet existerar inte" + kit-expired: "Fel, kitet existerar inte eller har gått ut" + ec-not-found: "Fel, den enderkistan existerar inte" + empty-kit: "Du kan inte spara ett tomt kit!" + empty-ec: "Du kan inte spara en tom enderkista!" + kit-slot-not-found: "Kit {slot} existerar inte!" + kit-deletion-failed: "Borttagning av kit misslyckades!" + invalid-number: "Välj ett giltigt nummer" + invalid-numbers: "Välj giltiga nummer" + invalid-kit-slot: "Välj en giltig kit-slot" + missing-kit-code: "Fel, du måste ange en kitkod för att kopiera" + missing-kit-slot-share: "Fel, du måste välja en kit-slot att dela" + missing-ec-slot-share: "Fel, du måste välja en enderkista-slot att dela" + command-cooldown: "Spamma inte kommandot (5 sekunders nedkylning)" + regear-misconfigured: "Detta kommando är inte korrekt konfigurerat, kontakta en administratör." + inventory-full: "Ditt inventarium är fullt, kan inte ge dig en regear-shulker!" + no-kit-loaded: "Du har inte laddat ett kit ännu!" + regear-elytra-blocked: "Du kan inte regeara medan du använder elytra!" + regear-combat-cooldown: "Du måste vara utanför strid i {seconds} sekunder till innan du kan regeara!" + regear-command-cooldown: "Du måste vänta {seconds} sekunder innan du kan använda detta kommando igen!" + missing-arguments: "Argument saknas!" + invalid-subcommand: "Ogiltigt underkommando!" + missing-import-type: "Importtyp saknas!" + invalid-import-type: "Ogiltig importtyp!" + import-files-missing: "Filer att importera saknas" + invalid-storage-type: "Ogiltig {role}-lagringstyp: {type}" + storage-same: "Källa och destination får inte vara samma!" + migration-failed: "Migrering misslyckades: {error}" + missing-kit-id: "Du måste ange ett kit-id" + public-kit-not-found: "Publikt kit {kitid} existerar inte" + add-public-kit-config: "Du kanske behöver lägga till ett publikt kit i konfigurationen" + public-kit-save-failed: "Fel vid sparande av kit {kitid}" + incorrect-usage: "Felaktig användning!" + players-only: "Endast spelare kan använda detta kommando" + players-only-inspect: "Detta kommando kan endast utföras av spelare." + invalid-slot-range: "Slot måste vara ett nummer mellan {min} och {max}." + player-not-found: "Kunde inte hitta en spelare med det namnet eller UUID." + kit-not-found-display: "Kit hittades inte" + inspect-kit-missing: "{player} har inget kit i slot {slot}" + inspect-ec-missing: "{player} har ingen enderkista i slot {slot}" + inspect-kit-load-error: "Ett fel inträffade vid laddning av kitdata. Se konsolen för detaljer." + inspect-ec-load-error: "Ett fel inträffade vid laddning av enderkista-data. Se konsolen för detaljer." + failed-to-update-kit: "Misslyckades att uppdatera kit för spelare {player}!" + failed-to-update-ec: "Misslyckades att uppdatera enderkista för spelare {player}!" + invalid-command-label: "Ogiltig kommandoetikett." + prefix-tag: "Fel: " + +success: + kit-saved: "Kit {slot} sparat!" + kit-loaded: "Kit {slot} laddat!" + kit-deleted: "Kit {slot} borttaget!" + kits-swapped: "Kit {slot1} och {slot2} har bytts!" + ec-saved: "Enderkista {slot} sparad!" + ec-loaded: "Enderkista {slot} laddad!" + public-kit-saved: "Publikt kit {kitname} sparat!" + public-kit-loaded: "Publikt kit laddat!" + public-kit-saved-admin: "Sparade kit {kitid}" + kitroom-loaded: "Kitrum laddat från SQL" + kitroom-saved: "Kitrum sparat till SQL" + kitroom-menu-saved: "Kitrum-meny sparad" + all-repaired: "Alla föremål reparerade!" + healed: "Du har blivit läkt!" + shulker-given: "Regear-shulker given!" + regeared: "Omutrustad!" + inventory-cleared: "Inventarium rensat" + admin-kit-deleted: "Kit {slot} borttaget för spelare!" + admin-ec-deleted: "Enderkista {slot} borttagen för spelare!" + admin-kit-updated: "Kit {slot} uppdaterat för spelare {player}!" + admin-ec-updated: "Enderkista {slot} uppdaterad för spelare {player}!" + migration-completed: "Migrering slutförd!" + migration-count: "Migrerat: {count} poster" + import-attempted: "Försök till import av KitsX-data!" + import-starting: "Startar import..." + +info: + custom-version-available: "Du kan spara en anpassad version av detta kit genom att importera till kit-redigeraren" + assign-publickit-instruction: "För att tilldela ett kit till denna publickit använd /savepublickit " + share-kit-code: "Använd /copykit {code} för att kopiera detta kit" + share-ec-code: "Använd /copyEC {code} för att kopiera denna enderkista" + share-code-expiry: "Koden går ut om 15 minuter" + import-instructions: "Kopiera datamappen från KitsX till PerPlayerKit-mappen" + migration-starting: "Startar migrering från {source} till {destination}..." + migration-large-dataset: "Detta kan ta ett tag för stora datamängder. Kontrollera konsolen för förlopp." + available-storage-types: "Tillgängliga lagringstyper: sqlite, mysql, redis, yml" + update-config-storage: "Kom ihåg att uppdatera din config.yml storage.type till '{type}' och starta om servern." + migration-failed-count: "Misslyckades: {count} poster" + migration-progress: "{message}" + +command: + perplayerkit-about: "PerPlayerKit är ett plugin som låter spelare ha sina egna kit." + deletekit-usage: "Användning: /deletekit " + swapkit-usage: "Användning: /swapkit " + savepublickit-usage: "Användning: /{command} " + perplayerkit-migrate-usage: "Användning: /perplayerkit migrate " + kitroom-usage-hint: "/kitroom " + inspect-usage: "Användning: /{command} " + +update: + new-version-available: "En ny version av PerPlayerKit är tillgänglig! Du kör version {current} och den senaste versionen är {latest}" + +about: + header-start: "==========[Om]==========" + title: "PerPlayerKit" + author: "Författare: {author}" + license: "Licens: {license}" + source-code: "Källkod: {source}" + version: "Version: {version}" + build-time: "Byggtid: {time}" + header-end: "========================" + +gui: + main-menu-title: "{player}s Kit" + kit-editor-title: "Kit: {slot}" + public-kit-editor-title: "Publikt Kit: {id}" + enderchest-editor-title: "Enderkista: {slot}" + inspect-kit-title: "Inspekterar {player}s kit {slot}" + inspect-ec-title: "Inspekterar {player}s enderkista {slot}" + kit-room-title: "Kitrum" + public-kit-room-title: "Publikt Kitrum" + view-public-kit-title: "Visar Publikt Kit: {id}" + enderchest-view-title: "Endast Visa Enderkista" + regear-shulker-title: "Regear-Shulker" + + kit-slot-name: "Kit {slot}" + enderchest-slot-name: "Enderkista {slot}" + kit-exists: "KIT FINNS" + kit-not-found: "KIT HITTADES INTE" + more-kits-coming: "FLER KIT KOMMER SNART" + unassigned-tag: "[EJ TILLDELAD]" + import-button: "IMPORTERA" + clear-kit-button: "RENSA KIT" + clear-ec-button: "RENSA ENDERKISTA" + back-button: "TILLBAKA" + close-button: "STÄNG" + load-kit-button: "LADDA KIT" + refill-button: "FYLL PÅ" + kit-room-button: "KITRUM" + premade-kits-button: "FÖRGJORDA KIT" + info-button: "INFO" + clear-inventory-button: "RENSA INVENTARIUM" + share-kits-button: "DELA KIT" + repair-items-button: "REPARERA FÖREMÅL" + edit-menu-button: "REDIGERA MENY" + edit-menu-lore: "SHIFT HÖGERKLICK FÖR ATT SPARA" + regear-shulker-name: "Regear-Shulker" + regear-shell-name: "Regear-Skal" + + lore-click-edit: "● Klicka för att redigera" + lore-click-create: "● Klicka för att skapa" + lore-shift-clear: "● Shift-klick för att rensa" + lore-shift-delete-kit: "● Shift-klick för att ta bort kit" + lore-shift-delete-ec: "● Shift-klick för att ta bort enderkista" + lore-shift-click: "● Shift-klick" + lore-import-inventory: "● Importera från inventarium" + lore-import-ec: "● Importera från enderkista" + lore-left-load: "● Vänsterklicka för att ladda kit" + lore-right-edit: "● Högerklicka för att redigera kit" + lore-share-kits: "● /sharekit " + lore-info-load: "● Klicka på en kit-slot för att ladda ditt kit" + lore-info-edit: "● Högerklicka eller klicka på boken för att redigera" + lore-info-share: "● Dela kit med /sharekit " + lore-admin-shift-edit: "● [ADMIN] Shift-klick för att redigera" + lore-unassigned-info: "● Admins har inte ställt in detta kit ännu" + lore-regear-restocks: "● Fyller på ditt kit" + lore-regear-shulker-use: "● Använd {primary}/rg för att få en till regear-shulker" + lore-regear-shell-click: "● Klicka för att använda!" diff --git a/src/main/resources/lang/uk.yml b/src/main/resources/lang/uk.yml new file mode 100644 index 0000000..445f185 --- /dev/null +++ b/src/main/resources/lang/uk.yml @@ -0,0 +1,204 @@ +# PerPlayerKit Language File - Ukrainian (Українська) +# Uses MiniMessage format: https://docs.advntr.dev/minimessage/format.html +# Placeholders use {name} syntax (e.g. {player}, {slot}). +# To use this file, set `language: uk` in config.yml. + +prefix: "[Кіти] " + +motd: + message: + - "" + - " Особисті набори " + - "" + - " Введіть /kit, /k або /pk щоб почати!" + - "" + - " " + - "" + +scheduled-broadcast: + messages: + - "Перегляньте публічні набори командою /pk!" + - "Хочете поділитися набором? Використайте /sharekit ." + - "Введіть /kit, /k або /pk щоб почати!" + +broadcast-messages: + player-repaired: "{player} полагодив спорядження" + player-healed: "{player} вилікувався" + player-opened-kit-room: "{player} відкрив кімнату наборів" + player-loaded-private-kit: "{player} завантажив набір" + player-loaded-public-kit: "{player} завантажив публічний набір" + player-loaded-enderchest: "{player} завантажив ендер-скриню." + player-copied-kit: "{player} скопіював набір" + player-copied-ec: "{player} скопіював ендер-скриню" + player-regeared: "{player} переекіпірувався" + generic: "{player} виконав дію." + +error: + disabled-in-world: "Набори тут вимкнено!" + unexpected: "Сталася непередбачена помилка, спробуйте ще раз." + kit-not-found: "Помилка, такого набору не існує" + kit-expired: "Помилка, набір не існує або термін його дії минув" + ec-not-found: "Помилка, такої ендер-скрині не існує" + empty-kit: "Не можна зберегти порожній набір!" + empty-ec: "Не можна зберегти порожню ендер-скриню!" + kit-slot-not-found: "Набір {slot} не існує!" + kit-deletion-failed: "Не вдалося видалити набір!" + invalid-number: "Введіть коректне число" + invalid-numbers: "Введіть коректні числа" + invalid-kit-slot: "Виберіть коректний слот набору" + missing-kit-code: "Помилка, ви повинні ввести код набору для копіювання" + missing-kit-slot-share: "Помилка, ви повинні вибрати слот набору для надсилання" + missing-ec-slot-share: "Помилка, ви повинні вибрати слот ендер-скрині для надсилання" + command-cooldown: "Не спамте командою (затримка 5 секунд)" + regear-misconfigured: "Цю команду налаштовано неправильно, зверніться до адміністратора." + inventory-full: "Ваш інвентар повний, неможливо видати шалкер переекіпірування!" + no-kit-loaded: "Ви ще не завантажили набір!" + regear-elytra-blocked: "Ви не можете переекіпіруватися використовуючи елітри!" + regear-combat-cooldown: "Ви повинні бути поза боєм ще {seconds} секунд для переекіпірування!" + regear-command-cooldown: "Ви повинні зачекати {seconds} секунд перед повторним використанням цієї команди!" + missing-arguments: "Відсутні аргументи!" + invalid-subcommand: "Невірна підкоманда!" + missing-import-type: "Відсутній тип імпорту!" + invalid-import-type: "Невірний тип імпорту!" + import-files-missing: "Файли для імпорту відсутні" + invalid-storage-type: "Невірний тип сховища {role}: {type}" + storage-same: "Джерело та призначення не можуть бути однаковими!" + migration-failed: "Міграція не вдалася: {error}" + missing-kit-id: "Ви повинні вказати id набору" + public-kit-not-found: "Публічний набір {kitid} не існує" + add-public-kit-config: "Можливо, вам потрібно додати публічний набір у конфігурації" + public-kit-save-failed: "Помилка збереження набору {kitid}" + incorrect-usage: "Невірне використання!" + players-only: "Тільки гравці можуть використовувати цю команду" + players-only-inspect: "Цю команду можуть використовувати лише гравці." + invalid-slot-range: "Слот має бути числом від {min} до {max}." + player-not-found: "Не вдалося знайти гравця з таким іменем або UUID." + kit-not-found-display: "Набір не знайдено" + inspect-kit-missing: "У {player} немає набору в слоті {slot}" + inspect-ec-missing: "У {player} немає ендер-скрині в слоті {slot}" + inspect-kit-load-error: "Сталася помилка під час завантаження даних набору. Дивіться консоль для деталей." + inspect-ec-load-error: "Сталася помилка під час завантаження даних ендер-скрині. Дивіться консоль для деталей." + failed-to-update-kit: "Не вдалося оновити набір гравця {player}!" + failed-to-update-ec: "Не вдалося оновити ендер-скриню гравця {player}!" + invalid-command-label: "Невірна мітка команди." + prefix-tag: "Помилка: " + +success: + kit-saved: "Набір {slot} збережено!" + kit-loaded: "Набір {slot} завантажено!" + kit-deleted: "Набір {slot} видалено!" + kits-swapped: "Набори {slot1} і {slot2} обміняно!" + ec-saved: "Ендер-скриню {slot} збережено!" + ec-loaded: "Ендер-скриню {slot} завантажено!" + public-kit-saved: "Публічний набір {kitname} збережено!" + public-kit-loaded: "Публічний набір завантажено!" + public-kit-saved-admin: "Збережено набір {kitid}" + kitroom-loaded: "Кімнату наборів завантажено з SQL" + kitroom-saved: "Кімнату наборів збережено до SQL" + kitroom-menu-saved: "Меню кімнати наборів збережено" + all-repaired: "Усі предмети полагоджено!" + healed: "Вас вилікувано!" + shulker-given: "Шалкер переекіпірування видано!" + regeared: "Переекіпіровано!" + inventory-cleared: "Інвентар очищено" + admin-kit-deleted: "Набір {slot} видалено в гравця!" + admin-ec-deleted: "Ендер-скриню {slot} видалено в гравця!" + admin-kit-updated: "Набір {slot} оновлено в гравця {player}!" + admin-ec-updated: "Ендер-скриню {slot} оновлено в гравця {player}!" + migration-completed: "Міграцію успішно завершено!" + migration-count: "Перенесено: {count} записів" + import-attempted: "Імпорт даних KitsX виконано!" + import-starting: "Починаю імпорт..." + +info: + custom-version-available: "Ви можете зберегти свою версію цього набору, імпортувавши його до редактора" + assign-publickit-instruction: "Щоб призначити набір для цього publickit використовуйте /savepublickit " + share-kit-code: "Використовуйте /copykit {code} щоб скопіювати цей набір" + share-ec-code: "Використовуйте /copyEC {code} щоб скопіювати цю ендер-скриню" + share-code-expiry: "Код діє 15 хвилин" + import-instructions: "Скопіюйте папку даних з KitsX у папку PerPlayerKit" + migration-starting: "Починаю міграцію з {source} до {destination}..." + migration-large-dataset: "Це може зайняти деякий час для великих наборів даних. Перевіряйте консоль для прогресу." + available-storage-types: "Доступні типи сховищ: sqlite, mysql, redis, yml" + update-config-storage: "Не забудьте оновити storage.type у config.yml на '{type}' та перезапустити сервер." + migration-failed-count: "Не вдалося: {count} записів" + migration-progress: "{message}" + +command: + perplayerkit-about: "PerPlayerKit — це плагін, що дозволяє гравцям мати власні набори." + deletekit-usage: "Використання: /deletekit <слот>" + swapkit-usage: "Використання: /swapkit <слот1> <слот2>" + savepublickit-usage: "Використання: /{command} " + perplayerkit-migrate-usage: "Використання: /perplayerkit migrate <джерело> <призначення>" + kitroom-usage-hint: "/kitroom " + inspect-usage: "Використання: /{command} <гравець|uuid> <слот>" + +update: + new-version-available: "Доступна нова версія PerPlayerKit! Ви використовуєте версію {current}, а остання версія — {latest}" + +about: + header-start: "==========[Про плагін]==========" + title: "PerPlayerKit" + author: "Автор: {author}" + license: "Ліцензія: {license}" + source-code: "Початковий код: {source}" + version: "Версія: {version}" + build-time: "Час збірки: {time}" + header-end: "================================" + +gui: + main-menu-title: "Набори {player}" + kit-editor-title: "Набір: {slot}" + public-kit-editor-title: "Публічний набір: {id}" + enderchest-editor-title: "Ендер-скриня: {slot}" + inspect-kit-title: "Перегляд набору {slot} гравця {player}" + inspect-ec-title: "Перегляд ендер-скрині {slot} гравця {player}" + kit-room-title: "Кімната наборів" + public-kit-room-title: "Кімната публічних наборів" + view-public-kit-title: "Перегляд публічного набору: {id}" + enderchest-view-title: "Ендер-скриня (лише перегляд)" + regear-shulker-title: "Шалкер переекіпірування" + + kit-slot-name: "Набір {slot}" + enderchest-slot-name: "Ендер-скриня {slot}" + kit-exists: "НАБІР ІСНУЄ" + kit-not-found: "НАБІР НЕ ЗНАЙДЕНО" + more-kits-coming: "СКОРО З'ЯВЛЯТЬСЯ НОВІ НАБОРИ" + unassigned-tag: "[НЕ ПРИЗНАЧЕНО]" + import-button: "ІМПОРТ" + clear-kit-button: "ОЧИСТИТИ НАБІР" + clear-ec-button: "ОЧИСТИТИ ЕНДЕР-СКРИНЮ" + back-button: "НАЗАД" + close-button: "ЗАКРИТИ" + load-kit-button: "ЗАВАНТАЖИТИ НАБІР" + refill-button: "ПОПОВНИТИ" + kit-room-button: "КІМНАТА НАБОРІВ" + premade-kits-button: "ГОТОВІ НАБОРИ" + info-button: "ІНФО" + clear-inventory-button: "ОЧИСТИТИ ІНВЕНТАР" + share-kits-button: "ПОДІЛИТИСЯ НАБОРАМИ" + repair-items-button: "ПОЛАГОДИТИ ПРЕДМЕТИ" + edit-menu-button: "МЕНЮ РЕДАГУВАННЯ" + edit-menu-lore: "SHIFT ПРАВИЙ КЛІК ЩОБ ЗБЕРЕГТИ" + regear-shulker-name: "Шалкер переекіпірування" + regear-shell-name: "Мушля переекіпірування" + + lore-click-edit: "● Натисніть для редагування" + lore-click-create: "● Натисніть для створення" + lore-shift-clear: "● Shift клік для очищення" + lore-shift-delete-kit: "● Shift клік для видалення набору" + lore-shift-delete-ec: "● Shift клік для видалення ендер-скрині" + lore-shift-click: "● Shift клік" + lore-import-inventory: "● Імпорт з інвентарю" + lore-import-ec: "● Імпорт з ендер-скрині" + lore-left-load: "● ЛКМ щоб завантажити набір" + lore-right-edit: "● ПКМ щоб редагувати набір" + lore-share-kits: "● /sharekit " + lore-info-load: "● Натисніть на слот набору, щоб завантажити ваш набір" + lore-info-edit: "● ПКМ або клік по книзі для редагування" + lore-info-share: "● Діліться наборами командою /sharekit " + lore-admin-shift-edit: "● [АДМІН] Shift клік для редагування" + lore-unassigned-info: "● Адміністратори ще не налаштували цей набір" + lore-regear-restocks: "● Поповнює ваш набір" + lore-regear-shulker-use: "● Використайте {primary}/rg щоб отримати ще один шалкер переекіпірування" + lore-regear-shell-click: "● Натисніть для використання!" diff --git a/src/main/resources/lang/zh.yml b/src/main/resources/lang/zh.yml new file mode 100644 index 0000000..3417f8e --- /dev/null +++ b/src/main/resources/lang/zh.yml @@ -0,0 +1,204 @@ +# PerPlayerKit Language File - Chinese (简体中文) +# Uses MiniMessage format: https://docs.advntr.dev/minimessage/format.html +# Placeholders use {name} syntax (e.g. {player}, {slot}). +# To use this file, set `language: zh` in config.yml. + +prefix: "[套件] " + +motd: + message: + - "" + - " 玩家专属套件 " + - "" + - " 输入 /kit/k /pk 开始使用!" + - "" + - " " + - "" + +scheduled-broadcast: + messages: + - "使用 /pk 命令查看公共套件!" + - "想要分享套件? 使用 /sharekit 命令。" + - "输入 /kit/k /pk 开始使用!" + +broadcast-messages: + player-repaired: "{player} 修理了装备" + player-healed: "{player} 治疗了自己" + player-opened-kit-room: "{player} 打开了套件房间" + player-loaded-private-kit: "{player} 加载了一个套件" + player-loaded-public-kit: "{player} 加载了一个公共套件" + player-loaded-enderchest: "{player} 加载了末影箱。" + player-copied-kit: "{player} 复制了一个套件" + player-copied-ec: "{player} 复制了一个末影箱" + player-regeared: "{player} 重新装备" + generic: "{player} 执行了一个操作。" + +error: + disabled-in-world: "此处禁用套件!" + unexpected: "发生意外错误,请重试。" + kit-not-found: "错误,该套件不存在" + kit-expired: "错误,套件不存在或已过期" + ec-not-found: "错误,该末影箱不存在" + empty-kit: "不能保存空套件!" + empty-ec: "不能保存空末影箱!" + kit-slot-not-found: "套件 {slot} 不存在!" + kit-deletion-failed: "删除套件失败!" + invalid-number: "请选择有效的数字" + invalid-numbers: "请选择有效的数字" + invalid-kit-slot: "请选择有效的套件槽位" + missing-kit-code: "错误,你必须输入要复制的套件代码" + missing-kit-slot-share: "错误,你必须选择要分享的套件槽位" + missing-ec-slot-share: "错误,你必须选择要分享的末影箱槽位" + command-cooldown: "请勿频繁使用命令 (5 秒冷却)" + regear-misconfigured: "此命令配置不正确,请联系管理员。" + inventory-full: "你的物品栏已满,无法获得重装潜影盒!" + no-kit-loaded: "你还没有加载套件!" + regear-elytra-blocked: "使用鞘翅时不能重装!" + regear-combat-cooldown: "你必须在脱离战斗 {seconds} 秒后才能重装!" + regear-command-cooldown: "你必须等待 {seconds} 秒才能再次使用此命令!" + missing-arguments: "缺少参数!" + invalid-subcommand: "无效的子命令!" + missing-import-type: "缺少导入类型!" + invalid-import-type: "无效的导入类型!" + import-files-missing: "缺少要导入的文件" + invalid-storage-type: "无效的 {role} 存储类型: {type}" + storage-same: "源和目标不能相同!" + migration-failed: "迁移失败: {error}" + missing-kit-id: "你需要指定一个套件 id" + public-kit-not-found: "公共套件 {kitid} 不存在" + add-public-kit-config: "你可能需要在配置中添加一个公共套件" + public-kit-save-failed: "保存套件 {kitid} 出错" + incorrect-usage: "用法错误!" + players-only: "只有玩家可以使用此命令" + players-only-inspect: "此命令只能由玩家执行。" + invalid-slot-range: "槽位必须是 {min} 到 {max} 之间的数字。" + player-not-found: "找不到该名称或 UUID 的玩家。" + kit-not-found-display: "套件未找到" + inspect-kit-missing: "{player} 的槽位 {slot} 没有套件" + inspect-ec-missing: "{player} 的槽位 {slot} 没有末影箱" + inspect-kit-load-error: "加载套件数据时出错。详情请查看控制台。" + inspect-ec-load-error: "加载末影箱数据时出错。详情请查看控制台。" + failed-to-update-kit: "更新玩家 {player} 的套件失败!" + failed-to-update-ec: "更新玩家 {player} 的末影箱失败!" + invalid-command-label: "无效的命令标签。" + prefix-tag: "错误: " + +success: + kit-saved: "套件 {slot} 已保存!" + kit-loaded: "套件 {slot} 已加载!" + kit-deleted: "套件 {slot} 已删除!" + kits-swapped: "套件 {slot1} 和 {slot2} 已交换!" + ec-saved: "末影箱 {slot} 已保存!" + ec-loaded: "末影箱 {slot} 已加载!" + public-kit-saved: "公共套件 {kitname} 已保存!" + public-kit-loaded: "公共套件已加载!" + public-kit-saved-admin: "已保存套件 {kitid}" + kitroom-loaded: "套件房间已从 SQL 加载" + kitroom-saved: "套件房间已保存到 SQL" + kitroom-menu-saved: "套件房间菜单已保存" + all-repaired: "所有物品已修复!" + healed: "你已被治愈!" + shulker-given: "已给予重装潜影盒!" + regeared: "已重装!" + inventory-cleared: "物品栏已清空" + admin-kit-deleted: "已为玩家删除套件 {slot}!" + admin-ec-deleted: "已为玩家删除末影箱 {slot}!" + admin-kit-updated: "已为玩家 {player} 更新套件 {slot}!" + admin-ec-updated: "已为玩家 {player} 更新末影箱 {slot}!" + migration-completed: "迁移成功完成!" + migration-count: "已迁移: {count} 条" + import-attempted: "已尝试导入 KitsX 数据!" + import-starting: "开始导入..." + +info: + custom-version-available: "你可以通过将此套件导入到编辑器来保存自定义版本" + assign-publickit-instruction: "使用 /savepublickit 为此 publickit 分配套件" + share-kit-code: "使用 /copykit {code} 复制此套件" + share-ec-code: "使用 /copyEC {code} 复制此末影箱" + share-code-expiry: "代码将在 15 分钟后过期" + import-instructions: "将 KitsX 的数据文件夹复制到 PerPlayerKit 文件夹" + migration-starting: "开始从 {source} 迁移到 {destination}..." + migration-large-dataset: "大型数据集可能需要一些时间。请查看控制台以了解进度。" + available-storage-types: "可用的存储类型: sqlite, mysql, redis, yml" + update-config-storage: "请记得将 config.yml 中的 storage.type 更新为 '{type}' 并重启服务器。" + migration-failed-count: "失败: {count} 条" + migration-progress: "{message}" + +command: + perplayerkit-about: "PerPlayerKit 是一个允许玩家拥有自己套件的插件。" + deletekit-usage: "用法: /deletekit <槽位>" + swapkit-usage: "用法: /swapkit <槽位1> <槽位2>" + savepublickit-usage: "用法: /{command} <套件id>" + perplayerkit-migrate-usage: "用法: /perplayerkit migrate <源> <目标>" + kitroom-usage-hint: "/kitroom " + inspect-usage: "用法: /{command} <玩家|uuid> <槽位>" + +update: + new-version-available: "PerPlayerKit 有新版本可用! 你正在运行版本 {current},最新版本是 {latest}" + +about: + header-start: "==========[关于]==========" + title: "PerPlayerKit" + author: "作者: {author}" + license: "许可证: {license}" + source-code: "源代码: {source}" + version: "版本: {version}" + build-time: "构建时间: {time}" + header-end: "==========================" + +gui: + main-menu-title: "{player} 的套件" + kit-editor-title: "套件: {slot}" + public-kit-editor-title: "公共套件: {id}" + enderchest-editor-title: "末影箱: {slot}" + inspect-kit-title: "查看 {player} 的套件 {slot}" + inspect-ec-title: "查看 {player} 的末影箱 {slot}" + kit-room-title: "套件房间" + public-kit-room-title: "公共套件房间" + view-public-kit-title: "查看公共套件: {id}" + enderchest-view-title: "末影箱 (仅查看)" + regear-shulker-title: "重装潜影盒" + + kit-slot-name: "套件 {slot}" + enderchest-slot-name: "末影箱 {slot}" + kit-exists: "套件存在" + kit-not-found: "套件未找到" + more-kits-coming: "更多套件即将推出" + unassigned-tag: "[未分配]" + import-button: "导入" + clear-kit-button: "清除套件" + clear-ec-button: "清除末影箱" + back-button: "返回" + close-button: "关闭" + load-kit-button: "加载套件" + refill-button: "补充" + kit-room-button: "套件房间" + premade-kits-button: "预设套件" + info-button: "信息" + clear-inventory-button: "清空物品栏" + share-kits-button: "分享套件" + repair-items-button: "修复物品" + edit-menu-button: "编辑菜单" + edit-menu-lore: "SHIFT 右键单击以保存" + regear-shulker-name: "重装潜影盒" + regear-shell-name: "重装贝壳" + + lore-click-edit: "● 单击以编辑" + lore-click-create: "● 单击以创建" + lore-shift-clear: "● Shift 单击以清除" + lore-shift-delete-kit: "● Shift 单击以删除套件" + lore-shift-delete-ec: "● Shift 单击以删除末影箱" + lore-shift-click: "● Shift 单击" + lore-import-inventory: "● 从物品栏导入" + lore-import-ec: "● 从末影箱导入" + lore-left-load: "● 左键单击加载套件" + lore-right-edit: "● 右键单击编辑套件" + lore-share-kits: "● /sharekit " + lore-info-load: "● 单击套件槽位加载你的套件" + lore-info-edit: "● 右键单击或单击书本编辑" + lore-info-share: "● 使用 /sharekit 分享套件" + lore-admin-shift-edit: "● [管理员] Shift 单击编辑" + lore-unassigned-info: "● 管理员尚未设置此套件" + lore-regear-restocks: "● 补充你的套件" + lore-regear-shulker-use: "● 使用 {primary}/rg 获取另一个重装潜影盒" + lore-regear-shell-click: "● 单击使用!" diff --git a/src/test/java/dev/noah/perplayerkit/ConfigMigratorTest.java b/src/test/java/dev/noah/perplayerkit/ConfigMigratorTest.java new file mode 100644 index 0000000..6099a82 --- /dev/null +++ b/src/test/java/dev/noah/perplayerkit/ConfigMigratorTest.java @@ -0,0 +1,117 @@ +package dev.noah.perplayerkit; + +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.Plugin; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.mockito.Mockito; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.logging.Logger; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.when; + +class ConfigMigratorTest { + + private Plugin pluginFor(File dataFolder) { + Plugin plugin = Mockito.mock(Plugin.class); + when(plugin.getDataFolder()).thenReturn(dataFolder); + when(plugin.getLogger()).thenReturn(Logger.getLogger("test")); + // Make getResource pull from the test classpath (which includes src/main/resources) + Mockito.doAnswer(invocation -> { + String name = invocation.getArgument(0); + InputStream in = ConfigMigratorTest.class.getClassLoader().getResourceAsStream(name); + return in; + }).when(plugin).getResource(Mockito.anyString()); + return plugin; + } + + @Test + void migrationIsNoOpWhenConfigAbsent(@TempDir Path tempDir) { + Plugin plugin = pluginFor(tempDir.toFile()); + + new ConfigMigrator(plugin).migrate(); + + assertFalse(new File(tempDir.toFile(), "config.yml").exists()); + } + + @Test + void migrationIsNoOpWhenConfigAlreadyV2(@TempDir Path tempDir) throws IOException { + File configFile = new File(tempDir.toFile(), "config.yml"); + Files.writeString(configFile.toPath(), "config-version: 2\nlanguage: en\n"); + Plugin plugin = pluginFor(tempDir.toFile()); + + new ConfigMigrator(plugin).migrate(); + + YamlConfiguration after = YamlConfiguration.loadConfiguration(configFile); + assertEquals(2, after.getInt("config-version")); + } + + @Test + void migrationBumpsVersionAndAddsLanguage(@TempDir Path tempDir) throws IOException { + File configFile = new File(tempDir.toFile(), "config.yml"); + Files.writeString(configFile.toPath(), + "config-version: 1\n" + + "prefix: \"[MyServer] \"\n" + + "disabled-command-message: \"&cNot here.\"\n" + + "messages:\n" + + " player-repaired:\n" + + " enabled: true\n" + + " message: \"%player% custom repair msg\"\n" + + " permission: \"perplayerkit.kitnotify\"\n"); + Plugin plugin = pluginFor(tempDir.toFile()); + + new ConfigMigrator(plugin).migrate(); + + YamlConfiguration after = YamlConfiguration.loadConfiguration(configFile); + assertEquals(2, after.getInt("config-version")); + assertEquals("en", after.getString("language")); + assertFalse(after.contains("prefix"), "prefix should be stripped from config.yml"); + assertFalse(after.contains("disabled-command-message"), "disabled-command-message should be stripped"); + assertFalse(after.contains("messages.player-repaired.message"), "message key should be stripped"); + assertTrue(after.getBoolean("messages.player-repaired.enabled"), "enabled flag preserved"); + + File langFile = new File(tempDir.toFile(), "lang/en.yml"); + assertTrue(langFile.exists(), "lang/en.yml should have been created"); + YamlConfiguration langCfg = YamlConfiguration.loadConfiguration(langFile); + assertEquals("[MyServer] ", langCfg.getString("prefix")); + assertEquals("&cNot here.", langCfg.getString("error.disabled-in-world")); + assertEquals("%player% custom repair msg", + langCfg.getString("broadcast-messages.player-repaired")); + } + + @Test + void migrationPreservesNonCustomizedDefaults(@TempDir Path tempDir) throws IOException { + // Default English prefix should not be migrated (it's the default value) + String defaultPrefix = "[Kits] "; + File configFile = new File(tempDir.toFile(), "config.yml"); + Files.writeString(configFile.toPath(), + "config-version: 1\nprefix: \"" + defaultPrefix + "\"\n", + StandardCharsets.UTF_8); + Plugin plugin = pluginFor(tempDir.toFile()); + + new ConfigMigrator(plugin).migrate(); + + File langFile = new File(tempDir.toFile(), "lang/en.yml"); + if (langFile.exists()) { + YamlConfiguration langCfg = YamlConfiguration.loadConfiguration(langFile); + // The prefix in the migrated lang file should still be the default + assertEquals(defaultPrefix, langCfg.getString("prefix")); + } + // The customizations section in the migrated lang file should not contain + // a redundant override since the original value matched the default. + // (We can't easily distinguish "set explicitly" vs "default" in YamlConfiguration + // without parsing manually, so this is a soft check.) + @SuppressWarnings("unused") + List ignored = List.of(); + } +} diff --git a/src/test/java/dev/noah/perplayerkit/commands/AbstractShareSlotCommandTest.java b/src/test/java/dev/noah/perplayerkit/commands/AbstractShareSlotCommandTest.java index a888e15..bd343a0 100644 --- a/src/test/java/dev/noah/perplayerkit/commands/AbstractShareSlotCommandTest.java +++ b/src/test/java/dev/noah/perplayerkit/commands/AbstractShareSlotCommandTest.java @@ -1,9 +1,12 @@ package dev.noah.perplayerkit.commands; import dev.noah.perplayerkit.commands.share.AbstractShareSlotCommand; +import dev.noah.perplayerkit.util.Lang; import dev.noah.perplayerkit.util.SoundManager; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; @@ -19,6 +22,16 @@ class AbstractShareSlotCommandTest { + @BeforeAll + static void setupLang() { + Lang.installForTesting(); + } + + @AfterAll + static void tearDownLang() { + Lang.resetForTesting(); + } + @Test void executesActionForValidSlot() { ShareRecorder recorder = new ShareRecorder(); @@ -40,7 +53,7 @@ void nonPlayerSenderGetsOnlyPlayersMessage() { command.onCommand(sender, null, "sharekit", new String[]{"2"}); - verify(sender).sendMessage("Only players can use this command"); + verify(sender).sendMessage(contains("Only players can use this command")); assertNull(recorder.lastSharedSlot); assertEquals(0, recorder.executionCount); } @@ -85,7 +98,7 @@ void cooldownPreventsImmediateSecondExecution() { private static class TestShareSlotCommand extends AbstractShareSlotCommand { private TestShareSlotCommand(ShareRecorder recorder) { - super("Error, missing slot", (player, slot) -> { + super("error.missing-kit-slot-share", (player, slot) -> { recorder.lastSharedSlot = slot; recorder.executionCount++; }); diff --git a/src/test/java/dev/noah/perplayerkit/commands/AbstractShortSlotCommandTest.java b/src/test/java/dev/noah/perplayerkit/commands/AbstractShortSlotCommandTest.java index 0208c0d..ee42474 100644 --- a/src/test/java/dev/noah/perplayerkit/commands/AbstractShortSlotCommandTest.java +++ b/src/test/java/dev/noah/perplayerkit/commands/AbstractShortSlotCommandTest.java @@ -2,19 +2,33 @@ import dev.noah.perplayerkit.commands.shortcuts.AbstractShortSlotCommand; import dev.noah.perplayerkit.util.DisabledCommand; +import dev.noah.perplayerkit.util.Lang; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.ArgumentMatchers.contains; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.verify; class AbstractShortSlotCommandTest { + @BeforeAll + static void setupLang() { + Lang.installForTesting(); + } + + @AfterAll + static void tearDownLang() { + Lang.resetForTesting(); + } + @Test void executesForShortPrefixLabel() { TestShortSlotCommand command = new TestShortSlotCommand(); @@ -68,7 +82,7 @@ void sendsErrorForInvalidLabel() { command.onCommand(player, null, "k0", new String[0]); } - verify(player).sendMessage("Invalid command label."); + verify(player).sendMessage(contains("Invalid command label")); assertNull(command.executedSlot); } @@ -79,7 +93,7 @@ void nonPlayerSenderGetsOnlyPlayersMessage() { command.onCommand(sender, null, "k1", new String[0]); - verify(sender).sendMessage("Only players can use this command."); + verify(sender).sendMessage(contains("Only players can use this command")); assertNull(command.executedSlot); } diff --git a/src/test/java/dev/noah/perplayerkit/util/LangTest.java b/src/test/java/dev/noah/perplayerkit/util/LangTest.java new file mode 100644 index 0000000..68386a5 --- /dev/null +++ b/src/test/java/dev/noah/perplayerkit/util/LangTest.java @@ -0,0 +1,59 @@ +package dev.noah.perplayerkit.util; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +class LangTest { + + @BeforeEach + void setUp() { + Lang.installForTesting(); + } + + @AfterEach + void tearDown() { + Lang.resetForTesting(); + } + + @Test + void rawReturnsKeyWhenMissing() { + String missing = Lang.get().raw("nonexistent.key"); + assertEquals("nonexistent.key", missing); + } + + @Test + void rawSubstitutesNamedPlaceholders() { + String result = Lang.get().raw("success.kit-saved", "slot", "3"); + assertEquals("Kit 3 saved!", result); + } + + @Test + void rawSubstitutesMultiplePlaceholders() { + String result = Lang.get().raw("success.kits-swapped", "slot1", "1", "slot2", "5"); + assertEquals("Kits 1 and 5 have been swapped!", result); + } + + @Test + void splitTemplateReturnsPrefixAndSuffix() { + String[] parts = Lang.get().splitTemplate("gui.kit-editor-title", "slot"); + assertEquals("Kit: ", parts[0]); + assertEquals("", parts[1]); + } + + @Test + void splitTemplateOnUnknownPlaceholderReturnsWholeTemplate() { + String[] parts = Lang.get().splitTemplate("gui.kit-editor-title", "bogus"); + assertEquals("Kit: {slot}", parts[0]); + assertEquals("", parts[1]); + } + + @Test + void componentRendersMiniMessage() { + // Just verify it doesn't throw and returns non-null + assertNotNull(Lang.get().component("error.players-only")); + } +} From 890cfa03a1feb8f736b1e7c3f800ad97b554a5b5 Mon Sep 17 00:00:00 2001 From: Noah Ross Date: Sat, 23 May 2026 23:39:55 -0400 Subject: [PATCH 2/3] address comments --- .../dev/noah/perplayerkit/ConfigMigrator.java | 4 +- .../dev/noah/perplayerkit/KitManager.java | 15 ++ .../commands/features/RegearCommand.java | 23 +- .../java/dev/noah/perplayerkit/gui/GUI.java | 31 ++- .../listeners/KitMenuCloseListener.java | 203 ++++-------------- .../java/dev/noah/perplayerkit/util/Lang.java | 7 +- src/main/resources/lang/da.yml | 22 +- src/main/resources/lang/de.yml | 22 +- src/main/resources/lang/en.yml | 44 ++-- src/main/resources/lang/es.yml | 22 +- src/main/resources/lang/fi.yml | 22 +- src/main/resources/lang/fr.yml | 28 +-- src/main/resources/lang/it.yml | 22 +- src/main/resources/lang/nl.yml | 22 +- src/main/resources/lang/pl.yml | 22 +- src/main/resources/lang/pt.yml | 28 +-- src/main/resources/lang/ro.yml | 22 +- src/main/resources/lang/sv.yml | 22 +- src/main/resources/lang/uk.yml | 22 +- src/main/resources/lang/zh.yml | 22 +- 20 files changed, 273 insertions(+), 352 deletions(-) diff --git a/src/main/java/dev/noah/perplayerkit/ConfigMigrator.java b/src/main/java/dev/noah/perplayerkit/ConfigMigrator.java index a7b0d57..d114fbe 100644 --- a/src/main/java/dev/noah/perplayerkit/ConfigMigrator.java +++ b/src/main/java/dev/noah/perplayerkit/ConfigMigrator.java @@ -126,7 +126,7 @@ private Map extractCustomizedStrings(FileConfiguration userConfi if (userConfig.contains("disabled-command-message")) { String current = userConfig.getString("disabled-command-message"); - String defaultValue = "Kits are disabled here!"; + String defaultValue = defaults.getString("error.disabled-in-world"); if (current != null && !current.equals(defaultValue)) { diffs.put("error.disabled-in-world", current); } @@ -151,7 +151,7 @@ private Map extractCustomizedStrings(FileConfiguration userConfi continue; } String current = userConfig.getString(oldPath); - String defaultValue = defaults.getString(oldPath); + String defaultValue = defaults.getString(newKey); if (current != null && !current.equals(defaultValue)) { diffs.put(newKey, current); } diff --git a/src/main/java/dev/noah/perplayerkit/KitManager.java b/src/main/java/dev/noah/perplayerkit/KitManager.java index 40191c6..5751e91 100644 --- a/src/main/java/dev/noah/perplayerkit/KitManager.java +++ b/src/main/java/dev/noah/perplayerkit/KitManager.java @@ -370,6 +370,9 @@ private boolean loadKitInternal(Player player, String kitId, Runnable notFoundMe } public boolean loadKit(Player player, int slot) { + if (player == null) { + return false; + } return loadKitInternal(player, IDUtil.getPlayerKitId(player.getUniqueId(), slot), () -> Lang.get().send(player, "error.kit-slot-not-found", "slot", String.valueOf(slot)), false, () -> { @@ -380,6 +383,9 @@ public boolean loadKit(Player player, int slot) { } public boolean loadKitSilent(Player player, int slot) { + if (player == null) { + return false; + } return loadKitInternal(player, IDUtil.getPlayerKitId(player.getUniqueId(), slot), null, false, null); } @@ -403,6 +409,9 @@ public boolean loadPublicKitSilent(Player player, String id) { } public boolean loadEnderchest(Player player, int slot) { + if (player == null) { + return false; + } return loadKitInternal(player, IDUtil.getECId(player.getUniqueId(), slot), () -> Lang.get().send(player, "error.kit-slot-not-found", "slot", String.valueOf(slot)), true, () -> { @@ -412,10 +421,16 @@ public boolean loadEnderchest(Player player, int slot) { } public boolean loadEnderchestSilent(Player player, int slot) { + if (player == null) { + return false; + } return loadKitInternal(player, IDUtil.getECId(player.getUniqueId(), slot), null, true, null); } public boolean loadLastKit(Player player) { + if (player == null) { + return false; + } if (lastKitUsedByPlayer.containsKey(player.getUniqueId())) { return loadKit(player, lastKitUsedByPlayer.get(player.getUniqueId())); } diff --git a/src/main/java/dev/noah/perplayerkit/commands/features/RegearCommand.java b/src/main/java/dev/noah/perplayerkit/commands/features/RegearCommand.java index cef0b94..c5e94ab 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/features/RegearCommand.java +++ b/src/main/java/dev/noah/perplayerkit/commands/features/RegearCommand.java @@ -248,19 +248,30 @@ private Inventory createRegearInventory(RegearInventoryHolder holder) { Inventory inventory = Bukkit.createInventory(holder, 27, StyleManager.get().getPrimaryColor() + Lang.get().legacy("gui.regear-shulker-title")); inventory.setItem(13, regearShellItem); + holder.setInventory(inventory); return inventory; } - public record RegearInventoryHolder( - Player player) implements InventoryHolder { + public static class RegearInventoryHolder implements InventoryHolder { + private final Player player; + private Inventory inventory; + + public RegearInventoryHolder(Player player) { + this.player = player; + } + + public Player player() { + return player; + } + + private void setInventory(Inventory inventory) { + this.inventory = inventory; + } @Override public @NotNull Inventory getInventory() { - // Inventory is created externally via RegearCommand#createRegearInventory. - // This method is required by InventoryHolder but not used at runtime — the - // inventory is opened through createRegearInventory which assigns the holder. - throw new UnsupportedOperationException("Use RegearCommand#createRegearInventory"); + return inventory; } } } diff --git a/src/main/java/dev/noah/perplayerkit/gui/GUI.java b/src/main/java/dev/noah/perplayerkit/gui/GUI.java index c87baec..cb4cd9f 100644 --- a/src/main/java/dev/noah/perplayerkit/gui/GUI.java +++ b/src/main/java/dev/noah/perplayerkit/gui/GUI.java @@ -49,14 +49,25 @@ public class GUI { private final Plugin plugin; private final boolean filterItemsOnImport; private static final Set kitDeletionFlag = new HashSet<>(); - private static final Map inspectTargets = new HashMap<>(); + private static final Map editorContexts = new HashMap<>(); - public static void setInspectTarget(UUID inspector, UUID target) { - inspectTargets.put(inspector, target); + public enum EditorType { + KIT, + PUBLIC_KIT, + ENDERCHEST, + INSPECT_KIT, + INSPECT_ENDERCHEST } - public static UUID getAndRemoveInspectTarget(UUID inspector) { - return inspectTargets.remove(inspector); + public record EditorContext(EditorType type, int slot, String id, UUID target, String playerName) { + } + + public static EditorContext getAndRemoveEditorContext(UUID viewer) { + return editorContexts.remove(viewer); + } + + private static void setEditorContext(Player viewer, EditorContext context) { + editorContexts.put(viewer.getUniqueId(), context); } public GUI(Plugin plugin) { @@ -106,6 +117,7 @@ public void OpenKitMenu(Player p, int slot) { menu.setCursorDropHandler(Menu.ALLOW_CURSOR_DROPPING); menu.open(p); + setEditorContext(p, new EditorContext(EditorType.KIT, slot, null, null, null)); } public void OpenPublicKitEditor(Player p, String kitId) { @@ -130,6 +142,7 @@ public void OpenPublicKitEditor(Player p, String kitId) { menu.setCursorDropHandler(Menu.ALLOW_CURSOR_DROPPING); menu.open(p); + setEditorContext(p, new EditorContext(EditorType.PUBLIC_KIT, 0, kitId, null, null)); } public void OpenECKitKenu(Player p, int slot) { @@ -153,11 +166,14 @@ public void OpenECKitKenu(Player p, int slot) { addImportEC(menu.getSlot(IMPORT_SLOT)); menu.setCursorDropHandler(Menu.ALLOW_CURSOR_DROPPING); menu.open(p); + setEditorContext(p, new EditorContext(EditorType.ENDERCHEST, slot, null, null, null)); } public void InspectKit(Player p, UUID target, int slot) { - setInspectTarget(p.getUniqueId(), target); String playerName = getPlayerName(target); + if (playerName == null) { + playerName = target.toString(); + } Menu menu = GuiMenuFactory.createInspectMenu(slot, playerName); if (KitManager.get().hasKit(target, slot)) { @@ -184,11 +200,11 @@ public void InspectKit(Player p, UUID target, int slot) { menu.setCursorDropHandler(Menu.ALLOW_CURSOR_DROPPING); menu.open(p); + setEditorContext(p, new EditorContext(EditorType.INSPECT_KIT, slot, null, target, playerName)); SoundManager.playOpenGui(p); } public void InspectEc(Player p, UUID target, int slot) { - setInspectTarget(p.getUniqueId(), target); String playerName = getPlayerName(target); if (playerName == null) { playerName = target.toString(); @@ -220,6 +236,7 @@ public void InspectEc(Player p, UUID target, int slot) { menu.setCursorDropHandler(Menu.ALLOW_CURSOR_DROPPING); menu.open(p); + setEditorContext(p, new EditorContext(EditorType.INSPECT_ENDERCHEST, slot, null, target, playerName)); SoundManager.playOpenGui(p); } diff --git a/src/main/java/dev/noah/perplayerkit/listeners/KitMenuCloseListener.java b/src/main/java/dev/noah/perplayerkit/listeners/KitMenuCloseListener.java index 7c6584d..1e2b1ea 100644 --- a/src/main/java/dev/noah/perplayerkit/listeners/KitMenuCloseListener.java +++ b/src/main/java/dev/noah/perplayerkit/listeners/KitMenuCloseListener.java @@ -21,205 +21,84 @@ import dev.noah.perplayerkit.KitManager; import dev.noah.perplayerkit.gui.GUI; import dev.noah.perplayerkit.util.Lang; -import dev.noah.perplayerkit.util.StyleManager; -import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.ItemStack; import java.util.UUID; public class KitMenuCloseListener implements Listener { - /** - * Parse a rendered inventory title back into placeholder values, using the - * localized template. Returns the placeholder values in order, or null if - * the title doesn't match the template. - * - * If {@code second} is null, the template is treated as containing only one - * placeholder and the returned array has length 1. - */ - private static String[] parseTitle(String title, String key, String first, String second) { - String template = Lang.get().raw(key); - String firstToken = "{" + first + "}"; - int firstIdx = template.indexOf(firstToken); - if (firstIdx < 0) { - return null; - } - - String fullPrefix = StyleManager.get().getPrimaryColor() + legacyConvert(template.substring(0, firstIdx)); - if (!title.startsWith(fullPrefix)) { - return null; - } - String remainder = title.substring(fullPrefix.length()); - - if (second == null) { - String suffix = legacyConvert(template.substring(firstIdx + firstToken.length())); - if (!remainder.endsWith(suffix)) { - return null; - } - return new String[]{remainder.substring(0, remainder.length() - suffix.length())}; - } - - String secondToken = "{" + second + "}"; - int secondIdx = template.indexOf(secondToken); - if (secondIdx < firstIdx + firstToken.length()) { - return null; - } - String infix = legacyConvert(template.substring(firstIdx + firstToken.length(), secondIdx)); - String suffix = legacyConvert(template.substring(secondIdx + secondToken.length())); - - if (!remainder.endsWith(suffix)) { - return null; - } - String body = remainder.substring(0, remainder.length() - suffix.length()); - int infixIdx = body.lastIndexOf(infix); - if (infixIdx < 0) { - return null; - } - return new String[]{body.substring(0, infixIdx), body.substring(infixIdx + infix.length())}; - } - - private static String legacyConvert(String miniMessage) { - return LegacyComponentSerializer.legacySection().serialize(MiniMessage.miniMessage().deserialize(miniMessage)); - } - @EventHandler - public void onKitEditorClose(InventoryCloseEvent e) { + public void onEditorClose(InventoryCloseEvent e) { Inventory inv = e.getInventory(); if (inv.getSize() != 54 || inv.getLocation() != null) { return; } - InventoryView view = e.getView(); - Integer slot = parseSingleSlot(view.getTitle(), "gui.kit-editor-title", "slot"); - if (slot == null) { - return; - } - Player p = (Player) e.getPlayer(); - ItemStack[] kit = copyContents(e.getInventory().getContents(), 41); - KitManager.get().savekit(p.getUniqueId(), slot, kit); - } - @EventHandler - public void onPublicKitEditorClose(InventoryCloseEvent e) { - Inventory inv = e.getInventory(); - if (inv.getSize() != 54 || inv.getLocation() != null) { + Player player = (Player) e.getPlayer(); + GUI.EditorContext context = GUI.getAndRemoveEditorContext(player.getUniqueId()); + if (context == null) { return; } - InventoryView view = e.getView(); - String[] parsed = parseTitle(view.getTitle(), "gui.public-kit-editor-title", "id", null); - if (parsed == null || parsed.length != 1 || parsed[0].isEmpty()) { - return; + + switch (context.type()) { + case KIT -> saveKit(player, context.slot(), inv); + case PUBLIC_KIT -> savePublicKit(player, context.id(), inv); + case ENDERCHEST -> saveEnderchest(player, context.slot(), inv); + case INSPECT_KIT -> saveInspectedKit(player, context, inv); + case INSPECT_ENDERCHEST -> saveInspectedEnderchest(player, context, inv); } - Player player = (Player) e.getPlayer(); - ItemStack[] kit = copyContents(e.getInventory().getContents(), 41); - KitManager.get().savePublicKit(player, parsed[0], kit); } - @EventHandler - public void onEnderchestEditorClose(InventoryCloseEvent e) { - Inventory inv = e.getInventory(); - if (inv.getSize() != 54 || inv.getLocation() != null) { - return; - } - InventoryView view = e.getView(); - Integer slot = parseSingleSlot(view.getTitle(), "gui.enderchest-editor-title", "slot"); - if (slot == null) { - return; - } - Player p = (Player) e.getPlayer(); - ItemStack[] ec = copyContentsFromOffset(e.getInventory().getContents(), 9, 27); - KitManager.get().saveEC(p.getUniqueId(), slot, ec); + private static void saveKit(Player player, int slot, Inventory inv) { + ItemStack[] kit = copyContents(inv.getContents(), 41); + KitManager.get().savekit(player.getUniqueId(), slot, kit); } - @EventHandler - public void onInspectKitEditorClose(InventoryCloseEvent e) { - Inventory inv = e.getInventory(); - if (inv.getSize() != 54 || inv.getLocation() != null) { - return; - } - InventoryView view = e.getView(); - String[] parsed = parseTitle(view.getTitle(), "gui.inspect-kit-title", "player", "slot"); - if (parsed == null) { - return; - } - Player p = (Player) e.getPlayer(); - if (!p.hasPermission("perplayerkit.admin")) { - return; - } - UUID targetUuid = GUI.getAndRemoveInspectTarget(p.getUniqueId()); - if (targetUuid == null) { + private static void savePublicKit(Player player, String id, Inventory inv) { + if (id == null || id.isEmpty()) { return; } - String playerName = parsed[0]; - int slot; - try { - slot = Integer.parseInt(parsed[1]); - } catch (NumberFormatException ex) { - return; - } - if (GUI.removeKitDeletionFlag(p)) { + ItemStack[] kit = copyContents(inv.getContents(), 41); + KitManager.get().savePublicKit(player, id, kit); + } + + private static void saveEnderchest(Player player, int slot, Inventory inv) { + ItemStack[] ec = copyContentsFromOffset(inv.getContents(), 9, 27); + KitManager.get().saveEC(player.getUniqueId(), slot, ec); + } + + private static void saveInspectedKit(Player player, GUI.EditorContext context, Inventory inv) { + if (!player.hasPermission("perplayerkit.admin") || context.target() == null || GUI.removeKitDeletionFlag(player)) { return; } - ItemStack[] kit = copyContents(e.getInventory().getContents(), 41); + UUID targetUuid = context.target(); + int slot = context.slot(); + String playerName = context.playerName(); + ItemStack[] kit = copyContents(inv.getContents(), 41); if (KitManager.get().savekit(targetUuid, slot, kit, true)) { - Lang.get().send(p, "success.admin-kit-updated", "slot", String.valueOf(slot), "player", playerName); + Lang.get().send(player, "success.admin-kit-updated", "slot", String.valueOf(slot), "player", playerName); } else { - Lang.get().send(p, "error.failed-to-update-kit", "player", playerName); + Lang.get().send(player, "error.failed-to-update-kit", "player", playerName); } } - @EventHandler - public void onInspectEnderchestEditorClose(InventoryCloseEvent e) { - Inventory inv = e.getInventory(); - if (inv.getSize() != 54 || inv.getLocation() != null) { - return; - } - InventoryView view = e.getView(); - String[] parsed = parseTitle(view.getTitle(), "gui.inspect-ec-title", "player", "slot"); - if (parsed == null) { - return; - } - Player p = (Player) e.getPlayer(); - if (!p.hasPermission("perplayerkit.admin")) { - return; - } - UUID targetUuid = GUI.getAndRemoveInspectTarget(p.getUniqueId()); - if (targetUuid == null) { + private static void saveInspectedEnderchest(Player player, GUI.EditorContext context, Inventory inv) { + if (!player.hasPermission("perplayerkit.admin") || context.target() == null || GUI.removeKitDeletionFlag(player)) { return; } - String playerName = parsed[0]; - int slot; - try { - slot = Integer.parseInt(parsed[1]); - } catch (NumberFormatException ex) { - return; - } - if (GUI.removeKitDeletionFlag(p)) { - return; - } - ItemStack[] ec = copyContentsFromOffset(e.getInventory().getContents(), 9, 27); + UUID targetUuid = context.target(); + int slot = context.slot(); + String playerName = context.playerName(); + ItemStack[] ec = copyContentsFromOffset(inv.getContents(), 9, 27); if (KitManager.get().saveECSilent(targetUuid, slot, ec)) { - Lang.get().send(p, "success.admin-ec-updated", "slot", String.valueOf(slot), "player", playerName); + Lang.get().send(player, "success.admin-ec-updated", "slot", String.valueOf(slot), "player", playerName); } else { - Lang.get().send(p, "error.failed-to-update-ec", "player", playerName); - } - } - - private static Integer parseSingleSlot(String title, String key, String placeholder) { - String[] parsed = parseTitle(title, key, placeholder, null); - if (parsed == null || parsed.length != 1) { - return null; - } - try { - return Integer.parseInt(parsed[0].trim()); - } catch (NumberFormatException ex) { - return null; + Lang.get().send(player, "error.failed-to-update-ec", "player", playerName); } } diff --git a/src/main/java/dev/noah/perplayerkit/util/Lang.java b/src/main/java/dev/noah/perplayerkit/util/Lang.java index a29d6a6..05d1990 100644 --- a/src/main/java/dev/noah/perplayerkit/util/Lang.java +++ b/src/main/java/dev/noah/perplayerkit/util/Lang.java @@ -184,11 +184,10 @@ public String raw(String key, String... pairs) { } public List rawList(String key) { - List value = lang.getStringList(key); - if (value == null || value.isEmpty()) { - value = fallback.getStringList(key); + if (lang.contains(key)) { + return lang.getStringList(key); } - return value; + return fallback.getStringList(key); } public Component component(String key) { diff --git a/src/main/resources/lang/da.yml b/src/main/resources/lang/da.yml index 94c2b55..c149e1d 100644 --- a/src/main/resources/lang/da.yml +++ b/src/main/resources/lang/da.yml @@ -18,7 +18,7 @@ motd: scheduled-broadcast: messages: - "Tjek offentlige kits med /pk-kommandoen!" - - "Vil du dele et kit? Brug /sharekit ." + - "Vil du dele et kit? Brug /sharekit \\." - "Skriv /kit, /k eller /pk for at komme i gang!" broadcast-messages: @@ -35,7 +35,7 @@ broadcast-messages: error: disabled-in-world: "Kits er deaktiveret her!" - unexpected: "Der opstod en uventet fejl, prøv igen." + unexpected: "Der opstod en uventet fejl, prøv igen." kit-not-found: "Fejl, det kit findes ikke" kit-expired: "Fejl, kit findes ikke eller er udløbet" ec-not-found: "Fejl, den enderkiste findes ikke" @@ -112,7 +112,7 @@ success: info: custom-version-available: "Du kan gemme en brugerdefineret version af dette kit ved at importere til kit-editoren" - assign-publickit-instruction: "For at tildele et kit til denne publickit brug /savepublickit " + assign-publickit-instruction: "For at tildele et kit til denne publickit brug /savepublickit \\" share-kit-code: "Brug /copykit {code} for at kopiere dette kit" share-ec-code: "Brug /copyEC {code} for at kopiere denne enderkiste" share-code-expiry: "Koden udløber om 15 minutter" @@ -126,12 +126,12 @@ info: command: perplayerkit-about: "PerPlayerKit er et plugin, der lader spillere have deres egne kits." - deletekit-usage: "Brug: /deletekit " - swapkit-usage: "Brug: /swapkit " - savepublickit-usage: "Brug: /{command} " - perplayerkit-migrate-usage: "Brug: /perplayerkit migrate " - kitroom-usage-hint: "/kitroom " - inspect-usage: "Brug: /{command} " + deletekit-usage: "Brug: /deletekit \\" + swapkit-usage: "Brug: /swapkit \\ \\" + savepublickit-usage: "Brug: /{command} \\" + perplayerkit-migrate-usage: "Brug: /perplayerkit migrate \\ \\" + kitroom-usage-hint: "/kitroom \\" + inspect-usage: "Brug: /{command} \\ \\" update: new-version-available: "En ny version af PerPlayerKit er tilgængelig! Du kører version {current} og den nyeste version er {latest}" @@ -193,10 +193,10 @@ gui: lore-import-ec: "● Importer fra enderkiste" lore-left-load: "● Venstreklik for at indlæse kit" lore-right-edit: "● Højreklik for at redigere kit" - lore-share-kits: "● /sharekit " + lore-share-kits: "● /sharekit \\" lore-info-load: "● Klik på en kit-slot for at indlæse dit kit" lore-info-edit: "● Højreklik eller klik på bogen for at redigere" - lore-info-share: "● Del kits med /sharekit " + lore-info-share: "● Del kits med /sharekit \\" lore-admin-shift-edit: "● [ADMIN] Shift-klik for at redigere" lore-unassigned-info: "● Admins har ikke konfigureret dette kit endnu" lore-regear-restocks: "● Genopfylder dit kit" diff --git a/src/main/resources/lang/de.yml b/src/main/resources/lang/de.yml index ef466e9..0001b75 100644 --- a/src/main/resources/lang/de.yml +++ b/src/main/resources/lang/de.yml @@ -18,7 +18,7 @@ motd: scheduled-broadcast: messages: - "Schau dir öffentliche Kits mit dem Befehl /pk an!" - - "Möchtest du ein Kit teilen? Verwende /sharekit ." + - "Möchtest du ein Kit teilen? Verwende /sharekit \\." - "Tippe /kit, /k oder /pk, um zu beginnen!" broadcast-messages: @@ -35,7 +35,7 @@ broadcast-messages: error: disabled-in-world: "Kits sind hier deaktiviert!" - unexpected: "Ein unerwarteter Fehler ist aufgetreten, bitte erneut versuchen." + unexpected: "Ein unerwarteter Fehler ist aufgetreten, bitte erneut versuchen." kit-not-found: "Fehler, dieses Kit existiert nicht" kit-expired: "Fehler, Kit existiert nicht oder ist abgelaufen" ec-not-found: "Fehler, diese Endertruhe existiert nicht" @@ -112,7 +112,7 @@ success: info: custom-version-available: "Du kannst eine eigene Version dieses Kits speichern, indem du es in den Kit-Editor importierst" - assign-publickit-instruction: "Um diesem publickit ein Kit zuzuweisen, benutze /savepublickit " + assign-publickit-instruction: "Um diesem publickit ein Kit zuzuweisen, benutze /savepublickit \\" share-kit-code: "Verwende /copykit {code}, um dieses Kit zu kopieren" share-ec-code: "Verwende /copyEC {code}, um diese Endertruhe zu kopieren" share-code-expiry: "Code läuft in 15 Minuten ab" @@ -126,12 +126,12 @@ info: command: perplayerkit-about: "PerPlayerKit ist ein Plugin, das Spielern erlaubt, eigene Kits zu haben." - deletekit-usage: "Verwendung: /deletekit " - swapkit-usage: "Verwendung: /swapkit " - savepublickit-usage: "Verwendung: /{command} " - perplayerkit-migrate-usage: "Verwendung: /perplayerkit migrate " - kitroom-usage-hint: "/kitroom " - inspect-usage: "Verwendung: /{command} " + deletekit-usage: "Verwendung: /deletekit \\" + swapkit-usage: "Verwendung: /swapkit \\ \\" + savepublickit-usage: "Verwendung: /{command} \\" + perplayerkit-migrate-usage: "Verwendung: /perplayerkit migrate \\ \\" + kitroom-usage-hint: "/kitroom \\" + inspect-usage: "Verwendung: /{command} \\ \\" update: new-version-available: "Eine neue Version von PerPlayerKit ist verfügbar! Du verwendest Version {current}, die neueste Version ist {latest}" @@ -193,10 +193,10 @@ gui: lore-import-ec: "● Aus Endertruhe importieren" lore-left-load: "● Linksklick zum Laden des Kits" lore-right-edit: "● Rechtsklick zum Bearbeiten des Kits" - lore-share-kits: "● /sharekit " + lore-share-kits: "● /sharekit \\" lore-info-load: "● Klicke einen Kit-Slot an, um dein Kit zu laden" lore-info-edit: "● Rechtsklick oder Klick auf das Buch zum Bearbeiten" - lore-info-share: "● Teile Kits mit /sharekit " + lore-info-share: "● Teile Kits mit /sharekit \\" lore-admin-shift-edit: "● [ADMIN] Shift-Klick zum Bearbeiten" lore-unassigned-info: "● Admins haben dieses Kit noch nicht eingerichtet" lore-regear-restocks: "● Füllt dein Kit auf" diff --git a/src/main/resources/lang/en.yml b/src/main/resources/lang/en.yml index 091927f..c256160 100644 --- a/src/main/resources/lang/en.yml +++ b/src/main/resources/lang/en.yml @@ -18,7 +18,7 @@ motd: scheduled-broadcast: messages: - "Check out public kits with the /pk command!" - - "Want to share a kit? Use the /sharekit command!" + - "Want to share a kit? Use the /sharekit \\ command!" - "Type /kit, /k or /pk to get started!" # Broadcast messages shown when a player performs an action (configured in config.yml messages.*). @@ -36,13 +36,13 @@ broadcast-messages: error: disabled-in-world: "Kits are disabled here!" - unexpected: "Unexpected error occurred, please try again." + unexpected: "Unexpected error occurred, please try again." kit-not-found: "Error, that kit does not exist" kit-expired: "Error, kit does not exist or has expired" ec-not-found: "Error, that EC does not exist" - empty-kit: "You cant save an empty kit!" - empty-ec: "You cant save an empty enderchest!" - kit-slot-not-found: "Kit {slot} doesnt exist!" + empty-kit: "You can't save an empty kit!" + empty-ec: "You can't save an empty ender chest!" + kit-slot-not-found: "Kit {slot} doesn't exist!" kit-deletion-failed: "Kit deletion failed!" invalid-number: "Select a real number" invalid-numbers: "Select real numbers" @@ -76,11 +76,11 @@ error: player-not-found: "Could not find a player with that name or UUID." kit-not-found-display: "Kit not found" inspect-kit-missing: "{player} does not have a kit in slot {slot}" - inspect-ec-missing: "{player} does not have an enderchest in slot {slot}" + inspect-ec-missing: "{player} does not have an ender chest in slot {slot}" inspect-kit-load-error: "An error occurred while loading kit data. See console for details." - inspect-ec-load-error: "An error occurred while loading enderchest data. See console for details." + inspect-ec-load-error: "An error occurred while loading ender chest data. See console for details." failed-to-update-kit: "Failed to update kit for player {player}!" - failed-to-update-ec: "Failed to update enderchest for player {player}!" + failed-to-update-ec: "Failed to update ender chest for player {player}!" invalid-command-label: "Invalid command label." prefix-tag: "Error: " @@ -113,9 +113,9 @@ success: info: custom-version-available: "You can save a custom version of this kit by importing into the kit editor" - assign-publickit-instruction: "To assign a kit to this publickit use /savepublickit " + assign-publickit-instruction: "To assign a kit to this publickit use /savepublickit \\" share-kit-code: "Use /copykit {code} to copy this kit" - share-ec-code: "Use /copyEC {code} to copy this enderchest" + share-ec-code: "Use /copyEC {code} to copy this ender chest" share-code-expiry: "Code expires in 15 minutes" import-instructions: "Copy data folder from KitsX into the PerPlayerKit folder" migration-starting: "Starting migration from {source} to {destination}..." @@ -127,12 +127,12 @@ info: command: perplayerkit-about: "PerPlayerKit is a plugin that allows players to have their own kits." - deletekit-usage: "Usage: /deletekit " - swapkit-usage: "Usage: /swapkit " - savepublickit-usage: "Usage: /{command} " - perplayerkit-migrate-usage: "Usage: /perplayerkit migrate " - kitroom-usage-hint: "/kitroom " - inspect-usage: "Usage: /{command} " + deletekit-usage: "Usage: /deletekit \\" + swapkit-usage: "Usage: /swapkit \\ \\" + savepublickit-usage: "Usage: /{command} \\" + perplayerkit-migrate-usage: "Usage: /perplayerkit migrate \\ \\" + kitroom-usage-hint: "/kitroom \\" + inspect-usage: "Usage: /{command} \\ \\" update: new-version-available: "A new version of PerPlayerKit is available! You are running version {current} and the latest version is {latest}" @@ -154,7 +154,7 @@ gui: public-kit-editor-title: "Public Kit: {id}" enderchest-editor-title: "Enderchest: {slot}" inspect-kit-title: "Inspecting {player}'s kit {slot}" - inspect-ec-title: "Inspecting {player}'s enderchest {slot}" + inspect-ec-title: "Inspecting {player}'s ender chest {slot}" kit-room-title: "Kit Room" public-kit-room-title: "Public Kit Room" view-public-kit-title: "Viewing Public Kit: {id}" @@ -191,18 +191,18 @@ gui: lore-click-create: "● Click to create" lore-shift-clear: "● Shift click to clear" lore-shift-delete-kit: "● Shift click to delete kit" - lore-shift-delete-ec: "● Shift click to delete enderchest" + lore-shift-delete-ec: "● Shift click to delete ender chest" lore-shift-click: "● Shift click" lore-import-inventory: "● Import from inventory" - lore-import-ec: "● Import from enderchest" + lore-import-ec: "● Import from ender chest" lore-left-load: "● Left click to load kit" lore-right-edit: "● Right click to edit kit" - lore-share-kits: "● /sharekit " + lore-share-kits: "● /sharekit \\" lore-info-load: "● Click a kit slot to load your kit" lore-info-edit: "● Right click or click the book to edit" - lore-info-share: "● Share kits with /sharekit " + lore-info-share: "● Share kits with /sharekit \\" lore-admin-shift-edit: "● [ADMIN] Shift click to edit" - lore-unassigned-info: "● Admins have not yet setup this kit yet" + lore-unassigned-info: "● Admins have not set up this kit yet" lore-regear-restocks: "● Restocks Your Kit" lore-regear-shulker-use: "● Use {primary}/rg to get another regear shulker" lore-regear-shell-click: "● Click to use!" diff --git a/src/main/resources/lang/es.yml b/src/main/resources/lang/es.yml index 178d2f9..fc58313 100644 --- a/src/main/resources/lang/es.yml +++ b/src/main/resources/lang/es.yml @@ -18,7 +18,7 @@ motd: scheduled-broadcast: messages: - "¡Mira los kits públicos con el comando /pk!" - - "¿Quieres compartir un kit? Usa /sharekit ." + - "¿Quieres compartir un kit? Usa /sharekit \\." - "Escribe /kit, /k o /pk para comenzar." broadcast-messages: @@ -35,7 +35,7 @@ broadcast-messages: error: disabled-in-world: "¡Los kits están deshabilitados aquí!" - unexpected: "Ocurrió un error inesperado, inténtalo de nuevo." + unexpected: "Ocurrió un error inesperado, inténtalo de nuevo." kit-not-found: "Error, ese kit no existe" kit-expired: "Error, el kit no existe o ha expirado" ec-not-found: "Error, ese cofre de ender no existe" @@ -112,7 +112,7 @@ success: info: custom-version-available: "Puedes guardar una versión personalizada de este kit importándolo en el editor" - assign-publickit-instruction: "Para asignar un kit a este publickit usa /savepublickit " + assign-publickit-instruction: "Para asignar un kit a este publickit usa /savepublickit \\" share-kit-code: "Usa /copykit {code} para copiar este kit" share-ec-code: "Usa /copyEC {code} para copiar este cofre de ender" share-code-expiry: "El código expira en 15 minutos" @@ -126,12 +126,12 @@ info: command: perplayerkit-about: "PerPlayerKit es un plugin que permite a los jugadores tener sus propios kits." - deletekit-usage: "Uso: /deletekit " - swapkit-usage: "Uso: /swapkit " - savepublickit-usage: "Uso: /{command} " - perplayerkit-migrate-usage: "Uso: /perplayerkit migrate " - kitroom-usage-hint: "/kitroom " - inspect-usage: "Uso: /{command} " + deletekit-usage: "Uso: /deletekit \\" + swapkit-usage: "Uso: /swapkit \\ \\" + savepublickit-usage: "Uso: /{command} \\" + perplayerkit-migrate-usage: "Uso: /perplayerkit migrate \\ \\" + kitroom-usage-hint: "/kitroom \\" + inspect-usage: "Uso: /{command} \\ \\" update: new-version-available: "¡Hay una nueva versión de PerPlayerKit disponible! Estás usando la versión {current} y la última es {latest}" @@ -193,10 +193,10 @@ gui: lore-import-ec: "● Importar desde cofre de ender" lore-left-load: "● Clic izquierdo para cargar kit" lore-right-edit: "● Clic derecho para editar kit" - lore-share-kits: "● /sharekit " + lore-share-kits: "● /sharekit \\" lore-info-load: "● Clic en una ranura para cargar tu kit" lore-info-edit: "● Clic derecho o en el libro para editar" - lore-info-share: "● Comparte kits con /sharekit " + lore-info-share: "● Comparte kits con /sharekit \\" lore-admin-shift-edit: "● [ADMIN] Shift clic para editar" lore-unassigned-info: "● Los admins aún no han configurado este kit" lore-regear-restocks: "● Reabastece tu kit" diff --git a/src/main/resources/lang/fi.yml b/src/main/resources/lang/fi.yml index 36030da..f04de5d 100644 --- a/src/main/resources/lang/fi.yml +++ b/src/main/resources/lang/fi.yml @@ -18,7 +18,7 @@ motd: scheduled-broadcast: messages: - "Katso julkiset kitit komennolla /pk!" - - "Haluatko jakaa kitin? Käytä /sharekit ." + - "Haluatko jakaa kitin? Käytä /sharekit \\." - "Kirjoita /kit, /k tai /pk aloittaaksesi!" broadcast-messages: @@ -35,7 +35,7 @@ broadcast-messages: error: disabled-in-world: "Kitit on poistettu käytöstä täällä!" - unexpected: "Tapahtui odottamaton virhe, yritä uudelleen." + unexpected: "Tapahtui odottamaton virhe, yritä uudelleen." kit-not-found: "Virhe, kittiä ei ole olemassa" kit-expired: "Virhe, kittiä ei ole olemassa tai se on vanhentunut" ec-not-found: "Virhe, ender-arkkua ei ole olemassa" @@ -112,7 +112,7 @@ success: info: custom-version-available: "Voit tallentaa oman version tästä kitistä tuomalla sen kittieditoriin" - assign-publickit-instruction: "Asettaaksesi kitin tälle publickitille käytä /savepublickit " + assign-publickit-instruction: "Asettaaksesi kitin tälle publickitille käytä /savepublickit \\" share-kit-code: "Käytä /copykit {code} kopioidaksesi tämän kitin" share-ec-code: "Käytä /copyEC {code} kopioidaksesi tämän ender-arkun" share-code-expiry: "Koodi vanhenee 15 minuutissa" @@ -126,12 +126,12 @@ info: command: perplayerkit-about: "PerPlayerKit on lisäosa, joka antaa pelaajille omat kitit." - deletekit-usage: "Käyttö: /deletekit " - swapkit-usage: "Käyttö: /swapkit " - savepublickit-usage: "Käyttö: /{command} " - perplayerkit-migrate-usage: "Käyttö: /perplayerkit migrate " - kitroom-usage-hint: "/kitroom " - inspect-usage: "Käyttö: /{command} " + deletekit-usage: "Käyttö: /deletekit \\" + swapkit-usage: "Käyttö: /swapkit \\ \\" + savepublickit-usage: "Käyttö: /{command} \\" + perplayerkit-migrate-usage: "Käyttö: /perplayerkit migrate \\ \\" + kitroom-usage-hint: "/kitroom \\" + inspect-usage: "Käyttö: /{command} \\ \\" update: new-version-available: "PerPlayerKitistä on saatavilla uusi versio! Käytät versiota {current} ja uusin versio on {latest}" @@ -193,10 +193,10 @@ gui: lore-import-ec: "● Tuo ender-arkusta" lore-left-load: "● Vasen klikkaus ladataksesi kitin" lore-right-edit: "● Oikea klikkaus muokataksesi kittiä" - lore-share-kits: "● /sharekit " + lore-share-kits: "● /sharekit \\" lore-info-load: "● Klikkaa kitin paikkaa ladataksesi kittisi" lore-info-edit: "● Oikea klikkaus tai kirjan klikkaus muokataksesi" - lore-info-share: "● Jaa kittejä komennolla /sharekit " + lore-info-share: "● Jaa kittejä komennolla /sharekit \\" lore-admin-shift-edit: "● [ADMIN] Shift-klikkaus muokataksesi" lore-unassigned-info: "● Ylläpitäjät eivät ole vielä asettaneet tätä kittiä" lore-regear-restocks: "● Täydentää kittisi" diff --git a/src/main/resources/lang/fr.yml b/src/main/resources/lang/fr.yml index 9dad8c3..04d37c4 100644 --- a/src/main/resources/lang/fr.yml +++ b/src/main/resources/lang/fr.yml @@ -18,7 +18,7 @@ motd: scheduled-broadcast: messages: - "Découvrez les kits publics avec la commande /pk !" - - "Vous voulez partager un kit ? Utilisez /sharekit ." + - "Vous voulez partager un kit ? Utilisez /sharekit \\." - "Tapez /kit, /k ou /pk pour commencer !" broadcast-messages: @@ -35,7 +35,7 @@ broadcast-messages: error: disabled-in-world: "Les kits sont désactivés ici !" - unexpected: "Une erreur inattendue s'est produite, veuillez réessayer." + unexpected: "Une erreur inattendue s'est produite, veuillez réessayer." kit-not-found: "Erreur, ce kit n'existe pas" kit-expired: "Erreur, le kit n'existe pas ou a expiré" ec-not-found: "Erreur, cet ender chest n'existe pas" @@ -112,7 +112,7 @@ success: info: custom-version-available: "Vous pouvez sauvegarder une version personnalisée de ce kit en l'important dans l'éditeur" - assign-publickit-instruction: "Pour assigner un kit à ce publickit utilisez /savepublickit " + assign-publickit-instruction: "Pour assigner un kit à ce publickit utilisez /savepublickit \\" share-kit-code: "Utilisez /copykit {code} pour copier ce kit" share-ec-code: "Utilisez /copyEC {code} pour copier cet ender chest" share-code-expiry: "Le code expire dans 15 minutes" @@ -126,12 +126,12 @@ info: command: perplayerkit-about: "PerPlayerKit est un plugin qui permet aux joueurs d'avoir leurs propres kits." - deletekit-usage: "Utilisation : /deletekit " - swapkit-usage: "Utilisation : /swapkit " - savepublickit-usage: "Utilisation : /{command} " - perplayerkit-migrate-usage: "Utilisation : /perplayerkit migrate " - kitroom-usage-hint: "/kitroom " - inspect-usage: "Utilisation : /{command} " + deletekit-usage: "Utilisation : /deletekit \\" + swapkit-usage: "Utilisation : /swapkit \\ \\" + savepublickit-usage: "Utilisation : /{command} \\" + perplayerkit-migrate-usage: "Utilisation : /perplayerkit migrate \\ \\" + kitroom-usage-hint: "/kitroom \\" + inspect-usage: "Utilisation : /{command} \\ \\" update: new-version-available: "Une nouvelle version de PerPlayerKit est disponible ! Vous utilisez la version {current} et la dernière est {latest}" @@ -150,17 +150,17 @@ gui: main-menu-title: "Kits de {player}" kit-editor-title: "Kit : {slot}" public-kit-editor-title: "Kit Public : {id}" - enderchest-editor-title: "Ender Chest : {slot}" + enderchest-editor-title: "ender chest : {slot}" inspect-kit-title: "Inspection du kit {slot} de {player}" inspect-ec-title: "Inspection de l'ender chest {slot} de {player}" kit-room-title: "Salle des Kits" public-kit-room-title: "Salle des Kits Publics" view-public-kit-title: "Voir le Kit Public : {id}" - enderchest-view-title: "Ender Chest (Lecture Seule)" + enderchest-view-title: "ender chest (Lecture Seule)" regear-shulker-title: "Shulker de Rééquipement" kit-slot-name: "Kit {slot}" - enderchest-slot-name: "Ender Chest {slot}" + enderchest-slot-name: "ender chest {slot}" kit-exists: "KIT EXISTE" kit-not-found: "KIT INTROUVABLE" more-kits-coming: "PLUS DE KITS À VENIR" @@ -193,10 +193,10 @@ gui: lore-import-ec: "● Importer depuis l'ender chest" lore-left-load: "● Clic gauche pour charger le kit" lore-right-edit: "● Clic droit pour éditer le kit" - lore-share-kits: "● /sharekit " + lore-share-kits: "● /sharekit \\" lore-info-load: "● Cliquez sur un emplacement pour charger votre kit" lore-info-edit: "● Clic droit ou sur le livre pour éditer" - lore-info-share: "● Partagez les kits avec /sharekit " + lore-info-share: "● Partagez les kits avec /sharekit \\" lore-admin-shift-edit: "● [ADMIN] Shift clic pour éditer" lore-unassigned-info: "● Les admins n'ont pas encore configuré ce kit" lore-regear-restocks: "● Réapprovisionne votre kit" diff --git a/src/main/resources/lang/it.yml b/src/main/resources/lang/it.yml index 79f03d4..6cd2159 100644 --- a/src/main/resources/lang/it.yml +++ b/src/main/resources/lang/it.yml @@ -18,7 +18,7 @@ motd: scheduled-broadcast: messages: - "Controlla i kit pubblici con il comando /pk!" - - "Vuoi condividere un kit? Usa /sharekit ." + - "Vuoi condividere un kit? Usa /sharekit \\." - "Digita /kit, /k o /pk per iniziare!" broadcast-messages: @@ -35,7 +35,7 @@ broadcast-messages: error: disabled-in-world: "I kit sono disabilitati qui!" - unexpected: "Si è verificato un errore inaspettato, riprova." + unexpected: "Si è verificato un errore inaspettato, riprova." kit-not-found: "Errore, quel kit non esiste" kit-expired: "Errore, il kit non esiste o è scaduto" ec-not-found: "Errore, quel baule di Ender non esiste" @@ -112,7 +112,7 @@ success: info: custom-version-available: "Puoi salvare una versione personalizzata di questo kit importandola nell'editor" - assign-publickit-instruction: "Per assegnare un kit a questo publickit usa /savepublickit " + assign-publickit-instruction: "Per assegnare un kit a questo publickit usa /savepublickit \\" share-kit-code: "Usa /copykit {code} per copiare questo kit" share-ec-code: "Usa /copyEC {code} per copiare questo baule di Ender" share-code-expiry: "Il codice scade tra 15 minuti" @@ -126,12 +126,12 @@ info: command: perplayerkit-about: "PerPlayerKit è un plugin che permette ai giocatori di avere i propri kit." - deletekit-usage: "Utilizzo: /deletekit " - swapkit-usage: "Utilizzo: /swapkit " - savepublickit-usage: "Utilizzo: /{command} " - perplayerkit-migrate-usage: "Utilizzo: /perplayerkit migrate " - kitroom-usage-hint: "/kitroom " - inspect-usage: "Utilizzo: /{command} " + deletekit-usage: "Utilizzo: /deletekit \\" + swapkit-usage: "Utilizzo: /swapkit \\ \\" + savepublickit-usage: "Utilizzo: /{command} \\" + perplayerkit-migrate-usage: "Utilizzo: /perplayerkit migrate \\ \\" + kitroom-usage-hint: "/kitroom \\" + inspect-usage: "Utilizzo: /{command} \\ \\" update: new-version-available: "È disponibile una nuova versione di PerPlayerKit! Stai usando la versione {current} e la più recente è {latest}" @@ -193,10 +193,10 @@ gui: lore-import-ec: "● Importa dal baule di Ender" lore-left-load: "● Click sinistro per caricare il kit" lore-right-edit: "● Click destro per modificare il kit" - lore-share-kits: "● /sharekit " + lore-share-kits: "● /sharekit \\" lore-info-load: "● Clicca uno slot kit per caricare il tuo kit" lore-info-edit: "● Click destro o clicca sul libro per modificare" - lore-info-share: "● Condividi kit con /sharekit " + lore-info-share: "● Condividi kit con /sharekit \\" lore-admin-shift-edit: "● [ADMIN] Shift+click per modificare" lore-unassigned-info: "● Gli amministratori non hanno ancora configurato questo kit" lore-regear-restocks: "● Rifornisce il tuo kit" diff --git a/src/main/resources/lang/nl.yml b/src/main/resources/lang/nl.yml index a20d0a4..73333d8 100644 --- a/src/main/resources/lang/nl.yml +++ b/src/main/resources/lang/nl.yml @@ -18,7 +18,7 @@ motd: scheduled-broadcast: messages: - "Bekijk openbare kits met het commando /pk!" - - "Wil je een kit delen? Gebruik /sharekit ." + - "Wil je een kit delen? Gebruik /sharekit \\." - "Typ /kit, /k of /pk om te beginnen!" broadcast-messages: @@ -35,7 +35,7 @@ broadcast-messages: error: disabled-in-world: "Kits zijn hier uitgeschakeld!" - unexpected: "Er is een onverwachte fout opgetreden, probeer het opnieuw." + unexpected: "Er is een onverwachte fout opgetreden, probeer het opnieuw." kit-not-found: "Fout, die kit bestaat niet" kit-expired: "Fout, kit bestaat niet of is verlopen" ec-not-found: "Fout, die Enderkist bestaat niet" @@ -112,7 +112,7 @@ success: info: custom-version-available: "Je kunt een aangepaste versie van deze kit opslaan door deze in de kit-editor te importeren" - assign-publickit-instruction: "Om een kit aan deze publickit toe te wijzen, gebruik /savepublickit " + assign-publickit-instruction: "Om een kit aan deze publickit toe te wijzen, gebruik /savepublickit \\" share-kit-code: "Gebruik /copykit {code} om deze kit te kopiëren" share-ec-code: "Gebruik /copyEC {code} om deze Enderkist te kopiëren" share-code-expiry: "Code verloopt over 15 minuten" @@ -126,12 +126,12 @@ info: command: perplayerkit-about: "PerPlayerKit is een plugin waarmee spelers hun eigen kits kunnen hebben." - deletekit-usage: "Gebruik: /deletekit " - swapkit-usage: "Gebruik: /swapkit " - savepublickit-usage: "Gebruik: /{command} " - perplayerkit-migrate-usage: "Gebruik: /perplayerkit migrate " - kitroom-usage-hint: "/kitroom " - inspect-usage: "Gebruik: /{command} " + deletekit-usage: "Gebruik: /deletekit \\" + swapkit-usage: "Gebruik: /swapkit \\ \\" + savepublickit-usage: "Gebruik: /{command} \\" + perplayerkit-migrate-usage: "Gebruik: /perplayerkit migrate \\ \\" + kitroom-usage-hint: "/kitroom \\" + inspect-usage: "Gebruik: /{command} \\ \\" update: new-version-available: "Er is een nieuwe versie van PerPlayerKit beschikbaar! Je gebruikt versie {current} en de nieuwste versie is {latest}" @@ -193,10 +193,10 @@ gui: lore-import-ec: "● Importeer uit Enderkist" lore-left-load: "● Linkermuisklik om kit te laden" lore-right-edit: "● Rechtermuisklik om kit te bewerken" - lore-share-kits: "● /sharekit " + lore-share-kits: "● /sharekit \\" lore-info-load: "● Klik op een kit-slot om je kit te laden" lore-info-edit: "● Rechtsklik of klik op het boek om te bewerken" - lore-info-share: "● Deel kits met /sharekit " + lore-info-share: "● Deel kits met /sharekit \\" lore-admin-shift-edit: "● [ADMIN] Shift-klik om te bewerken" lore-unassigned-info: "● Beheerders hebben deze kit nog niet ingesteld" lore-regear-restocks: "● Vult je kit aan" diff --git a/src/main/resources/lang/pl.yml b/src/main/resources/lang/pl.yml index 13ccff1..538c2df 100644 --- a/src/main/resources/lang/pl.yml +++ b/src/main/resources/lang/pl.yml @@ -18,7 +18,7 @@ motd: scheduled-broadcast: messages: - "Sprawdź zestawy publiczne komendą /pk!" - - "Chcesz udostępnić zestaw? Użyj /sharekit ." + - "Chcesz udostępnić zestaw? Użyj /sharekit \\." - "Wpisz /kit, /k lub /pk, aby zacząć!" broadcast-messages: @@ -35,7 +35,7 @@ broadcast-messages: error: disabled-in-world: "Zestawy są tutaj wyłączone!" - unexpected: "Wystąpił nieoczekiwany błąd, spróbuj ponownie." + unexpected: "Wystąpił nieoczekiwany błąd, spróbuj ponownie." kit-not-found: "Błąd, ten zestaw nie istnieje" kit-expired: "Błąd, zestaw nie istnieje lub wygasł" ec-not-found: "Błąd, ta skrzynia Endera nie istnieje" @@ -112,7 +112,7 @@ success: info: custom-version-available: "Możesz zapisać własną wersję tego zestawu, importując ją do edytora" - assign-publickit-instruction: "Aby przypisać zestaw do tego publickit, użyj /savepublickit " + assign-publickit-instruction: "Aby przypisać zestaw do tego publickit, użyj /savepublickit \\" share-kit-code: "Użyj /copykit {code}, aby skopiować ten zestaw" share-ec-code: "Użyj /copyEC {code}, aby skopiować tę skrzynię Endera" share-code-expiry: "Kod wygaśnie za 15 minut" @@ -126,12 +126,12 @@ info: command: perplayerkit-about: "PerPlayerKit to plugin pozwalający graczom mieć własne zestawy." - deletekit-usage: "Użycie: /deletekit " - swapkit-usage: "Użycie: /swapkit " - savepublickit-usage: "Użycie: /{command} " - perplayerkit-migrate-usage: "Użycie: /perplayerkit migrate <źródło> " - kitroom-usage-hint: "/kitroom " - inspect-usage: "Użycie: /{command} " + deletekit-usage: "Użycie: /deletekit \\" + swapkit-usage: "Użycie: /swapkit \\ \\" + savepublickit-usage: "Użycie: /{command} \\" + perplayerkit-migrate-usage: "Użycie: /perplayerkit migrate \\<źródło> \\" + kitroom-usage-hint: "/kitroom \\" + inspect-usage: "Użycie: /{command} \\ \\" update: new-version-available: "Dostępna jest nowa wersja PerPlayerKit! Używasz wersji {current}, a najnowsza to {latest}" @@ -193,10 +193,10 @@ gui: lore-import-ec: "● Importuj ze skrzyni Endera" lore-left-load: "● Lewy klik, aby załadować zestaw" lore-right-edit: "● Prawy klik, aby edytować zestaw" - lore-share-kits: "● /sharekit " + lore-share-kits: "● /sharekit \\" lore-info-load: "● Kliknij slot zestawu, aby załadować swój zestaw" lore-info-edit: "● Prawy klik lub klik księgi, aby edytować" - lore-info-share: "● Udostępniaj zestawy komendą /sharekit " + lore-info-share: "● Udostępniaj zestawy komendą /sharekit \\" lore-admin-shift-edit: "● [ADMIN] Shift+klik, aby edytować" lore-unassigned-info: "● Administratorzy jeszcze nie skonfigurowali tego zestawu" lore-regear-restocks: "● Uzupełnia twój zestaw" diff --git a/src/main/resources/lang/pt.yml b/src/main/resources/lang/pt.yml index 483df47..15c93c7 100644 --- a/src/main/resources/lang/pt.yml +++ b/src/main/resources/lang/pt.yml @@ -18,7 +18,7 @@ motd: scheduled-broadcast: messages: - "Confira os kits públicos com o comando /pk!" - - "Quer compartilhar um kit? Use /sharekit ." + - "Quer compartilhar um kit? Use /sharekit \\." - "Digite /kit, /k ou /pk para começar!" broadcast-messages: @@ -35,7 +35,7 @@ broadcast-messages: error: disabled-in-world: "Os kits estão desativados aqui!" - unexpected: "Ocorreu um erro inesperado, tente novamente." + unexpected: "Ocorreu um erro inesperado, tente novamente." kit-not-found: "Erro, esse kit não existe" kit-expired: "Erro, o kit não existe ou expirou" ec-not-found: "Erro, esse EC não existe" @@ -112,7 +112,7 @@ success: info: custom-version-available: "Você pode salvar uma versão personalizada deste kit importando-o no editor" - assign-publickit-instruction: "Para atribuir um kit a este publickit use /savepublickit " + assign-publickit-instruction: "Para atribuir um kit a este publickit use /savepublickit \\" share-kit-code: "Use /copykit {code} para copiar este kit" share-ec-code: "Use /copyEC {code} para copiar este ender chest" share-code-expiry: "O código expira em 15 minutos" @@ -126,12 +126,12 @@ info: command: perplayerkit-about: "PerPlayerKit é um plugin que permite que jogadores tenham seus próprios kits." - deletekit-usage: "Uso: /deletekit " - swapkit-usage: "Uso: /swapkit " - savepublickit-usage: "Uso: /{command} " - perplayerkit-migrate-usage: "Uso: /perplayerkit migrate " - kitroom-usage-hint: "/kitroom " - inspect-usage: "Uso: /{command} " + deletekit-usage: "Uso: /deletekit \\" + swapkit-usage: "Uso: /swapkit \\ \\" + savepublickit-usage: "Uso: /{command} \\" + perplayerkit-migrate-usage: "Uso: /perplayerkit migrate \\ \\" + kitroom-usage-hint: "/kitroom \\" + inspect-usage: "Uso: /{command} \\ \\" update: new-version-available: "Uma nova versão do PerPlayerKit está disponível! Você está usando a versão {current} e a mais recente é {latest}" @@ -150,17 +150,17 @@ gui: main-menu-title: "Kits de {player}" kit-editor-title: "Kit: {slot}" public-kit-editor-title: "Kit Público: {id}" - enderchest-editor-title: "Ender Chest: {slot}" + enderchest-editor-title: "ender chest: {slot}" inspect-kit-title: "Inspecionando kit {slot} de {player}" inspect-ec-title: "Inspecionando ender chest {slot} de {player}" kit-room-title: "Sala de Kits" public-kit-room-title: "Sala de Kits Públicos" view-public-kit-title: "Visualizando Kit Público: {id}" - enderchest-view-title: "Ender Chest (Somente Visualização)" + enderchest-view-title: "ender chest (Somente Visualização)" regear-shulker-title: "Shulker de Reequipar" kit-slot-name: "Kit {slot}" - enderchest-slot-name: "Ender Chest {slot}" + enderchest-slot-name: "ender chest {slot}" kit-exists: "KIT EXISTE" kit-not-found: "KIT NÃO ENCONTRADO" more-kits-coming: "MAIS KITS EM BREVE" @@ -193,10 +193,10 @@ gui: lore-import-ec: "● Importar do ender chest" lore-left-load: "● Clique esquerdo para carregar kit" lore-right-edit: "● Clique direito para editar kit" - lore-share-kits: "● /sharekit " + lore-share-kits: "● /sharekit \\" lore-info-load: "● Clique em um slot para carregar seu kit" lore-info-edit: "● Clique direito ou no livro para editar" - lore-info-share: "● Compartilhe kits com /sharekit " + lore-info-share: "● Compartilhe kits com /sharekit \\" lore-admin-shift-edit: "● [ADMIN] Shift clique para editar" lore-unassigned-info: "● Admins ainda não configuraram este kit" lore-regear-restocks: "● Reabastece seu kit" diff --git a/src/main/resources/lang/ro.yml b/src/main/resources/lang/ro.yml index 87517a2..5747fb7 100644 --- a/src/main/resources/lang/ro.yml +++ b/src/main/resources/lang/ro.yml @@ -18,7 +18,7 @@ motd: scheduled-broadcast: messages: - "Verifică kiturile publice cu comanda /pk!" - - "Vrei să partajezi un kit? Folosește /sharekit ." + - "Vrei să partajezi un kit? Folosește /sharekit \\." - "Scrie /kit, /k sau /pk pentru a începe!" broadcast-messages: @@ -35,7 +35,7 @@ broadcast-messages: error: disabled-in-world: "Kiturile sunt dezactivate aici!" - unexpected: "A apărut o eroare neașteptată, încearcă din nou." + unexpected: "A apărut o eroare neașteptată, încearcă din nou." kit-not-found: "Eroare, acel kit nu există" kit-expired: "Eroare, kitul nu există sau a expirat" ec-not-found: "Eroare, acel cufăr Ender nu există" @@ -112,7 +112,7 @@ success: info: custom-version-available: "Poți salva o versiune personalizată a acestui kit importând-o în editor" - assign-publickit-instruction: "Pentru a atribui un kit acestui publickit folosește /savepublickit " + assign-publickit-instruction: "Pentru a atribui un kit acestui publickit folosește /savepublickit \\" share-kit-code: "Folosește /copykit {code} pentru a copia acest kit" share-ec-code: "Folosește /copyEC {code} pentru a copia acest cufăr Ender" share-code-expiry: "Codul expiră în 15 minute" @@ -126,12 +126,12 @@ info: command: perplayerkit-about: "PerPlayerKit este un plugin care permite jucătorilor să aibă propriile kituri." - deletekit-usage: "Utilizare: /deletekit " - swapkit-usage: "Utilizare: /swapkit " - savepublickit-usage: "Utilizare: /{command} " - perplayerkit-migrate-usage: "Utilizare: /perplayerkit migrate " - kitroom-usage-hint: "/kitroom " - inspect-usage: "Utilizare: /{command} " + deletekit-usage: "Utilizare: /deletekit \\" + swapkit-usage: "Utilizare: /swapkit \\ \\" + savepublickit-usage: "Utilizare: /{command} \\" + perplayerkit-migrate-usage: "Utilizare: /perplayerkit migrate \\ \\" + kitroom-usage-hint: "/kitroom \\" + inspect-usage: "Utilizare: /{command} \\ \\" update: new-version-available: "Este disponibilă o nouă versiune de PerPlayerKit! Folosești versiunea {current}, iar cea mai recentă este {latest}" @@ -193,10 +193,10 @@ gui: lore-import-ec: "● Importă din cufăr Ender" lore-left-load: "● Click stânga pentru încărcare kit" lore-right-edit: "● Click dreapta pentru editare kit" - lore-share-kits: "● /sharekit " + lore-share-kits: "● /sharekit \\" lore-info-load: "● Click pe un slot pentru a încărca kitul tău" lore-info-edit: "● Click dreapta sau pe carte pentru editare" - lore-info-share: "● Partajează kituri cu /sharekit " + lore-info-share: "● Partajează kituri cu /sharekit \\" lore-admin-shift-edit: "● [ADMIN] Shift+click pentru editare" lore-unassigned-info: "● Administratorii încă nu au configurat acest kit" lore-regear-restocks: "● Reumple kitul tău" diff --git a/src/main/resources/lang/sv.yml b/src/main/resources/lang/sv.yml index dd8ef0b..e49a55c 100644 --- a/src/main/resources/lang/sv.yml +++ b/src/main/resources/lang/sv.yml @@ -18,7 +18,7 @@ motd: scheduled-broadcast: messages: - "Kolla in publika kit med kommandot /pk!" - - "Vill du dela ett kit? Använd /sharekit ." + - "Vill du dela ett kit? Använd /sharekit \\." - "Skriv /kit, /k eller /pk för att börja!" broadcast-messages: @@ -35,7 +35,7 @@ broadcast-messages: error: disabled-in-world: "Kit är inaktiverade här!" - unexpected: "Ett oväntat fel inträffade, försök igen." + unexpected: "Ett oväntat fel inträffade, försök igen." kit-not-found: "Fel, det kitet existerar inte" kit-expired: "Fel, kitet existerar inte eller har gått ut" ec-not-found: "Fel, den enderkistan existerar inte" @@ -112,7 +112,7 @@ success: info: custom-version-available: "Du kan spara en anpassad version av detta kit genom att importera till kit-redigeraren" - assign-publickit-instruction: "För att tilldela ett kit till denna publickit använd /savepublickit " + assign-publickit-instruction: "För att tilldela ett kit till denna publickit använd /savepublickit \\" share-kit-code: "Använd /copykit {code} för att kopiera detta kit" share-ec-code: "Använd /copyEC {code} för att kopiera denna enderkista" share-code-expiry: "Koden går ut om 15 minuter" @@ -126,12 +126,12 @@ info: command: perplayerkit-about: "PerPlayerKit är ett plugin som låter spelare ha sina egna kit." - deletekit-usage: "Användning: /deletekit " - swapkit-usage: "Användning: /swapkit " - savepublickit-usage: "Användning: /{command} " - perplayerkit-migrate-usage: "Användning: /perplayerkit migrate " - kitroom-usage-hint: "/kitroom " - inspect-usage: "Användning: /{command} " + deletekit-usage: "Användning: /deletekit \\" + swapkit-usage: "Användning: /swapkit \\ \\" + savepublickit-usage: "Användning: /{command} \\" + perplayerkit-migrate-usage: "Användning: /perplayerkit migrate \\ \\" + kitroom-usage-hint: "/kitroom \\" + inspect-usage: "Användning: /{command} \\ \\" update: new-version-available: "En ny version av PerPlayerKit är tillgänglig! Du kör version {current} och den senaste versionen är {latest}" @@ -193,10 +193,10 @@ gui: lore-import-ec: "● Importera från enderkista" lore-left-load: "● Vänsterklicka för att ladda kit" lore-right-edit: "● Högerklicka för att redigera kit" - lore-share-kits: "● /sharekit " + lore-share-kits: "● /sharekit \\" lore-info-load: "● Klicka på en kit-slot för att ladda ditt kit" lore-info-edit: "● Högerklicka eller klicka på boken för att redigera" - lore-info-share: "● Dela kit med /sharekit " + lore-info-share: "● Dela kit med /sharekit \\" lore-admin-shift-edit: "● [ADMIN] Shift-klick för att redigera" lore-unassigned-info: "● Admins har inte ställt in detta kit ännu" lore-regear-restocks: "● Fyller på ditt kit" diff --git a/src/main/resources/lang/uk.yml b/src/main/resources/lang/uk.yml index 445f185..7402aef 100644 --- a/src/main/resources/lang/uk.yml +++ b/src/main/resources/lang/uk.yml @@ -18,7 +18,7 @@ motd: scheduled-broadcast: messages: - "Перегляньте публічні набори командою /pk!" - - "Хочете поділитися набором? Використайте /sharekit ." + - "Хочете поділитися набором? Використайте /sharekit \\." - "Введіть /kit, /k або /pk щоб почати!" broadcast-messages: @@ -35,7 +35,7 @@ broadcast-messages: error: disabled-in-world: "Набори тут вимкнено!" - unexpected: "Сталася непередбачена помилка, спробуйте ще раз." + unexpected: "Сталася непередбачена помилка, спробуйте ще раз." kit-not-found: "Помилка, такого набору не існує" kit-expired: "Помилка, набір не існує або термін його дії минув" ec-not-found: "Помилка, такої ендер-скрині не існує" @@ -112,7 +112,7 @@ success: info: custom-version-available: "Ви можете зберегти свою версію цього набору, імпортувавши його до редактора" - assign-publickit-instruction: "Щоб призначити набір для цього publickit використовуйте /savepublickit " + assign-publickit-instruction: "Щоб призначити набір для цього publickit використовуйте /savepublickit \\" share-kit-code: "Використовуйте /copykit {code} щоб скопіювати цей набір" share-ec-code: "Використовуйте /copyEC {code} щоб скопіювати цю ендер-скриню" share-code-expiry: "Код діє 15 хвилин" @@ -126,12 +126,12 @@ info: command: perplayerkit-about: "PerPlayerKit — це плагін, що дозволяє гравцям мати власні набори." - deletekit-usage: "Використання: /deletekit <слот>" - swapkit-usage: "Використання: /swapkit <слот1> <слот2>" - savepublickit-usage: "Використання: /{command} " - perplayerkit-migrate-usage: "Використання: /perplayerkit migrate <джерело> <призначення>" - kitroom-usage-hint: "/kitroom " - inspect-usage: "Використання: /{command} <гравець|uuid> <слот>" + deletekit-usage: "Використання: /deletekit \\<слот>" + swapkit-usage: "Використання: /swapkit \\<слот1> \\<слот2>" + savepublickit-usage: "Використання: /{command} \\" + perplayerkit-migrate-usage: "Використання: /perplayerkit migrate \\<джерело> \\<призначення>" + kitroom-usage-hint: "/kitroom \\" + inspect-usage: "Використання: /{command} \\<гравець|uuid> \\<слот>" update: new-version-available: "Доступна нова версія PerPlayerKit! Ви використовуєте версію {current}, а остання версія — {latest}" @@ -193,10 +193,10 @@ gui: lore-import-ec: "● Імпорт з ендер-скрині" lore-left-load: "● ЛКМ щоб завантажити набір" lore-right-edit: "● ПКМ щоб редагувати набір" - lore-share-kits: "● /sharekit " + lore-share-kits: "● /sharekit \\" lore-info-load: "● Натисніть на слот набору, щоб завантажити ваш набір" lore-info-edit: "● ПКМ або клік по книзі для редагування" - lore-info-share: "● Діліться наборами командою /sharekit " + lore-info-share: "● Діліться наборами командою /sharekit \\" lore-admin-shift-edit: "● [АДМІН] Shift клік для редагування" lore-unassigned-info: "● Адміністратори ще не налаштували цей набір" lore-regear-restocks: "● Поповнює ваш набір" diff --git a/src/main/resources/lang/zh.yml b/src/main/resources/lang/zh.yml index 3417f8e..3f48af4 100644 --- a/src/main/resources/lang/zh.yml +++ b/src/main/resources/lang/zh.yml @@ -18,7 +18,7 @@ motd: scheduled-broadcast: messages: - "使用 /pk 命令查看公共套件!" - - "想要分享套件? 使用 /sharekit 命令。" + - "想要分享套件? 使用 /sharekit \\ 命令。" - "输入 /kit/k /pk 开始使用!" broadcast-messages: @@ -35,7 +35,7 @@ broadcast-messages: error: disabled-in-world: "此处禁用套件!" - unexpected: "发生意外错误,请重试。" + unexpected: "发生意外错误,请重试。" kit-not-found: "错误,该套件不存在" kit-expired: "错误,套件不存在或已过期" ec-not-found: "错误,该末影箱不存在" @@ -112,7 +112,7 @@ success: info: custom-version-available: "你可以通过将此套件导入到编辑器来保存自定义版本" - assign-publickit-instruction: "使用 /savepublickit 为此 publickit 分配套件" + assign-publickit-instruction: "使用 /savepublickit \\ 为此 publickit 分配套件" share-kit-code: "使用 /copykit {code} 复制此套件" share-ec-code: "使用 /copyEC {code} 复制此末影箱" share-code-expiry: "代码将在 15 分钟后过期" @@ -126,12 +126,12 @@ info: command: perplayerkit-about: "PerPlayerKit 是一个允许玩家拥有自己套件的插件。" - deletekit-usage: "用法: /deletekit <槽位>" - swapkit-usage: "用法: /swapkit <槽位1> <槽位2>" - savepublickit-usage: "用法: /{command} <套件id>" - perplayerkit-migrate-usage: "用法: /perplayerkit migrate <源> <目标>" - kitroom-usage-hint: "/kitroom " - inspect-usage: "用法: /{command} <玩家|uuid> <槽位>" + deletekit-usage: "用法: /deletekit \\<槽位>" + swapkit-usage: "用法: /swapkit \\<槽位1> \\<槽位2>" + savepublickit-usage: "用法: /{command} \\<套件id>" + perplayerkit-migrate-usage: "用法: /perplayerkit migrate \\<源> \\<目标>" + kitroom-usage-hint: "/kitroom \\" + inspect-usage: "用法: /{command} \\<玩家|uuid> \\<槽位>" update: new-version-available: "PerPlayerKit 有新版本可用! 你正在运行版本 {current},最新版本是 {latest}" @@ -193,10 +193,10 @@ gui: lore-import-ec: "● 从末影箱导入" lore-left-load: "● 左键单击加载套件" lore-right-edit: "● 右键单击编辑套件" - lore-share-kits: "● /sharekit " + lore-share-kits: "● /sharekit \\" lore-info-load: "● 单击套件槽位加载你的套件" lore-info-edit: "● 右键单击或单击书本编辑" - lore-info-share: "● 使用 /sharekit 分享套件" + lore-info-share: "● 使用 /sharekit \\ 分享套件" lore-admin-shift-edit: "● [管理员] Shift 单击编辑" lore-unassigned-info: "● 管理员尚未设置此套件" lore-regear-restocks: "● 补充你的套件" From 25a5c9270ea5c5176d7c3943221db353b7672d2d Mon Sep 17 00:00:00 2001 From: Noah Ross Date: Sun, 24 May 2026 00:52:39 -0400 Subject: [PATCH 3/3] Address follow-up i18n review comments --- .../commands/features/RegearCommand.java | 1 + src/main/resources/lang/pt.yml | 26 +++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/main/java/dev/noah/perplayerkit/commands/features/RegearCommand.java b/src/main/java/dev/noah/perplayerkit/commands/features/RegearCommand.java index c5e94ab..3ae51e6 100644 --- a/src/main/java/dev/noah/perplayerkit/commands/features/RegearCommand.java +++ b/src/main/java/dev/noah/perplayerkit/commands/features/RegearCommand.java @@ -259,6 +259,7 @@ public static class RegearInventoryHolder implements InventoryHolder { public RegearInventoryHolder(Player player) { this.player = player; + this.inventory = Bukkit.createInventory(this, 27); } public Player player() { diff --git a/src/main/resources/lang/pt.yml b/src/main/resources/lang/pt.yml index 15c93c7..caf37d7 100644 --- a/src/main/resources/lang/pt.yml +++ b/src/main/resources/lang/pt.yml @@ -27,9 +27,9 @@ broadcast-messages: player-opened-kit-room: "{player} abriu a Sala de Kits" player-loaded-private-kit: "{player} carregou um kit" player-loaded-public-kit: "{player} carregou um kit público" - player-loaded-enderchest: "{player} carregou um ender chest." + player-loaded-enderchest: "{player} carregou um baú do End." player-copied-kit: "{player} copiou um kit" - player-copied-ec: "{player} copiou um ender chest" + player-copied-ec: "{player} copiou um baú do End" player-regeared: "{player} se reequipou" generic: "{player} realizou uma ação." @@ -40,7 +40,7 @@ error: kit-expired: "Erro, o kit não existe ou expirou" ec-not-found: "Erro, esse EC não existe" empty-kit: "Você não pode salvar um kit vazio!" - empty-ec: "Você não pode salvar um ender chest vazio!" + empty-ec: "Você não pode salvar um baú do End vazio!" kit-slot-not-found: "O kit {slot} não existe!" kit-deletion-failed: "Falha ao excluir o kit!" invalid-number: "Selecione um número válido" @@ -75,11 +75,11 @@ error: player-not-found: "Não foi possível encontrar um jogador com esse nome ou UUID." kit-not-found-display: "Kit não encontrado" inspect-kit-missing: "{player} não tem um kit no slot {slot}" - inspect-ec-missing: "{player} não tem um ender chest no slot {slot}" + inspect-ec-missing: "{player} não tem um baú do End no slot {slot}" inspect-kit-load-error: "Ocorreu um erro ao carregar os dados do kit. Veja o console para detalhes." - inspect-ec-load-error: "Ocorreu um erro ao carregar os dados do ender chest. Veja o console para detalhes." + inspect-ec-load-error: "Ocorreu um erro ao carregar os dados do baú do End. Veja o console para detalhes." failed-to-update-kit: "Falha ao atualizar o kit do jogador {player}!" - failed-to-update-ec: "Falha ao atualizar o ender chest do jogador {player}!" + failed-to-update-ec: "Falha ao atualizar o baú do End do jogador {player}!" invalid-command-label: "Rótulo de comando inválido." prefix-tag: "Erro: " @@ -114,7 +114,7 @@ info: custom-version-available: "Você pode salvar uma versão personalizada deste kit importando-o no editor" assign-publickit-instruction: "Para atribuir um kit a este publickit use /savepublickit \\" share-kit-code: "Use /copykit {code} para copiar este kit" - share-ec-code: "Use /copyEC {code} para copiar este ender chest" + share-ec-code: "Use /copyEC {code} para copiar este baú do End" share-code-expiry: "O código expira em 15 minutos" import-instructions: "Copie a pasta de dados do KitsX para a pasta PerPlayerKit" migration-starting: "Iniciando migração de {source} para {destination}..." @@ -150,17 +150,17 @@ gui: main-menu-title: "Kits de {player}" kit-editor-title: "Kit: {slot}" public-kit-editor-title: "Kit Público: {id}" - enderchest-editor-title: "ender chest: {slot}" + enderchest-editor-title: "Baú do End: {slot}" inspect-kit-title: "Inspecionando kit {slot} de {player}" - inspect-ec-title: "Inspecionando ender chest {slot} de {player}" + inspect-ec-title: "Inspecionando Baú do End {slot} de {player}" kit-room-title: "Sala de Kits" public-kit-room-title: "Sala de Kits Públicos" view-public-kit-title: "Visualizando Kit Público: {id}" - enderchest-view-title: "ender chest (Somente Visualização)" + enderchest-view-title: "Baú do End (Somente Visualização)" regear-shulker-title: "Shulker de Reequipar" kit-slot-name: "Kit {slot}" - enderchest-slot-name: "ender chest {slot}" + enderchest-slot-name: "Baú do End {slot}" kit-exists: "KIT EXISTE" kit-not-found: "KIT NÃO ENCONTRADO" more-kits-coming: "MAIS KITS EM BREVE" @@ -187,10 +187,10 @@ gui: lore-click-create: "● Clique para criar" lore-shift-clear: "● Shift clique para limpar" lore-shift-delete-kit: "● Shift clique para excluir kit" - lore-shift-delete-ec: "● Shift clique para excluir ender chest" + lore-shift-delete-ec: "● Shift clique para excluir baú do End" lore-shift-click: "● Shift clique" lore-import-inventory: "● Importar do inventário" - lore-import-ec: "● Importar do ender chest" + lore-import-ec: "● Importar do baú do End" lore-left-load: "● Clique esquerdo para carregar kit" lore-right-edit: "● Clique direito para editar kit" lore-share-kits: "● /sharekit \\"