diff --git a/pom.xml b/pom.xml index d936797..35552f3 100644 --- a/pom.xml +++ b/pom.xml @@ -43,8 +43,8 @@ MINECRAFT --> - org.spigotmc - spigot + io.papermc.paper + paper-api 1.20.1-R0.1-SNAPSHOT provided @@ -63,7 +63,7 @@ xyz.xenondevs.invui invui - 1.11 + 1.14 pom @@ -73,8 +73,8 @@ com.github.seeseemelk - MockBukkit-v1.19 - 2.29.0 + MockBukkit-v1.20 + 3.9.0 test @@ -95,7 +95,7 @@ com.github.jsixface yamlconfig - 1.1.2 + 1.2 @@ -120,12 +120,12 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M7 + 3.0.0-M9 org.apache.maven.plugins maven-shade-plugin - 3.4.1 + 3.5.0 package diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index 84dd3f2..ec82768 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -3,15 +3,12 @@ package xyz.atnrch.nicko; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.command.PluginCommand; -import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.plugin.java.JavaPluginLoader; import xyz.atnrch.nicko.command.NickoCommand; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.ConfigurationManager; import xyz.atnrch.nicko.event.PlayerJoinListener; import xyz.atnrch.nicko.event.PlayerQuitListener; -import xyz.atnrch.nicko.gui.items.common.UnavailableItem; import xyz.atnrch.nicko.i18n.Locale; import xyz.atnrch.nicko.i18n.LocaleFileManager; import xyz.atnrch.nicko.mojang.MojangAPI; @@ -22,7 +19,6 @@ import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SimpleItem; -import java.io.File; import java.io.IOException; public class NickoBukkit extends JavaPlugin { @@ -44,16 +40,8 @@ public class NickoBukkit extends JavaPlugin { /** * Used by MockBukkit */ - protected NickoBukkit(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { - this(loader, description, dataFolder, file, null); - } - - /** - * Used by MockBukkit - */ - protected NickoBukkit(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file, Configuration configuration) { - super(loader, description, dataFolder, file); - unitTesting = true; + protected NickoBukkit(Configuration configuration) { + this.unitTesting = true; this.configuration = configuration; getLogger().info("Unit Testing Mode enabled."); } @@ -103,7 +91,6 @@ public class NickoBukkit extends JavaPlugin { Structure.addGlobalIngredient('#', new SimpleItem(new ItemBuilder(Material.AIR))); Structure.addGlobalIngredient('%', new SimpleItem(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setDisplayName(" "))); - Structure.addGlobalIngredient('U', new UnavailableItem()); if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { getLogger().info("Enabling PlaceHolderAPI support..."); @@ -120,11 +107,12 @@ public class NickoBukkit extends JavaPlugin { @Override public void onDisable() { if (!getDataStore().getStorage().isError()) { - getLogger().info("Closing persistence..."); nameStore.clearStoredNames(); Bukkit.getOnlinePlayers().forEach(player -> dataStore.saveData(player)); if (!dataStore.getStorage().getProvider().close()) { getLogger().severe("Failed to close persistence!"); + } else { + getLogger().info("Persistence closed."); } } diff --git a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java index aa65338..0e7d16f 100644 --- a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java @@ -11,20 +11,25 @@ import xyz.atnrch.nicko.appearance.AppearanceManager; import xyz.atnrch.nicko.i18n.I18N; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.mojang.MojangUtils; +import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.PlayerDataStore; import java.util.Collections; import java.util.List; +import java.util.Optional; public class AnvilManager { private final Player player; private final AppearanceManager appearanceManager; - private final PlayerDataStore dataStore; + private final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore(); + private final NickoProfile profile; public AnvilManager(Player player) { this.player = player; - this.appearanceManager = AppearanceManager.get(player); - this.dataStore = NickoBukkit.getInstance().getDataStore(); + + final Optional optionalProfile = dataStore.getData(player.getUniqueId()); + this.profile = optionalProfile.orElse(NickoProfile.EMPTY_PROFILE.clone()); + this.appearanceManager = new AppearanceManager(player); } public void openNameThenSkinAnvil() { @@ -39,7 +44,7 @@ public class AnvilManager { getNameAnvil().open(player); } - public AnvilGUI.Builder getNameThenSkinAnvil() { + private AnvilGUI.Builder getNameThenSkinAnvil() { return new AnvilGUI.Builder() .plugin(NickoBukkit.getInstance()) .itemLeft(getLeftItem(false)) @@ -49,8 +54,8 @@ public class AnvilManager { if (MojangUtils.isUsernameInvalid(snapshot.getText())) { return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); } else { - appearanceManager.setName(snapshot.getText()); - dataStore.updateCache(player.getUniqueId(), appearanceManager.getProfile()); + profile.setName(snapshot.getText()); + dataStore.updateCache(player.getUniqueId(), profile); openSkinAnvil(); return Collections.singletonList(AnvilGUI.ResponseAction.close()); } @@ -60,7 +65,7 @@ public class AnvilManager { .text("New name..."); } - public AnvilGUI.Builder getNameAnvil() { + private AnvilGUI.Builder getNameAnvil() { return new AnvilGUI.Builder() .plugin(NickoBukkit.getInstance()) .itemLeft(getLeftItem(false)) @@ -70,8 +75,8 @@ public class AnvilManager { if (MojangUtils.isUsernameInvalid(snapshot.getText())) { return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); } else { - appearanceManager.setName(snapshot.getText()); - dataStore.updateCache(player.getUniqueId(), appearanceManager.getProfile()); + profile.setName(snapshot.getText()); + dataStore.updateCache(player.getUniqueId(), profile); final ActionResult actionResult = appearanceManager.updatePlayer(false, false); return sendResultAndClose(actionResult); } @@ -91,8 +96,8 @@ public class AnvilManager { if (MojangUtils.isUsernameInvalid(snapshot.getText())) { return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); } else { - appearanceManager.setSkin(snapshot.getText()); - dataStore.updateCache(player.getUniqueId(), appearanceManager.getProfile()); + profile.setSkin(snapshot.getText()); + dataStore.updateCache(player.getUniqueId(), profile); final ActionResult actionResult = appearanceManager.updatePlayer(true, false); return sendResultAndClose(actionResult); } diff --git a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java index f46770d..d655d0e 100644 --- a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java @@ -11,7 +11,6 @@ import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerTeleportEvent; import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.i18n.I18NDict; -import xyz.atnrch.nicko.i18n.Locale; import xyz.atnrch.nicko.mojang.MojangAPI; import xyz.atnrch.nicko.mojang.MojangSkin; import xyz.atnrch.nicko.profile.NickoProfile; @@ -22,96 +21,36 @@ import xyz.atnrch.nicko.wrapper.*; import java.io.IOException; import java.util.EnumSet; import java.util.Optional; -import java.util.UUID; import java.util.concurrent.ExecutionException; public class AppearanceManager { - private final NickoProfile profile; - private final Player player; - private final UUID uuid; private final NickoBukkit instance = NickoBukkit.getInstance(); private final PlayerDataStore dataStore = instance.getDataStore(); private final PlayerNameStore nameStore = instance.getNameStore(); - private AppearanceManager(UUID uuid) { - this.player = Bukkit.getPlayer(uuid); - this.uuid = uuid; - this.profile = dataStore.getData(uuid).orElse(NickoProfile.EMPTY_PROFILE.clone()); - } + private final Player player; - private AppearanceManager(String name) { - this.player = null; - this.uuid = null; - this.profile = dataStore.getOfflineData(name).orElse(NickoProfile.EMPTY_PROFILE.clone()); - } - - public static AppearanceManager get(Player player) { - return new AppearanceManager(player.getUniqueId()); - } - - public static AppearanceManager get(String name) { - return new AppearanceManager(name); - } - - public boolean hasData() { - return !profile.isEmpty(); - } - - public void setSkin(String skin) { - profile.setSkin(skin); - dataStore.getCache().cache(uuid, profile); - } - - public String getSkin() { - return profile.getSkin(); - } - - public boolean needsASkinChange() { - return profile.getSkin() != null && !profile.getSkin().equals(player.getName()); - } - - public void setName(String name) { - profile.setName(name); - dataStore.getCache().cache(uuid, profile); - } - - public String getName() { - return profile.getName(); - } - - public void setLocale(Locale locale) { - profile.setLocale(locale); - dataStore.getCache().cache(uuid, profile); - } - - public Locale getLocale() { - return profile.getLocale(); - } - - public NickoProfile getProfile() { - return profile; - } - - public void setNameAndSkin(String name, String skin) { - this.profile.setName(name); - this.profile.setSkin(skin); - dataStore.getCache().cache(uuid, profile); + public AppearanceManager(Player player) { + this.player = player; } public ActionResult reset() { + final NickoProfile profile = getNickoProfile(); final String defaultName = nameStore.getStoredName(player); - this.profile.setName(defaultName); - this.profile.setSkin(defaultName); + profile.setName(defaultName); + profile.setSkin(defaultName); + dataStore.getCache().cache(player.getUniqueId(), profile); final ActionResult actionResult = updatePlayer(true, true); if (!actionResult.isError()) { - this.profile.setSkin(null); - this.profile.setName(null); - dataStore.getCache().cache(uuid, profile); + profile.setSkin(null); + profile.setName(null); + dataStore.getCache().cache(player.getUniqueId(), profile); } return actionResult; } public ActionResult updatePlayer(boolean skinChange, boolean reset) { + final NickoProfile profile = getNickoProfile(); final String displayName = profile.getName() == null ? player.getName() : profile.getName(); final WrappedGameProfile gameProfile = WrappedGameProfile.fromPlayer(player).withName(displayName); final ActionResult result = updateGameProfileSkin(gameProfile, skinChange, reset); @@ -124,6 +63,11 @@ public class AppearanceManager { return result; } + private NickoProfile getNickoProfile() { + final Optional optionalProfile = dataStore.getData(player.getUniqueId()); + return optionalProfile.orElse(NickoProfile.EMPTY_PROFILE.clone()); + } + public void updateOthers() { final WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy(); final WrapperPlayServerNamedEntitySpawn spawn = new WrapperPlayServerNamedEntitySpawn(); @@ -139,15 +83,16 @@ public class AppearanceManager { private ActionResult updateGameProfileSkin(WrappedGameProfile gameProfile, boolean skinChange, boolean reset) { - final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); + final NickoProfile profile = getNickoProfile(); + final boolean changeOnlyName = profile.getSkin() != null && profile.getSkin().equals(player.getName()); - if (skinChange || changeOnlyName) { + if (skinChange || !changeOnlyName) { Optional skin; try { - final MojangAPI mojang = NickoBukkit.getInstance().getMojangAPI(); - final Optional uuid = mojang.getUUID(profile.getSkin()); + final MojangAPI mojangAPI = NickoBukkit.getInstance().getMojangAPI(); + final Optional uuid = mojangAPI.getUUID(profile.getSkin()); if (uuid.isPresent()) { - skin = reset ? mojang.getSkinWithoutCaching(uuid.get()) : mojang.getSkin(uuid.get()); + skin = reset ? mojangAPI.getSkinWithoutCaching(uuid.get()) : mojangAPI.getSkin(uuid.get()); if (skin.isPresent()) { final MojangSkin skinResult = skin.get(); final Multimap properties = gameProfile.getProperties(); @@ -177,6 +122,7 @@ public class AppearanceManager { private void respawnPlayer() { final World world = player.getWorld(); final boolean wasFlying = player.isFlying(); + final boolean wasAllowedToFly = player.getAllowFlight(); final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(); respawn.setDimension(world); respawn.setSeed(world.getSeed()); @@ -185,9 +131,10 @@ public class AppearanceManager { respawn.setDifficulty(world.getDifficulty()); respawn.setCopyMetadata(true); respawn.sendPacket(player); - player.setFlying(wasFlying); player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.updateInventory(); + player.setAllowFlight(wasAllowedToFly); + player.setFlying(wasFlying); + player.updateInventory(); // Marked as unstable. } @SuppressWarnings("deprecation") @@ -218,6 +165,9 @@ public class AppearanceManager { // No, I'll not waste another day fixing their mess. // Go cry about it to Mojang. // (Long live NoEncryption!) + // TODO (Ineanto, 9/1/23): + // Try to provide chat session data after ProtocolLib's update to support Chat Sessions. + // This could remove the mandatory NoEncryption (or similar "encryption removing") dependency with Nicko. add.setData(ImmutableList.of(new PlayerInfoData( player.getUniqueId(), player.getPing(), diff --git a/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java b/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java index d8429c2..13b1df8 100644 --- a/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java +++ b/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java @@ -1,13 +1,12 @@ package xyz.atnrch.nicko.command; -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.command.sub.NickoCheckSubCmd; -import xyz.atnrch.nicko.command.sub.NickoDebugSubCmd; -import xyz.atnrch.nicko.gui.HomeGUI; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.gui.HomeGUI; import xyz.atnrch.nicko.i18n.I18N; import xyz.atnrch.nicko.i18n.I18NDict; @@ -17,25 +16,19 @@ public class NickoCommand implements CommandExecutor { "§6/nicko help §f- §7Print this help message.\n"; @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { if (sender instanceof Player) { final Player player = (Player) sender; if (args.length >= 1) { - switch (args[0]) { - case "debug": - new NickoDebugSubCmd().execute(player, args); - break; - case "check": - new NickoCheckSubCmd().execute(player, args); - break; - default: - sendHelpMessage(sender); - break; + if (args[0].equals("debug")) { + new NickoDebugCmd().execute(player, args); + } else { + sendHelpMessage(sender); } return false; } - if(player.isOp() || player.hasPermission("nicko.use") || player.hasPermission("nicko.*")) { + if (player.isOp() || player.hasPermission("nicko.use") || player.hasPermission("nicko.*")) { new HomeGUI(player).open(); } else { final I18N i18N = new I18N(player); @@ -49,7 +42,7 @@ public class NickoCommand implements CommandExecutor { } public void sendHelpMessage(CommandSender sender) { - helpMessage = helpMessage.replace("{version}", NickoBukkit.getInstance().getDescription().getVersion()); + helpMessage = helpMessage.replace("{version}", NickoBukkit.getInstance().getPluginMeta().getVersion()); sender.sendMessage(helpMessage); } } diff --git a/src/main/java/xyz/atnrch/nicko/command/sub/NickoDebugSubCmd.java b/src/main/java/xyz/atnrch/nicko/command/NickoDebugCmd.java similarity index 53% rename from src/main/java/xyz/atnrch/nicko/command/sub/NickoDebugSubCmd.java rename to src/main/java/xyz/atnrch/nicko/command/NickoDebugCmd.java index 3bfa40d..4f5b877 100644 --- a/src/main/java/xyz/atnrch/nicko/command/sub/NickoDebugSubCmd.java +++ b/src/main/java/xyz/atnrch/nicko/command/NickoDebugCmd.java @@ -1,21 +1,26 @@ -package xyz.atnrch.nicko.command.sub; +package xyz.atnrch.nicko.command; +import org.bukkit.Bukkit; +import org.bukkit.Sound; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.appearance.ActionResult; import xyz.atnrch.nicko.appearance.AppearanceManager; import xyz.atnrch.nicko.i18n.I18N; import xyz.atnrch.nicko.mojang.MojangUtils; -import org.bukkit.Bukkit; -import org.bukkit.Sound; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; +import xyz.atnrch.nicko.profile.NickoProfile; +import xyz.atnrch.nicko.storage.PlayerDataStore; -public class NickoDebugSubCmd { +import java.util.Optional; + +public class NickoDebugCmd { public void execute(CommandSender sender, String[] args) { final String prefix = NickoBukkit.getInstance().getNickoConfig().getPrefix(); Player target; String name, skin; + String playerName = null; if (args.length == 3) { target = (Player) sender; name = args[1]; @@ -26,7 +31,7 @@ public class NickoDebugSubCmd { return; } - final String playerName = args[1]; + playerName = args[1]; name = args[2]; skin = args[3]; @@ -47,15 +52,22 @@ public class NickoDebugSubCmd { return; } - final AppearanceManager appearanceManager = AppearanceManager.get(target.getPlayer()); - appearanceManager.setNameAndSkin(name, skin); - final ActionResult result = appearanceManager.updatePlayer(true, false); - if (!result.isError()) { - target.sendMessage(prefix + "§aWhoosh!"); - target.playSound(target.getLocation(), Sound.ENTITY_ITEM_FRAME_PLACE, 1, 1); - } else { - final I18N i18n = new I18N(target); - target.sendMessage(prefix + "§cWhoops. Something happened: " + i18n.translatePrefixless(result.getErrorKey())); + final Optional optionalProfile = NickoProfile.get(target); + if (optionalProfile.isPresent()) { + final NickoProfile profile = optionalProfile.get(); + final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore(); + profile.setName(name); + profile.setSkin(skin); + dataStore.updateCache(target.getUniqueId(), profile); + final AppearanceManager appearanceManager = new AppearanceManager(target); + final ActionResult result = appearanceManager.updatePlayer(true, false); + if (!result.isError()) { + target.sendMessage(prefix + "§aWhoosh!"); + target.playSound(target.getLocation(), Sound.ENTITY_ITEM_FRAME_PLACE, 1, 1); + } else { + final I18N i18n = new I18N(target); + target.sendMessage(prefix + "§cWhoops. Something happened: " + i18n.translatePrefixless(result.getErrorKey())); + } } } } diff --git a/src/main/java/xyz/atnrch/nicko/command/sub/NickoCheckSubCmd.java b/src/main/java/xyz/atnrch/nicko/command/sub/NickoCheckSubCmd.java deleted file mode 100644 index 6b70a01..0000000 --- a/src/main/java/xyz/atnrch/nicko/command/sub/NickoCheckSubCmd.java +++ /dev/null @@ -1,44 +0,0 @@ -package xyz.atnrch.nicko.command.sub; - -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.appearance.AppearanceManager; -import xyz.atnrch.nicko.i18n.I18N; -import xyz.atnrch.nicko.i18n.I18NDict; -import xyz.atnrch.nicko.mojang.MojangUtils; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; - -import java.util.StringJoiner; - -public class NickoCheckSubCmd { - public void execute(Player player, String[] args) { - final String targetName = args[1]; - final Player target = Bukkit.getPlayerExact(targetName); - final I18N i18n = new I18N(player); - - AppearanceManager appearanceManager; - if (MojangUtils.isUsernameInvalid(targetName)) { - player.sendMessage(i18n.translate(I18NDict.Error.INVALID_USERNAME)); - return; - } - - if (target == null) { - appearanceManager = AppearanceManager.get(targetName); - } else { - appearanceManager = AppearanceManager.get(target); - } - - final StringJoiner builder = new StringJoiner("\n"); - builder.add("§c" + NickoBukkit.getInstance().getNickoConfig().getPrefix() + "§cCheck for: §f§o" + targetName); - if (appearanceManager.hasData()) { - builder.add("§cNicked: §a✔"); - builder.add("§cName: §6" + appearanceManager.getName()); - builder.add("§cSkin: §6" + appearanceManager.getSkin()); - } else { - builder.add("§cNicked: §c❌"); - builder.add("§cName: §7N/A"); - builder.add("§cSkin: §7N/A"); - } - player.sendMessage(builder.toString()); - } -} diff --git a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java index b4a3a19..498030d 100644 --- a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java @@ -10,8 +10,12 @@ import xyz.atnrch.nicko.appearance.ActionResult; import xyz.atnrch.nicko.appearance.AppearanceManager; import xyz.atnrch.nicko.i18n.I18N; import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.profile.NickoProfile; +import xyz.atnrch.nicko.storage.PlayerDataStore; import xyz.atnrch.nicko.storage.name.PlayerNameStore; +import java.util.Optional; + public class PlayerJoinListener implements Listener { @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { @@ -19,19 +23,25 @@ public class PlayerJoinListener implements Listener { final NickoBukkit instance = NickoBukkit.getInstance(); final I18N i18n = new I18N(player); final PlayerNameStore nameStore = instance.getNameStore(); + final PlayerDataStore dataStore = instance.getDataStore(); // TODO: 2/20/23 Fetch data from BungeeCord nameStore.storeName(player); Bukkit.getScheduler().runTaskLater(instance, () -> { - final AppearanceManager appearanceManager = AppearanceManager.get(player); - if (appearanceManager.hasData()) { - final ActionResult actionResult = appearanceManager.updatePlayer(appearanceManager.needsASkinChange(), false); - if (!actionResult.isError()) { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Restore.OK)); - } else { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Restore.ERROR, i18n.translatePrefixless(actionResult.getErrorKey()))); + final Optional optionalProfile = dataStore.getData(player.getUniqueId()); + + optionalProfile.ifPresent(profile -> { + if (profile.hasData()) { + final AppearanceManager appearanceManager = new AppearanceManager(player); + final boolean needsASkinChange = profile.getSkin() != null && !profile.getSkin().equals(player.getName()); + final ActionResult actionResult = appearanceManager.updatePlayer(needsASkinChange, false); + if (!actionResult.isError()) { + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Restore.OK)); + } else { + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Restore.ERROR, i18n.translatePrefixless(actionResult.getErrorKey()))); + } } - } + }); }, 20L); } } diff --git a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java index 8c19b38..107e03b 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java @@ -4,25 +4,36 @@ import xyz.atnrch.nicko.gui.items.admin.ManageCacheItem; import xyz.atnrch.nicko.gui.items.admin.ManagePlayerItem; import xyz.atnrch.nicko.gui.items.common.GoBackItem; import org.bukkit.entity.Player; +import xyz.atnrch.nicko.gui.items.common.UnavailableItem; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; public class AdminGUI { - private final String title = "Nicko > Administration"; private final Player player; private final Gui gui; + private final String title; public AdminGUI(Player player) { + final I18N i18n = new I18N(player); + this.title = i18n.translatePrefixless(I18NDict.GUI.Titles.ADMIN); + final HomeGUI parent = new HomeGUI(player); + final GoBackItem backItem = new GoBackItem(player); + final UnavailableItem unavailableItem = new UnavailableItem(player); + final ManagePlayerItem managePlayerItem = new ManagePlayerItem(i18n, player); + this.gui = Gui.normal() .setStructure( "# # # # # # # # #", - "# # # S C U # # #", + "# # # S C X # # #", "B # # # # # # # #" ) - .addIngredient('S', new ManageCacheItem()) - .addIngredient('C', new ManagePlayerItem()) - .addIngredient('B', new GoBackItem(parent.getGUI(), parent.getTitle())) + .addIngredient('S', new ManageCacheItem(i18n)) + .addIngredient('C', managePlayerItem.get()) + .addIngredient('U', unavailableItem.get()) + .addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle())) .build(); this.player = player; } diff --git a/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java b/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java index c32227d..5c081f9 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java @@ -3,28 +3,39 @@ package xyz.atnrch.nicko.gui; import org.bukkit.entity.Player; import xyz.atnrch.nicko.gui.items.admin.cache.CacheStatisticsItem; import xyz.atnrch.nicko.gui.items.admin.cache.InvalidateCacheItem; -import xyz.atnrch.nicko.gui.items.admin.cache.InvalidateEntryItem; +import xyz.atnrch.nicko.gui.items.admin.cache.InvalidateSkinItem; import xyz.atnrch.nicko.gui.items.common.GoBackItem; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; public class CacheManagementGUI { - private final String title = "Nicko > Admin... > Cache"; private final Player player; private final Gui gui; + private final String title; public CacheManagementGUI(Player player) { + final I18N i18n = new I18N(player); + this.title = i18n.translatePrefixless(I18NDict.GUI.Titles.CACHE); + final AdminGUI parent = new AdminGUI(player); + final GoBackItem backItem = new GoBackItem(player); + + final CacheStatisticsItem cacheStatisticsItem = new CacheStatisticsItem(player); + final InvalidateCacheItem invalidateCacheItem = new InvalidateCacheItem(player); + final InvalidateSkinItem invalidateSkinItem = new InvalidateSkinItem(player); + this.gui = Gui.normal() .setStructure( "# # # # # # # # #", - "# # # S A D # # #", + "# # # S C E # # #", "B # # # # # # # #" ) - .addIngredient('B', new GoBackItem(parent.getGUI(), parent.getTitle())) - .addIngredient('S', new CacheStatisticsItem()) - .addIngredient('A', new InvalidateCacheItem()) - .addIngredient('D', new InvalidateEntryItem()) + .addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle())) + .addIngredient('S', cacheStatisticsItem.get()) + .addIngredient('C', invalidateCacheItem.get()) + .addIngredient('E', invalidateSkinItem.get()) .build(); this.player = player; } diff --git a/src/main/java/xyz/atnrch/nicko/gui/ChoiceGUI.java b/src/main/java/xyz/atnrch/nicko/gui/ChoiceGUI.java new file mode 100644 index 0000000..5b7b7e6 --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/gui/ChoiceGUI.java @@ -0,0 +1,42 @@ +package xyz.atnrch.nicko.gui; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import xyz.atnrch.nicko.gui.items.common.choice.CancelItem; +import xyz.atnrch.nicko.gui.items.common.choice.ChoiceCallback; +import xyz.atnrch.nicko.gui.items.common.choice.ConfirmItem; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; +import xyz.xenondevs.invui.gui.Gui; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.SimpleItem; +import xyz.xenondevs.invui.window.Window; + +public class ChoiceGUI { + private final Player player; + private final Gui gui; + + public ChoiceGUI(Player player, ChoiceCallback callback) { + final I18N i18n = new I18N(player); + final ConfirmItem confirmItem = new ConfirmItem(player, callback); + final CancelItem cancelItem = new CancelItem(player, callback); + final ItemTranslation chooseItemTranslation = i18n.translateItem(I18NDict.GUI.Choice.CHOOSE); + + this.gui = Gui.normal() + .setStructure( + "@ @ @ @ % & & & &", + "@ @ @ @ I & & & &", + "@ @ @ @ % & & & &" + ) + .addIngredient('@', confirmItem.get()) + .addIngredient('&', cancelItem.get()) + .addIngredient('I', new SimpleItem(new ItemBuilder(Material.PAPER).setDisplayName(chooseItemTranslation.getName()).get())) + .build(); + this.player = player; + } + + public void open() { + Window.single().setGui(gui).setTitle("... > Invalidate > Confirm").open(player); + } +} diff --git a/src/main/java/xyz/atnrch/nicko/gui/ConfirmGUI.java b/src/main/java/xyz/atnrch/nicko/gui/ConfirmGUI.java deleted file mode 100644 index a857a37..0000000 --- a/src/main/java/xyz/atnrch/nicko/gui/ConfirmGUI.java +++ /dev/null @@ -1,34 +0,0 @@ -package xyz.atnrch.nicko.gui; - -import org.bukkit.Material; -import org.bukkit.entity.Player; -import xyz.atnrch.nicko.gui.items.common.confirm.ChoiceCallback; -import xyz.atnrch.nicko.gui.items.common.confirm.CancelItem; -import xyz.atnrch.nicko.gui.items.common.confirm.ConfirmItem; -import xyz.xenondevs.invui.gui.Gui; -import xyz.xenondevs.invui.item.builder.ItemBuilder; -import xyz.xenondevs.invui.item.impl.SimpleItem; -import xyz.xenondevs.invui.window.Window; - -public class ConfirmGUI { - private final Player player; - private final Gui gui; - - public ConfirmGUI(Player player, ChoiceCallback callback) { - this.gui = Gui.normal() - .setStructure( - "@ @ @ @ % & & & &", - "@ @ @ @ I & & & &", - "@ @ @ @ % & & & &" - ) - .addIngredient('@', new ConfirmItem(callback)) - .addIngredient('&', new CancelItem(callback)) - .addIngredient('I', new SimpleItem(new ItemBuilder(Material.PAPER).setDisplayName("§6Select an option").get())) - .build(); - this.player = player; - } - - public void open() { - Window.single().setGui(gui).setTitle("... > Invalidate > Confirm").open(player); - } -} diff --git a/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java b/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java index 7b9d156..9303f45 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java @@ -8,13 +8,15 @@ import xyz.atnrch.nicko.gui.items.home.AdminAccessItem; import xyz.atnrch.nicko.gui.items.home.ExitItem; import xyz.atnrch.nicko.gui.items.home.ResetItem; import xyz.atnrch.nicko.gui.items.home.SettingsAccessItem; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; public class HomeGUI { - private final String title = "Nicko - Home"; private final Player player; private final Gui gui; + private final String title; public HomeGUI(Player player) { final String[] dynamicStructure = new String[]{ @@ -26,15 +28,26 @@ public class HomeGUI { dynamicStructure[2] = dynamicStructure[2].replace("A", "#"); } + final I18N i18n = new I18N(player); + this.title = i18n.translatePrefixless(I18NDict.GUI.Titles.HOME); + + final ExitItem exitItem = new ExitItem(player); + final ResetItem resetItem = new ResetItem(player); + final ChangeNameItem changeNameItem = new ChangeNameItem(player); + final ChangeBothItem changeBothItem = new ChangeBothItem(player); + final ChangeSkinItem changeSkinItem = new ChangeSkinItem(player); + final SettingsAccessItem settingsAccessItem = new SettingsAccessItem(player); + final AdminAccessItem adminAccessItem = new AdminAccessItem(player); + this.gui = Gui.normal() .setStructure(dynamicStructure) - .addIngredient('E', new ExitItem()) - .addIngredient('R', new ResetItem()) - .addIngredient('N', new ChangeNameItem()) - .addIngredient('B', new ChangeBothItem()) - .addIngredient('S', new ChangeSkinItem(player)) - .addIngredient('P', new SettingsAccessItem()) - .addIngredient('A', new AdminAccessItem()) + .addIngredient('E', exitItem.get()) + .addIngredient('R', resetItem.get()) + .addIngredient('N', changeNameItem.get()) + .addIngredient('B', changeBothItem.get()) + .addIngredient('S', changeSkinItem.get()) + .addIngredient('P', settingsAccessItem.get()) + .addIngredient('A', adminAccessItem.get()) .build(); this.player = player; } diff --git a/src/main/java/xyz/atnrch/nicko/gui/CacheDetailedGUI.java b/src/main/java/xyz/atnrch/nicko/gui/InvalidateSkinGUI.java similarity index 70% rename from src/main/java/xyz/atnrch/nicko/gui/CacheDetailedGUI.java rename to src/main/java/xyz/atnrch/nicko/gui/InvalidateSkinGUI.java index 8d5935a..768ffc5 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/CacheDetailedGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/InvalidateSkinGUI.java @@ -2,6 +2,8 @@ package xyz.atnrch.nicko.gui; import xyz.atnrch.nicko.gui.items.common.GoBackItem; import xyz.atnrch.nicko.gui.items.common.ScrollUpItem; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.mojang.MojangSkin; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.gui.ScrollGui; @@ -19,13 +21,15 @@ import java.util.Optional; import java.util.concurrent.ConcurrentMap; import java.util.stream.Collectors; -public class CacheDetailedGUI { - public static final String TITLE = "... > Cache > Invalidate"; - +public class InvalidateSkinGUI { private final Player player; private final Gui gui; + private final String title; + + public InvalidateSkinGUI(Player player) { + final I18N i18n = new I18N(player); + this.title = i18n.translatePrefixless(I18NDict.GUI.Titles.INVALIDATE_SKIN); - public CacheDetailedGUI(Player player) { final ConcurrentMap> skins = NickoBukkit.getInstance().getMojangAPI().getSkinCache().asMap(); final List loadedSkins = skins.entrySet().stream() .filter(entry -> entry.getValue().isPresent()) @@ -37,6 +41,10 @@ public class CacheDetailedGUI { .collect(Collectors.toList()); final CacheManagementGUI parent = new CacheManagementGUI(player); + final ScrollUpItem scrollUpItem = new ScrollUpItem(i18n); + final ScrollDownItem scrollDownItem = new ScrollDownItem(i18n); + final GoBackItem backItem = new GoBackItem(player); + gui = ScrollGui.items(guiItemBuilder -> { guiItemBuilder.setStructure( "x x x x x x x x U", @@ -46,9 +54,9 @@ public class CacheDetailedGUI { "x x x x x x x x D", "B % % % % % % % %"); guiItemBuilder.addIngredient('x', Markers.CONTENT_LIST_SLOT_HORIZONTAL); - guiItemBuilder.addIngredient('U', new ScrollUpItem()); - guiItemBuilder.addIngredient('D', new ScrollDownItem()); - guiItemBuilder.addIngredient('B', new GoBackItem(parent.getGUI(), parent.getTitle())); + guiItemBuilder.addIngredient('U', scrollUpItem); + guiItemBuilder.addIngredient('D', scrollDownItem); + guiItemBuilder.addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle())); guiItemBuilder.setContent(items); }); @@ -56,6 +64,6 @@ public class CacheDetailedGUI { } public void open() { - Window.single().setGui(gui).setTitle(TITLE).open(player); + Window.single().setGui(gui).setTitle(title).open(player); } } diff --git a/src/main/java/xyz/atnrch/nicko/gui/PlayerCheckGUI.java b/src/main/java/xyz/atnrch/nicko/gui/PlayerCheckGUI.java index a09b80d..5326d6d 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/PlayerCheckGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/PlayerCheckGUI.java @@ -7,6 +7,8 @@ import xyz.atnrch.nicko.gui.items.admin.check.PlayerInformationItem; import xyz.atnrch.nicko.gui.items.common.GoBackItem; import xyz.atnrch.nicko.gui.items.common.ScrollDownItem; import xyz.atnrch.nicko.gui.items.common.ScrollUpItem; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.gui.structure.Markers; @@ -17,18 +19,24 @@ import java.util.List; import java.util.stream.Collectors; public class PlayerCheckGUI { - public static final String TITLE = "Nicko > Admin... > Check"; - private final Player player; private final Gui gui; + private final String title; public PlayerCheckGUI(Player player) { + final I18N i18n = new I18N(player); + this.title = i18n.translatePrefixless(I18NDict.GUI.Titles.CHECK); + final List items = Bukkit.getOnlinePlayers().stream() .map(Entity::getUniqueId) - .map(PlayerInformationItem::new) + .map(uuid -> new PlayerInformationItem(i18n, uuid)) .collect(Collectors.toList()); final AdminGUI parent = new AdminGUI(player); + final GoBackItem backItem = new GoBackItem(player); + final ScrollUpItem scrollUpItem = new ScrollUpItem(i18n); + final ScrollDownItem scrollDownItem = new ScrollDownItem(i18n); + gui = ScrollGui.items(guiItemBuilder -> { guiItemBuilder.setStructure( "x x x x x x x x U", @@ -38,9 +46,9 @@ public class PlayerCheckGUI { "x x x x x x x x D", "B % % % % % % % %"); guiItemBuilder.addIngredient('x', Markers.CONTENT_LIST_SLOT_HORIZONTAL); - guiItemBuilder.addIngredient('U', new ScrollUpItem()); - guiItemBuilder.addIngredient('D', new ScrollDownItem()); - guiItemBuilder.addIngredient('B', new GoBackItem(parent.getGUI(), parent.getTitle())); + guiItemBuilder.addIngredient('U', scrollUpItem); + guiItemBuilder.addIngredient('D', scrollDownItem); + guiItemBuilder.addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle())); guiItemBuilder.setContent(items); }); @@ -48,6 +56,6 @@ public class PlayerCheckGUI { } public void open() { - Window.single().setGui(gui).setTitle(TITLE).open(player); + Window.single().setGui(gui).setTitle(title).open(player); } } diff --git a/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java b/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java index 3917d31..a19be9e 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java @@ -1,17 +1,19 @@ package xyz.atnrch.nicko.gui; import xyz.atnrch.nicko.gui.items.common.GoBackItem; +import xyz.atnrch.nicko.gui.items.common.UnavailableItem; import xyz.atnrch.nicko.gui.items.settings.BungeeCordCyclingItem; import xyz.atnrch.nicko.gui.items.settings.LanguageCyclingItem; import org.bukkit.entity.Player; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; public class SettingsGUI { - public static final String TITLE = "Nicko > Settings"; - private final Player player; private final Gui gui; + private final String title; public SettingsGUI(Player player) { final String[] dynamicStructure = new String[]{ @@ -23,17 +25,26 @@ public class SettingsGUI { // TODO: 3/6/23 Replace when Redis is not enabled dynamicStructure[1] = dynamicStructure[1].replace("T", "U"); + final I18N i18n = new I18N(player); + this.title = i18n.translatePrefixless(I18NDict.GUI.Titles.SETTINGS); + final HomeGUI parent = new HomeGUI(player); + final UnavailableItem unavailableItem = new UnavailableItem(player); + final LanguageCyclingItem languageItem = new LanguageCyclingItem(player); + final BungeeCordCyclingItem bungeeCordItem = new BungeeCordCyclingItem(player); + final GoBackItem backItem = new GoBackItem(player); + this.gui = Gui.normal() .setStructure(dynamicStructure) - .addIngredient('B', new GoBackItem(parent.getGUI(), parent.getTitle())) - .addIngredient('L', new LanguageCyclingItem().get(player)) - .addIngredient('T', new BungeeCordCyclingItem().get(player)) + .addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle())) + .addIngredient('L', languageItem.get()) + .addIngredient('U', unavailableItem.get()) + .addIngredient('T', bungeeCordItem.get()) .build(); this.player = player; } public void open() { - Window.single().setGui(gui).setTitle(TITLE).open(player); + Window.single().setGui(gui).setTitle(title).open(player); } } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCacheItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCacheItem.java index 0a65cc9..a63a7f0 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCacheItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCacheItem.java @@ -1,24 +1,33 @@ package xyz.atnrch.nicko.gui.items.admin; -import xyz.xenondevs.invui.item.builder.ItemBuilder; -import xyz.xenondevs.invui.item.builder.SkullBuilder; -import xyz.xenondevs.invui.item.impl.AsyncItem; -import xyz.atnrch.nicko.gui.CacheManagementGUI; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; import org.jetbrains.annotations.NotNull; +import xyz.atnrch.nicko.gui.CacheManagementGUI; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.builder.SkullBuilder; +import xyz.xenondevs.invui.item.impl.AsyncItem; +import xyz.xenondevs.invui.item.impl.SuppliedItem; public class ManageCacheItem extends AsyncItem { - public ManageCacheItem() { - super(new ItemBuilder(Material.PAINTING) - .setDisplayName("Manage §6skin §fcache...") - .addLoreLines("§7Access the skin cache management panel."), + public ManageCacheItem(I18N i18n) { + super(new SuppliedItem(() -> { + final ItemBuilder builder = new ItemBuilder(Material.PAINTING); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.LOADING); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); + return builder; + }, (click -> true)).getItemProvider(), () -> { final SkullBuilder builder = new SkullBuilder("Notch"); - builder.setDisplayName("Manage §6skin §fcache..."); - builder.addLoreLines("§7Access the skin cache management panel."); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.MANAGE_CACHE); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); return builder; }); } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManagePlayerItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManagePlayerItem.java index dcf133f..0736036 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManagePlayerItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManagePlayerItem.java @@ -2,30 +2,32 @@ package xyz.atnrch.nicko.gui.items.admin; import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.jetbrains.annotations.NotNull; import xyz.atnrch.nicko.gui.PlayerCheckGUI; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class ManagePlayerItem extends SuppliedItem { - public ManagePlayerItem() { - super(() -> { - final ItemBuilder builder = new ItemBuilder(Material.WRITABLE_BOOK); - builder.setDisplayName("Check a player..."); - builder.addLoreLines("§7See players' disguise information."); - return builder; - }, - click -> true); +public class ManagePlayerItem { + private final Player player; + private final I18N i18n; + + public ManagePlayerItem(I18N i18n, Player player) { + this.i18n = i18n; + this.player = player; } - @Override - public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent - event) { - if (clickType.isLeftClick() || clickType.isRightClick()) { - event.getView().close(); + public SuppliedItem get() { + return new SuppliedItem(() -> { + final ItemBuilder builder = new ItemBuilder(Material.WRITABLE_BOOK); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.MANAGE_PLAYER); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); + return builder; + }, click -> { new PlayerCheckGUI(player).open(); - } + return true; + }); } } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntryItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntryItem.java index a66f206..37f8bc3 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntryItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntryItem.java @@ -6,9 +6,9 @@ import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; import org.jetbrains.annotations.NotNull; import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.gui.ConfirmGUI; -import xyz.atnrch.nicko.gui.CacheDetailedGUI; -import xyz.atnrch.nicko.gui.items.common.confirm.ChoiceCallback; +import xyz.atnrch.nicko.gui.ChoiceGUI; +import xyz.atnrch.nicko.gui.InvalidateSkinGUI; +import xyz.atnrch.nicko.gui.items.common.choice.ChoiceCallback; import xyz.atnrch.nicko.i18n.I18N; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.mojang.MojangAPI; @@ -40,7 +40,7 @@ public class CacheEntryItem extends AsyncItem { public void handleClick(@NotNull ClickType click, @NotNull Player player, @NotNull InventoryClickEvent event) { if (click.isLeftClick() || click.isRightClick()) { event.getView().close(); - new ConfirmGUI(player, new ChoiceCallback() { + new ChoiceGUI(player, new ChoiceCallback() { @Override public void onConfirm() { final I18N i18n = new I18N(player); @@ -50,7 +50,7 @@ public class CacheEntryItem extends AsyncItem { @Override public void onCancel() { - new CacheDetailedGUI(player).open(); + new InvalidateSkinGUI(player).open(); } }).open(); } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheStatisticsItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheStatisticsItem.java index 9398e7a..027100e 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheStatisticsItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheStatisticsItem.java @@ -2,7 +2,11 @@ package xyz.atnrch.nicko.gui.items.admin.cache; import com.google.common.cache.CacheStats; import com.google.common.cache.LoadingCache; +import org.bukkit.entity.Player; import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; import xyz.atnrch.nicko.mojang.MojangSkin; import org.bukkit.Material; import xyz.xenondevs.invui.item.builder.ItemBuilder; @@ -10,17 +14,26 @@ import xyz.xenondevs.invui.item.impl.SuppliedItem; import java.util.Optional; -public class CacheStatisticsItem extends SuppliedItem { - public CacheStatisticsItem() { - super(() -> { +public class CacheStatisticsItem { + private final I18N i18n; + + public CacheStatisticsItem(Player player) { + this.i18n = new I18N(player); + } + + public SuppliedItem get() { + return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.BOOK); final LoadingCache> cache = NickoBukkit.getInstance().getMojangAPI().getSkinCache(); final CacheStats stats = cache.stats(); - builder.setDisplayName("Statistics"); - builder.addLoreLines( - "Request Count: §b" + stats.requestCount(), - "Skin Cached: §b" + Math.round(cache.size()), - "§8§oCache is cleared every 24 hours."); + + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.Cache.STATISTICS, + stats.requestCount(), + Math.round(cache.size()) + ); + // TODO (Ineanto, 9/11/23): This doesn't work. + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); return builder; }, (event) -> true); } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCacheItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCacheItem.java index 7c1c04f..3d0aca5 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCacheItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCacheItem.java @@ -6,18 +6,23 @@ import xyz.atnrch.nicko.i18n.I18NDict; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; +import xyz.atnrch.nicko.i18n.ItemTranslation; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class InvalidateCacheItem extends SuppliedItem { - public InvalidateCacheItem() { - super(() -> { +public class InvalidateCacheItem { + private final I18N i18n; + + public InvalidateCacheItem(Player player) { + this.i18n = new I18N(player); + } + + public SuppliedItem get() { + return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.TNT); - builder.setDisplayName("Invalidate cache"); - builder.addLoreLines( - "§c§oNOT RECOMMENDED", - "§7Invalidates every skin entry present in the cache.", - "§7Does not reset player disguises."); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.Cache.INVALIDATE_CACHE); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); return builder; }, (click) -> { final ClickType clickType = click.getClickType(); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateEntryItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateEntryItem.java deleted file mode 100644 index 71627b8..0000000 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateEntryItem.java +++ /dev/null @@ -1,28 +0,0 @@ -package xyz.atnrch.nicko.gui.items.admin.cache; - -import xyz.atnrch.nicko.gui.CacheDetailedGUI; -import org.bukkit.Material; -import org.bukkit.event.inventory.ClickType; -import xyz.xenondevs.invui.item.builder.ItemBuilder; -import xyz.xenondevs.invui.item.impl.SuppliedItem; - -public class InvalidateEntryItem extends SuppliedItem { - public InvalidateEntryItem() { - super(() -> { - final ItemBuilder builder = new ItemBuilder(Material.PAPER); - builder.setDisplayName("Invalidate specific entry"); - builder.addLoreLines("§7Select a specific skin to invalidate.", - "§7Useful if a skin has been updated", - "§7recently and the cache no longer up-to-date."); - return builder; - }, (click) -> { - final ClickType clickType = click.getClickType(); - if (clickType.isLeftClick() || clickType.isRightClick()) { - click.getEvent().getView().close(); - new CacheDetailedGUI(click.getPlayer()).open(); - return true; - } - return false; - }); - } -} diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateSkinItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateSkinItem.java new file mode 100644 index 0000000..d7ed378 --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateSkinItem.java @@ -0,0 +1,37 @@ +package xyz.atnrch.nicko.gui.items.admin.cache; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import xyz.atnrch.nicko.gui.InvalidateSkinGUI; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.SuppliedItem; + +public class InvalidateSkinItem { + private final I18N i18n; + + public InvalidateSkinItem(Player player) { + this.i18n = new I18N(player); + } + + public SuppliedItem get() { + return new SuppliedItem(() -> { + final ItemBuilder builder = new ItemBuilder(Material.PAPER); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.Cache.INVALIDATE_SKIN); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); + return builder; + }, (click) -> { + final ClickType clickType = click.getClickType(); + if (clickType.isLeftClick() || clickType.isRightClick()) { + click.getEvent().getView().close(); + new InvalidateSkinGUI(click.getPlayer()).open(); + return true; + } + return false; + }); + } +} diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/check/PlayerInformationItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/check/PlayerInformationItem.java index 6b68fcf..76578e4 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/check/PlayerInformationItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/check/PlayerInformationItem.java @@ -4,38 +4,48 @@ import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.appearance.AppearanceManager; -import xyz.atnrch.nicko.mojang.MojangAPI; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; +import xyz.atnrch.nicko.profile.NickoProfile; +import xyz.atnrch.nicko.storage.PlayerDataStore; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.builder.SkullBuilder; import xyz.xenondevs.invui.item.impl.AsyncItem; +import xyz.xenondevs.invui.item.impl.SuppliedItem; +import java.util.Optional; import java.util.UUID; public class PlayerInformationItem extends AsyncItem { - private final MojangAPI mojangAPI = NickoBukkit.getInstance().getMojangAPI(); - - public PlayerInformationItem(UUID uuid) { - super(new ItemBuilder(Material.PAINTING).setDisplayName("§7§oLoading..."), () -> { + public PlayerInformationItem(I18N i18n, UUID uuid) { + super(new SuppliedItem(() -> { + final ItemBuilder builder = new ItemBuilder(Material.PAINTING); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.LOADING); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); + return builder; + }, (click -> true)).getItemProvider(), () -> { final Player player = Bukkit.getPlayer(uuid); final SkullBuilder skull = new SkullBuilder(uuid); + final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore(); + final Optional optionalProfile = dataStore.getData(uuid); - final AppearanceManager appearanceManager = AppearanceManager.get(player); - if (appearanceManager.hasData()) { - skull.addLoreLines( - "§cNicked: §a✔", - "§cName: §6" + appearanceManager.getName(), - "§cSkin: §6" + appearanceManager.getSkin() - ); + + if (optionalProfile.isPresent()) { + final NickoProfile profile = optionalProfile.get(); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.CHECK, player.getName(), (profile.hasData() ? "§a✔" : "§c❌"), profile.getName(), profile.getSkin()); + skull.setDisplayName("§6" + translation.getName()); + translation.getLore().forEach(skull::addLoreLines); } else { + // Default item name in case the profile is not found + skull.setDisplayName("§6§lYou should not see this!"); skull.addLoreLines( - "§cNicked: §c❌", - "§cName: §7N/A", - "§cSkin: §7N/A" + "§cPlease file a bug report", + "§cat https://ineanto.xyz/git/ineanto/nicko!" ); } - skull.setDisplayName("§6" + player.getName()); return skull; }); } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeBothItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeBothItem.java index 2da2968..91259b3 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeBothItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeBothItem.java @@ -1,17 +1,28 @@ package xyz.atnrch.nicko.gui.items.appearance; +import org.bukkit.entity.Player; import xyz.atnrch.nicko.anvil.AnvilManager; import org.bukkit.Material; import org.bukkit.event.inventory.ClickType; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class ChangeBothItem extends SuppliedItem { - public ChangeBothItem() { - super(() -> { +public class ChangeBothItem { + private final I18N i18n; + + public ChangeBothItem(Player player) { + this.i18n = new I18N(player); + } + + public SuppliedItem get() { + return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.TOTEM_OF_UNDYING); - builder.setDisplayName("§6Skin §fand §6name §fchange"); - builder.addLoreLines("§7Will open a GUI to change both your name and your skin."); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Home.CHANGE_BOTH); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); return builder; }, click -> { final ClickType clickType = click.getClickType(); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeNameItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeNameItem.java index 985ebe4..243f91c 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeNameItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeNameItem.java @@ -1,17 +1,28 @@ package xyz.atnrch.nicko.gui.items.appearance; +import org.bukkit.entity.Player; import xyz.atnrch.nicko.anvil.AnvilManager; import org.bukkit.Material; import org.bukkit.event.inventory.ClickType; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class ChangeNameItem extends SuppliedItem { - public ChangeNameItem() { - super(() -> { +public class ChangeNameItem { + private final I18N i18n; + + public ChangeNameItem(Player player) { + this.i18n = new I18N(player); + } + + public SuppliedItem get() { + return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.NAME_TAG); - builder.setDisplayName("Change §6name"); - builder.addLoreLines("§7Will open a GUI to change your name only."); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Home.CHANGE_NAME); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); return builder; }, click -> { final ClickType clickType = click.getClickType(); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeSkinItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeSkinItem.java index 58b90b1..2903cdf 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeSkinItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeSkinItem.java @@ -3,15 +3,27 @@ package xyz.atnrch.nicko.gui.items.appearance; import xyz.atnrch.nicko.anvil.AnvilManager; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; import xyz.xenondevs.invui.item.builder.SkullBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class ChangeSkinItem extends SuppliedItem { +public class ChangeSkinItem { + private final I18N i18n; + private final Player player; + public ChangeSkinItem(Player player) { - super(() -> { + this.i18n = new I18N(player); + this.player = player; + } + + public SuppliedItem get() { + return new SuppliedItem(() -> { final SkullBuilder builder = new SkullBuilder(player.getName()); - builder.setDisplayName("Change §6skin"); - builder.addLoreLines("§7Will open a GUI to change your skin only."); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Home.CHANGE_SKIN); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); return builder; }, click -> { final ClickType clickType = click.getClickType(); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/GoBackItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/GoBackItem.java index e7a28ac..db9ea70 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/GoBackItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/GoBackItem.java @@ -1,17 +1,27 @@ package xyz.atnrch.nicko.gui.items.common; import org.bukkit.Material; +import org.bukkit.entity.Player; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; import xyz.xenondevs.invui.window.Window; -public class GoBackItem extends SuppliedItem { - public GoBackItem(Gui gui, String parentTitle) { - super(() -> { +public class GoBackItem { + private final I18N i18n; + + public GoBackItem(Player player) { + this.i18n = new I18N(player); + } + + public SuppliedItem get(Gui gui, String parentTitle) { + return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.ARROW); - builder.setDisplayName("Go back"); - builder.addLoreLines("§7Return to the previous window."); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.GO_BACK); + builder.setDisplayName(translation.getName()); return builder; }, click -> { click.getEvent().getView().close(); @@ -19,4 +29,4 @@ public class GoBackItem extends SuppliedItem { return true; }); } -} +} \ No newline at end of file diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollDownItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollDownItem.java index e39dad1..6a8515b 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollDownItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollDownItem.java @@ -1,24 +1,28 @@ package xyz.atnrch.nicko.gui.items.common; import org.bukkit.Material; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.item.ItemProvider; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.controlitem.ScrollItem; public class ScrollDownItem extends ScrollItem { + final I18N i18n; - public ScrollDownItem() { + public ScrollDownItem(I18N i18n) { super(1); + this.i18n = i18n; } @Override public ItemProvider getItemProvider(ScrollGui gui) { ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); - builder.setDisplayName("Scroll down"); - if (!gui.canScroll(1)) - builder.addLoreLines("§7§o(You can't scroll further down.)"); - + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.SCROLL_UP); + builder.setDisplayName(translation.getName()); + if (!gui.canScroll(1)) translation.getLore().forEach(builder::addLoreLines); return builder; } } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollUpItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollUpItem.java index b02f05b..6b2a714 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollUpItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollUpItem.java @@ -1,24 +1,28 @@ package xyz.atnrch.nicko.gui.items.common; import org.bukkit.Material; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.item.ItemProvider; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.controlitem.ScrollItem; public class ScrollUpItem extends ScrollItem { + final I18N i18n; - public ScrollUpItem() { + public ScrollUpItem(I18N i18n) { super(-1); + this.i18n = i18n; } @Override public ItemProvider getItemProvider(ScrollGui gui) { - ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE); - builder.setDisplayName("Scroll up"); - if (!gui.canScroll(-1)) - builder.addLoreLines("§7§o(You've reached the top.)"); - + final ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.SCROLL_UP); + builder.setDisplayName(translation.getName()); + if (!gui.canScroll(-1)) translation.getLore().forEach(builder::addLoreLines); return builder; } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/UnavailableItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/UnavailableItem.java index 1eb4928..8532511 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/UnavailableItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/UnavailableItem.java @@ -1,15 +1,26 @@ package xyz.atnrch.nicko.gui.items.common; import org.bukkit.Material; +import org.bukkit.entity.Player; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class UnavailableItem extends SuppliedItem { - public UnavailableItem() { - super(() -> { +public class UnavailableItem { + private final I18N i18n; + + public UnavailableItem(Player player) { + this.i18n = new I18N(player); + } + + public SuppliedItem get() { + return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.RED_TERRACOTTA); - builder.setDisplayName("Unavailable"); - builder.addLoreLines("§7§oThis button is disabled."); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.UNAVAILABLE); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); return builder; }, click -> true); } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/choice/CancelItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/choice/CancelItem.java new file mode 100644 index 0000000..3be6245 --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/choice/CancelItem.java @@ -0,0 +1,32 @@ +package xyz.atnrch.nicko.gui.items.common.choice; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.SuppliedItem; + +public class CancelItem { + private final I18N i18n; + private final ChoiceCallback callback; + + public CancelItem(Player player, ChoiceCallback callback) { + this.i18n = new I18N(player); + this.callback = callback; + } + + public SuppliedItem get() { + return new SuppliedItem(() -> { + final ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Choice.CANCEL); + builder.setDisplayName(translation.getName()); + return builder; + }, click -> { + click.getEvent().getView().close(); + callback.onCancel(); + return true; + }); + } +} \ No newline at end of file diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/ChoiceCallback.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/choice/ChoiceCallback.java similarity index 61% rename from src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/ChoiceCallback.java rename to src/main/java/xyz/atnrch/nicko/gui/items/common/choice/ChoiceCallback.java index c1d5c0c..e1e3f84 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/ChoiceCallback.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/choice/ChoiceCallback.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.gui.items.common.confirm; +package xyz.atnrch.nicko.gui.items.common.choice; public interface ChoiceCallback { void onConfirm(); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/choice/ConfirmItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/choice/ConfirmItem.java new file mode 100644 index 0000000..fe5dc97 --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/choice/ConfirmItem.java @@ -0,0 +1,32 @@ +package xyz.atnrch.nicko.gui.items.common.choice; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.SuppliedItem; + +public class ConfirmItem { + private final I18N i18n; + private final ChoiceCallback callback; + + public ConfirmItem(Player player, ChoiceCallback callback) { + this.i18n = new I18N(player); + this.callback = callback; + } + + public SuppliedItem get() { + return new SuppliedItem(() -> { + final ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Choice.CONFIRM); + builder.setDisplayName(translation.getName()); + return builder; + }, click -> { + click.getEvent().getView().close(); + callback.onConfirm(); + return true; + }); + } +} diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/CancelItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/CancelItem.java deleted file mode 100644 index eb654be..0000000 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/CancelItem.java +++ /dev/null @@ -1,19 +0,0 @@ -package xyz.atnrch.nicko.gui.items.common.confirm; - -import org.bukkit.Material; -import xyz.xenondevs.invui.item.builder.ItemBuilder; -import xyz.xenondevs.invui.item.impl.SuppliedItem; - -public class CancelItem extends SuppliedItem { - public CancelItem(ChoiceCallback callback) { - super(() -> { - final ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE); - builder.setDisplayName("§cCancel"); - return builder; - }, click -> { - click.getEvent().getView().close(); - callback.onCancel(); - return true; - }); - } -} \ No newline at end of file diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/ConfirmItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/ConfirmItem.java deleted file mode 100644 index d32fbb3..0000000 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/ConfirmItem.java +++ /dev/null @@ -1,19 +0,0 @@ -package xyz.atnrch.nicko.gui.items.common.confirm; - -import org.bukkit.Material; -import xyz.xenondevs.invui.item.builder.ItemBuilder; -import xyz.xenondevs.invui.item.impl.SuppliedItem; - -public class ConfirmItem extends SuppliedItem { - public ConfirmItem(ChoiceCallback callback) { - super(() -> { - final ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); - builder.setDisplayName("§aConfirm"); - return builder; - }, click -> { - click.getEvent().getView().close(); - callback.onConfirm(); - return true; - }); - } -} diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/home/AdminAccessItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/home/AdminAccessItem.java index 298ebe4..9afff1d 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/home/AdminAccessItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/home/AdminAccessItem.java @@ -1,17 +1,28 @@ package xyz.atnrch.nicko.gui.items.home; import org.bukkit.Material; +import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import xyz.atnrch.nicko.gui.AdminGUI; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class AdminAccessItem extends SuppliedItem { - public AdminAccessItem() { - super(() -> { +public class AdminAccessItem { + private final I18N i18n; + + public AdminAccessItem(Player player) { + this.i18n = new I18N(player); + } + + public SuppliedItem get() { + return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.COMMAND_BLOCK_MINECART); - builder.setDisplayName("Administration panel"); - builder.addLoreLines("§7Configure and manage Nicko."); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Home.ADMIN); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); return builder; }, click -> { final ClickType clickType = click.getClickType(); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/home/ExitItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/home/ExitItem.java index f4ca6f4..0bcb23e 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/home/ExitItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/home/ExitItem.java @@ -1,21 +1,34 @@ package xyz.atnrch.nicko.gui.items.home; -import com.comphenix.protocol.utility.MinecraftVersion; import org.bukkit.Material; +import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; import xyz.xenondevs.invui.item.builder.ItemBuilder; -import xyz.xenondevs.invui.item.impl.SimpleItem; +import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class ExitItem extends SimpleItem { - public ExitItem() { - super(new ItemBuilder(Material.OAK_DOOR).setDisplayName("Exit"), click -> { - if(MinecraftVersion.BEE_UPDATE.atOrAbove()) { +public class ExitItem { + private final I18N i18n; - } + public ExitItem(Player player) { + this.i18n = new I18N(player); + } + + public SuppliedItem get() { + return new SuppliedItem(() -> { + final ItemBuilder builder = new ItemBuilder(Material.OAK_DOOR); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.EXIT); + builder.setDisplayName(translation.getName()); + return builder; + }, click -> { + click.getEvent().getView().close(); final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { click.getEvent().getView().close(); } + return true; }); } } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/home/ResetItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/home/ResetItem.java index 4b46e9c..ff9df25 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/home/ResetItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/home/ResetItem.java @@ -1,42 +1,54 @@ package xyz.atnrch.nicko.gui.items.home; -import xyz.atnrch.nicko.appearance.AppearanceManager; -import xyz.atnrch.nicko.i18n.I18N; -import xyz.atnrch.nicko.i18n.I18NDict; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; +import xyz.atnrch.nicko.appearance.AppearanceManager; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; +import xyz.atnrch.nicko.profile.NickoProfile; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class ResetItem extends SuppliedItem { - public ResetItem() { - super(() -> { +import java.util.Optional; + +public class ResetItem { + private final I18N i18n; + + public ResetItem(Player player) { + this.i18n = new I18N(player); + } + + public SuppliedItem get() { + return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.TNT); - builder.setDisplayName("Reset appearance"); - builder.addLoreLines("§7Completely remove your disguise."); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Home.RESET); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); return builder; }, (event) -> { final Player player = event.getPlayer(); - final I18N i18n = new I18N(player); - final ClickType clickType = event.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { - final AppearanceManager appearanceManager = AppearanceManager.get(player); + final Optional optionalProfile = NickoProfile.get(player); + optionalProfile.ifPresent(profile -> { + if (!profile.hasData()) { + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.MISSING)); + event.getEvent().getView().close(); + return; + } - if (!appearanceManager.hasData()) { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.MISSING)); - event.getEvent().getView().close(); - return true; - } - - if (!appearanceManager.reset().isError()) { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.OK)); - return true; - } else { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.ERROR)); - return false; - } + final AppearanceManager appearanceManager = new AppearanceManager(player); + if (!appearanceManager.reset().isError()) { + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.OK)); + } else { + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.ERROR)); + profile.setSkin(null); + profile.setName(null); + } + }); + return true; } return false; }); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/home/SettingsAccessItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/home/SettingsAccessItem.java index c4a27ce..d566161 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/home/SettingsAccessItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/home/SettingsAccessItem.java @@ -1,17 +1,28 @@ package xyz.atnrch.nicko.gui.items.home; +import org.bukkit.entity.Player; import xyz.atnrch.nicko.gui.SettingsGUI; import org.bukkit.Material; import org.bukkit.event.inventory.ClickType; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class SettingsAccessItem extends SuppliedItem { - public SettingsAccessItem() { - super(() -> { +public class SettingsAccessItem { + private final I18N i18n; + + public SettingsAccessItem(Player player) { + this.i18n = new I18N(player); + } + + public SuppliedItem get() { + return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.COMPARATOR); - builder.setDisplayName("Settings"); - builder.addLoreLines("§7Configure your experience."); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Home.SETTINGS); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); return builder; }, click -> { final ClickType clickType = click.getClickType(); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/settings/BungeeCordCyclingItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/settings/BungeeCordCyclingItem.java index ef2ca6b..24a0e3b 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/settings/BungeeCordCyclingItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/settings/BungeeCordCyclingItem.java @@ -1,10 +1,14 @@ package xyz.atnrch.nicko.gui.items.settings; -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.profile.NickoProfile; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; +import xyz.atnrch.nicko.profile.NickoProfile; +import xyz.atnrch.nicko.storage.PlayerDataStore; import xyz.xenondevs.invui.item.ItemProvider; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.AbstractItem; @@ -14,18 +18,28 @@ import xyz.xenondevs.invui.item.impl.SimpleItem; import java.util.Optional; public class BungeeCordCyclingItem { - private final ItemProvider[] providers = new ItemProvider[]{ - getItemProviderForValue(true), - getItemProviderForValue(false) - }; + private final Player player; + private final I18N i18n; + private final ItemProvider[] providers; - public AbstractItem get(Player player) { - final Optional profile = NickoBukkit.getInstance().getDataStore().getData(player.getUniqueId()); + public BungeeCordCyclingItem(Player player) { + this.player = player; + this.i18n = new I18N(player); + this.providers = new ItemProvider[]{ + getItemProviderForValue(true), + getItemProviderForValue(false) + }; + } + + public AbstractItem get() { + final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore(); + final Optional profile = dataStore.getData(player.getUniqueId()); if (profile.isPresent()) { final NickoProfile nickoProfile = profile.get(); int startingState = nickoProfile.isBungeecordTransfer() ? 0 : 1; return CycleItem.withStateChangeHandler((observer, integer) -> { nickoProfile.setBungeecordTransfer(integer != 1); + dataStore.updateCache(player.getUniqueId(), nickoProfile); observer.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 0.707107f); // 0.707107 ~= C }, startingState, providers); } @@ -35,15 +49,20 @@ public class BungeeCordCyclingItem { private ItemProvider getItemProviderForValue(boolean enabled) { final ItemBuilder builder = new ItemBuilder(Material.COMPASS); - builder.setDisplayName("BungeeCord transfer"); - if (enabled) { - builder.addLoreLines("§7> §cDisabled"); - builder.addLoreLines("§6§l> §a§lEnabled"); - } else { - builder.addLoreLines("§6§l> §c§lDisabled"); - builder.addLoreLines("§7> §aEnabled"); - } - builder.addLoreLines("§7§oCycle through the values by", "§7§oleft and right clicking."); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Settings.BUNGEECORD); + + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); + /* + if (enabled) { + builder.addLoreLines("§7> §cDisabled"); + builder.addLoreLines("§6§l> §a§lEnabled"); + } else { + builder.addLoreLines("§6§l> §c§lDisabled"); + builder.addLoreLines("§7> §aEnabled"); + } + builder.addLoreLines("§7§oCycle through the values by", "§7§oleft and right clicking."); + */ return builder; } } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCyclingItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCyclingItem.java index d15b8b7..67f64d2 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCyclingItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCyclingItem.java @@ -4,8 +4,10 @@ import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.gui.SettingsGUI; import xyz.atnrch.nicko.i18n.I18N; import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; import xyz.atnrch.nicko.i18n.Locale; import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.PlayerDataStore; @@ -21,9 +23,17 @@ import java.util.List; import java.util.Optional; public class LanguageCyclingItem { - private final ItemProvider[] providers = getItems(); + private final Player player; + private final ItemProvider[] providers; + private final I18N i18n; - public AbstractItem get(Player player) { + public LanguageCyclingItem(Player player) { + this.player = player; + this.i18n = new I18N(player); + this.providers = getItems(); + } + + public AbstractItem get() { final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore(); final Optional profile = dataStore.getData(player.getUniqueId()); if (profile.isPresent()) { @@ -32,11 +42,12 @@ public class LanguageCyclingItem { return CycleItem.withStateChangeHandler((observer, integer) -> { nickoProfile.setLocale(Locale.values()[integer]); observer.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 0.707107f); // 0.707107 ~= C + player.getOpenInventory().close(); // TODO (Ineanto, 7/14/23): This checks a 2nd time for the profile. if (dataStore.updateCache(player.getUniqueId(), nickoProfile).isError()) { - final I18N i18n = new I18N(player); player.sendMessage(i18n.translate(I18NDict.Event.Settings.ERROR)); - player.getOpenInventory().close(); + } else { + new SettingsGUI(player).open(); } }, localeOrdinal, providers); } @@ -46,7 +57,9 @@ public class LanguageCyclingItem { private ItemProvider generateItem(Locale locale, List locales) { final ItemBuilder builder = new ItemBuilder(Material.OAK_SIGN); - builder.setDisplayName("Language"); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Settings.LANGUAGE); + + builder.setDisplayName(translation.getName()); for (Locale value : locales) { if (locale != value) { builder.addLoreLines("§7> " + value.getName()); @@ -54,15 +67,15 @@ public class LanguageCyclingItem { builder.addLoreLines("§6§l> §f" + value.getName()); } } - builder.addLoreLines("§7§oCycle through the values by", "§7§oleft and right clicking."); + translation.getLore().forEach(builder::addLoreLines); return builder; } private ItemProvider[] getItems() { final NickoBukkit instance = NickoBukkit.getInstance(); final ArrayList items = new ArrayList<>(); - final ArrayList localesToGenerate = new ArrayList<>(); + Collections.addAll(localesToGenerate, Locale.values()); if (!instance.getNickoConfig().isCustomLocale()) { localesToGenerate.remove(Locale.CUSTOM); diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java index 466af0a..0087468 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java @@ -3,50 +3,96 @@ package xyz.atnrch.nicko.i18n; import com.github.jsixface.YamlConfig; import org.bukkit.entity.Player; import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.appearance.AppearanceManager; +import xyz.atnrch.nicko.profile.NickoProfile; import java.io.InputStream; import java.text.MessageFormat; import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.Iterator; +import java.util.Optional; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class I18N { private final MessageFormat formatter = new MessageFormat(""); + private final Logger logger = Logger.getLogger("I18N"); private final NickoBukkit instance = NickoBukkit.getInstance(); + private final Pattern replacementPattern = Pattern.compile("\\{\\d+}$", Pattern.DOTALL); + private final YamlConfig yamlConfig; private final Player player; private final Locale playerLocale; public I18N(Player player) { this.player = player; this.playerLocale = getPlayerLocale(); + this.yamlConfig = getYamlConfig(); } public I18N(Locale locale) { this.player = null; this.playerLocale = locale; + this.yamlConfig = getYamlConfig(); } - public List translateItem(String key, Object... arguments) { - final ArrayList lines = new ArrayList<>(); - final String itemNameKey = readString(key + ".name"); - final ArrayList itemLoreKey = readList(key + ".lore"); - try { - // Item Name - formatter.applyPattern(itemNameKey); - final String itemNameTranslated = formatter.format(arguments); - lines.add(itemNameTranslated); - return lines; - } catch (Exception e) { - return Collections.singletonList(key); + public ItemTranslation translateItem(String key, Object... args) { + final String nameKey = key + ".name"; + final String loreKey = key + ".lore"; + final String name = readString(nameKey); + final ArrayList lore = readList(loreKey); + + if (name == null) { + logger.warning(nameKey + " doesn't exists! Please translate this entry."); + return new ItemTranslation(nameKey, new ArrayList() {{ + add(loreKey); + }}); } + + // Add all elements to a list + final ArrayList toTranslate = new ArrayList<>(); + toTranslate.add(name); + if (lore != null && !lore.isEmpty()) { + toTranslate.addAll(lore); + } + + // Set starting index to 0 + int lineIndex = 0; + int replacementIndex = 0; + + // While iterator next value exists/isn't null + final Iterator iterator = toTranslate.iterator(); + while (iterator.hasNext() && iterator.next() != null) { + // Get the current line + final String currentLine = toTranslate.get(lineIndex); + + // If the line doesn't contain {i}, skip it + final Matcher matcher = replacementPattern.matcher(currentLine); + if (!matcher.find()) { + lineIndex++; + continue; + } + + // If it does, replace the content with the args at position replacementIndex + if (replacementIndex < args.length && args[replacementIndex] != null) { + // Replace with the corresponding varargs index + toTranslate.set(lineIndex, currentLine.replace("{" + replacementIndex + "}", args[replacementIndex].toString())); + replacementIndex++; + } + + // Increment the index + lineIndex++; + } + + if (lore == null || lore.isEmpty()) { + return new ItemTranslation(toTranslate.get(0), new ArrayList<>()); + } + return new ItemTranslation(toTranslate.get(0), new ArrayList<>(toTranslate.subList(1, toTranslate.size()))); } public String translate(String key, Object... arguments) { - final String string = readString(key); - + final String translation = readString(key); try { - formatter.applyPattern(string); + formatter.applyPattern(translation); return instance.getNickoConfig().getPrefix() + formatter.format(arguments); } catch (Exception e) { return instance.getNickoConfig().getPrefix() + key; @@ -64,43 +110,27 @@ public class I18N { } private String readString(String key) { - YamlConfig yamlFile; - if (playerLocale == Locale.CUSTOM) { - yamlFile = instance.getLocaleFileManager().getYamlFile(); - } else { - final InputStream resource = instance.getResource(playerLocale.getCode() + ".yml"); - yamlFile = YamlConfig.load(resource); - } - return yamlFile.getString(key); + return yamlConfig.getString(key); } private ArrayList readList(String key) { - final ArrayList lines = new ArrayList<>(); - YamlConfig yamlFile; - if (playerLocale == Locale.CUSTOM) { - yamlFile = instance.getLocaleFileManager().getYamlFile(); - } else { - final InputStream resource = instance.getResource(playerLocale.getCode() + ".yml"); - yamlFile = YamlConfig.load(resource); - } - - // 9 is a magic number - for (int i = 0; i < yamlFile.getInt(key + ".length"); i++) { - final String line = yamlFile.getString(key + ".content[" + i + "]"); - System.out.println("line = " + line); - if (line != null && !line.equals("{" + i + "}")) { - lines.add(line); - } - } - return lines; + return yamlConfig.getStringList(key); } - private Locale getPlayerLocale() { - try { - final AppearanceManager appearanceManager = AppearanceManager.get(player); - return !appearanceManager.hasData() ? Locale.FALLBACK_LOCALE : appearanceManager.getLocale(); - } catch (IllegalArgumentException exception) { - instance.getLogger().severe("Invalid locale provided by " + player.getName() + ", defaulting to " + Locale.FALLBACK_LOCALE.getCode() + "."); + private YamlConfig getYamlConfig() { + if (playerLocale == Locale.CUSTOM) { + return instance.getLocaleFileManager().getYamlFile(); + } else { + final InputStream resource = instance.getResource(playerLocale.getCode() + ".yml"); + return new YamlConfig(resource); + } + } + + public Locale getPlayerLocale() { + final Optional optionalProfile = NickoProfile.get(player); + if (optionalProfile.isPresent()) { + return optionalProfile.get().getLocale(); + } else { return Locale.FALLBACK_LOCALE; } } diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index cc4317e..f60b0ad 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -2,14 +2,17 @@ package xyz.atnrch.nicko.i18n; public class I18NDict { public static class Error { - public static final String GENERIC = "error.generic"; - public static final String PERMISSION = "error.permission"; - public static final String CACHE = "error.cache"; - public static final String MOJANG_NAME = "error.mojang_name"; - public static final String MOJANG_SKIN = "error.mojang_skin"; - public static final String INVALID_USERNAME = "error.invalid_username"; - public static final String SQL_ERROR = "error.sql"; - public static final String JSON_ERROR = "error.json"; + public static final String ERROR_KEY = "error."; + + public static final String GENERIC = ERROR_KEY + "generic"; + public static final String PERMISSION = ERROR_KEY + "permission"; + public static final String CACHE = ERROR_KEY + "cache"; + public static final String MOJANG_NAME = ERROR_KEY + "mojang_name"; + public static final String MOJANG_SKIN = ERROR_KEY + "mojang_skin"; + @Deprecated + public static final String INVALID_USERNAME = ERROR_KEY + "invalid_username"; + public static final String SQL_ERROR = ERROR_KEY + "sql"; + public static final String JSON_ERROR = ERROR_KEY + "json"; } public static class Event { @@ -64,11 +67,63 @@ public class I18NDict { private static final String GUI_KEY = "gui."; public static final String EXIT = GUI_KEY + "exit"; + public static final String GO_BACK = GUI_KEY + "go_back"; + public static final String UNAVAILABLE = GUI_KEY + "unavailable"; + public static final String LOADING = GUI_KEY + "loading"; + public static final String SCROLL_UP = GUI_KEY + "scroll_up"; + public static final String SCROLL_DOWN = GUI_KEY + "scroll_down"; + + public static class Titles { + public static final String TITLE_KEY = GUI_KEY + "title."; + + public static final String HOME = TITLE_KEY + "home"; + public static final String SETTINGS = TITLE_KEY + "settings"; + public static final String ADMIN = TITLE_KEY + "admin"; + public static final String CHECK = TITLE_KEY + "check"; + public static final String CACHE = TITLE_KEY + "cache"; + public static final String INVALIDATE_SKIN = TITLE_KEY + "invalidate_skin"; + } + + public static class Choice { + private static final String CHOICE_KEY = GUI_KEY + "choice."; + + public static final String CONFIRM = CHOICE_KEY + "confirm"; + public static final String CHOOSE = CHOICE_KEY + "choose"; + public static final String CANCEL = CHOICE_KEY + "cancel"; + } public static class Home { private static final String HOME_KEY = GUI_KEY + "home."; public static final String ADMIN = HOME_KEY + "admin"; + public static final String CHANGE_NAME = HOME_KEY + "change_name"; + public static final String CHANGE_SKIN = HOME_KEY + "change_skin"; + public static final String CHANGE_BOTH = HOME_KEY + "change_both"; + public static final String RESET = HOME_KEY + "reset"; + public static final String SETTINGS = HOME_KEY + "settings"; + } + + public static class Settings { + private static final String SETTINGS_KEY = GUI_KEY + "settings."; + + public static final String LANGUAGE = SETTINGS_KEY + "language"; + public static final String BUNGEECORD = SETTINGS_KEY + "bungeecord"; + } + + public static class Admin { + private static final String ADMIN_KEY = GUI_KEY + "admin."; + + public static final String MANAGE_CACHE = ADMIN_KEY + "manage_cache"; + public static final String MANAGE_PLAYER = ADMIN_KEY + "manage_player"; + public static final String CHECK = ADMIN_KEY + "check"; + + public static class Cache { + private static final String CACHE_KEY = ADMIN_KEY + "cache."; + + public static final String STATISTICS = CACHE_KEY + "statistics"; + public static final String INVALIDATE_CACHE = CACHE_KEY + "invalidate_cache"; + public static final String INVALIDATE_SKIN = CACHE_KEY + "invalidate_skin"; + } } } } diff --git a/src/main/java/xyz/atnrch/nicko/i18n/ItemTranslation.java b/src/main/java/xyz/atnrch/nicko/i18n/ItemTranslation.java new file mode 100644 index 0000000..035724e --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/i18n/ItemTranslation.java @@ -0,0 +1,21 @@ +package xyz.atnrch.nicko.i18n; + +import java.util.ArrayList; + +public class ItemTranslation { + private final String name; + private final ArrayList lore; + + public ItemTranslation(String name, ArrayList lore) { + this.name = name; + this.lore = lore; + } + + public String getName() { + return name; + } + + public ArrayList getLore() { + return lore; + } +} diff --git a/src/main/java/xyz/atnrch/nicko/i18n/LocaleFileManager.java b/src/main/java/xyz/atnrch/nicko/i18n/LocaleFileManager.java index f2ffba8..4ffb155 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/LocaleFileManager.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/LocaleFileManager.java @@ -15,7 +15,7 @@ public class LocaleFileManager { public String getString(String key) { if (!file.exists()) return key; try (BufferedInputStream inputStream = new BufferedInputStream(Files.newInputStream(file.toPath()))) { - final YamlConfig yamlConfig = YamlConfig.load(inputStream); + final YamlConfig yamlConfig = new YamlConfig(inputStream); return yamlConfig.getString(key); } catch (IOException e) { return key; @@ -44,7 +44,7 @@ public class LocaleFileManager { public YamlConfig getYamlFile() { if (yamlFile == null) { try (BufferedInputStream inputStream = new BufferedInputStream(Files.newInputStream(file.toPath()))) { - yamlFile = YamlConfig.load(inputStream); + yamlFile = new YamlConfig(inputStream); } catch (IOException ignored) { return null; } diff --git a/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java b/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java index 770de6e..1754509 100644 --- a/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java +++ b/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java @@ -51,20 +51,30 @@ public class NickoExpansion extends PlaceholderExpansion { final Optional optionalProfile = instance.getDataStore().getData(player.getUniqueId()); if (optionalProfile.isPresent()) { final NickoProfile profile = optionalProfile.get(); - if (!profile.isEmpty()) { - name = profile.getName(); - skin = profile.getSkin(); + if (profile.hasData()) { + if (profile.getName() != null) { + name = profile.getName(); + } + + if (profile.getSkin() != null) { + skin = profile.getSkin(); + } } locale = profile.getLocale().getName(); bungeecord = profile.isBungeecordTransfer(); } switch (params) { - case "name": return name; - case "skin": return skin; - case "locale": return locale; - case "bungeecord": return String.valueOf(bungeecord); - default: return null; + case "name": + return name; + case "skin": + return skin; + case "locale": + return locale; + case "bungeecord": + return String.valueOf(bungeecord); + default: + return null; } } } diff --git a/src/main/java/xyz/atnrch/nicko/profile/AppearanceData.java b/src/main/java/xyz/atnrch/nicko/profile/AppearanceData.java new file mode 100644 index 0000000..362e576 --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/profile/AppearanceData.java @@ -0,0 +1,31 @@ +package xyz.atnrch.nicko.profile; + +public class AppearanceData { + private String name; + private String skin; + + public AppearanceData(String name, String skin) { + this.name = name; + this.skin = skin; + } + + public boolean isEmpty() { + return name == null && skin == null; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSkin() { + return skin; + } + + public void setSkin(String skin) { + this.skin = skin; + } +} diff --git a/src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java b/src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java index eabad4f..05a544b 100644 --- a/src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java +++ b/src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java @@ -1,10 +1,20 @@ package xyz.atnrch.nicko.profile; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.i18n.Locale; +import xyz.atnrch.nicko.storage.PlayerDataStore; + +import java.util.Optional; +import java.util.UUID; public class NickoProfile implements Cloneable { + public static final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore(); public static final NickoProfile EMPTY_PROFILE = new NickoProfile(null, null, Locale.ENGLISH, true); + private transient final Player player; + private String name; private String skin; private Locale locale; @@ -15,10 +25,35 @@ public class NickoProfile implements Cloneable { this.skin = skin; this.locale = locale; this.bungeecordTransfer = bungeecordTransfer; + this.player = null; } - public boolean isEmpty() { - return name == null && skin == null; + public NickoProfile(Player player, String name, String skin, Locale locale, boolean bungeecordTransfer) { + this.player = player; + this.name = name; + this.skin = skin; + this.locale = locale; + this.bungeecordTransfer = bungeecordTransfer; + } + + public NickoProfile(UUID uuid, String name, String skin, Locale locale, boolean bungeecordTransfer) { + this.name = name; + this.skin = skin; + this.locale = locale; + this.bungeecordTransfer = bungeecordTransfer; + this.player = Bukkit.getPlayer(uuid); + } + + public static Optional get(Player player) { + return dataStore.getData(player.getUniqueId()); + } + + public static Optional get(UUID uuid) { + return dataStore.getData(uuid); + } + + public boolean hasData() { + return name != null || skin != null; } public String getName() { @@ -37,9 +72,13 @@ public class NickoProfile implements Cloneable { this.skin = skin; } - public Locale getLocale() { return locale; } + public Locale getLocale() { + return locale; + } - public void setLocale(Locale locale) { this.locale = locale; } + public void setLocale(Locale locale) { + this.locale = locale; + } public boolean isBungeecordTransfer() { return bungeecordTransfer; @@ -52,11 +91,11 @@ public class NickoProfile implements Cloneable { @Override public String toString() { return "NickoProfile{" + - "name='" + name + '\'' + - ", skin='" + skin + '\'' + - ", locale=" + locale + - ", bungeecordTransfer=" + bungeecordTransfer + - '}'; + "name='" + name + '\'' + + ", skin='" + skin + '\'' + + ", locale=" + locale + + ", bungeecordTransfer=" + bungeecordTransfer + + '}'; } @Override diff --git a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java index 1b6c0ce..0412913 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java +++ b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java @@ -76,12 +76,12 @@ public class PlayerDataStore { if (storage.isError()) return ActionResult.error(I18NDict.Error.GENERIC); if (cache.isError()) return ActionResult.error(I18NDict.Error.CACHE); if (!cache.isCached(player.getUniqueId())) return ActionResult.error(I18NDict.Error.GENERIC); - if (!cache.retrieve(player.getUniqueId()).isPresent()) - return ActionResult.error(I18NDict.Error.GENERIC); - // TODO (Ineanto, 5/20/23): Remove value from cache - //profiles.remove(player.getUniqueId()); - return storage.store(player.getUniqueId(), cache.retrieve(player.getUniqueId()).get()); + final Optional cachedProfile = cache.retrieve(player.getUniqueId()); + if (!cachedProfile.isPresent()) return ActionResult.error(I18NDict.Error.GENERIC); + + cache.delete(player.getUniqueId()); + return storage.store(player.getUniqueId(), cachedProfile.get()); } public Storage getStorage() { diff --git a/src/main/java/xyz/atnrch/nicko/storage/map/MapCacheProvider.java b/src/main/java/xyz/atnrch/nicko/storage/map/MapCacheProvider.java index ba57607..3a83100 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/map/MapCacheProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/map/MapCacheProvider.java @@ -19,7 +19,6 @@ public class MapCacheProvider implements CacheProvider { @Override public boolean close() { - profiles = null; return true; } diff --git a/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java b/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java index a8d532c..d6ad5e4 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java @@ -50,6 +50,7 @@ public class RedisCache extends Cache { @Override public Optional retrieve(UUID uuid) { try (Jedis jedis = provider.getJedis()) { + // 29/08/23: what the fuck was I talking about? // TODO (Ineanto, 5/20/23): Check if cached before because Jedis returns a bulk reply so this is unsafe final String data = jedis.get("nicko:" + uuid.toString()); final NickoProfile profile = gson.fromJson(data, NickoProfile.class); diff --git a/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCacheProvider.java b/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCacheProvider.java index c655cfb..f4d5afe 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCacheProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCacheProvider.java @@ -1,5 +1,6 @@ package xyz.atnrch.nicko.storage.redis; +import redis.clients.jedis.exceptions.JedisConnectionException; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.DataSourceConfiguration; import xyz.atnrch.nicko.storage.CacheProvider; @@ -18,7 +19,11 @@ public class RedisCacheProvider implements CacheProvider { public boolean init() { final DataSourceConfiguration redisConfiguration = configuration.getRedisConfiguration(); pool = new JedisPool(redisConfiguration.getAddress(), redisConfiguration.getPort()); - return !pool.isClosed() && pool.getResource() != null; + try { + return !pool.isClosed() && pool.getResource() != null; + } catch (JedisConnectionException exception) { + return false; + } } @Override diff --git a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java index 903328d..2c3a159 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java @@ -91,9 +91,6 @@ public class SQLStorage extends Storage { locale = resultSet.getString("locale"); bungeecord = resultSet.getBoolean("bungeecord"); } - System.out.println("name = " + name); - System.out.println("skin = " + skin); - System.out.println("locale = " + locale); final NickoProfile profile = new NickoProfile(name, skin, Locale.fromCode(locale), bungeecord); return Optional.of(profile); diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java index 38f0a84..2106bd0 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java @@ -40,7 +40,7 @@ public class WrapperPlayServerRespawn extends AbstractPacket { public void setDimension(World value) { if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { - // 1.19 to 1.19.4 + // 1.19 to 1.20.1 // Thank you lukalt! final InternalStructure dimensionType = handle.getStructures().read(0); dimensionType.getMinecraftKeys().write(0, new MinecraftKey("minecraft", "dimension_type")); diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 7087dd6..e896a3b 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -25,4 +25,102 @@ event: admin: cache: invalidate_cache: "§fComplete cache invalidated." - invalidate_entry: "§6{0} §fhas been invalidated." \ No newline at end of file + invalidate_entry: "§6{0} §fhas been invalidated." + +gui: + title: + home: "Nicko - Home" + settings: "Nicko > Settings" + admin: "Nicko > Administration" + check: "Nicko > Admin... > Check" + cache: "Nicko > Admin... > Cache" + invalidate_skin: "... > Cache > Invalidate" + + exit: + name: "Exit" + go_back: + name: "Back" + unavailable: + name: "Unavailable" + lore: + - "§7§oThis button is disabled." + loading: + name: "§7§oLoading..." + choice: + confirm: + name: "§aConfirm" + choose: + name: "§6§oChoose an option..." + cancel: + name: "§cCancel" + scroll_up: + name: "Scroll up" + lore: + - "§8§o(You can't scroll any higher.)" + scroll_down: + name: "Scroll down" + lore: + - "§8§o(You can't scroll any further down.)" + home: + admin: + name: "Administration panel" + lore: + - "§7Configure and manage Nicko." + settings: + name: "Settings" + lore: + - "§7Fine tune your experience with Nicko." + change_name: + name: "§6Nickname §fchange" + change_skin: + name: "§6Skin §fchange" + change_both: + name: "Change §6both" + reset: + name: "Reset appearance" + lore: + - "§7Completely remove your disguise." + admin: + manage_cache: + name: "Manage §6skin §fcache..." + lore: + - "§7View and manage the skin cache." + manage_player: + name: "Check a player..." + lore: + - "§7See players' disguise information." + check: + name: "{0}" + lore: + - "§cNicked: §a{1}" + - "§cName: §6{2}" + - "§cSkin: §6{3}" + cache: + statistics: + name: "Statistics" + lore: + - "§fRequest count: §b{0}" + - "§fNumber of skin cached: §b{1}" + - "§8§oCache is cleared every 24 hours." + invalidate_cache: + name: "Invalidate cache" + lore: + - "§c§oNOT RECOMMENDED" + - "§7Invalidate the entirety of the skin cache." + - "§7This doesn't reset player's disguises." + invalidate_skin: + name: "Invalidate a skin..." + lore: + - "§7Select a specific skin to invalidate." + - "§7Useful if a skin has been recently updated." + settings: + language: + name: "Language" + lore: + - "§7§oGet through the values" + - "§7§oby left or right clicking." + bungeecord: + name: "Bungeecord Transfer" + lore: + - "§7§oGet through the values" + - "§7§oby left or right clicking." \ No newline at end of file diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index ff0bc85..a5a070c 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -1,7 +1,7 @@ error: generic: "Une erreur inconnue c'est produite." permission: "§cVous ne possédez pas la permission." - invalid_username: "§cLe pseudo n''est pas un pseudo Minecraft valide." + invalid_username: "§cLe pseudo n'est pas un pseudo Minecraft valide." mojang_name: "Un compte Minecraft avec ce nom n'existe pas." mojang_skin: "Ce compte Minecraft n'a pas de skin." cache: "Impossible de récupérer le skin depuis le cache." @@ -9,6 +9,8 @@ error: json: "Erreur JSON" event: + settings: + error: "§cImpossible de mettre à jour vos paramètres. §7§o({0})" appearance: set: error: "§cImpossible d''appliquer votre déguisement. §7§o({0})" @@ -26,20 +28,48 @@ event: invalidate_entry: "§6{0} §fa été invalidé." gui: - exit: "Quitter" + title: + home: "Nicko - Accueil" + settings: "Nicko > Paramètres" + admin: "Nicko > Administration" + check: "Nicko > Admin... > Vérification" + cache: "Nicko > Admin... > Cache" + invalidate_skin: "... > Cache > Invalider" + + exit: + name: "Quitter" + go_back: + name: "Retour" + unavailable: + name: "Indisponible" + lore: + - "§7§oCe boutton est désactivé." + loading: + name: "§7§oChargement..." + choice: + confirm: + name: "§aConfirmer" + choose: + name: "§6§oChoisissez une option..." + cancel: + name: "§cAnnuler" + scroll_up: + name: "Défiler vers le haut" + lore: + - "§8§o(Impossible de défiler plus haut.)" + scroll_down: + name: "Défiler vers le bas" + lore: + - "§8§o(Impossible de défiler plus bas.)" home: admin: - name: "Panel d''administration" + name: "Panel d'administration" lore: - length: 1 - content: - - "Configurez et gérez Nicko." + - "§7Configurez et gérez Nicko." settings: name: "Paramètres" lore: - length: 1 - content: - "Configurez votre expérience." + - "§7Gérez votre expérience avec Nicko." change_name: name: "Changer le §6pseudo" change_skin: @@ -49,12 +79,50 @@ gui: reset: name: "Réinitialiser l'apparence" lore: - - "Supprime complètement votre déguisement." + - "§7Supprime complètement votre déguisement." + admin: + manage_cache: + name: "Gérer le cache de §6skin..." + lore: + - "§7Consultez et gérez le cache de skin." + manage_player: + name: "Vérifier un joueur..." + lore: + - "§7Vérifiez les informations de déguisement d'un joueur." + check: + name: "{0}" + lore: + - "§cDéguisé: §a{1}" + - "§cNom: §6{2}" + - "§cSkin: §6{3}" + cache: + statistics: + name: "Statistiques" + lore: + - "§fNombre de requêtes: §b{0}" + - "§fNb. de skin dans le cache: §b{1}" + - "§8§oLe cache est vidé toutes les 24 heures." + invalidate_cache: + name: "Invalider le cache" + lore: + - "§c§oDÉCONSEILLÉ" + - "§7Invalide l'entièreté du cache des skin." + - "§7Ne retire pas les déguisements" + - "§7pour les joueurs en disposant." + invalidate_skin: + name: "Invalider un skin..." + lore: + - "§7Sélectionnez une apparence spécifique à" + - "§7invalider. Utile dans le cas où un skin" + - "§7a récemment été mis à jour." settings: language: - name: "Language" + name: "Langage" + lore: + - "§7§oParcourez les valeurs" + - "§7§oavec un clique gauche/droit." + bungeecord: + name: "Transfert Bungeecord" lore: - # The language values will be filled at {0} - - "{0}" - "§7§oParcourez les valeurs" - "§7§oavec un clique gauche/droit." \ No newline at end of file diff --git a/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java b/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java new file mode 100644 index 0000000..a1b6e55 --- /dev/null +++ b/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java @@ -0,0 +1,57 @@ +package xyz.atnrch.nicko.test.i18n; + +import be.seeseemelk.mockbukkit.MockBukkit; +import be.seeseemelk.mockbukkit.entity.PlayerMock; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.config.Configuration; +import xyz.atnrch.nicko.config.DataSourceConfiguration; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.ItemTranslation; +import xyz.atnrch.nicko.i18n.Locale; + +import static org.junit.jupiter.api.Assertions.*; + +public class ItemTranslationTest { + private static PlayerMock player; + + @BeforeAll + public static void setup() { + final Configuration config = new Configuration( + DataSourceConfiguration.SQL_EMPTY, + DataSourceConfiguration.REDIS_EMPTY, + "", + false); + MockBukkit.mock(); + MockBukkit.load(NickoBukkit.class, config); + } + + @Test + @DisplayName("Translate Item Without Lore") + public void translateItemTranslationWithoutLore() { + final I18N i18n = new I18N(Locale.FRENCH); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.GO_BACK); + assertTrue(translation.getLore().isEmpty()); + assertEquals(translation.getName(), "Retour"); + } + + @Test + @DisplayName("Translate Item") + public void translateItemLore() { + final I18N i18n = new I18N(Locale.FRENCH); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.Cache.STATISTICS, "1", "1"); + assertFalse(translation.getLore().isEmpty()); + assertEquals("§fNombre de requêtes: §b1", translation.getLore().get(0)); + assertEquals("§fNb. de skin dans le cache: §b1", translation.getLore().get(1)); + assertEquals("§8§oLe cache est vidé toutes les 24 heures.", translation.getLore().get(2)); + } + + @AfterAll + public static void shutdown() { + MockBukkit.unmock(); + } +} diff --git a/src/test/java/xyz/atnrch/nicko/test/i18n/I18NLoreTest.java b/src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java similarity index 67% rename from src/test/java/xyz/atnrch/nicko/test/i18n/I18NLoreTest.java rename to src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java index 2c17db5..6e16840 100644 --- a/src/test/java/xyz/atnrch/nicko/test/i18n/I18NLoreTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java @@ -1,7 +1,6 @@ package xyz.atnrch.nicko.test.i18n; import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; import be.seeseemelk.mockbukkit.entity.PlayerMock; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -14,10 +13,9 @@ import xyz.atnrch.nicko.i18n.I18N; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.i18n.Locale; -import java.util.List; +import static org.junit.jupiter.api.Assertions.assertEquals; -public class I18NLoreTest { - private static NickoBukkit plugin; +public class TranslationTest { private static PlayerMock player; @BeforeAll @@ -27,16 +25,16 @@ public class I18NLoreTest { DataSourceConfiguration.REDIS_EMPTY, "", false); - final ServerMock server = MockBukkit.mock(); - plugin = MockBukkit.load(NickoBukkit.class, config); + MockBukkit.mock(); + MockBukkit.load(NickoBukkit.class, config); } @Test - @DisplayName("Translate Item Lore") - public void translateItemLore() { + @DisplayName("Translate Line With Replacement") + public void translateItemTranslationWithoutLore() { final I18N i18n = new I18N(Locale.FRENCH); - List strings = i18n.translateItem(I18NDict.GUI.Home.ADMIN); - System.out.println("strings = " + strings); + final String translation = i18n.translatePrefixless(I18NDict.Event.Settings.ERROR, "Test"); + assertEquals("§cImpossible de mettre à jour vos paramètres. §7§o(Test)", translation); } @AfterAll diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java index 04585a3..c6020bc 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java @@ -46,7 +46,7 @@ public class SQLStorageTest { @DisplayName("Store empty profile") @Order(2) public void storeEmptyProfile() { - final Optional optionalProfile = dataStore.getData(uuid); + final Optional optionalProfile = NickoProfile.get(uuid); assertTrue(optionalProfile.isPresent()); } @@ -54,7 +54,9 @@ public class SQLStorageTest { @DisplayName("Update profile") @Order(3) public void updateProfile() { - final Optional optionalProfile = dataStore.getData(uuid); + final Optional optionalProfile = NickoProfile.get(uuid); + assertTrue(optionalProfile.isPresent()); + final NickoProfile profile = optionalProfile.get(); assertNull(profile.getName()); assertNull(profile.getSkin()); @@ -74,10 +76,10 @@ public class SQLStorageTest { @DisplayName("Get updated profile") @Order(4) public void hasProfileBeenUpdated() { - final Optional profile = dataStore.getData(uuid); - assertTrue(profile.isPresent()); + final Optional optionalProfile = NickoProfile.get(uuid); + assertTrue(optionalProfile.isPresent()); - final NickoProfile updatedProfile = profile.get(); + final NickoProfile updatedProfile = optionalProfile.get(); assertEquals(updatedProfile.getName(), "Notch"); assertEquals(updatedProfile.getSkin(), "Notch"); assertEquals(updatedProfile.getLocale(), Locale.FRENCH); diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/redis/RedisCacheTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/redis/RedisCacheTest.java index beea0b6..e3bb4de 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/redis/RedisCacheTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/redis/RedisCacheTest.java @@ -6,7 +6,6 @@ import be.seeseemelk.mockbukkit.entity.PlayerMock; import org.junit.jupiter.api.*; import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.appearance.AppearanceManager; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.DataSourceConfiguration; import xyz.atnrch.nicko.profile.NickoProfile; @@ -46,10 +45,14 @@ public class RedisCacheTest { @DisplayName("Update Cache Profile") @Order(2) public void updateCache() { + final Optional optionalProfile = NickoProfile.get(player); + assertTrue(optionalProfile.isPresent()); + + final NickoProfile profile = optionalProfile.get(); final PlayerDataStore dataStore = plugin.getDataStore(); - final AppearanceManager appearanceManager = AppearanceManager.get(player); - appearanceManager.setName("Notch"); - dataStore.updateCache(player.getUniqueId(), appearanceManager.getProfile()); + profile.setName("Notch"); + dataStore.updateCache(player.getUniqueId(), profile); + final Optional retrieve = dataStore.getCache().retrieve(player.getUniqueId()); assertTrue(retrieve.isPresent()); final NickoProfile retrieved = retrieve.get();