diff --git a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java index aa65338..5675560 100644 --- a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java @@ -11,20 +11,28 @@ 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.AppearanceData; +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 AppearanceData appearanceData; + 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 = optionalProfile.map(NickoProfile::getAppearanceManager).orElse(null); + this.appearanceData = optionalProfile.map(NickoProfile::getAppearanceData).orElse(null); } public void openNameThenSkinAnvil() { @@ -49,8 +57,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()); + appearanceData.setName(snapshot.getText()); + dataStore.updateCache(player.getUniqueId(), profile); openSkinAnvil(); return Collections.singletonList(AnvilGUI.ResponseAction.close()); } @@ -70,8 +78,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()); + appearanceData.setName(snapshot.getText()); + dataStore.updateCache(player.getUniqueId(), profile); final ActionResult actionResult = appearanceManager.updatePlayer(false, false); return sendResultAndClose(actionResult); } @@ -91,8 +99,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()); + appearanceData.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..efab3c3 100644 --- a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java @@ -11,9 +11,9 @@ 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.AppearanceData; import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.PlayerDataStore; import xyz.atnrch.nicko.storage.name.PlayerNameStore; @@ -26,93 +26,45 @@ 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 NickoProfile profile; + private final AppearanceData appearanceData; + private final Player player; + private final UUID uuid; - private AppearanceManager(String name) { - this.player = null; - this.uuid = null; - this.profile = dataStore.getOfflineData(name).orElse(NickoProfile.EMPTY_PROFILE.clone()); - } + public AppearanceManager(Player player) { + this.uuid = player.getUniqueId(); + this.player = player; - 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); + final Optional optionalProfile = dataStore.getData(player.getUniqueId()); + if (!optionalProfile.isPresent()) { + this.profile = NickoProfile.EMPTY_PROFILE.clone(); + this.appearanceData = profile.getAppearanceData(); + instance.getLogger().warning("Unable to appearance data for: " + player.getUniqueId() + "."); + } else { + this.profile = optionalProfile.get(); + this.appearanceData = profile.getAppearanceData(); + } } public ActionResult reset() { final String defaultName = nameStore.getStoredName(player); - this.profile.setName(defaultName); - this.profile.setSkin(defaultName); + appearanceData.setName(defaultName); + appearanceData.setSkin(defaultName); final ActionResult actionResult = updatePlayer(true, true); if (!actionResult.isError()) { - this.profile.setSkin(null); - this.profile.setName(null); + appearanceData.setSkin(null); + appearanceData.setName(null); dataStore.getCache().cache(uuid, profile); } return actionResult; } public ActionResult updatePlayer(boolean skinChange, boolean reset) { - final String displayName = profile.getName() == null ? player.getName() : profile.getName(); + final String displayName = appearanceData.getName() == null ? player.getName() : appearanceData.getName(); final WrappedGameProfile gameProfile = WrappedGameProfile.fromPlayer(player).withName(displayName); final ActionResult result = updateGameProfileSkin(gameProfile, skinChange, reset); if (!result.isError()) { @@ -139,15 +91,15 @@ public class AppearanceManager { private ActionResult updateGameProfileSkin(WrappedGameProfile gameProfile, boolean skinChange, boolean reset) { - final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); + final boolean changeOnlyName = appearanceData.getSkin() != null && !appearanceData.getSkin().equalsIgnoreCase(player.getName()); 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(appearanceData.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(); @@ -187,7 +139,7 @@ public class AppearanceManager { respawn.sendPacket(player); player.setFlying(wasFlying); player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.updateInventory(); + player.updateInventory(); // Marked as unstable. } @SuppressWarnings("deprecation") diff --git a/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java b/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java index d8429c2..b6cc62b 100644 --- a/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java +++ b/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java @@ -1,8 +1,7 @@ package xyz.atnrch.nicko.command; +import org.jetbrains.annotations.NotNull; 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; @@ -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); 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 50% 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..224f360 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,27 @@ -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.AppearanceData; +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 +32,7 @@ public class NickoDebugSubCmd { return; } - final String playerName = args[1]; + playerName = args[1]; name = args[2]; skin = args[3]; @@ -47,15 +53,25 @@ 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(); + final AppearanceData appearanceData = profile.getAppearanceData(); + final AppearanceManager appearanceManager = profile.getAppearanceManager(); + appearanceData.setName(name); + appearanceData.setSkin(skin); + dataStore.updateCache(target.getUniqueId(), profile); + 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 7b998c3..4433b8e 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,20 +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.map(NickoProfile::getAppearanceData).ifPresent(appearanceData -> { + final AppearanceManager appearanceManager = new AppearanceManager(player); + if (!appearanceData.isEmpty()) { + final boolean needsASkinChange = appearanceData.getSkin() != null && !appearanceData.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); - System.out.println("i18n.getPlayerLocale().getCode() = " + i18n.getPlayerLocale().getCode()); } } 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..71c2c6f 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,12 +4,15 @@ 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.profile.AppearanceData; +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 java.util.Optional; import java.util.UUID; public class PlayerInformationItem extends AsyncItem { @@ -19,23 +22,28 @@ public class PlayerInformationItem extends AsyncItem { super(new ItemBuilder(Material.PAINTING).setDisplayName("§7§oLoading..."), () -> { 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() - ); - } else { - skull.addLoreLines( - "§cNicked: §c❌", - "§cName: §7N/A", - "§cSkin: §7N/A" - ); - } + optionalProfile.ifPresent(profile -> { + final AppearanceData appearanceData = profile.getAppearanceData(); + if (!appearanceData.isEmpty()) { + skull.addLoreLines( + "§cNicked: §a✔", + "§cName: §6" + appearanceData.getName(), + "§cSkin: §6" + appearanceData.getSkin() + ); + } else { + skull.addLoreLines( + "§cNicked: §c❌", + "§cName: §7N/A", + "§cSkin: §7N/A" + ); + } + + skull.setDisplayName("§6" + player.getName()); + }); - skull.setDisplayName("§6" + player.getName()); return skull; }); } 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..5191867 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,14 +1,17 @@ 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.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.profile.NickoProfile; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicBoolean; + public class ResetItem extends SuppliedItem { public ResetItem() { super(() -> { @@ -22,21 +25,24 @@ public class ResetItem extends SuppliedItem { final ClickType clickType = event.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { - final AppearanceManager appearanceManager = AppearanceManager.get(player); + final Optional optionalProfile = NickoProfile.get(player); + final AtomicBoolean result = new AtomicBoolean(false); + optionalProfile.ifPresent(profile -> { + if (profile.getAppearanceData().isEmpty()) { + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.MISSING)); + event.getEvent().getView().close(); + result.set(true); + } - 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; - } + if (!profile.getAppearanceManager().reset().isError()) { + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.OK)); + result.set(false); + } else { + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.ERROR)); + result.set(true); + } + }); + return result.get(); } return false; }); 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 1c3efc0..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 @@ -8,6 +8,7 @@ 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; @@ -31,12 +32,14 @@ public class BungeeCordCyclingItem { } public AbstractItem get() { - final Optional profile = NickoBukkit.getInstance().getDataStore().getData(player.getUniqueId()); + 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); } 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 f3419cc..5081e7d 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 @@ -1,5 +1,6 @@ package xyz.atnrch.nicko.gui.items.settings; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; @@ -29,6 +30,7 @@ public class LanguageCyclingItem { public LanguageCyclingItem(Player player) { this.player = player; this.i18n = new I18N(player); + Bukkit.broadcastMessage(i18n.getPlayerLocale().getCode()); this.providers = getItems(); } diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java index 4859efe..20db750 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java @@ -3,12 +3,13 @@ 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.Iterator; +import java.util.Optional; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -126,11 +127,10 @@ public class I18N { } public 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() + "."); + 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 00a2248..b3976fe 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 { diff --git a/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java b/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java index 770de6e..9fcd597 100644 --- a/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java +++ b/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java @@ -5,6 +5,7 @@ import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.profile.AppearanceData; import xyz.atnrch.nicko.profile.NickoProfile; import java.util.Optional; @@ -51,20 +52,26 @@ 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(); + final AppearanceData appearanceData = profile.getAppearanceData(); + if (!appearanceData.isEmpty()) { + name = appearanceData.getName(); + skin = appearanceData.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..6685476 100644 --- a/src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java +++ b/src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java @@ -1,45 +1,70 @@ package xyz.atnrch.nicko.profile; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.appearance.AppearanceManager; 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 NickoProfile EMPTY_PROFILE = new NickoProfile(null, null, Locale.ENGLISH, true); + public static final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore(); + public static final NickoProfile EMPTY_PROFILE = new NickoProfile(new AppearanceData(null, null), Locale.ENGLISH, true); - private String name; - private String skin; + private final AppearanceData appearanceData; + private final Player player; private Locale locale; private boolean bungeecordTransfer; - public NickoProfile(String name, String skin, Locale locale, boolean bungeecordTransfer) { - this.name = name; - this.skin = skin; + public NickoProfile(AppearanceData appearanceData, Locale locale, boolean bungeecordTransfer) { + this.appearanceData = appearanceData; + this.locale = locale; + this.bungeecordTransfer = bungeecordTransfer; + this.player = null; + } + + public NickoProfile(Player player, AppearanceData appearanceData, Locale locale, boolean bungeecordTransfer) { + this.player = player; + this.appearanceData = appearanceData; this.locale = locale; this.bungeecordTransfer = bungeecordTransfer; } - public boolean isEmpty() { - return name == null && skin == null; + public NickoProfile(UUID uuid, AppearanceData appearanceData, Locale locale, boolean bungeecordTransfer) { + this.appearanceData = appearanceData; + this.locale = locale; + this.bungeecordTransfer = bungeecordTransfer; + this.player = Bukkit.getPlayer(uuid); } - public String getName() { - return name; + public static Optional get(Player player) { + return dataStore.getData(player.getUniqueId()); } - public void setName(String name) { - this.name = name; + public static Optional get(UUID uuid) { + return dataStore.getData(uuid); } - public String getSkin() { - return skin; + public AppearanceManager getAppearanceManager() { + if (player == null) return null; + return new AppearanceManager(player); } - public void setSkin(String skin) { - this.skin = skin; + public AppearanceData getAppearanceData() { + return appearanceData; } - 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 +77,11 @@ public class NickoProfile implements Cloneable { @Override public String toString() { return "NickoProfile{" + - "name='" + name + '\'' + - ", skin='" + skin + '\'' + - ", locale=" + locale + - ", bungeecordTransfer=" + bungeecordTransfer + - '}'; + "name='" + appearanceData.getName() + '\'' + + ", skin='" + appearanceData.getSkin() + '\'' + + ", locale=" + locale + + ", bungeecordTransfer=" + bungeecordTransfer + + '}'; } @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..f12e879 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java @@ -4,6 +4,7 @@ import xyz.atnrch.nicko.appearance.ActionResult; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.i18n.Locale; +import xyz.atnrch.nicko.profile.AppearanceData; import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.Storage; @@ -95,7 +96,7 @@ public class SQLStorage extends Storage { System.out.println("skin = " + skin); System.out.println("locale = " + locale); - final NickoProfile profile = new NickoProfile(name, skin, Locale.fromCode(locale), bungeecord); + final NickoProfile profile = new NickoProfile(new AppearanceData(name, skin), Locale.fromCode(locale), bungeecord); return Optional.of(profile); } catch (SQLException e) { logger.warning("Couldn't fetch profile: " + e.getMessage()); @@ -123,9 +124,10 @@ public class SQLStorage extends Storage { private PreparedStatement getInsertStatement(Connection connection, UUID uuid, NickoProfile profile) throws SQLException { final String sql = "INSERT IGNORE INTO nicko.DATA (`uuid`, `name`, `skin`, `locale`, `bungeecord`) VALUES (?, ?, ?, ?, ?)"; final PreparedStatement statement = connection.prepareStatement(sql); + final AppearanceData appearanceData = profile.getAppearanceData(); statement.setString(1, uuid.toString()); - statement.setString(2, profile.getName() == null ? null : profile.getName()); - statement.setString(3, profile.getSkin() == null ? null : profile.getSkin()); + statement.setString(2, appearanceData.getName() == null ? null : appearanceData.getName()); + statement.setString(3, appearanceData.getSkin() == null ? null : appearanceData.getSkin()); statement.setString(4, profile.getLocale().getCode()); statement.setBoolean(5, profile.isBungeecordTransfer()); return statement; @@ -134,8 +136,9 @@ public class SQLStorage extends Storage { private PreparedStatement getUpdateStatement(Connection connection, UUID uuid, NickoProfile profile) throws SQLException { final String sql = "UPDATE nicko.DATA SET name = ?, skin = ?, locale = ?, bungeecord = ? WHERE uuid = ?"; final PreparedStatement statement = connection.prepareStatement(sql); - statement.setString(1, profile.getName() == null ? null : profile.getName()); - statement.setString(2, profile.getSkin() == null ? null : profile.getSkin()); + final AppearanceData appearanceData = profile.getAppearanceData(); + statement.setString(1, appearanceData.getName() == null ? null : appearanceData.getName()); + statement.setString(2, appearanceData.getSkin() == null ? null : appearanceData.getSkin()); statement.setString(3, profile.getLocale().getCode()); statement.setBoolean(4, profile.isBungeecordTransfer()); statement.setString(5, uuid.toString()); 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..720ad9d 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java @@ -7,6 +7,7 @@ import xyz.atnrch.nicko.appearance.ActionResult; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.DataSourceConfiguration; import xyz.atnrch.nicko.i18n.Locale; +import xyz.atnrch.nicko.profile.AppearanceData; import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.PlayerDataStore; @@ -46,7 +47,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,15 +55,18 @@ 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()); + final AppearanceData appearanceData = profile.getAppearanceData(); + assertNull(appearanceData.getName()); + assertNull(appearanceData.getSkin()); assertEquals(profile.getLocale(), Locale.ENGLISH); assertTrue(profile.isBungeecordTransfer()); - profile.setName("Notch"); - profile.setSkin("Notch"); + appearanceData.setName("Notch"); + appearanceData.setSkin("Notch"); profile.setLocale(Locale.FRENCH); profile.setBungeecordTransfer(false); @@ -74,12 +78,13 @@ 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(); - assertEquals(updatedProfile.getName(), "Notch"); - assertEquals(updatedProfile.getSkin(), "Notch"); + final NickoProfile updatedProfile = optionalProfile.get(); + final AppearanceData appearanceData = updatedProfile.getAppearanceData(); + assertEquals(appearanceData.getName(), "Notch"); + assertEquals(appearanceData.getSkin(), "Notch"); assertEquals(updatedProfile.getLocale(), Locale.FRENCH); assertFalse(updatedProfile.isBungeecordTransfer()); } 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..183005e 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,9 +6,9 @@ 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.AppearanceData; import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.PlayerDataStore; @@ -46,14 +46,20 @@ 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()); + final AppearanceData appearanceData = profile.getAppearanceData(); + appearanceData.setName("Notch"); + dataStore.updateCache(player.getUniqueId(), profile); + final Optional retrieve = dataStore.getCache().retrieve(player.getUniqueId()); assertTrue(retrieve.isPresent()); final NickoProfile retrieved = retrieve.get(); - assertEquals(retrieved.getName(), "Notch"); + final AppearanceData retrievedAppearanceData = retrieved.getAppearanceData(); + assertEquals(retrievedAppearanceData.getName(), "Notch"); } @Test