From d37a0bd3bafeead5188e2661b58ea96e0ec478c7 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 2 Apr 2023 23:39:44 +0200 Subject: [PATCH 001/296] other: rework config later --- .../main/java/net/artelnatif/nicko/config/Configuration.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/main/java/net/artelnatif/nicko/config/Configuration.java b/core/src/main/java/net/artelnatif/nicko/config/Configuration.java index 3dbd3ec..31016bb 100644 --- a/core/src/main/java/net/artelnatif/nicko/config/Configuration.java +++ b/core/src/main/java/net/artelnatif/nicko/config/Configuration.java @@ -2,6 +2,10 @@ package net.artelnatif.nicko.config; import com.fasterxml.jackson.annotation.JsonProperty; +/** + * TODO: 4/2/23 Convert using Bukkit YAML API + * Link + **/ public class Configuration { @JsonProperty("sql") private final DataSourceConfiguration sqlConfiguration; From 35e2db02e9aa02f6b1d95ce770b2667507e93c20 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 3 Apr 2023 10:56:43 +0200 Subject: [PATCH 002/296] feat: remove NMS dependency --- core/pom.xml | 14 +- .../net/artelnatif/nicko/NickoBukkit.java | 26 ++-- .../nicko/appearance/AppearanceManager.java | 100 ++++++++++++- .../nicko/event/PlayerJoinListener.java | 2 +- .../net/artelnatif/nicko/impl/Internals.java | 38 ----- .../nicko/impl/InternalsProvider.java | 29 ---- .../artelnatif/nicko/mojang/MojangAPI.java | 2 +- core/src/main/resources/plugin.yml | 3 +- pom.xml | 8 +- v1_13_R1/pom.xml | 28 ---- .../net/artelnatif/nicko/impl/v1_13_R1.java | 128 ---------------- v1_13_R2/pom.xml | 28 ---- .../net/artelnatif/nicko/impl/v1_13_R2.java | 128 ---------------- v1_14_R1/pom.xml | 28 ---- .../net/artelnatif/nicko/impl/v1_14_R1.java | 126 ---------------- v1_15_R1/pom.xml | 28 ---- .../net/artelnatif/nicko/impl/v1_15_R1.java | 129 ---------------- v1_16_R1/pom.xml | 28 ---- .../net/artelnatif/nicko/impl/v1_16_R1.java | 132 ----------------- v1_16_R2/pom.xml | 28 ---- .../net/artelnatif/nicko/impl/v1_16_R2.java | 132 ----------------- v1_16_R3/pom.xml | 28 ---- .../net/artelnatif/nicko/impl/v1_16_R3.java | 136 ----------------- v1_17_R1/pom.xml | 28 ---- .../net/artelnatif/nicko/impl/v1_17_R1.java | 101 ------------- v1_18_R1/pom.xml | 29 ---- .../net/artelnatif/nicko/impl/v1_18_R1.java | 103 ------------- v1_18_R2/pom.xml | 29 ---- .../net/artelnatif/nicko/impl/v1_18_R2.java | 103 ------------- v1_19_R1/pom.xml | 29 ---- .../net/artelnatif/nicko/impl/v1_19_R1.java | 107 ------------- v1_19_R2/pom.xml | 68 --------- .../net/artelnatif/nicko/impl/v1_19_R2.java | 132 ----------------- v1_19_R3/pom.xml | 68 --------- .../net/artelnatif/nicko/impl/v1_19_R3.java | 140 ------------------ 35 files changed, 127 insertions(+), 2139 deletions(-) delete mode 100644 core/src/main/java/net/artelnatif/nicko/impl/Internals.java delete mode 100644 core/src/main/java/net/artelnatif/nicko/impl/InternalsProvider.java delete mode 100644 v1_13_R1/pom.xml delete mode 100644 v1_13_R1/src/main/java/net/artelnatif/nicko/impl/v1_13_R1.java delete mode 100644 v1_13_R2/pom.xml delete mode 100644 v1_13_R2/src/main/java/net/artelnatif/nicko/impl/v1_13_R2.java delete mode 100644 v1_14_R1/pom.xml delete mode 100644 v1_14_R1/src/main/java/net/artelnatif/nicko/impl/v1_14_R1.java delete mode 100644 v1_15_R1/pom.xml delete mode 100644 v1_15_R1/src/main/java/net/artelnatif/nicko/impl/v1_15_R1.java delete mode 100644 v1_16_R1/pom.xml delete mode 100644 v1_16_R1/src/main/java/net/artelnatif/nicko/impl/v1_16_R1.java delete mode 100644 v1_16_R2/pom.xml delete mode 100644 v1_16_R2/src/main/java/net/artelnatif/nicko/impl/v1_16_R2.java delete mode 100644 v1_16_R3/pom.xml delete mode 100644 v1_16_R3/src/main/java/net/artelnatif/nicko/impl/v1_16_R3.java delete mode 100644 v1_17_R1/pom.xml delete mode 100644 v1_17_R1/src/main/java/net/artelnatif/nicko/impl/v1_17_R1.java delete mode 100644 v1_18_R1/pom.xml delete mode 100644 v1_18_R1/src/main/java/net/artelnatif/nicko/impl/v1_18_R1.java delete mode 100644 v1_18_R2/pom.xml delete mode 100644 v1_18_R2/src/main/java/net/artelnatif/nicko/impl/v1_18_R2.java delete mode 100644 v1_19_R1/pom.xml delete mode 100644 v1_19_R1/src/main/java/net/artelnatif/nicko/impl/v1_19_R1.java delete mode 100644 v1_19_R2/pom.xml delete mode 100644 v1_19_R2/src/main/java/net/artelnatif/nicko/impl/v1_19_R2.java delete mode 100644 v1_19_R3/pom.xml delete mode 100644 v1_19_R3/src/main/java/net/artelnatif/nicko/impl/v1_19_R3.java diff --git a/core/pom.xml b/core/pom.xml index 6c98136..602d6b4 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -18,6 +18,10 @@ + + dmulloy2-repo + https://repo.dmulloy2.net/repository/public/ + papermc https://repo.papermc.io/repository/maven-public/ @@ -37,6 +41,12 @@ + + com.comphenix.protocol + ProtocolLib + 5.0.0-SNAPSHOT + provided + me.clip @@ -92,12 +102,12 @@ com.fasterxml.jackson.core jackson-core - 2.14.2 + 2.13.3 com.fasterxml.jackson.dataformat jackson-dataformat-yaml - 2.14.2 + 2.13.3 diff --git a/core/src/main/java/net/artelnatif/nicko/NickoBukkit.java b/core/src/main/java/net/artelnatif/nicko/NickoBukkit.java index b5cc0ec..fc8e1bf 100644 --- a/core/src/main/java/net/artelnatif/nicko/NickoBukkit.java +++ b/core/src/main/java/net/artelnatif/nicko/NickoBukkit.java @@ -1,19 +1,16 @@ package net.artelnatif.nicko; -import net.artelnatif.nicko.gui.items.common.OptionUnavailable; -import xyz.xenondevs.invui.gui.structure.Structure; -import xyz.xenondevs.invui.item.builder.ItemBuilder; -import xyz.xenondevs.invui.item.impl.SimpleItem; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.ProtocolManager; import net.artelnatif.nicko.command.NickoCommand; import net.artelnatif.nicko.config.Configuration; import net.artelnatif.nicko.config.ConfigurationManager; import net.artelnatif.nicko.event.PlayerJoinListener; import net.artelnatif.nicko.event.PlayerQuitListener; +import net.artelnatif.nicko.gui.items.common.OptionUnavailable; import net.artelnatif.nicko.gui.items.main.ExitGUI; import net.artelnatif.nicko.i18n.Locale; import net.artelnatif.nicko.i18n.LocaleFileManager; -import net.artelnatif.nicko.impl.Internals; -import net.artelnatif.nicko.impl.InternalsProvider; import net.artelnatif.nicko.mojang.MojangAPI; import net.artelnatif.nicko.placeholder.PlaceHolderHook; import net.artelnatif.nicko.storage.PlayerDataStore; @@ -24,6 +21,9 @@ import org.bukkit.command.PluginCommand; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPluginLoader; +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; @@ -39,6 +39,7 @@ public class NickoBukkit extends JavaPlugin { private Configuration configuration; private LocaleFileManager localeFileManager; private PlayerNameStore nameStore; + private ProtocolManager protocolManager; public NickoBukkit() { this.unitTesting = false; } @@ -65,6 +66,7 @@ public class NickoBukkit extends JavaPlugin { configurationManager = new ConfigurationManager(getDataFolder()); configurationManager.saveDefaultConfig(); + protocolManager = ProtocolLibrary.getProtocolManager(); mojangAPI = new MojangAPI(); dataStore = new PlayerDataStore(mojangAPI, getNickoConfig()); nameStore = new PlayerNameStore(); @@ -78,14 +80,6 @@ public class NickoBukkit extends JavaPlugin { } if (!unitTesting) { - getLogger().info("Loading internals..."); - if (getInternals() == null) { - getLogger().severe("Nicko could not find a valid implementation for this server version. Is your server supported?"); - dataStore.getStorage().setError(true); - getServer().getPluginManager().disablePlugin(this); - } - - localeFileManager = new LocaleFileManager(); if (configuration.isCustomLocale()) { if (localeFileManager.dumpFromLocale(Locale.ENGLISH)) { @@ -161,7 +155,5 @@ public class NickoBukkit extends JavaPlugin { return localeFileManager; } - public Internals getInternals() { - return InternalsProvider.getInternals(); - } + public ProtocolManager getProtocolManager() { return protocolManager; } } diff --git a/core/src/main/java/net/artelnatif/nicko/appearance/AppearanceManager.java b/core/src/main/java/net/artelnatif/nicko/appearance/AppearanceManager.java index 3120f39..7ce4a3b 100644 --- a/core/src/main/java/net/artelnatif/nicko/appearance/AppearanceManager.java +++ b/core/src/main/java/net/artelnatif/nicko/appearance/AppearanceManager.java @@ -1,14 +1,27 @@ package net.artelnatif.nicko.appearance; +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.*; +import com.google.common.collect.Multimap; import net.artelnatif.nicko.NickoBukkit; import net.artelnatif.nicko.disguise.ActionResult; import net.artelnatif.nicko.disguise.NickoProfile; +import net.artelnatif.nicko.i18n.I18NDict; +import net.artelnatif.nicko.mojang.MojangAPI; +import net.artelnatif.nicko.mojang.MojangSkin; import net.artelnatif.nicko.storage.PlayerDataStore; import net.artelnatif.nicko.storage.name.PlayerNameStore; import org.bukkit.Bukkit; +import org.bukkit.World; import org.bukkit.entity.Player; +import java.io.IOException; +import java.util.List; +import java.util.Optional; +import java.util.Set; import java.util.UUID; +import java.util.concurrent.ExecutionException; public class AppearanceManager { private final NickoProfile profile; @@ -80,10 +93,93 @@ public class AppearanceManager { } public ActionResult resetPlayer() { - return NickoBukkit.getInstance().getInternals().updateProfile(player, profile, true, true); + // TODO: 4/3/23 Reset player + return new ActionResult<>(); } public ActionResult updatePlayer(boolean skinChange) { - return NickoBukkit.getInstance().getInternals().updateProfile(player, profile, skinChange, false); + final String displayName = profile.getName() == null ? player.getName() : profile.getName(); + final WrappedGameProfile gameProfile = new WrappedGameProfile(player.getUniqueId(), displayName); + + final ActionResult result = updateGameProfileSkin(gameProfile, skinChange); + if (!result.isError()) { + updateTabList(gameProfile, displayName); + } + return new ActionResult<>(); + } + + private ActionResult updateGameProfileSkin(WrappedGameProfile gameProfile, boolean skinChange) { + final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); + + if (skinChange || changeOnlyName) { + Optional skin; + try { + final MojangAPI mojang = NickoBukkit.getInstance().getMojangAPI(); + final Optional uuid = mojang.getUUID(profile.getSkin()); + if (uuid.isPresent()) { + skin = mojang.getSkin(uuid.get()); + if (skin.isPresent()) { + final MojangSkin skinResult = skin.get(); + final Multimap properties = gameProfile.getProperties(); + properties.removeAll("textures"); + properties.put("textures", new WrappedSignedProperty("textures", skinResult.getValue(), skinResult.getSignature())); + Bukkit.broadcastMessage("Modified properties"); + } + } + Bukkit.broadcastMessage("Respawning player"); + respawnPlayer(); + return new ActionResult<>(); + } catch (ExecutionException e) { + return new ActionResult<>(I18NDict.Error.SKIN_FAIL_CACHE); + } catch (IOException e) { + return new ActionResult<>(I18NDict.Error.NAME_FAIL_MOJANG); + } + } + return new ActionResult<>(); + } + + private void respawnPlayer() { + final PacketContainer respawnOtherWorld = getRespawnPacket(Bukkit.getWorld("world_the_end")); + final PacketContainer respawn = getRespawnPacket(player.getWorld()); + instance.getProtocolManager().sendServerPacket(player, respawnOtherWorld); + instance.getProtocolManager().sendServerPacket(player, respawn); + } + + private PacketContainer getRespawnPacket(World world) { + final PacketContainer packet = new PacketContainer(PacketType.Play.Server.RESPAWN); + final EnumWrappers.NativeGameMode gamemode = EnumWrappers.NativeGameMode.fromBukkit(player.getGameMode()); + packet.getWorldKeys().write(0, world); + packet.getLongs().write(0, world.getSeed()); + + packet.getGameModes().write(0, gamemode); // gamemode + packet.getGameModes().write(1, gamemode); // previous gamemode + + packet.getBooleans().write(0, false); + packet.getBooleans().write(1, false); + return packet; + } + + private void updateTabList(WrappedGameProfile gameProfile, String displayName) { + final PacketContainer infoAdd = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); + infoAdd.getPlayerInfoActions().write(0, Set.of( + EnumWrappers.PlayerInfoAction.ADD_PLAYER, + EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE, + EnumWrappers.PlayerInfoAction.UPDATE_DISPLAY_NAME, + EnumWrappers.PlayerInfoAction.UPDATE_LISTED, + EnumWrappers.PlayerInfoAction.UPDATE_LATENCY + )); + + infoAdd.getPlayerInfoDataLists().write(1, List.of(new PlayerInfoData( + gameProfile, + 0, + EnumWrappers.NativeGameMode.fromBukkit(player.getGameMode()), + WrappedChatComponent.fromText(displayName) + ))); + + final PacketContainer infoRemove = new PacketContainer(PacketType.Play.Server.PLAYER_INFO_REMOVE); + infoRemove.getUUIDLists().write(0, List.of(player.getUniqueId())); + + instance.getProtocolManager().broadcastServerPacket(infoRemove); + instance.getProtocolManager().broadcastServerPacket(infoAdd); } } diff --git a/core/src/main/java/net/artelnatif/nicko/event/PlayerJoinListener.java b/core/src/main/java/net/artelnatif/nicko/event/PlayerJoinListener.java index 2afa2c3..fc1a3c4 100644 --- a/core/src/main/java/net/artelnatif/nicko/event/PlayerJoinListener.java +++ b/core/src/main/java/net/artelnatif/nicko/event/PlayerJoinListener.java @@ -34,7 +34,7 @@ public class PlayerJoinListener implements Listener { if (!actionResult.isError()) { player.sendMessage(I18N.translate(player, I18NDict.Event.PreviousSkin.SUCCESS)); } else { - player.sendMessage(I18N.translate(player, I18NDict.Event.PreviousSkin.FAIL, I18N.translate(player, actionResult.getErrorMessage()))); + player.sendMessage(I18N.translate(player, I18NDict.Event.PreviousSkin.FAIL, I18N.translateWithoutPrefix(player, actionResult.getErrorMessage()))); } } }, 20L); diff --git a/core/src/main/java/net/artelnatif/nicko/impl/Internals.java b/core/src/main/java/net/artelnatif/nicko/impl/Internals.java deleted file mode 100644 index 0c68318..0000000 --- a/core/src/main/java/net/artelnatif/nicko/impl/Internals.java +++ /dev/null @@ -1,38 +0,0 @@ -package net.artelnatif.nicko.impl; - -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.i18n.I18NDict; -import net.artelnatif.nicko.mojang.MojangAPI; -import net.artelnatif.nicko.mojang.MojangSkin; -import org.bukkit.entity.Player; - -import java.io.IOException; -import java.util.Optional; -import java.util.concurrent.ExecutionException; - -public interface Internals { - void updateSelf(Player player); - - void updateOthers(Player player); - - ActionResult updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset); - - default ActionResult fetchSkinTextures(NickoProfile profile, boolean reset) { - Optional skin; - try { - final MojangAPI mojang = NickoBukkit.getInstance().getMojangAPI(); - final Optional uuid = mojang.getUUID(profile.getSkin()); - if (uuid.isPresent()) { - skin = (reset ? mojang.getSkinWithoutCaching(uuid.get()) : mojang.getSkin(uuid.get())); - return skin.map(ActionResult::new).orElseGet(() -> new ActionResult<>(I18NDict.Error.SKIN_FAIL_MOJANG)); - } - return new ActionResult<>(I18NDict.Error.NAME_FAIL_MOJANG); - } catch (ExecutionException e) { - return new ActionResult<>(I18NDict.Error.SKIN_FAIL_CACHE); - } catch (IOException e) { - return new ActionResult<>(I18NDict.Error.NAME_FAIL_MOJANG); - } - } -} diff --git a/core/src/main/java/net/artelnatif/nicko/impl/InternalsProvider.java b/core/src/main/java/net/artelnatif/nicko/impl/InternalsProvider.java deleted file mode 100644 index d0ebd0d..0000000 --- a/core/src/main/java/net/artelnatif/nicko/impl/InternalsProvider.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.artelnatif.nicko.impl; - -import org.bukkit.Bukkit; - -import java.lang.reflect.InvocationTargetException; -import java.util.logging.Logger; - -public class InternalsProvider { - private static final Logger logger = Logger.getLogger("Internals"); - private static Internals internals; - - static { - try { - final String packageName = Internals.class.getPackage().getName(); - final String bukkitVersion = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; - final String fullClassName = packageName + "." + bukkitVersion; - final Class clazz = Class.forName(fullClassName); - internals = (Internals) clazz.getConstructors()[0].newInstance(); - logger.info("Loaded support for " + bukkitVersion); - } catch (InvocationTargetException | ClassNotFoundException | InstantiationException | IllegalAccessException | - ClassCastException exception) { - internals = null; - } - } - - public static Internals getInternals() { - return internals; - } -} diff --git a/core/src/main/java/net/artelnatif/nicko/mojang/MojangAPI.java b/core/src/main/java/net/artelnatif/nicko/mojang/MojangAPI.java index d8b3bf2..7c1f852 100644 --- a/core/src/main/java/net/artelnatif/nicko/mojang/MojangAPI.java +++ b/core/src/main/java/net/artelnatif/nicko/mojang/MojangAPI.java @@ -25,7 +25,7 @@ public class MojangAPI { private final Logger logger = Logger.getLogger("MojangAPI"); - private final CacheLoader> loader = new CacheLoader>() { + private final CacheLoader> loader = new CacheLoader<>() { @Nonnull public Optional load(@Nonnull String uuid) throws Exception { return getSkinFromMojang(uuid); diff --git a/core/src/main/resources/plugin.yml b/core/src/main/resources/plugin.yml index 093c4b8..af81d31 100644 --- a/core/src/main/resources/plugin.yml +++ b/core/src/main/resources/plugin.yml @@ -1,9 +1,10 @@ name: Nicko main: net.artelnatif.nicko.NickoBukkit version: 1.0-SNAPSHOT -author: Aro +author: Ineanto api-version: 1.13 softdepend: [ PlaceholderAPI ] +depend: [ ProtocolLib ] commands: nicko: description: "Opens Nicko's GUI." diff --git a/pom.xml b/pom.xml index e9f92dc..c67c610 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ core dist - v1_13_R1 + - 11 - 11 + 17 + 17 \ No newline at end of file diff --git a/v1_13_R1/pom.xml b/v1_13_R1/pom.xml deleted file mode 100644 index 6aa987b..0000000 --- a/v1_13_R1/pom.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - nicko-parent - net.artelnatif - 1.0-SNAPSHOT - - 4.0.0 - - v1_13_R1 - 1.0-SNAPSHOT - - - - org.spigotmc - spigot - 1.13-R0.1-SNAPSHOT - provided - - - net.artelnatif - core - 1.0-SNAPSHOT - - - \ No newline at end of file diff --git a/v1_13_R1/src/main/java/net/artelnatif/nicko/impl/v1_13_R1.java b/v1_13_R1/src/main/java/net/artelnatif/nicko/impl/v1_13_R1.java deleted file mode 100644 index 013ddd4..0000000 --- a/v1_13_R1/src/main/java/net/artelnatif/nicko/impl/v1_13_R1.java +++ /dev/null @@ -1,128 +0,0 @@ -package net.artelnatif.nicko.impl; - -import com.google.common.collect.Lists; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import com.mojang.authlib.properties.PropertyMap; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.mojang.MojangSkin; -import net.minecraft.server.v1_13_R1.*; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_13_R1.entity.CraftPlayer; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerTeleportEvent; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; - -public class v1_13_R1 implements Internals { - @Override - public void updateSelf(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final WorldServer worldServer = entityPlayer.getWorldServer(); - final PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(worldServer.dimension, - worldServer.getDifficulty(), - worldServer.worldData.getType(), - entityPlayer.playerInteractManager.getGameMode()); - - final boolean wasFlying = player.isFlying(); - entityPlayer.playerConnection.sendPacket(respawn); - player.setFlying(wasFlying); - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.updateInventory(); - } - - @Override - public void updateOthers(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(entityPlayer.getBukkitEntity().getEntityId()); - final PacketPlayOutNamedEntitySpawn spawn = new PacketPlayOutNamedEntitySpawn(entityPlayer); - - final DataWatcher dataWatcher = entityPlayer.getDataWatcher(); - final DataWatcherObject displayedSkinPartDataWatcher = new DataWatcherObject<>(17, DataWatcherRegistry.a); - dataWatcher.set(displayedSkinPartDataWatcher, (byte) 0x7f); - final PacketPlayOutEntityMetadata entityMetadata = new PacketPlayOutEntityMetadata(entityPlayer.getBukkitEntity().getEntityId(), dataWatcher, true); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - if (onlineEntityPlayer.getBukkitEntity().getUniqueId() != player.getUniqueId()) { - onlineEntityPlayer.playerConnection.sendPacket(destroy); - onlineEntityPlayer.playerConnection.sendPacket(spawn); - } - onlineEntityPlayer.playerConnection.sendPacket(entityMetadata); - }); - } - - @Override - public ActionResult updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset) { - final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); - final String profileName = profile.getName() == null ? player.getName() : profile.getName(); - - final CraftPlayer craftPlayer = (CraftPlayer) player; - final EntityPlayer entityPlayer = craftPlayer.getHandle(); - final GameProfile gameProfile = new GameProfile(player.getUniqueId(), profileName); - - if (skinChange || changeOnlyName) { - final ActionResult skinFetch = fetchSkinTextures(profile, reset); - if (!skinFetch.isError()) { - final MojangSkin skin = skinFetch.getResult(); - final PropertyMap properties = gameProfile.getProperties(); - properties.removeAll("textures"); - properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); - updateSelf(player); - } - } - - final PacketPlayOutPlayerInfo remove = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, entityPlayer); - final PacketPlayOutPlayerInfo add = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER); - final IChatBaseComponent name = new ChatComponentText(profileName); - - final Object infoData = yes( - add, - gameProfile, - entityPlayer.ping, - EnumGamemode.getById(player.getGameMode().ordinal()), - name - ); - spoofPlayerInfoPacket(add, Lists.newArrayList(infoData)); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - onlineEntityPlayer.playerConnection.sendPacket(remove); - onlineEntityPlayer.playerConnection.sendPacket(add); - }); - updateOthers(player); - return new ActionResult<>(); - } - - private void spoofPlayerInfoPacket(Object object, Object newValue) { - try { - final Field field = object.getClass().getDeclaredField("b"); - field.setAccessible(true); - field.set(object, newValue); - } catch (NoSuchFieldException | IllegalAccessException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to spoof packet, that's bad! (" + e.getMessage() + ")"); - } - } - - public Object yes(PacketPlayOutPlayerInfo packet, GameProfile gameProfile, int ping, EnumGamemode gamemode, IChatBaseComponent name) { - try { - final Class clazz = Class.forName("net.minecraft.server.v1_13_R1.PacketPlayOutPlayerInfo$PlayerInfoData"); - final Constructor infoConstructor = clazz.getDeclaredConstructor( - PacketPlayOutPlayerInfo.class, - GameProfile.class, - int.class, - EnumGamemode.class, - IChatBaseComponent.class - ); - return infoConstructor.newInstance(packet, gameProfile, ping, gamemode, name); - } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | InstantiationException | - IllegalAccessException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to instantiate PlayerInfoData, that's bad! (" + e.getMessage() + ")"); - return null; - } - } -} diff --git a/v1_13_R2/pom.xml b/v1_13_R2/pom.xml deleted file mode 100644 index 1e1606a..0000000 --- a/v1_13_R2/pom.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - nicko-parent - net.artelnatif - 1.0-SNAPSHOT - - 4.0.0 - - v1_13_R2 - 1.0-SNAPSHOT - - - - org.spigotmc - spigot - 1.13.2-R0.1-SNAPSHOT - provided - - - net.artelnatif - core - 1.0-SNAPSHOT - - - \ No newline at end of file diff --git a/v1_13_R2/src/main/java/net/artelnatif/nicko/impl/v1_13_R2.java b/v1_13_R2/src/main/java/net/artelnatif/nicko/impl/v1_13_R2.java deleted file mode 100644 index ada42dc..0000000 --- a/v1_13_R2/src/main/java/net/artelnatif/nicko/impl/v1_13_R2.java +++ /dev/null @@ -1,128 +0,0 @@ -package net.artelnatif.nicko.impl; - -import com.google.common.collect.Lists; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import com.mojang.authlib.properties.PropertyMap; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.mojang.MojangSkin; -import net.minecraft.server.v1_13_R2.*; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerTeleportEvent; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; - -public class v1_13_R2 implements Internals { - @Override - public void updateSelf(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final WorldServer worldServer = entityPlayer.getWorldServer(); - final PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(worldServer.dimension, - worldServer.getDifficulty(), - worldServer.S(), - entityPlayer.playerInteractManager.getGameMode()); - - final boolean wasFlying = player.isFlying(); - entityPlayer.playerConnection.sendPacket(respawn); - player.setFlying(wasFlying); - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.updateInventory(); - } - - @Override - public void updateOthers(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(entityPlayer.getBukkitEntity().getEntityId()); - final PacketPlayOutNamedEntitySpawn spawn = new PacketPlayOutNamedEntitySpawn(entityPlayer); - - final DataWatcher dataWatcher = entityPlayer.getDataWatcher(); - final DataWatcherObject displayedSkinPartDataWatcher = new DataWatcherObject<>(17, DataWatcherRegistry.a); - dataWatcher.set(displayedSkinPartDataWatcher, (byte) 0x7f); - final PacketPlayOutEntityMetadata entityMetadata = new PacketPlayOutEntityMetadata(entityPlayer.getBukkitEntity().getEntityId(), dataWatcher, true); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - if (onlineEntityPlayer.getBukkitEntity().getUniqueId() != player.getUniqueId()) { - onlineEntityPlayer.playerConnection.sendPacket(destroy); - onlineEntityPlayer.playerConnection.sendPacket(spawn); - } - onlineEntityPlayer.playerConnection.sendPacket(entityMetadata); - }); - } - - @Override - public ActionResult updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset) { - final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); - final String profileName = profile.getName() == null ? player.getName() : profile.getName(); - - final CraftPlayer craftPlayer = (CraftPlayer) player; - final EntityPlayer entityPlayer = craftPlayer.getHandle(); - final GameProfile gameProfile = new GameProfile(player.getUniqueId(), profileName); - - if (skinChange || changeOnlyName) { - final ActionResult skinFetch = fetchSkinTextures(profile, reset); - if (!skinFetch.isError()) { - final MojangSkin skin = skinFetch.getResult(); - final PropertyMap properties = gameProfile.getProperties(); - properties.removeAll("textures"); - properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); - updateSelf(player); - } - } - - final PacketPlayOutPlayerInfo remove = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, entityPlayer); - final PacketPlayOutPlayerInfo add = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER); - final IChatBaseComponent name = new ChatComponentText(profileName); - - final Object infoData = yes( - add, - gameProfile, - entityPlayer.ping, - EnumGamemode.getById(player.getGameMode().ordinal()), - name - ); - spoofPlayerInfoPacket(add, Lists.newArrayList(infoData)); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - onlineEntityPlayer.playerConnection.sendPacket(remove); - onlineEntityPlayer.playerConnection.sendPacket(add); - }); - updateOthers(player); - return new ActionResult<>(); - } - - private void spoofPlayerInfoPacket(Object object, Object newValue) { - try { - final Field field = object.getClass().getDeclaredField("b"); - field.setAccessible(true); - field.set(object, newValue); - } catch (NoSuchFieldException | IllegalAccessException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to spoof packet, that's bad! (" + e.getMessage() + ")"); - } - } - - public Object yes(PacketPlayOutPlayerInfo packet, GameProfile gameProfile, int ping, EnumGamemode gamemode, IChatBaseComponent name) { - try { - final Class clazz = Class.forName("net.minecraft.server.v1_13_R2.PacketPlayOutPlayerInfo$PlayerInfoData"); - final Constructor infoConstructor = clazz.getDeclaredConstructor( - PacketPlayOutPlayerInfo.class, - GameProfile.class, - int.class, - EnumGamemode.class, - IChatBaseComponent.class - ); - return infoConstructor.newInstance(packet, gameProfile, ping, gamemode, name); - } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | InstantiationException | - IllegalAccessException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to instantiate PlayerInfoData, that's bad! (" + e.getMessage() + ")"); - return null; - } - } -} diff --git a/v1_14_R1/pom.xml b/v1_14_R1/pom.xml deleted file mode 100644 index f69fa93..0000000 --- a/v1_14_R1/pom.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - nicko-parent - net.artelnatif - 1.0-SNAPSHOT - - 4.0.0 - - v1_14_R1 - 1.0-SNAPSHOT - - - - org.spigotmc - spigot - 1.14.4-R0.1-SNAPSHOT - provided - - - net.artelnatif - core - 1.0-SNAPSHOT - - - \ No newline at end of file diff --git a/v1_14_R1/src/main/java/net/artelnatif/nicko/impl/v1_14_R1.java b/v1_14_R1/src/main/java/net/artelnatif/nicko/impl/v1_14_R1.java deleted file mode 100644 index 8cb1887..0000000 --- a/v1_14_R1/src/main/java/net/artelnatif/nicko/impl/v1_14_R1.java +++ /dev/null @@ -1,126 +0,0 @@ -package net.artelnatif.nicko.impl; - -import com.google.common.collect.Lists; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import com.mojang.authlib.properties.PropertyMap; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.mojang.MojangSkin; -import net.minecraft.server.v1_14_R1.*; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerTeleportEvent; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; - -public class v1_14_R1 implements Internals { - @Override - public void updateSelf(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(entityPlayer.getWorldServer().getWorldProvider().getDimensionManager(), - entityPlayer.getWorld().P(), - entityPlayer.playerInteractManager.getGameMode()); - - final boolean wasFlying = player.isFlying(); - entityPlayer.playerConnection.sendPacket(respawn); - player.setFlying(wasFlying); - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.updateInventory(); - } - - @Override - public void updateOthers(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(entityPlayer.getBukkitEntity().getEntityId()); - final PacketPlayOutNamedEntitySpawn spawn = new PacketPlayOutNamedEntitySpawn(entityPlayer); - - final DataWatcher dataWatcher = entityPlayer.getDataWatcher(); - final DataWatcherObject displayedSkinPartDataWatcher = new DataWatcherObject<>(17, DataWatcherRegistry.a); - dataWatcher.set(displayedSkinPartDataWatcher, (byte) 0x7f); - final PacketPlayOutEntityMetadata entityMetadata = new PacketPlayOutEntityMetadata(entityPlayer.getBukkitEntity().getEntityId(), dataWatcher, true); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - if (onlineEntityPlayer.getBukkitEntity().getUniqueId() != player.getUniqueId()) { - onlineEntityPlayer.playerConnection.sendPacket(destroy); - onlineEntityPlayer.playerConnection.sendPacket(spawn); - } - onlineEntityPlayer.playerConnection.sendPacket(entityMetadata); - }); - } - - @Override - public ActionResult updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset) { - final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); - final String profileName = profile.getName() == null ? player.getName() : profile.getName(); - - final CraftPlayer craftPlayer = (CraftPlayer) player; - final EntityPlayer entityPlayer = craftPlayer.getHandle(); - final GameProfile gameProfile = new GameProfile(player.getUniqueId(), profileName); - - if (skinChange || changeOnlyName) { - final ActionResult skinFetch = fetchSkinTextures(profile, reset); - if (!skinFetch.isError()) { - final MojangSkin skin = skinFetch.getResult(); - final PropertyMap properties = gameProfile.getProperties(); - properties.removeAll("textures"); - properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); - updateSelf(player); - } - } - - final PacketPlayOutPlayerInfo remove = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, entityPlayer); - final PacketPlayOutPlayerInfo add = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER); - final IChatBaseComponent name = new ChatComponentText(profileName); - - final Object infoData = yes( - add, - gameProfile, - entityPlayer.ping, - EnumGamemode.getById(player.getGameMode().ordinal()), - name - ); - spoofPlayerInfoPacket(add, Lists.newArrayList(infoData)); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - onlineEntityPlayer.playerConnection.sendPacket(remove); - onlineEntityPlayer.playerConnection.sendPacket(add); - }); - updateOthers(player); - return new ActionResult<>(); - } - - private void spoofPlayerInfoPacket(Object object, Object newValue) { - try { - final Field field = object.getClass().getDeclaredField("b"); - field.setAccessible(true); - field.set(object, newValue); - } catch (NoSuchFieldException | IllegalAccessException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to spoof packet, that's bad! (" + e.getMessage() + ")"); - } - } - - public Object yes(PacketPlayOutPlayerInfo packet, GameProfile gameProfile, int ping, EnumGamemode gamemode, IChatBaseComponent name) { - try { - final Class clazz = Class.forName("net.minecraft.server.v1_14_R1.PacketPlayOutPlayerInfo$PlayerInfoData"); - final Constructor infoConstructor = clazz.getDeclaredConstructor( - PacketPlayOutPlayerInfo.class, - GameProfile.class, - int.class, - EnumGamemode.class, - IChatBaseComponent.class - ); - return infoConstructor.newInstance(packet, gameProfile, ping, gamemode, name); - } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | InstantiationException | - IllegalAccessException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to instantiate PlayerInfoData, that's bad! (" + e.getMessage() + ")"); - return null; - } - } -} diff --git a/v1_15_R1/pom.xml b/v1_15_R1/pom.xml deleted file mode 100644 index 783358e..0000000 --- a/v1_15_R1/pom.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - nicko-parent - net.artelnatif - 1.0-SNAPSHOT - - 4.0.0 - - v1_15_R1 - 1.0-SNAPSHOT - - - - org.spigotmc - spigot - 1.15.2-R0.1-SNAPSHOT - provided - - - net.artelnatif - core - 1.0-SNAPSHOT - - - \ No newline at end of file diff --git a/v1_15_R1/src/main/java/net/artelnatif/nicko/impl/v1_15_R1.java b/v1_15_R1/src/main/java/net/artelnatif/nicko/impl/v1_15_R1.java deleted file mode 100644 index 1bffee0..0000000 --- a/v1_15_R1/src/main/java/net/artelnatif/nicko/impl/v1_15_R1.java +++ /dev/null @@ -1,129 +0,0 @@ -package net.artelnatif.nicko.impl; - -import com.google.common.collect.Lists; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import com.mojang.authlib.properties.PropertyMap; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.mojang.MojangSkin; -import net.minecraft.server.v1_15_R1.*; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_15_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerTeleportEvent; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; - -public class v1_15_R1 implements Internals { - @Override - public void updateSelf(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final CraftWorld world = entityPlayer.getWorld().getWorld(); - final PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(entityPlayer.getWorldServer().getWorldProvider().getDimensionManager(), - world.getSeed(), - entityPlayer.getWorld().P(), - entityPlayer.playerInteractManager.getGameMode()); - - final boolean wasFlying = player.isFlying(); - entityPlayer.playerConnection.sendPacket(respawn); - player.setFlying(wasFlying); - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.updateInventory(); - } - - @Override - public void updateOthers(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(entityPlayer.getBukkitEntity().getEntityId()); - final PacketPlayOutNamedEntitySpawn spawn = new PacketPlayOutNamedEntitySpawn(entityPlayer); - - final DataWatcher dataWatcher = entityPlayer.getDataWatcher(); - final DataWatcherObject displayedSkinPartDataWatcher = new DataWatcherObject<>(17, DataWatcherRegistry.a); - dataWatcher.set(displayedSkinPartDataWatcher, (byte) 0x7f); - final PacketPlayOutEntityMetadata entityMetadata = new PacketPlayOutEntityMetadata(entityPlayer.getBukkitEntity().getEntityId(), dataWatcher, true); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - if (onlineEntityPlayer.getBukkitEntity().getUniqueId() != player.getUniqueId()) { - onlineEntityPlayer.playerConnection.sendPacket(destroy); - onlineEntityPlayer.playerConnection.sendPacket(spawn); - } - onlineEntityPlayer.playerConnection.sendPacket(entityMetadata); - }); - } - - @Override - public ActionResult updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset) { - final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); - final String profileName = profile.getName() == null ? player.getName() : profile.getName(); - - final CraftPlayer craftPlayer = (CraftPlayer) player; - final EntityPlayer entityPlayer = craftPlayer.getHandle(); - final GameProfile gameProfile = new GameProfile(player.getUniqueId(), profileName); - - if (skinChange || changeOnlyName) { - final ActionResult skinFetch = fetchSkinTextures(profile, reset); - if (!skinFetch.isError()) { - final MojangSkin skin = skinFetch.getResult(); - final PropertyMap properties = gameProfile.getProperties(); - properties.removeAll("textures"); - properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); - updateSelf(player); - } - } - - final PacketPlayOutPlayerInfo remove = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, entityPlayer); - final PacketPlayOutPlayerInfo add = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER); - final IChatBaseComponent name = new ChatComponentText(profileName); - - final Object infoData = yes( - add, - gameProfile, - entityPlayer.ping, - EnumGamemode.getById(player.getGameMode().ordinal()), - name - ); - spoofPlayerInfoPacket(add, Lists.newArrayList(infoData)); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - onlineEntityPlayer.playerConnection.sendPacket(remove); - onlineEntityPlayer.playerConnection.sendPacket(add); - }); - updateOthers(player); - return new ActionResult<>(); - } - - private void spoofPlayerInfoPacket(Object object, Object newValue) { - try { - final Field field = object.getClass().getDeclaredField("b"); - field.setAccessible(true); - field.set(object, newValue); - } catch (NoSuchFieldException | IllegalAccessException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to spoof packet, that's bad! (" + e.getMessage() + ")"); - } - } - - public Object yes(PacketPlayOutPlayerInfo packet, GameProfile gameProfile, int ping, EnumGamemode gamemode, IChatBaseComponent name) { - try { - final Class clazz = Class.forName("net.minecraft.server.v1_15_R1.PacketPlayOutPlayerInfo$PlayerInfoData"); - final Constructor infoConstructor = clazz.getDeclaredConstructor( - PacketPlayOutPlayerInfo.class, - GameProfile.class, - int.class, - EnumGamemode.class, - IChatBaseComponent.class - ); - return infoConstructor.newInstance(packet, gameProfile, ping, gamemode, name); - } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | InstantiationException | - IllegalAccessException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to instantiate PlayerInfoData, that's bad! (" + e.getMessage() + ")"); - return null; - } - } -} diff --git a/v1_16_R1/pom.xml b/v1_16_R1/pom.xml deleted file mode 100644 index 032d146..0000000 --- a/v1_16_R1/pom.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - nicko-parent - net.artelnatif - 1.0-SNAPSHOT - - 4.0.0 - - v1_16_R1 - 1.0-SNAPSHOT - - - - org.spigotmc - spigot - 1.16.1-R0.1-SNAPSHOT - provided - - - net.artelnatif - core - 1.0-SNAPSHOT - - - \ No newline at end of file diff --git a/v1_16_R1/src/main/java/net/artelnatif/nicko/impl/v1_16_R1.java b/v1_16_R1/src/main/java/net/artelnatif/nicko/impl/v1_16_R1.java deleted file mode 100644 index c7939c1..0000000 --- a/v1_16_R1/src/main/java/net/artelnatif/nicko/impl/v1_16_R1.java +++ /dev/null @@ -1,132 +0,0 @@ -package net.artelnatif.nicko.impl; - -import com.google.common.collect.Lists; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import com.mojang.authlib.properties.PropertyMap; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.mojang.MojangSkin; -import net.minecraft.server.v1_16_R1.*; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_16_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerTeleportEvent; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; - -public class v1_16_R1 implements Internals { - @Override - public void updateSelf(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final ResourceKey levelResourceKey = entityPlayer.getWorld().getDimensionKey(); - final CraftWorld world = entityPlayer.getWorld().getWorld(); - final PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(entityPlayer.getWorld().getTypeKey(), - levelResourceKey, world.getSeed(), - entityPlayer.playerInteractManager.c(), entityPlayer.playerInteractManager.getGameMode(), - false, - false, - false); - - final boolean wasFlying = player.isFlying(); - entityPlayer.playerConnection.sendPacket(respawn); - player.setFlying(wasFlying); - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.updateInventory(); - } - - @Override - public void updateOthers(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(entityPlayer.getBukkitEntity().getEntityId()); - final PacketPlayOutNamedEntitySpawn spawn = new PacketPlayOutNamedEntitySpawn(entityPlayer); - - final DataWatcher dataWatcher = entityPlayer.getDataWatcher(); - final DataWatcherObject displayedSkinPartDataWatcher = new DataWatcherObject<>(17, DataWatcherRegistry.a); - dataWatcher.set(displayedSkinPartDataWatcher, (byte) 0x7f); - final PacketPlayOutEntityMetadata entityMetadata = new PacketPlayOutEntityMetadata(entityPlayer.getBukkitEntity().getEntityId(), dataWatcher, true); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - if (onlineEntityPlayer.getBukkitEntity().getUniqueId() != player.getUniqueId()) { - onlineEntityPlayer.playerConnection.sendPacket(destroy); - onlineEntityPlayer.playerConnection.sendPacket(spawn); - } - onlineEntityPlayer.playerConnection.sendPacket(entityMetadata); - }); - } - - @Override - public ActionResult updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset) { - final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); - final String profileName = profile.getName() == null ? player.getName() : profile.getName(); - - final CraftPlayer craftPlayer = (CraftPlayer) player; - final EntityPlayer entityPlayer = craftPlayer.getHandle(); - final GameProfile gameProfile = new GameProfile(player.getUniqueId(), profileName); - - if (skinChange || changeOnlyName) { - final ActionResult skinFetch = fetchSkinTextures(profile, reset); - if (!skinFetch.isError()) { - final MojangSkin skin = skinFetch.getResult(); - final PropertyMap properties = gameProfile.getProperties(); - properties.removeAll("textures"); - properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); - updateSelf(player); - } - } - - final PacketPlayOutPlayerInfo remove = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, entityPlayer); - final PacketPlayOutPlayerInfo add = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER); - final IChatBaseComponent name = new ChatComponentText(profileName); - - final Object infoData = yes( - add, - gameProfile, - entityPlayer.ping, - EnumGamemode.getById(player.getGameMode().ordinal()), - name - ); - spoofPlayerInfoPacket(add, Lists.newArrayList(infoData)); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - onlineEntityPlayer.playerConnection.sendPacket(remove); - onlineEntityPlayer.playerConnection.sendPacket(add); - }); - updateOthers(player); - return new ActionResult<>(); - } - - private void spoofPlayerInfoPacket(Object object, Object newValue) { - try { - final Field field = object.getClass().getDeclaredField("b"); - field.setAccessible(true); - field.set(object, newValue); - } catch (NoSuchFieldException | IllegalAccessException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to spoof packet, that's bad! (" + e.getMessage() + ")"); - } - } - - public Object yes(PacketPlayOutPlayerInfo packet, GameProfile gameProfile, int ping, EnumGamemode gamemode, IChatBaseComponent name) { - try { - final Class clazz = Class.forName("net.minecraft.server.v1_16_R1.PacketPlayOutPlayerInfo$PlayerInfoData"); - final Constructor infoConstructor = clazz.getDeclaredConstructor( - PacketPlayOutPlayerInfo.class, - GameProfile.class, - int.class, - EnumGamemode.class, - IChatBaseComponent.class - ); - return infoConstructor.newInstance(packet, gameProfile, ping, gamemode, name); - } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | InstantiationException | - IllegalAccessException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to instantiate PlayerInfoData, that's bad! (" + e.getMessage() + ")"); - return null; - } - } -} diff --git a/v1_16_R2/pom.xml b/v1_16_R2/pom.xml deleted file mode 100644 index 658413d..0000000 --- a/v1_16_R2/pom.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - nicko-parent - net.artelnatif - 1.0-SNAPSHOT - - 4.0.0 - - v1_16_R2 - 1.0-SNAPSHOT - - - - org.spigotmc - spigot - 1.16.3-R0.1-SNAPSHOT - provided - - - net.artelnatif - core - 1.0-SNAPSHOT - - - \ No newline at end of file diff --git a/v1_16_R2/src/main/java/net/artelnatif/nicko/impl/v1_16_R2.java b/v1_16_R2/src/main/java/net/artelnatif/nicko/impl/v1_16_R2.java deleted file mode 100644 index 244970a..0000000 --- a/v1_16_R2/src/main/java/net/artelnatif/nicko/impl/v1_16_R2.java +++ /dev/null @@ -1,132 +0,0 @@ -package net.artelnatif.nicko.impl; - -import com.google.common.collect.Lists; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import com.mojang.authlib.properties.PropertyMap; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.mojang.MojangSkin; -import net.minecraft.server.v1_16_R2.*; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_16_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerTeleportEvent; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; - -public class v1_16_R2 implements Internals { - @Override - public void updateSelf(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final ResourceKey levelResourceKey = entityPlayer.getWorld().getDimensionKey(); - final CraftWorld world = entityPlayer.getWorld().getWorld(); - final PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(entityPlayer.getWorld().getDimensionManager(), - levelResourceKey, world.getSeed(), - entityPlayer.playerInteractManager.c(), entityPlayer.playerInteractManager.getGameMode(), - false, - false, - false); - - final boolean wasFlying = player.isFlying(); - entityPlayer.playerConnection.sendPacket(respawn); - player.setFlying(wasFlying); - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.updateInventory(); - } - - @Override - public void updateOthers(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(entityPlayer.getBukkitEntity().getEntityId()); - final PacketPlayOutNamedEntitySpawn spawn = new PacketPlayOutNamedEntitySpawn(entityPlayer); - - final DataWatcher dataWatcher = entityPlayer.getDataWatcher(); - final DataWatcherObject displayedSkinPartDataWatcher = new DataWatcherObject<>(17, DataWatcherRegistry.a); - dataWatcher.set(displayedSkinPartDataWatcher, (byte) 0x7f); - final PacketPlayOutEntityMetadata entityMetadata = new PacketPlayOutEntityMetadata(entityPlayer.getBukkitEntity().getEntityId(), dataWatcher, true); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - if (onlineEntityPlayer.getBukkitEntity().getUniqueId() != player.getUniqueId()) { - onlineEntityPlayer.playerConnection.sendPacket(destroy); - onlineEntityPlayer.playerConnection.sendPacket(spawn); - } - onlineEntityPlayer.playerConnection.sendPacket(entityMetadata); - }); - } - - @Override - public ActionResult updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset) { - final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); - final String profileName = profile.getName() == null ? player.getName() : profile.getName(); - - final CraftPlayer craftPlayer = (CraftPlayer) player; - final EntityPlayer entityPlayer = craftPlayer.getHandle(); - final GameProfile gameProfile = new GameProfile(player.getUniqueId(), profileName); - - if (skinChange || changeOnlyName) { - final ActionResult skinFetch = fetchSkinTextures(profile, reset); - if (!skinFetch.isError()) { - final MojangSkin skin = skinFetch.getResult(); - final PropertyMap properties = gameProfile.getProperties(); - properties.removeAll("textures"); - properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); - updateSelf(player); - } - } - - final PacketPlayOutPlayerInfo remove = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, entityPlayer); - final PacketPlayOutPlayerInfo add = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER); - final IChatBaseComponent name = new ChatComponentText(profileName); - - final Object infoData = yes( - add, - gameProfile, - entityPlayer.ping, - EnumGamemode.getById(player.getGameMode().ordinal()), - name - ); - spoofPlayerInfoPacket(add, Lists.newArrayList(infoData)); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - onlineEntityPlayer.playerConnection.sendPacket(remove); - onlineEntityPlayer.playerConnection.sendPacket(add); - }); - updateOthers(player); - return new ActionResult<>(); - } - - private void spoofPlayerInfoPacket(Object object, Object newValue) { - try { - final Field field = object.getClass().getDeclaredField("b"); - field.setAccessible(true); - field.set(object, newValue); - } catch (NoSuchFieldException | IllegalAccessException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to spoof packet, that's bad! (" + e.getMessage() + ")"); - } - } - - public Object yes(PacketPlayOutPlayerInfo packet, GameProfile gameProfile, int ping, EnumGamemode gamemode, IChatBaseComponent name) { - try { - final Class clazz = Class.forName("net.minecraft.server.v1_16_R2.PacketPlayOutPlayerInfo$PlayerInfoData"); - final Constructor infoConstructor = clazz.getDeclaredConstructor( - PacketPlayOutPlayerInfo.class, - GameProfile.class, - int.class, - EnumGamemode.class, - IChatBaseComponent.class - ); - return infoConstructor.newInstance(packet, gameProfile, ping, gamemode, name); - } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | InstantiationException | - IllegalAccessException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to instantiate PlayerInfoData, that's bad! (" + e.getMessage() + ")"); - return null; - } - } -} diff --git a/v1_16_R3/pom.xml b/v1_16_R3/pom.xml deleted file mode 100644 index 055dbe2..0000000 --- a/v1_16_R3/pom.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - nicko-parent - net.artelnatif - 1.0-SNAPSHOT - - 4.0.0 - - v1_16_R3 - 1.0-SNAPSHOT - - - - org.spigotmc - spigot - 1.16.5-R0.1-SNAPSHOT - provided - - - net.artelnatif - core - 1.0-SNAPSHOT - - - \ No newline at end of file diff --git a/v1_16_R3/src/main/java/net/artelnatif/nicko/impl/v1_16_R3.java b/v1_16_R3/src/main/java/net/artelnatif/nicko/impl/v1_16_R3.java deleted file mode 100644 index b0744ea..0000000 --- a/v1_16_R3/src/main/java/net/artelnatif/nicko/impl/v1_16_R3.java +++ /dev/null @@ -1,136 +0,0 @@ -package net.artelnatif.nicko.impl; - -import com.google.common.collect.Lists; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import com.mojang.authlib.properties.PropertyMap; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.mojang.MojangSkin; -import net.minecraft.server.v1_16_R3.*; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_16_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerTeleportEvent; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; - -public class v1_16_R3 implements Internals { - @Override - public void updateSelf(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final ResourceKey levelResourceKey = entityPlayer.getWorld().getDimensionKey(); - final CraftWorld world = entityPlayer.getWorld().getWorld(); - final PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(entityPlayer.getWorld().getDimensionManager(), - levelResourceKey, world.getSeed(), - entityPlayer.playerInteractManager.c(), entityPlayer.playerInteractManager.getGameMode(), - false, - false, - false); - - final boolean wasFlying = player.isFlying(); - entityPlayer.playerConnection.sendPacket(respawn); - player.setFlying(wasFlying); - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.updateInventory(); - } - - @Override - public void updateOthers(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(entityPlayer.getBukkitEntity().getEntityId()); - final PacketPlayOutNamedEntitySpawn spawn = new PacketPlayOutNamedEntitySpawn(entityPlayer); - - final DataWatcher dataWatcher = entityPlayer.getDataWatcher(); - final DataWatcherObject displayedSkinPartDataWatcher = new DataWatcherObject<>(17, DataWatcherRegistry.a); - dataWatcher.set(displayedSkinPartDataWatcher, (byte) 0x7f); - final PacketPlayOutEntityMetadata entityMetadata = new PacketPlayOutEntityMetadata(entityPlayer.getBukkitEntity().getEntityId(), dataWatcher, true); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - if (onlineEntityPlayer.getBukkitEntity().getUniqueId() != player.getUniqueId()) { - onlineEntityPlayer.playerConnection.sendPacket(destroy); - onlineEntityPlayer.playerConnection.sendPacket(spawn); - } - onlineEntityPlayer.playerConnection.sendPacket(entityMetadata); - }); - } - - @Override - public ActionResult updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset) { - final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); - final String profileName = profile.getName() == null ? player.getName() : profile.getName(); - - final CraftPlayer craftPlayer = (CraftPlayer) player; - final EntityPlayer entityPlayer = craftPlayer.getHandle(); - final GameProfile gameProfile = new GameProfile(player.getUniqueId(), profileName); - - if (skinChange || changeOnlyName) { - final ActionResult skinFetch = fetchSkinTextures(profile, reset); - if (!skinFetch.isError()) { - final MojangSkin skin = skinFetch.getResult(); - final PropertyMap properties = gameProfile.getProperties(); - properties.removeAll("textures"); - properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); - updateSelf(player); - } - } - - final PacketPlayOutPlayerInfo remove = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, entityPlayer); - final PacketPlayOutPlayerInfo add = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER); - final IChatBaseComponent name = new ChatComponentText(profileName); - - // ok so what the actual fuck - // the PlayerDataInfo inner class is NOT static - // thus the compiler can't access it when compiling?????? - // i swear this is so dumb that I have to resort to doing this - final Object infoData = yes( - add, - gameProfile, - entityPlayer.ping, - EnumGamemode.getById(player.getGameMode().ordinal()), - name - ); - spoofPlayerInfoPacket(add, Lists.newArrayList(infoData)); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - onlineEntityPlayer.playerConnection.sendPacket(remove); - onlineEntityPlayer.playerConnection.sendPacket(add); - }); - updateOthers(player); - return new ActionResult<>(); - } - - private void spoofPlayerInfoPacket(Object object, Object newValue) { - try { - final Field field = object.getClass().getDeclaredField("b"); - field.setAccessible(true); - field.set(object, newValue); - } catch (NoSuchFieldException | IllegalAccessException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to spoof packet, that's bad! (" + e.getMessage() + ")"); - } - } - - public Object yes(PacketPlayOutPlayerInfo packet, GameProfile gameProfile, int ping, EnumGamemode gamemode, IChatBaseComponent name) { - try { - final Class clazz = Class.forName("net.minecraft.server.v1_16_R3.PacketPlayOutPlayerInfo$PlayerInfoData"); - final Constructor infoConstructor = clazz.getDeclaredConstructor( - PacketPlayOutPlayerInfo.class, - GameProfile.class, - int.class, - EnumGamemode.class, - IChatBaseComponent.class - ); - return infoConstructor.newInstance(packet, gameProfile, ping, gamemode, name); - } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | InstantiationException | - IllegalAccessException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to instantiate PlayerInfoData, that's bad! (" + e.getMessage() + ")"); - return null; - } - } -} diff --git a/v1_17_R1/pom.xml b/v1_17_R1/pom.xml deleted file mode 100644 index 7ca2642..0000000 --- a/v1_17_R1/pom.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - nicko-parent - net.artelnatif - 1.0-SNAPSHOT - - 4.0.0 - - v1_17_R1 - 1.0-SNAPSHOT - - - - org.spigotmc - spigot - 1.17.1-R0.1-SNAPSHOT - provided - - - net.artelnatif - core - 1.0-SNAPSHOT - - - \ No newline at end of file diff --git a/v1_17_R1/src/main/java/net/artelnatif/nicko/impl/v1_17_R1.java b/v1_17_R1/src/main/java/net/artelnatif/nicko/impl/v1_17_R1.java deleted file mode 100644 index 24cd2a0..0000000 --- a/v1_17_R1/src/main/java/net/artelnatif/nicko/impl/v1_17_R1.java +++ /dev/null @@ -1,101 +0,0 @@ -package net.artelnatif.nicko.impl; - -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import com.mojang.authlib.properties.PropertyMap; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.mojang.MojangSkin; -import net.minecraft.network.chat.IChatBaseComponent; -import net.minecraft.network.protocol.game.*; -import net.minecraft.network.syncher.DataWatcher; -import net.minecraft.network.syncher.DataWatcherObject; -import net.minecraft.network.syncher.DataWatcherRegistry; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.level.EntityPlayer; -import net.minecraft.world.level.EnumGamemode; -import net.minecraft.world.level.World; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerTeleportEvent; - -public class v1_17_R1 implements Internals { - @Override - public void updateSelf(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final ResourceKey levelResourceKey = entityPlayer.getWorld().getDimensionKey(); - final CraftWorld world = entityPlayer.getWorld().getWorld(); - final PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(entityPlayer.getWorld().getDimensionManager(), - levelResourceKey, world.getSeed(), - entityPlayer.c.getGamemode(), entityPlayer.d.c(), - false, - false, - false); - - final boolean wasFlying = player.isFlying(); - entityPlayer.b.sendPacket(respawn); - player.setFlying(wasFlying); - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.updateInventory(); - } - - @Override - public void updateOthers(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(entityPlayer.getBukkitEntity().getEntityId()); - final PacketPlayOutNamedEntitySpawn spawn = new PacketPlayOutNamedEntitySpawn(entityPlayer); - - final DataWatcher dataWatcher = entityPlayer.getDataWatcher(); - final DataWatcherObject displayedSkinPartDataWatcher = new DataWatcherObject<>(17, DataWatcherRegistry.a); - dataWatcher.set(displayedSkinPartDataWatcher, (byte) 0x7f); - final PacketPlayOutEntityMetadata entityMetadata = new PacketPlayOutEntityMetadata(entityPlayer.getBukkitEntity().getEntityId(), dataWatcher, true); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - if (onlineEntityPlayer.getBukkitEntity().getUniqueId() != player.getUniqueId()) { - onlineEntityPlayer.b.sendPacket(destroy); - onlineEntityPlayer.b.sendPacket(spawn); - } - onlineEntityPlayer.b.sendPacket(entityMetadata); - }); - } - - @Override - public ActionResult updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset) { - final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); - final String profileName = profile.getName() == null ? player.getName() : profile.getName(); - - final CraftPlayer craftPlayer = (CraftPlayer) player; - final EntityPlayer entityPlayer = craftPlayer.getHandle(); - final GameProfile gameProfile = new GameProfile(player.getUniqueId(), profileName); - - if (skinChange || changeOnlyName) { - final ActionResult skinFetch = fetchSkinTextures(profile, reset); - if (!skinFetch.isError()) { - final MojangSkin skin = skinFetch.getResult(); - final PropertyMap properties = gameProfile.getProperties(); - properties.removeAll("textures"); - properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); - updateSelf(player); - } - } - - final PacketPlayOutPlayerInfo remove = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.e, entityPlayer); - final PacketPlayOutPlayerInfo add = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.a); - - add.b().clear(); - add.b().add(new PacketPlayOutPlayerInfo.PlayerInfoData(gameProfile, - player.getPing(), - EnumGamemode.getById(player.getGameMode().ordinal()), IChatBaseComponent.a(profileName))); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - onlineEntityPlayer.b.sendPacket(remove); - onlineEntityPlayer.b.sendPacket(add); - }); - updateOthers(player); - return new ActionResult<>(); - } -} diff --git a/v1_18_R1/pom.xml b/v1_18_R1/pom.xml deleted file mode 100644 index d842952..0000000 --- a/v1_18_R1/pom.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - 4.0.0 - - - net.artelnatif - nicko-parent - 1.0-SNAPSHOT - - - v1_18_R1 - 1.0-SNAPSHOT - - - - org.spigotmc - spigot - 1.18.1-R0.1-SNAPSHOT - provided - - - net.artelnatif - core - 1.0-SNAPSHOT - - - \ No newline at end of file diff --git a/v1_18_R1/src/main/java/net/artelnatif/nicko/impl/v1_18_R1.java b/v1_18_R1/src/main/java/net/artelnatif/nicko/impl/v1_18_R1.java deleted file mode 100644 index 1f1b7b7..0000000 --- a/v1_18_R1/src/main/java/net/artelnatif/nicko/impl/v1_18_R1.java +++ /dev/null @@ -1,103 +0,0 @@ -package net.artelnatif.nicko.impl; - -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import com.mojang.authlib.properties.PropertyMap; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.mojang.MojangSkin; -import net.minecraft.network.chat.IChatBaseComponent; -import net.minecraft.network.protocol.game.*; -import net.minecraft.network.syncher.DataWatcher; -import net.minecraft.network.syncher.DataWatcherObject; -import net.minecraft.network.syncher.DataWatcherRegistry; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.level.EntityPlayer; -import net.minecraft.world.level.EnumGamemode; -import net.minecraft.world.level.World; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_18_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_18_R1.entity.CraftPlayer; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerTeleportEvent; - -public class v1_18_R1 implements Internals { - @Override - public void updateSelf(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final ResourceKey levelResourceKey = entityPlayer.x().aa(); - final CraftWorld world = entityPlayer.W().getWorld(); - // again, wtf is that - // f*ck obfuscation - final PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(entityPlayer.W().q_(), - levelResourceKey, world.getSeed(), - entityPlayer.d.b(), entityPlayer.d.c(), - false, - false, - false); - - final boolean wasFlying = player.isFlying(); - entityPlayer.b.a(respawn); - player.setFlying(wasFlying); - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.updateInventory(); - } - - @Override - public void updateOthers(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(entityPlayer.getBukkitEntity().getEntityId()); - final PacketPlayOutNamedEntitySpawn spawn = new PacketPlayOutNamedEntitySpawn(entityPlayer); - - final DataWatcher dataWatcher = entityPlayer.ai(); - final DataWatcherObject displayedSkinPartDataWatcher = new DataWatcherObject<>(17, DataWatcherRegistry.a); - dataWatcher.b(displayedSkinPartDataWatcher, (byte) 0x7f); - final PacketPlayOutEntityMetadata entityMetadata = new PacketPlayOutEntityMetadata(entityPlayer.getBukkitEntity().getEntityId(), dataWatcher, true); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - if (onlineEntityPlayer.getBukkitEntity().getUniqueId() != player.getUniqueId()) { - onlineEntityPlayer.b.a(destroy); - onlineEntityPlayer.b.a(spawn); - } - onlineEntityPlayer.b.a(entityMetadata); - }); - } - - @Override - public ActionResult updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset) { - final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); - final String profileName = profile.getName() == null ? player.getName() : profile.getName(); - - final CraftPlayer craftPlayer = (CraftPlayer) player; - final EntityPlayer entityPlayer = craftPlayer.getHandle(); - final GameProfile gameProfile = new GameProfile(player.getUniqueId(), profileName); - - if (skinChange || changeOnlyName) { - final ActionResult skinFetch = fetchSkinTextures(profile, reset); - if (!skinFetch.isError()) { - final MojangSkin skin = skinFetch.getResult(); - final PropertyMap properties = gameProfile.getProperties(); - properties.removeAll("textures"); - properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); - updateSelf(player); - } - } - - final PacketPlayOutPlayerInfo remove = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.e, entityPlayer); - final PacketPlayOutPlayerInfo add = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.a); - - add.b().clear(); - add.b().add(new PacketPlayOutPlayerInfo.PlayerInfoData(gameProfile, - player.getPing(), - EnumGamemode.a(player.getGameMode().ordinal()), IChatBaseComponent.a(profileName))); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - onlineEntityPlayer.b.a(remove); - onlineEntityPlayer.b.a(add); - }); - updateOthers(player); - return new ActionResult<>(); - } -} diff --git a/v1_18_R2/pom.xml b/v1_18_R2/pom.xml deleted file mode 100644 index 4eb30ad..0000000 --- a/v1_18_R2/pom.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - 4.0.0 - - - net.artelnatif - nicko-parent - 1.0-SNAPSHOT - - - v1_18_R2 - 1.0-SNAPSHOT - - - - org.spigotmc - spigot - 1.18.2-R0.1-SNAPSHOT - provided - - - net.artelnatif - core - 1.0-SNAPSHOT - - - \ No newline at end of file diff --git a/v1_18_R2/src/main/java/net/artelnatif/nicko/impl/v1_18_R2.java b/v1_18_R2/src/main/java/net/artelnatif/nicko/impl/v1_18_R2.java deleted file mode 100644 index 1f085f6..0000000 --- a/v1_18_R2/src/main/java/net/artelnatif/nicko/impl/v1_18_R2.java +++ /dev/null @@ -1,103 +0,0 @@ -package net.artelnatif.nicko.impl; - -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import com.mojang.authlib.properties.PropertyMap; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.mojang.MojangSkin; -import net.minecraft.core.Holder; -import net.minecraft.network.chat.IChatBaseComponent; -import net.minecraft.network.protocol.game.*; -import net.minecraft.network.syncher.DataWatcher; -import net.minecraft.network.syncher.DataWatcherObject; -import net.minecraft.network.syncher.DataWatcherRegistry; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.level.EntityPlayer; -import net.minecraft.world.level.EnumGamemode; -import net.minecraft.world.level.World; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerTeleportEvent; - -public class v1_18_R2 implements Internals { - @Override - public void updateSelf(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final ResourceKey levelResourceKey = entityPlayer.x().aa(); - final CraftWorld world = entityPlayer.s.getWorld(); - // wtf is that ? - final PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(Holder.a(entityPlayer.s.q_()), - levelResourceKey, world.getSeed(), - entityPlayer.d.b(), entityPlayer.d.c(), - false, - false, - false); - - final boolean wasFlying = player.isFlying(); - entityPlayer.b.a(respawn); - player.setFlying(wasFlying); - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.updateInventory(); - } - - @Override - public void updateOthers(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(entityPlayer.getBukkitEntity().getEntityId()); - final PacketPlayOutNamedEntitySpawn spawn = new PacketPlayOutNamedEntitySpawn(entityPlayer); - - final DataWatcher dataWatcher = entityPlayer.ai(); - final DataWatcherObject displayedSkinPartDataWatcher = new DataWatcherObject<>(17, DataWatcherRegistry.a); - dataWatcher.b(displayedSkinPartDataWatcher, (byte) 0x7f); - final PacketPlayOutEntityMetadata entityMetadata = new PacketPlayOutEntityMetadata(entityPlayer.getBukkitEntity().getEntityId(), dataWatcher, true); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - if (onlineEntityPlayer.getBukkitEntity().getUniqueId() != player.getUniqueId()) { - onlineEntityPlayer.b.a(destroy); - onlineEntityPlayer.b.a(spawn); - } - onlineEntityPlayer.b.a(entityMetadata); - }); - } - - @Override - public ActionResult updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset) { - final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); - final String profileName = profile.getName() == null ? player.getName() : profile.getName(); - - final CraftPlayer craftPlayer = (CraftPlayer) player; - final EntityPlayer entityPlayer = craftPlayer.getHandle(); - final GameProfile gameProfile = new GameProfile(player.getUniqueId(), profileName); - - if (skinChange || changeOnlyName) { - final ActionResult skinFetch = fetchSkinTextures(profile, reset); - if (!skinFetch.isError()) { - final MojangSkin skin = skinFetch.getResult(); - final PropertyMap properties = gameProfile.getProperties(); - properties.removeAll("textures"); - properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); - updateSelf(player); - } - } - - final PacketPlayOutPlayerInfo remove = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.e, entityPlayer); - final PacketPlayOutPlayerInfo add = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.a); - - add.b().clear(); - add.b().add(new PacketPlayOutPlayerInfo.PlayerInfoData(gameProfile, - player.getPing(), - EnumGamemode.a(player.getGameMode().ordinal()), IChatBaseComponent.a(profileName))); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - onlineEntityPlayer.b.a(remove); - onlineEntityPlayer.b.a(add); - }); - updateOthers(player); - return new ActionResult<>(); - } -} \ No newline at end of file diff --git a/v1_19_R1/pom.xml b/v1_19_R1/pom.xml deleted file mode 100644 index ccdb982..0000000 --- a/v1_19_R1/pom.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - 4.0.0 - - - net.artelnatif - nicko-parent - 1.0-SNAPSHOT - - - v1_19_R1 - 1.0-SNAPSHOT - - - - org.spigotmc - spigot - 1.19.2-R0.1-SNAPSHOT - provided - - - net.artelnatif - core - 1.0-SNAPSHOT - - - \ No newline at end of file diff --git a/v1_19_R1/src/main/java/net/artelnatif/nicko/impl/v1_19_R1.java b/v1_19_R1/src/main/java/net/artelnatif/nicko/impl/v1_19_R1.java deleted file mode 100644 index fe98d37..0000000 --- a/v1_19_R1/src/main/java/net/artelnatif/nicko/impl/v1_19_R1.java +++ /dev/null @@ -1,107 +0,0 @@ -package net.artelnatif.nicko.impl; - -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import com.mojang.authlib.properties.PropertyMap; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.mojang.MojangSkin; -import net.minecraft.network.chat.IChatBaseComponent; -import net.minecraft.network.protocol.game.*; -import net.minecraft.network.syncher.DataWatcher; -import net.minecraft.network.syncher.DataWatcherObject; -import net.minecraft.network.syncher.DataWatcherRegistry; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.level.EntityPlayer; -import net.minecraft.world.entity.player.ProfilePublicKey; -import net.minecraft.world.level.EnumGamemode; -import net.minecraft.world.level.World; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerTeleportEvent; - -import java.util.Optional; - -public class v1_19_R1 implements Internals { - @Override - public void updateSelf(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final ResourceKey levelResourceKey = entityPlayer.x().ab(); - final PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(entityPlayer.x().Z(), - levelResourceKey, entityPlayer.s.getWorld().getSeed(), - entityPlayer.d.b(), entityPlayer.d.c(), - false, - false, - false, - Optional.empty()); - - final boolean wasFlying = player.isFlying(); - entityPlayer.b.a(respawn); - player.setFlying(wasFlying); - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.updateInventory(); - } - - @Override - public void updateOthers(Player player) { - final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle(); - final PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(entityPlayer.getBukkitEntity().getEntityId()); - final PacketPlayOutNamedEntitySpawn spawn = new PacketPlayOutNamedEntitySpawn(entityPlayer); - - final DataWatcher dataWatcher = entityPlayer.ai(); - final DataWatcherObject displayedSkinPartDataWatcher = new DataWatcherObject<>(17, DataWatcherRegistry.a); - dataWatcher.b(displayedSkinPartDataWatcher, (byte) 0x7f); - final PacketPlayOutEntityMetadata entityMetadata = new PacketPlayOutEntityMetadata(entityPlayer.getBukkitEntity().getEntityId(), dataWatcher, true); - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - if (onlineEntityPlayer.getBukkitEntity().getUniqueId() != player.getUniqueId()) { - onlineEntityPlayer.b.a(destroy); - onlineEntityPlayer.b.a(spawn); - } - onlineEntityPlayer.b.a(entityMetadata); - }); - } - - @Override - public ActionResult updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset) { - final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); - final String profileName = profile.getName() == null ? player.getName() : profile.getName(); - - final CraftPlayer craftPlayer = (CraftPlayer) player; - final EntityPlayer entityPlayer = craftPlayer.getHandle(); - final GameProfile gameProfile = new GameProfile(player.getUniqueId(), profileName); - - if (skinChange || changeOnlyName) { - final ActionResult skinFetch = fetchSkinTextures(profile, reset); - if (!skinFetch.isError()) { - final MojangSkin skin = skinFetch.getResult(); - final PropertyMap properties = gameProfile.getProperties(); - properties.removeAll("textures"); - properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); - updateSelf(player); - } - } - - final PacketPlayOutPlayerInfo add = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.a); - final PacketPlayOutPlayerInfo remove = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.e, entityPlayer); - // "It's a Surprise Tool That Will Help Us Later!" - final ProfilePublicKey.a key = remove.b().get(0).e(); - - add.b().clear(); - add.b().add(new PacketPlayOutPlayerInfo.PlayerInfoData(gameProfile, - player.getPing(), - EnumGamemode.a(player.getGameMode().ordinal()), - IChatBaseComponent.a(profileName), - key)); // f mojang - - Bukkit.getOnlinePlayers().forEach(online -> { - EntityPlayer onlineEntityPlayer = ((CraftPlayer) online).getHandle(); - onlineEntityPlayer.b.a(remove); - onlineEntityPlayer.b.a(add); - }); - updateOthers(player); - return new ActionResult<>(); - } -} diff --git a/v1_19_R2/pom.xml b/v1_19_R2/pom.xml deleted file mode 100644 index 385efc4..0000000 --- a/v1_19_R2/pom.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - 4.0.0 - - - net.artelnatif - nicko-parent - 1.0-SNAPSHOT - - - v1_19_R2 - 1.0-SNAPSHOT - - - - - net.md-5 - specialsource-maven-plugin - 1.2.4 - - - package - - remap - - remap-obf - - org.spigotmc:minecraft-server:1.19.3-R0.1-SNAPSHOT:txt:maps-mojang - true - org.spigotmc:spigot:1.19.3-R0.1-SNAPSHOT:jar:remapped-mojang - true - remapped-obf - - - - package - - remap - - remap-spigot - - ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar - org.spigotmc:minecraft-server:1.19.3-R0.1-SNAPSHOT:csrg:maps-spigot - org.spigotmc:spigot:1.19.3-R0.1-SNAPSHOT:jar:remapped-obf - - - - - - - - - - org.spigotmc - spigot - 1.19.3-R0.1-SNAPSHOT - remapped-mojang - provided - - - net.artelnatif - core - 1.0-SNAPSHOT - - - \ No newline at end of file diff --git a/v1_19_R2/src/main/java/net/artelnatif/nicko/impl/v1_19_R2.java b/v1_19_R2/src/main/java/net/artelnatif/nicko/impl/v1_19_R2.java deleted file mode 100644 index 4059960..0000000 --- a/v1_19_R2/src/main/java/net/artelnatif/nicko/impl/v1_19_R2.java +++ /dev/null @@ -1,132 +0,0 @@ -package net.artelnatif.nicko.impl; - -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import com.mojang.authlib.properties.PropertyMap; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.mojang.MojangSkin; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.RemoteChatSession; -import net.minecraft.network.protocol.game.*; -import net.minecraft.network.syncher.EntityDataAccessor; -import net.minecraft.network.syncher.EntityDataSerializers; -import net.minecraft.network.syncher.SynchedEntityData; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.player.ProfilePublicKey; -import net.minecraft.world.level.Level; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerTeleportEvent; - -import java.lang.reflect.Field; -import java.util.*; - -public class v1_19_R2 implements Internals { - @Override - public void updateSelf(Player player) { - final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); - final ServerLevel level = serverPlayer.getLevel(); - final ResourceKey levelResourceKey = serverPlayer.getLevel().dimension(); - final ClientboundRespawnPacket respawn = new ClientboundRespawnPacket(serverPlayer.level.dimensionTypeId(), - levelResourceKey, level.getWorld().getSeed(), - serverPlayer.gameMode.getGameModeForPlayer(), serverPlayer.gameMode.getPreviousGameModeForPlayer(), - level.isDebug(), - level.isFlat(), - (byte) 0x00, - Optional.empty()); - - final boolean wasFlying = player.isFlying(); - serverPlayer.connection.send(respawn); - player.setFlying(wasFlying); - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.updateInventory(); - } - - @Override - public void updateOthers(Player player) { - final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); - final ClientboundRemoveEntitiesPacket remove = new ClientboundRemoveEntitiesPacket(serverPlayer.getBukkitEntity().getEntityId()); - final ClientboundAddEntityPacket add = new ClientboundAddEntityPacket(serverPlayer); - - final SynchedEntityData entityData = serverPlayer.getEntityData(); - final EntityDataAccessor skinPartAccessor = new EntityDataAccessor<>(17, EntityDataSerializers.BYTE); - entityData.set(skinPartAccessor, (byte) 0x7f); - final ClientboundSetEntityDataPacket entityMetadata = new ClientboundSetEntityDataPacket(serverPlayer.getBukkitEntity().getEntityId(), entityData.getNonDefaultValues()); - - Bukkit.getOnlinePlayers().forEach(online -> { - final ServerPlayer onlineServerPlayer = ((CraftPlayer) online).getHandle(); - if (onlineServerPlayer.getBukkitEntity().getUniqueId() != player.getUniqueId()) { - onlineServerPlayer.connection.send(remove); - onlineServerPlayer.connection.send(add); - } - onlineServerPlayer.connection.send(entityMetadata); - }); - } - - @Override - public ActionResult updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset) { - final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); - final String profileName = profile.getName() == null ? player.getName() : profile.getName(); - - final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); - final GameProfile gameProfile = new GameProfile(player.getUniqueId(), profileName); - - if (skinChange || changeOnlyName) { - final ActionResult skinFetch = fetchSkinTextures(profile, reset); - if (!skinFetch.isError()) { - final MojangSkin skin = skinFetch.getResult(); - final PropertyMap properties = gameProfile.getProperties(); - properties.removeAll("textures"); - properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); - updateSelf(player); - } - } - - final ClientboundPlayerInfoUpdatePacket init = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(Collections.singletonList(serverPlayer)); - final ClientboundPlayerInfoRemovePacket remove = new ClientboundPlayerInfoRemovePacket(Collections.singletonList(player.getUniqueId())); - - RemoteChatSession chatSession; - if (serverPlayer.getChatSession() == null) { - NickoBukkit.getInstance().getLogger().warning("Chat Session of " + serverPlayer.displayName + " is null!"); - NickoBukkit.getInstance().getLogger().warning("If your server is in offline mode/under BungeeCord you can safely ignore this message."); - chatSession = null; - } else { - final UUID uuid = serverPlayer.getChatSession().sessionId(); - final ProfilePublicKey ppk = serverPlayer.getChatSession().profilePublicKey(); - chatSession = new RemoteChatSession(uuid, ppk); - } - - spoofPlayerInfoPacket(init, Collections.singletonList(new ClientboundPlayerInfoUpdatePacket.Entry( - player.getUniqueId(), - gameProfile, - true, - serverPlayer.latency, - serverPlayer.gameMode.getGameModeForPlayer(), - Component.literal(profileName), - chatSession == null ? null : chatSession.asData() - ))); - - Bukkit.getOnlinePlayers().forEach(online -> { - final ServerPlayer onlinePlayer = ((CraftPlayer) online).getHandle(); - onlinePlayer.connection.send(remove); - onlinePlayer.connection.send(init); - }); - updateOthers(player); - return new ActionResult<>(); - } - - private void spoofPlayerInfoPacket(Object object, Object newValue) { - try { - final Field field = object.getClass().getDeclaredField("b"); - field.setAccessible(true); - field.set(object, newValue); - } catch (NoSuchFieldException | IllegalAccessException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to spoof packet, that's bad! (" + e.getMessage() + ")"); - } - } -} diff --git a/v1_19_R3/pom.xml b/v1_19_R3/pom.xml deleted file mode 100644 index eefd19d..0000000 --- a/v1_19_R3/pom.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - 4.0.0 - - - net.artelnatif - nicko-parent - 1.0-SNAPSHOT - - - v1_19_R3 - 1.0-SNAPSHOT - - - - - net.md-5 - specialsource-maven-plugin - 1.2.4 - - - package - - remap - - remap-obf - - org.spigotmc:minecraft-server:1.19.4-R0.1-SNAPSHOT:txt:maps-mojang - true - org.spigotmc:spigot:1.19.4-R0.1-SNAPSHOT:jar:remapped-mojang - true - remapped-obf - - - - package - - remap - - remap-spigot - - ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar - org.spigotmc:minecraft-server:1.19.4-R0.1-SNAPSHOT:csrg:maps-spigot - org.spigotmc:spigot:1.19.4-R0.1-SNAPSHOT:jar:remapped-obf - - - - - - - - - - org.spigotmc - spigot - 1.19.4-R0.1-SNAPSHOT - remapped-mojang - provided - - - net.artelnatif - core - 1.0-SNAPSHOT - - - \ No newline at end of file diff --git a/v1_19_R3/src/main/java/net/artelnatif/nicko/impl/v1_19_R3.java b/v1_19_R3/src/main/java/net/artelnatif/nicko/impl/v1_19_R3.java deleted file mode 100644 index d0ef0eb..0000000 --- a/v1_19_R3/src/main/java/net/artelnatif/nicko/impl/v1_19_R3.java +++ /dev/null @@ -1,140 +0,0 @@ -package net.artelnatif.nicko.impl; - -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import com.mojang.authlib.properties.PropertyMap; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.mojang.MojangSkin; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.RemoteChatSession; -import net.minecraft.network.protocol.game.*; -import net.minecraft.network.syncher.EntityDataAccessor; -import net.minecraft.network.syncher.EntityDataSerializers; -import net.minecraft.network.syncher.SynchedEntityData; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.player.ProfilePublicKey; -import net.minecraft.world.level.Level; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerTeleportEvent; - -import java.lang.reflect.Field; -import java.util.Collections; -import java.util.Optional; -import java.util.UUID; -import java.util.logging.Logger; - -public class v1_19_R3 implements Internals { - final Logger logger = Bukkit.getLogger(); - - @Override - public void updateSelf(Player player) { - final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); - final ServerLevel level = serverPlayer.getLevel(); - final ResourceKey levelResourceKey = serverPlayer.getLevel().dimension(); - final ClientboundRespawnPacket respawn = new ClientboundRespawnPacket(serverPlayer.level.dimensionTypeId(), - levelResourceKey, level.getWorld().getSeed(), - serverPlayer.gameMode.getGameModeForPlayer(), serverPlayer.gameMode.getPreviousGameModeForPlayer(), - level.isDebug(), - level.isFlat(), - (byte) 0x00, - Optional.empty()); - - final boolean wasFlying = player.isFlying(); - serverPlayer.connection.send(respawn); - player.setFlying(wasFlying); - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.updateInventory(); - } - - @Override - public void updateOthers(Player player) { - final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); - - final ClientboundRemoveEntitiesPacket remove = new ClientboundRemoveEntitiesPacket(serverPlayer.getBukkitEntity().getEntityId()); - final ClientboundAddEntityPacket add = new ClientboundAddEntityPacket(serverPlayer); - - final SynchedEntityData entityData = serverPlayer.getEntityData(); - final EntityDataAccessor skinPartAccessor = new EntityDataAccessor<>(17, EntityDataSerializers.BYTE); - entityData.set(skinPartAccessor, (byte) 0x7f); - final ClientboundSetEntityDataPacket entityMetadata = new ClientboundSetEntityDataPacket(serverPlayer.getBukkitEntity().getEntityId(), entityData.getNonDefaultValues()); - - Bukkit.getOnlinePlayers().forEach(online -> { - final ServerPlayer onlineServerPlayer = ((CraftPlayer) online).getHandle(); - if (onlineServerPlayer.getBukkitEntity().getUniqueId() != player.getUniqueId()) { - onlineServerPlayer.connection.send(remove); - onlineServerPlayer.connection.send(add); - } - onlineServerPlayer.connection.send(entityMetadata); - }); - } - - @Override - public ActionResult updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset) { - final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); - final String profileName = profile.getName() == null ? player.getName() : profile.getName(); - - final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); - final GameProfile gameProfile = new GameProfile(player.getUniqueId(), profileName); - - if (skinChange || changeOnlyName) { - final ActionResult skinFetch = fetchSkinTextures(profile, reset); - if (!skinFetch.isError()) { - final MojangSkin skin = skinFetch.getResult(); - final PropertyMap properties = gameProfile.getProperties(); - properties.removeAll("textures"); - properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); - updateSelf(player); - } - } - - final ClientboundPlayerInfoUpdatePacket init = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(Collections.singletonList(serverPlayer)); - final ClientboundPlayerInfoRemovePacket remove = new ClientboundPlayerInfoRemovePacket(Collections.singletonList(player.getUniqueId())); - - RemoteChatSession chatSession; - if (serverPlayer.getChatSession() == null) { - NickoBukkit.getInstance().getLogger().warning("Chat Session of " + serverPlayer.displayName + " is null!"); - NickoBukkit.getInstance().getLogger().warning("If your server is in offline mode/under BungeeCord you can safely ignore this message."); - chatSession = null; - } else { - final UUID uuid = serverPlayer.getChatSession().sessionId(); - final ProfilePublicKey ppk = serverPlayer.getChatSession().profilePublicKey(); - chatSession = new RemoteChatSession(uuid, ppk); - } - - spoofPlayerInfoPacket(init, Collections.singletonList(new ClientboundPlayerInfoUpdatePacket.Entry( - player.getUniqueId(), - gameProfile, - true, - serverPlayer.latency, - serverPlayer.gameMode.getGameModeForPlayer(), - Component.literal(profileName), - chatSession == null ? null : chatSession.asData() - ))); - - - Bukkit.getOnlinePlayers().forEach(online -> { - final ServerPlayer onlinePlayer = ((CraftPlayer) online).getHandle(); - onlinePlayer.connection.send(remove); - onlinePlayer.connection.send(init); - }); - // TODO: 3/17/23 Update signature to avoid duplicate for loop - updateOthers(player); - return new ActionResult<>(); - } - - private void spoofPlayerInfoPacket(Object object, Object newValue) { - try { - final Field field = object.getClass().getDeclaredField("b"); - field.setAccessible(true); - field.set(object, newValue); - } catch (NoSuchFieldException | IllegalAccessException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to spoof packet, that's bad! (" + e.getMessage() + ")"); - } - } -} From 6e0ef4a243f6255b8f0ac890627b06a71d12dc7a Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 3 Apr 2023 11:00:34 +0200 Subject: [PATCH 003/296] feat(build): remove dist --- core/pom.xml | 2 +- dist/pom.xml | 115 --------------------------------------------------- pom.xml | 14 ------- 3 files changed, 1 insertion(+), 130 deletions(-) delete mode 100644 dist/pom.xml diff --git a/core/pom.xml b/core/pom.xml index 602d6b4..dc79a10 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -127,7 +127,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.3.1-SNAPSHOT + 3.4.1 package diff --git a/dist/pom.xml b/dist/pom.xml deleted file mode 100644 index b1ecb77..0000000 --- a/dist/pom.xml +++ /dev/null @@ -1,115 +0,0 @@ - - - 4.0.0 - - - net.artelnatif - nicko-parent - 1.0-SNAPSHOT - - - dist - 1.0-SNAPSHOT - - - ../target - nicko-${project.version} - - - org.apache.maven.plugins - maven-shade-plugin - 3.3.1-SNAPSHOT - - - package - - shade - - - - - net.artelnatif:* - - - - - - - - - - - - net.artelnatif - core - ${project.parent.version} - - - net.artelnatif - v1_13_R1 - ${project.parent.version} - - - net.artelnatif - v1_13_R2 - ${project.parent.version} - - - net.artelnatif - v1_14_R1 - ${project.parent.version} - - - net.artelnatif - v1_15_R1 - ${project.parent.version} - - - net.artelnatif - v1_16_R1 - ${project.parent.version} - - - net.artelnatif - v1_16_R2 - ${project.parent.version} - - - net.artelnatif - v1_16_R3 - ${project.parent.version} - - - net.artelnatif - v1_17_R1 - ${project.parent.version} - - - net.artelnatif - v1_18_R1 - ${project.parent.version} - - - net.artelnatif - v1_18_R2 - ${project.parent.version} - - - net.artelnatif - v1_19_R1 - ${project.parent.version} - - - net.artelnatif - v1_19_R2 - ${project.parent.version} - - - net.artelnatif - v1_19_R3 - ${project.parent.version} - - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index c67c610..c2fa63a 100644 --- a/pom.xml +++ b/pom.xml @@ -12,20 +12,6 @@ core - dist - From d17aadc09a060fbbe11db13da50ecbe6f97355f6 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 3 Apr 2023 11:03:05 +0200 Subject: [PATCH 004/296] feat(build): rework structure --- core/pom.xml | 188 ------------------ pom.xml | 177 ++++++++++++++++- .../net/artelnatif/nicko/NickoBukkit.java | 0 .../artelnatif/nicko/anvil/AnvilManager.java | 0 .../nicko/appearance/AppearanceManager.java | 0 .../nicko/command/NickoCommand.java | 0 .../nicko/command/sub/NickoCheckSubCmd.java | 0 .../nicko/command/sub/NickoDebugSubCmd.java | 0 .../nicko/config/Configuration.java | 0 .../nicko/config/ConfigurationManager.java | 0 .../nicko/config/DataSourceConfiguration.java | 0 .../nicko/disguise/ActionResult.java | 0 .../nicko/disguise/NickoProfile.java | 0 .../nicko/event/PlayerJoinListener.java | 0 .../nicko/event/PlayerQuitListener.java | 0 .../net/artelnatif/nicko/gui/AdminGUI.java | 0 .../net/artelnatif/nicko/gui/MainGUI.java | 0 .../net/artelnatif/nicko/gui/SettingsGUI.java | 0 .../nicko/gui/admin/CacheManagementGUI.java | 0 .../gui/admin/cache/CacheDetailedGUI.java | 0 .../nicko/gui/items/admin/ManageCache.java | 0 .../gui/items/admin/cache/CacheDetailed.java | 0 .../items/admin/cache/CacheInvalidate.java | 0 .../gui/items/admin/cache/CacheOverview.java | 0 .../items/admin/cache/SkinPlaceholder.java | 0 .../nicko/gui/items/common/GoBack.java | 0 .../gui/items/common/OptionUnavailable.java | 0 .../nicko/gui/items/common/ScrollDown.java | 0 .../nicko/gui/items/common/ScrollUp.java | 0 .../nicko/gui/items/main/AdminSubGUI.java | 0 .../nicko/gui/items/main/ExitGUI.java | 0 .../nicko/gui/items/main/ResetAppearance.java | 0 .../nicko/gui/items/main/SettingsSubGUI.java | 0 .../gui/items/settings/BungeeCordCycling.java | 0 .../gui/items/settings/LanguageCycling.java | 0 .../nicko/gui/items/skin/ChangeName.java | 0 .../gui/items/skin/ChangeNameAndSkin.java | 0 .../nicko/gui/items/skin/ChangeSkin.java | 0 .../java/net/artelnatif/nicko/i18n/I18N.java | 0 .../net/artelnatif/nicko/i18n/I18NDict.java | 0 .../net/artelnatif/nicko/i18n/Locale.java | 0 .../nicko/i18n/LocaleFileManager.java | 0 .../artelnatif/nicko/mojang/MojangAPI.java | 0 .../artelnatif/nicko/mojang/MojangSkin.java | 0 .../artelnatif/nicko/mojang/MojangUtils.java | 0 .../nicko/placeholder/NickoExpansion.java | 0 .../nicko/placeholder/PlaceHolderHook.java | 0 .../nicko/storage/PlayerDataStore.java | 0 .../net/artelnatif/nicko/storage/Storage.java | 0 .../nicko/storage/StorageProvider.java | 0 .../artelnatif/nicko/storage/cache/Cache.java | 0 .../nicko/storage/cache/CacheProvider.java | 0 .../nicko/storage/cache/redis/RedisCache.java | 0 .../cache/redis/RedisCacheProvider.java | 0 .../nicko/storage/json/JSONStorage.java | 0 .../storage/json/JSONStorageProvider.java | 0 .../nicko/storage/name/PlayerNameStore.java | 0 .../nicko/storage/sql/SQLStorage.java | 0 .../nicko/storage/sql/SQLStorageProvider.java | 0 {core/src => src}/main/resources/config.yml | 0 {core/src => src}/main/resources/en.yml | 0 {core/src => src}/main/resources/fr.yml | 0 {core/src => src}/main/resources/plugin.yml | 0 .../nicko/test/NickoPluginTest.java | 0 .../nicko/test/config/ConfigurationTest.java | 0 .../nicko/test/storage/BrokenSQLTest.java | 0 .../nicko/test/storage/SQLStorageTest.java | 0 .../test/storage/cache/CacheStorageTest.java | 0 68 files changed, 171 insertions(+), 194 deletions(-) delete mode 100644 core/pom.xml rename {core/src => src}/main/java/net/artelnatif/nicko/NickoBukkit.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/anvil/AnvilManager.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/appearance/AppearanceManager.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/command/NickoCommand.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/command/sub/NickoCheckSubCmd.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/command/sub/NickoDebugSubCmd.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/config/Configuration.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/config/ConfigurationManager.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/config/DataSourceConfiguration.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/disguise/ActionResult.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/disguise/NickoProfile.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/event/PlayerJoinListener.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/event/PlayerQuitListener.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/AdminGUI.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/MainGUI.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/SettingsGUI.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/admin/CacheManagementGUI.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/admin/cache/CacheDetailedGUI.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/items/admin/ManageCache.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheDetailed.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheInvalidate.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheOverview.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/items/admin/cache/SkinPlaceholder.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/items/common/GoBack.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/items/common/OptionUnavailable.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/items/common/ScrollDown.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/items/common/ScrollUp.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/items/main/AdminSubGUI.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/items/main/ExitGUI.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/items/main/ResetAppearance.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/items/main/SettingsSubGUI.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/items/settings/BungeeCordCycling.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/items/settings/LanguageCycling.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/items/skin/ChangeName.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/items/skin/ChangeNameAndSkin.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/gui/items/skin/ChangeSkin.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/i18n/I18N.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/i18n/I18NDict.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/i18n/Locale.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/i18n/LocaleFileManager.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/mojang/MojangAPI.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/mojang/MojangSkin.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/mojang/MojangUtils.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/placeholder/NickoExpansion.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/placeholder/PlaceHolderHook.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/storage/PlayerDataStore.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/storage/Storage.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/storage/StorageProvider.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/storage/cache/Cache.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/storage/cache/CacheProvider.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/storage/cache/redis/RedisCache.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/storage/cache/redis/RedisCacheProvider.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/storage/json/JSONStorage.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/storage/json/JSONStorageProvider.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/storage/name/PlayerNameStore.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/storage/sql/SQLStorage.java (100%) rename {core/src => src}/main/java/net/artelnatif/nicko/storage/sql/SQLStorageProvider.java (100%) rename {core/src => src}/main/resources/config.yml (100%) rename {core/src => src}/main/resources/en.yml (100%) rename {core/src => src}/main/resources/fr.yml (100%) rename {core/src => src}/main/resources/plugin.yml (100%) rename {core/src => src}/test/java/net/artelnatif/nicko/test/NickoPluginTest.java (100%) rename {core/src => src}/test/java/net/artelnatif/nicko/test/config/ConfigurationTest.java (100%) rename {core/src => src}/test/java/net/artelnatif/nicko/test/storage/BrokenSQLTest.java (100%) rename {core/src => src}/test/java/net/artelnatif/nicko/test/storage/SQLStorageTest.java (100%) rename {core/src => src}/test/java/net/artelnatif/nicko/test/storage/cache/CacheStorageTest.java (100%) diff --git a/core/pom.xml b/core/pom.xml deleted file mode 100644 index dc79a10..0000000 --- a/core/pom.xml +++ /dev/null @@ -1,188 +0,0 @@ - - - 4.0.0 - - core - 1.0-SNAPSHOT - - - net.artelnatif - nicko-parent - 1.0-SNAPSHOT - - - - UTF-8 - - - - - dmulloy2-repo - https://repo.dmulloy2.net/repository/public/ - - - papermc - https://repo.papermc.io/repository/maven-public/ - - - spigot-repo - https://hub.spigotmc.org/nexus/content/groups/public/ - - - codemc-snapshots - https://repo.codemc.io/repository/maven-snapshots/ - - - placeholderapi - https://repo.extendedclip.com/content/repositories/placeholderapi/ - - - - - - com.comphenix.protocol - ProtocolLib - 5.0.0-SNAPSHOT - provided - - - - me.clip - placeholderapi - 2.11.2 - provided - - - - org.spigotmc - spigot-api - 1.19.4-R0.1-SNAPSHOT - provided - - - - xyz.xenondevs.invui - invui - 1.0-SNAPSHOT - - - - net.wesjd - anvilgui - 1.6.3-SNAPSHOT - - - - com.google.guava - guava - 31.1-jre - provided - - - - com.github.seeseemelk - MockBukkit-v1.19 - 2.29.0 - test - - - - org.mariadb.jdbc - mariadb-java-client - 3.1.2 - - - - com.github.jsixface - yamlconfig - 1.1.2 - - - com.fasterxml.jackson.core - jackson-core - 2.13.3 - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - 2.13.3 - - - - redis.clients - jedis - 4.3.0 - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M7 - - - org.apache.maven.plugins - maven-shade-plugin - 3.4.1 - - - package - - shade - - - - - net.wesjd:anvilgui - xyz.xenondevs.invui:* - com.github.jsixface:* - com.fasterxml.jackson.dataformat - com.fasterxml.jackson.core - org.mariadb.jdbc - - - - - net.wesjd.anvilgui - net.artelnatif.libs.anvilgui - - - xyz.xenondevs.invui - net.artelnatif.libs.invui - - - com.github.jsixface - net.artelnatif.libs.yaml - - - com.fasterxml.jackson.dataformat - net.artelnatif.libs.jackson.yaml - - - com.fasterxml.jackson.core - net.artelnatif.libs.jackson.core - - - org.mariadb.jdbc - net.artelnatif.libs.mariadb - - - - false - - - - - - - - true - ${basedir}/src/main/resources/ - - - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index c2fa63a..d0ef690 100644 --- a/pom.xml +++ b/pom.xml @@ -5,17 +5,182 @@ 4.0.0 net.artelnatif - nicko-parent + nicko 1.0-SNAPSHOT Nicko - pom - - - core - 17 17 + UTF-8 + + + + dmulloy2-repo + https://repo.dmulloy2.net/repository/public/ + + + papermc + https://repo.papermc.io/repository/maven-public/ + + + spigot-repo + https://hub.spigotmc.org/nexus/content/groups/public/ + + + codemc-snapshots + https://repo.codemc.io/repository/maven-snapshots/ + + + placeholderapi + https://repo.extendedclip.com/content/repositories/placeholderapi/ + + + + + + com.comphenix.protocol + ProtocolLib + 5.0.0-SNAPSHOT + provided + + + + me.clip + placeholderapi + 2.11.2 + provided + + + + org.spigotmc + spigot-api + 1.19.4-R0.1-SNAPSHOT + provided + + + + xyz.xenondevs.invui + invui + 1.0-SNAPSHOT + + + + net.wesjd + anvilgui + 1.6.3-SNAPSHOT + + + + com.google.guava + guava + 31.1-jre + provided + + + + com.github.seeseemelk + MockBukkit-v1.19 + 2.29.0 + test + + + + org.mariadb.jdbc + mariadb-java-client + 3.1.2 + + + + com.github.jsixface + yamlconfig + 1.1.2 + + + com.fasterxml.jackson.core + jackson-core + 2.13.3 + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + 2.13.3 + + + + redis.clients + jedis + 4.3.0 + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M7 + + + org.apache.maven.plugins + maven-shade-plugin + 3.4.1 + + + package + + shade + + + + + net.wesjd:anvilgui + xyz.xenondevs.invui:* + com.github.jsixface:* + com.fasterxml.jackson.dataformat + com.fasterxml.jackson.core + org.mariadb.jdbc + + + + + net.wesjd.anvilgui + net.artelnatif.libs.anvilgui + + + xyz.xenondevs.invui + net.artelnatif.libs.invui + + + com.github.jsixface + net.artelnatif.libs.yaml + + + com.fasterxml.jackson.dataformat + net.artelnatif.libs.jackson.yaml + + + com.fasterxml.jackson.core + net.artelnatif.libs.jackson.core + + + org.mariadb.jdbc + net.artelnatif.libs.mariadb + + + + false + + + + + + + + true + ${basedir}/src/main/resources/ + + + \ No newline at end of file diff --git a/core/src/main/java/net/artelnatif/nicko/NickoBukkit.java b/src/main/java/net/artelnatif/nicko/NickoBukkit.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/NickoBukkit.java rename to src/main/java/net/artelnatif/nicko/NickoBukkit.java diff --git a/core/src/main/java/net/artelnatif/nicko/anvil/AnvilManager.java b/src/main/java/net/artelnatif/nicko/anvil/AnvilManager.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/anvil/AnvilManager.java rename to src/main/java/net/artelnatif/nicko/anvil/AnvilManager.java diff --git a/core/src/main/java/net/artelnatif/nicko/appearance/AppearanceManager.java b/src/main/java/net/artelnatif/nicko/appearance/AppearanceManager.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/appearance/AppearanceManager.java rename to src/main/java/net/artelnatif/nicko/appearance/AppearanceManager.java diff --git a/core/src/main/java/net/artelnatif/nicko/command/NickoCommand.java b/src/main/java/net/artelnatif/nicko/command/NickoCommand.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/command/NickoCommand.java rename to src/main/java/net/artelnatif/nicko/command/NickoCommand.java diff --git a/core/src/main/java/net/artelnatif/nicko/command/sub/NickoCheckSubCmd.java b/src/main/java/net/artelnatif/nicko/command/sub/NickoCheckSubCmd.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/command/sub/NickoCheckSubCmd.java rename to src/main/java/net/artelnatif/nicko/command/sub/NickoCheckSubCmd.java diff --git a/core/src/main/java/net/artelnatif/nicko/command/sub/NickoDebugSubCmd.java b/src/main/java/net/artelnatif/nicko/command/sub/NickoDebugSubCmd.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/command/sub/NickoDebugSubCmd.java rename to src/main/java/net/artelnatif/nicko/command/sub/NickoDebugSubCmd.java diff --git a/core/src/main/java/net/artelnatif/nicko/config/Configuration.java b/src/main/java/net/artelnatif/nicko/config/Configuration.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/config/Configuration.java rename to src/main/java/net/artelnatif/nicko/config/Configuration.java diff --git a/core/src/main/java/net/artelnatif/nicko/config/ConfigurationManager.java b/src/main/java/net/artelnatif/nicko/config/ConfigurationManager.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/config/ConfigurationManager.java rename to src/main/java/net/artelnatif/nicko/config/ConfigurationManager.java diff --git a/core/src/main/java/net/artelnatif/nicko/config/DataSourceConfiguration.java b/src/main/java/net/artelnatif/nicko/config/DataSourceConfiguration.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/config/DataSourceConfiguration.java rename to src/main/java/net/artelnatif/nicko/config/DataSourceConfiguration.java diff --git a/core/src/main/java/net/artelnatif/nicko/disguise/ActionResult.java b/src/main/java/net/artelnatif/nicko/disguise/ActionResult.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/disguise/ActionResult.java rename to src/main/java/net/artelnatif/nicko/disguise/ActionResult.java diff --git a/core/src/main/java/net/artelnatif/nicko/disguise/NickoProfile.java b/src/main/java/net/artelnatif/nicko/disguise/NickoProfile.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/disguise/NickoProfile.java rename to src/main/java/net/artelnatif/nicko/disguise/NickoProfile.java diff --git a/core/src/main/java/net/artelnatif/nicko/event/PlayerJoinListener.java b/src/main/java/net/artelnatif/nicko/event/PlayerJoinListener.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/event/PlayerJoinListener.java rename to src/main/java/net/artelnatif/nicko/event/PlayerJoinListener.java diff --git a/core/src/main/java/net/artelnatif/nicko/event/PlayerQuitListener.java b/src/main/java/net/artelnatif/nicko/event/PlayerQuitListener.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/event/PlayerQuitListener.java rename to src/main/java/net/artelnatif/nicko/event/PlayerQuitListener.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/AdminGUI.java b/src/main/java/net/artelnatif/nicko/gui/AdminGUI.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/AdminGUI.java rename to src/main/java/net/artelnatif/nicko/gui/AdminGUI.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/MainGUI.java b/src/main/java/net/artelnatif/nicko/gui/MainGUI.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/MainGUI.java rename to src/main/java/net/artelnatif/nicko/gui/MainGUI.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/SettingsGUI.java b/src/main/java/net/artelnatif/nicko/gui/SettingsGUI.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/SettingsGUI.java rename to src/main/java/net/artelnatif/nicko/gui/SettingsGUI.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/admin/CacheManagementGUI.java b/src/main/java/net/artelnatif/nicko/gui/admin/CacheManagementGUI.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/admin/CacheManagementGUI.java rename to src/main/java/net/artelnatif/nicko/gui/admin/CacheManagementGUI.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/admin/cache/CacheDetailedGUI.java b/src/main/java/net/artelnatif/nicko/gui/admin/cache/CacheDetailedGUI.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/admin/cache/CacheDetailedGUI.java rename to src/main/java/net/artelnatif/nicko/gui/admin/cache/CacheDetailedGUI.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/items/admin/ManageCache.java b/src/main/java/net/artelnatif/nicko/gui/items/admin/ManageCache.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/items/admin/ManageCache.java rename to src/main/java/net/artelnatif/nicko/gui/items/admin/ManageCache.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheDetailed.java b/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheDetailed.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheDetailed.java rename to src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheDetailed.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheInvalidate.java b/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheInvalidate.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheInvalidate.java rename to src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheInvalidate.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheOverview.java b/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheOverview.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheOverview.java rename to src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheOverview.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/SkinPlaceholder.java b/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/SkinPlaceholder.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/SkinPlaceholder.java rename to src/main/java/net/artelnatif/nicko/gui/items/admin/cache/SkinPlaceholder.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/items/common/GoBack.java b/src/main/java/net/artelnatif/nicko/gui/items/common/GoBack.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/items/common/GoBack.java rename to src/main/java/net/artelnatif/nicko/gui/items/common/GoBack.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/items/common/OptionUnavailable.java b/src/main/java/net/artelnatif/nicko/gui/items/common/OptionUnavailable.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/items/common/OptionUnavailable.java rename to src/main/java/net/artelnatif/nicko/gui/items/common/OptionUnavailable.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/items/common/ScrollDown.java b/src/main/java/net/artelnatif/nicko/gui/items/common/ScrollDown.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/items/common/ScrollDown.java rename to src/main/java/net/artelnatif/nicko/gui/items/common/ScrollDown.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/items/common/ScrollUp.java b/src/main/java/net/artelnatif/nicko/gui/items/common/ScrollUp.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/items/common/ScrollUp.java rename to src/main/java/net/artelnatif/nicko/gui/items/common/ScrollUp.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/items/main/AdminSubGUI.java b/src/main/java/net/artelnatif/nicko/gui/items/main/AdminSubGUI.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/items/main/AdminSubGUI.java rename to src/main/java/net/artelnatif/nicko/gui/items/main/AdminSubGUI.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/items/main/ExitGUI.java b/src/main/java/net/artelnatif/nicko/gui/items/main/ExitGUI.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/items/main/ExitGUI.java rename to src/main/java/net/artelnatif/nicko/gui/items/main/ExitGUI.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/items/main/ResetAppearance.java b/src/main/java/net/artelnatif/nicko/gui/items/main/ResetAppearance.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/items/main/ResetAppearance.java rename to src/main/java/net/artelnatif/nicko/gui/items/main/ResetAppearance.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/items/main/SettingsSubGUI.java b/src/main/java/net/artelnatif/nicko/gui/items/main/SettingsSubGUI.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/items/main/SettingsSubGUI.java rename to src/main/java/net/artelnatif/nicko/gui/items/main/SettingsSubGUI.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/items/settings/BungeeCordCycling.java b/src/main/java/net/artelnatif/nicko/gui/items/settings/BungeeCordCycling.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/items/settings/BungeeCordCycling.java rename to src/main/java/net/artelnatif/nicko/gui/items/settings/BungeeCordCycling.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/items/settings/LanguageCycling.java b/src/main/java/net/artelnatif/nicko/gui/items/settings/LanguageCycling.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/items/settings/LanguageCycling.java rename to src/main/java/net/artelnatif/nicko/gui/items/settings/LanguageCycling.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeName.java b/src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeName.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeName.java rename to src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeName.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeNameAndSkin.java b/src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeNameAndSkin.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeNameAndSkin.java rename to src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeNameAndSkin.java diff --git a/core/src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeSkin.java b/src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeSkin.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeSkin.java rename to src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeSkin.java diff --git a/core/src/main/java/net/artelnatif/nicko/i18n/I18N.java b/src/main/java/net/artelnatif/nicko/i18n/I18N.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/i18n/I18N.java rename to src/main/java/net/artelnatif/nicko/i18n/I18N.java diff --git a/core/src/main/java/net/artelnatif/nicko/i18n/I18NDict.java b/src/main/java/net/artelnatif/nicko/i18n/I18NDict.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/i18n/I18NDict.java rename to src/main/java/net/artelnatif/nicko/i18n/I18NDict.java diff --git a/core/src/main/java/net/artelnatif/nicko/i18n/Locale.java b/src/main/java/net/artelnatif/nicko/i18n/Locale.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/i18n/Locale.java rename to src/main/java/net/artelnatif/nicko/i18n/Locale.java diff --git a/core/src/main/java/net/artelnatif/nicko/i18n/LocaleFileManager.java b/src/main/java/net/artelnatif/nicko/i18n/LocaleFileManager.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/i18n/LocaleFileManager.java rename to src/main/java/net/artelnatif/nicko/i18n/LocaleFileManager.java diff --git a/core/src/main/java/net/artelnatif/nicko/mojang/MojangAPI.java b/src/main/java/net/artelnatif/nicko/mojang/MojangAPI.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/mojang/MojangAPI.java rename to src/main/java/net/artelnatif/nicko/mojang/MojangAPI.java diff --git a/core/src/main/java/net/artelnatif/nicko/mojang/MojangSkin.java b/src/main/java/net/artelnatif/nicko/mojang/MojangSkin.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/mojang/MojangSkin.java rename to src/main/java/net/artelnatif/nicko/mojang/MojangSkin.java diff --git a/core/src/main/java/net/artelnatif/nicko/mojang/MojangUtils.java b/src/main/java/net/artelnatif/nicko/mojang/MojangUtils.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/mojang/MojangUtils.java rename to src/main/java/net/artelnatif/nicko/mojang/MojangUtils.java diff --git a/core/src/main/java/net/artelnatif/nicko/placeholder/NickoExpansion.java b/src/main/java/net/artelnatif/nicko/placeholder/NickoExpansion.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/placeholder/NickoExpansion.java rename to src/main/java/net/artelnatif/nicko/placeholder/NickoExpansion.java diff --git a/core/src/main/java/net/artelnatif/nicko/placeholder/PlaceHolderHook.java b/src/main/java/net/artelnatif/nicko/placeholder/PlaceHolderHook.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/placeholder/PlaceHolderHook.java rename to src/main/java/net/artelnatif/nicko/placeholder/PlaceHolderHook.java diff --git a/core/src/main/java/net/artelnatif/nicko/storage/PlayerDataStore.java b/src/main/java/net/artelnatif/nicko/storage/PlayerDataStore.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/storage/PlayerDataStore.java rename to src/main/java/net/artelnatif/nicko/storage/PlayerDataStore.java diff --git a/core/src/main/java/net/artelnatif/nicko/storage/Storage.java b/src/main/java/net/artelnatif/nicko/storage/Storage.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/storage/Storage.java rename to src/main/java/net/artelnatif/nicko/storage/Storage.java diff --git a/core/src/main/java/net/artelnatif/nicko/storage/StorageProvider.java b/src/main/java/net/artelnatif/nicko/storage/StorageProvider.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/storage/StorageProvider.java rename to src/main/java/net/artelnatif/nicko/storage/StorageProvider.java diff --git a/core/src/main/java/net/artelnatif/nicko/storage/cache/Cache.java b/src/main/java/net/artelnatif/nicko/storage/cache/Cache.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/storage/cache/Cache.java rename to src/main/java/net/artelnatif/nicko/storage/cache/Cache.java diff --git a/core/src/main/java/net/artelnatif/nicko/storage/cache/CacheProvider.java b/src/main/java/net/artelnatif/nicko/storage/cache/CacheProvider.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/storage/cache/CacheProvider.java rename to src/main/java/net/artelnatif/nicko/storage/cache/CacheProvider.java diff --git a/core/src/main/java/net/artelnatif/nicko/storage/cache/redis/RedisCache.java b/src/main/java/net/artelnatif/nicko/storage/cache/redis/RedisCache.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/storage/cache/redis/RedisCache.java rename to src/main/java/net/artelnatif/nicko/storage/cache/redis/RedisCache.java diff --git a/core/src/main/java/net/artelnatif/nicko/storage/cache/redis/RedisCacheProvider.java b/src/main/java/net/artelnatif/nicko/storage/cache/redis/RedisCacheProvider.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/storage/cache/redis/RedisCacheProvider.java rename to src/main/java/net/artelnatif/nicko/storage/cache/redis/RedisCacheProvider.java diff --git a/core/src/main/java/net/artelnatif/nicko/storage/json/JSONStorage.java b/src/main/java/net/artelnatif/nicko/storage/json/JSONStorage.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/storage/json/JSONStorage.java rename to src/main/java/net/artelnatif/nicko/storage/json/JSONStorage.java diff --git a/core/src/main/java/net/artelnatif/nicko/storage/json/JSONStorageProvider.java b/src/main/java/net/artelnatif/nicko/storage/json/JSONStorageProvider.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/storage/json/JSONStorageProvider.java rename to src/main/java/net/artelnatif/nicko/storage/json/JSONStorageProvider.java diff --git a/core/src/main/java/net/artelnatif/nicko/storage/name/PlayerNameStore.java b/src/main/java/net/artelnatif/nicko/storage/name/PlayerNameStore.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/storage/name/PlayerNameStore.java rename to src/main/java/net/artelnatif/nicko/storage/name/PlayerNameStore.java diff --git a/core/src/main/java/net/artelnatif/nicko/storage/sql/SQLStorage.java b/src/main/java/net/artelnatif/nicko/storage/sql/SQLStorage.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/storage/sql/SQLStorage.java rename to src/main/java/net/artelnatif/nicko/storage/sql/SQLStorage.java diff --git a/core/src/main/java/net/artelnatif/nicko/storage/sql/SQLStorageProvider.java b/src/main/java/net/artelnatif/nicko/storage/sql/SQLStorageProvider.java similarity index 100% rename from core/src/main/java/net/artelnatif/nicko/storage/sql/SQLStorageProvider.java rename to src/main/java/net/artelnatif/nicko/storage/sql/SQLStorageProvider.java diff --git a/core/src/main/resources/config.yml b/src/main/resources/config.yml similarity index 100% rename from core/src/main/resources/config.yml rename to src/main/resources/config.yml diff --git a/core/src/main/resources/en.yml b/src/main/resources/en.yml similarity index 100% rename from core/src/main/resources/en.yml rename to src/main/resources/en.yml diff --git a/core/src/main/resources/fr.yml b/src/main/resources/fr.yml similarity index 100% rename from core/src/main/resources/fr.yml rename to src/main/resources/fr.yml diff --git a/core/src/main/resources/plugin.yml b/src/main/resources/plugin.yml similarity index 100% rename from core/src/main/resources/plugin.yml rename to src/main/resources/plugin.yml diff --git a/core/src/test/java/net/artelnatif/nicko/test/NickoPluginTest.java b/src/test/java/net/artelnatif/nicko/test/NickoPluginTest.java similarity index 100% rename from core/src/test/java/net/artelnatif/nicko/test/NickoPluginTest.java rename to src/test/java/net/artelnatif/nicko/test/NickoPluginTest.java diff --git a/core/src/test/java/net/artelnatif/nicko/test/config/ConfigurationTest.java b/src/test/java/net/artelnatif/nicko/test/config/ConfigurationTest.java similarity index 100% rename from core/src/test/java/net/artelnatif/nicko/test/config/ConfigurationTest.java rename to src/test/java/net/artelnatif/nicko/test/config/ConfigurationTest.java diff --git a/core/src/test/java/net/artelnatif/nicko/test/storage/BrokenSQLTest.java b/src/test/java/net/artelnatif/nicko/test/storage/BrokenSQLTest.java similarity index 100% rename from core/src/test/java/net/artelnatif/nicko/test/storage/BrokenSQLTest.java rename to src/test/java/net/artelnatif/nicko/test/storage/BrokenSQLTest.java diff --git a/core/src/test/java/net/artelnatif/nicko/test/storage/SQLStorageTest.java b/src/test/java/net/artelnatif/nicko/test/storage/SQLStorageTest.java similarity index 100% rename from core/src/test/java/net/artelnatif/nicko/test/storage/SQLStorageTest.java rename to src/test/java/net/artelnatif/nicko/test/storage/SQLStorageTest.java diff --git a/core/src/test/java/net/artelnatif/nicko/test/storage/cache/CacheStorageTest.java b/src/test/java/net/artelnatif/nicko/test/storage/cache/CacheStorageTest.java similarity index 100% rename from core/src/test/java/net/artelnatif/nicko/test/storage/cache/CacheStorageTest.java rename to src/test/java/net/artelnatif/nicko/test/storage/cache/CacheStorageTest.java From fd732fc88656ff32340ceaa87b1582d900c914fb Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 3 Apr 2023 12:15:47 +0200 Subject: [PATCH 005/296] feat: use packetevents --- dependency-reduced-pom.xml | 164 ++++++++++++++++++ pom.xml | 10 +- .../net/artelnatif/nicko/NickoBukkit.java | 6 - .../nicko/appearance/AppearanceManager.java | 100 +++++------ src/main/resources/plugin.yml | 3 +- 5 files changed, 220 insertions(+), 63 deletions(-) create mode 100644 dependency-reduced-pom.xml diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml new file mode 100644 index 0000000..f502d6a --- /dev/null +++ b/dependency-reduced-pom.xml @@ -0,0 +1,164 @@ + + + 4.0.0 + net.artelnatif + nicko + Nicko + 1.0-SNAPSHOT + + + + true + ${basedir}/src/main/resources/ + + + + + maven-surefire-plugin + 3.0.0-M7 + + + maven-shade-plugin + 3.4.1 + + + package + + shade + + + + + net.wesjd:anvilgui + xyz.xenondevs.invui:* + com.github.jsixface:* + com.fasterxml.jackson.dataformat + com.fasterxml.jackson.core + org.mariadb.jdbc + + + + + net.wesjd.anvilgui + net.artelnatif.libs.anvilgui + + + xyz.xenondevs.invui + net.artelnatif.libs.invui + + + com.github.jsixface + net.artelnatif.libs.yaml + + + com.fasterxml.jackson.dataformat + net.artelnatif.libs.jackson.yaml + + + com.fasterxml.jackson.core + net.artelnatif.libs.jackson.core + + + org.mariadb.jdbc + net.artelnatif.libs.mariadb + + + false + + + + + + + + + papermc + https://repo.papermc.io/repository/maven-public/ + + + spigot-repo + https://hub.spigotmc.org/nexus/content/groups/public/ + + + codemc-snapshots + https://repo.codemc.io/repository/maven-snapshots/ + + + placeholderapi + https://repo.extendedclip.com/content/repositories/placeholderapi/ + + + + + com.github.retrooper.packetevents + spigot + 2.0.0-SNAPSHOT + provided + + + me.clip + placeholderapi + 2.11.2 + provided + + + org.spigotmc + spigot-api + 1.19.4-R0.1-SNAPSHOT + provided + + + com.google.guava + guava + 31.1-jre + provided + + + com.github.seeseemelk + MockBukkit-v1.19 + 2.29.0 + test + + + paper-api + io.papermc.paper + + + junit-jupiter + org.junit.jupiter + + + hamcrest-library + org.hamcrest + + + adventure-platform-bungeecord + net.kyori + + + maven-resolver-provider + org.apache.maven + + + maven-resolver-connector-basic + org.apache.maven.resolver + + + maven-resolver-transport-http + org.apache.maven.resolver + + + + + redis.clients + jedis + 4.3.0 + compile + + + + 17 + 17 + UTF-8 + + diff --git a/pom.xml b/pom.xml index d0ef690..d975ad7 100644 --- a/pom.xml +++ b/pom.xml @@ -16,10 +16,6 @@ - - dmulloy2-repo - https://repo.dmulloy2.net/repository/public/ - papermc https://repo.papermc.io/repository/maven-public/ @@ -40,9 +36,9 @@ - com.comphenix.protocol - ProtocolLib - 5.0.0-SNAPSHOT + com.github.retrooper.packetevents + spigot + 2.0.0-SNAPSHOT provided diff --git a/src/main/java/net/artelnatif/nicko/NickoBukkit.java b/src/main/java/net/artelnatif/nicko/NickoBukkit.java index fc8e1bf..c8a798b 100644 --- a/src/main/java/net/artelnatif/nicko/NickoBukkit.java +++ b/src/main/java/net/artelnatif/nicko/NickoBukkit.java @@ -1,7 +1,5 @@ package net.artelnatif.nicko; -import com.comphenix.protocol.ProtocolLibrary; -import com.comphenix.protocol.ProtocolManager; import net.artelnatif.nicko.command.NickoCommand; import net.artelnatif.nicko.config.Configuration; import net.artelnatif.nicko.config.ConfigurationManager; @@ -39,7 +37,6 @@ public class NickoBukkit extends JavaPlugin { private Configuration configuration; private LocaleFileManager localeFileManager; private PlayerNameStore nameStore; - private ProtocolManager protocolManager; public NickoBukkit() { this.unitTesting = false; } @@ -66,7 +63,6 @@ public class NickoBukkit extends JavaPlugin { configurationManager = new ConfigurationManager(getDataFolder()); configurationManager.saveDefaultConfig(); - protocolManager = ProtocolLibrary.getProtocolManager(); mojangAPI = new MojangAPI(); dataStore = new PlayerDataStore(mojangAPI, getNickoConfig()); nameStore = new PlayerNameStore(); @@ -154,6 +150,4 @@ public class NickoBukkit extends JavaPlugin { public LocaleFileManager getLocaleFileManager() { return localeFileManager; } - - public ProtocolManager getProtocolManager() { return protocolManager; } } diff --git a/src/main/java/net/artelnatif/nicko/appearance/AppearanceManager.java b/src/main/java/net/artelnatif/nicko/appearance/AppearanceManager.java index 7ce4a3b..e182d64 100644 --- a/src/main/java/net/artelnatif/nicko/appearance/AppearanceManager.java +++ b/src/main/java/net/artelnatif/nicko/appearance/AppearanceManager.java @@ -1,9 +1,13 @@ package net.artelnatif.nicko.appearance; -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.wrappers.*; -import com.google.common.collect.Multimap; +import com.github.retrooper.packetevents.PacketEvents; +import com.github.retrooper.packetevents.protocol.player.TextureProperty; +import com.github.retrooper.packetevents.protocol.player.UserProfile; +import com.github.retrooper.packetevents.protocol.world.Difficulty; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoRemove; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerRespawn; +import io.github.retrooper.packetevents.util.SpigotConversionUtil; import net.artelnatif.nicko.NickoBukkit; import net.artelnatif.nicko.disguise.ActionResult; import net.artelnatif.nicko.disguise.NickoProfile; @@ -12,14 +16,15 @@ import net.artelnatif.nicko.mojang.MojangAPI; import net.artelnatif.nicko.mojang.MojangSkin; import net.artelnatif.nicko.storage.PlayerDataStore; import net.artelnatif.nicko.storage.name.PlayerNameStore; +import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.entity.Player; import java.io.IOException; +import java.util.EnumSet; import java.util.List; import java.util.Optional; -import java.util.Set; import java.util.UUID; import java.util.concurrent.ExecutionException; @@ -99,16 +104,17 @@ public class AppearanceManager { public ActionResult updatePlayer(boolean skinChange) { final String displayName = profile.getName() == null ? player.getName() : profile.getName(); - final WrappedGameProfile gameProfile = new WrappedGameProfile(player.getUniqueId(), displayName); + Bukkit.broadcastMessage("Building UserProfile"); + final UserProfile userProfile = new UserProfile(player.getUniqueId(), displayName); - final ActionResult result = updateGameProfileSkin(gameProfile, skinChange); + final ActionResult result = updateGameProfileSkin(userProfile, skinChange); if (!result.isError()) { - updateTabList(gameProfile, displayName); + updateTabList(userProfile, displayName); } return new ActionResult<>(); } - private ActionResult updateGameProfileSkin(WrappedGameProfile gameProfile, boolean skinChange) { + private ActionResult updateGameProfileSkin(UserProfile userProfile, boolean skinChange) { final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); if (skinChange || changeOnlyName) { @@ -120,9 +126,9 @@ public class AppearanceManager { skin = mojang.getSkin(uuid.get()); if (skin.isPresent()) { final MojangSkin skinResult = skin.get(); - final Multimap properties = gameProfile.getProperties(); - properties.removeAll("textures"); - properties.put("textures", new WrappedSignedProperty("textures", skinResult.getValue(), skinResult.getSignature())); + final List properties = userProfile.getTextureProperties(); + properties.clear(); + properties.add(new TextureProperty("textures", skinResult.getValue(), skinResult.getSignature())); Bukkit.broadcastMessage("Modified properties"); } } @@ -139,47 +145,43 @@ public class AppearanceManager { } private void respawnPlayer() { - final PacketContainer respawnOtherWorld = getRespawnPacket(Bukkit.getWorld("world_the_end")); - final PacketContainer respawn = getRespawnPacket(player.getWorld()); - instance.getProtocolManager().sendServerPacket(player, respawnOtherWorld); - instance.getProtocolManager().sendServerPacket(player, respawn); + final World world = player.getWorld(); + final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn( + SpigotConversionUtil.fromBukkitWorld(world), + world.getName(), + Difficulty.getById(world.getDifficulty().ordinal()), + world.getSeed(), + SpigotConversionUtil.fromBukkitGameMode(player.getGameMode()), + null, + false, + false, + false, + null, + null + ); + PacketEvents.getAPI().getPlayerManager().sendPacket(player, respawn); } - private PacketContainer getRespawnPacket(World world) { - final PacketContainer packet = new PacketContainer(PacketType.Play.Server.RESPAWN); - final EnumWrappers.NativeGameMode gamemode = EnumWrappers.NativeGameMode.fromBukkit(player.getGameMode()); - packet.getWorldKeys().write(0, world); - packet.getLongs().write(0, world.getSeed()); - - packet.getGameModes().write(0, gamemode); // gamemode - packet.getGameModes().write(1, gamemode); // previous gamemode - - packet.getBooleans().write(0, false); - packet.getBooleans().write(1, false); - return packet; - } - - private void updateTabList(WrappedGameProfile gameProfile, String displayName) { - final PacketContainer infoAdd = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); - infoAdd.getPlayerInfoActions().write(0, Set.of( - EnumWrappers.PlayerInfoAction.ADD_PLAYER, - EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE, - EnumWrappers.PlayerInfoAction.UPDATE_DISPLAY_NAME, - EnumWrappers.PlayerInfoAction.UPDATE_LISTED, - EnumWrappers.PlayerInfoAction.UPDATE_LATENCY + private void updateTabList(UserProfile userProfile, String displayName) { + final WrapperPlayServerPlayerInfoUpdate infoAdd = new WrapperPlayServerPlayerInfoUpdate(EnumSet.of( + WrapperPlayServerPlayerInfoUpdate.Action.ADD_PLAYER, + WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_GAME_MODE, + WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_DISPLAY_NAME, + WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_LISTED, + WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_LATENCY + ), new WrapperPlayServerPlayerInfoUpdate.PlayerInfo( + userProfile, + true, + 0, + SpigotConversionUtil.fromBukkitGameMode(player.getGameMode()), + Component.text(displayName), + null )); - infoAdd.getPlayerInfoDataLists().write(1, List.of(new PlayerInfoData( - gameProfile, - 0, - EnumWrappers.NativeGameMode.fromBukkit(player.getGameMode()), - WrappedChatComponent.fromText(displayName) - ))); + final WrapperPlayServerPlayerInfoRemove infoRemove = new WrapperPlayServerPlayerInfoRemove(player.getUniqueId()); + Bukkit.broadcastMessage("Updating tablist"); + PacketEvents.getAPI().getPlayerManager().sendPacket(player, infoRemove); + PacketEvents.getAPI().getPlayerManager().sendPacket(player, infoAdd); - final PacketContainer infoRemove = new PacketContainer(PacketType.Play.Server.PLAYER_INFO_REMOVE); - infoRemove.getUUIDLists().write(0, List.of(player.getUniqueId())); - - instance.getProtocolManager().broadcastServerPacket(infoRemove); - instance.getProtocolManager().broadcastServerPacket(infoAdd); } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index af81d31..9599f7a 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -4,7 +4,8 @@ version: 1.0-SNAPSHOT author: Ineanto api-version: 1.13 softdepend: [ PlaceholderAPI ] -depend: [ ProtocolLib ] +load: POSTWORLD +depend: [ packetevents ] commands: nicko: description: "Opens Nicko's GUI." From 7f3ecddc5198c97652ed5ad98eff81fb724dca3a Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 25 Apr 2023 18:34:49 +0200 Subject: [PATCH 006/296] feat: protocollib, java 8 --- .gitignore | 3 +- dependency-reduced-pom.xml | 16 +- pom.xml | 20 ++- .../net/artelnatif/nicko/NickoBukkit.java | 6 + .../artelnatif/nicko/anvil/AnvilManager.java | 2 +- .../nicko/command/sub/NickoCheckSubCmd.java | 2 +- .../nicko/command/sub/NickoDebugSubCmd.java | 2 +- .../AppearanceManager.java | 75 +++------- .../nicko/event/PlayerJoinListener.java | 2 +- .../nicko/gui/items/main/ResetAppearance.java | 2 +- .../artelnatif/nicko/mojang/MojangAPI.java | 2 +- .../nicko/wrapper/AbstractPacket.java | 88 +++++++++++ .../wrapper/WrapperPlayServerRespawn.java | 37 +++++ src/main/resources/plugin.yml | 1 - v1_19_R3/pom.xml | 68 +++++++++ .../net/artelnatif/nicko/impl/v1_19_R3.java | 140 ++++++++++++++++++ 16 files changed, 387 insertions(+), 79 deletions(-) rename src/main/java/net/artelnatif/nicko/{appearance => disguise}/AppearanceManager.java (57%) create mode 100644 src/main/java/net/artelnatif/nicko/wrapper/AbstractPacket.java create mode 100644 src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java create mode 100644 v1_19_R3/pom.xml create mode 100644 v1_19_R3/src/main/java/net/artelnatif/nicko/impl/v1_19_R3.java diff --git a/.gitignore b/.gitignore index d7a802e..67f8558 100644 --- a/.gitignore +++ b/.gitignore @@ -46,5 +46,4 @@ v1_19_R1/target target # Maven Dependency Reduced Pom -dist/dependency-reduced-pom.xml -core/dependency-reduced-pom.xml \ No newline at end of file +dependency-reduced-pom.xml \ No newline at end of file diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index f502d6a..5f3a8ad 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -87,13 +87,17 @@ placeholderapi https://repo.extendedclip.com/content/repositories/placeholderapi/ + + dmulloy2-repo + https://repo.dmulloy2.net/repository/public/ + - com.github.retrooper.packetevents - spigot - 2.0.0-SNAPSHOT - provided + com.comphenix.protocol + ProtocolLib + 5.0.0-SNAPSHOT + compile me.clip @@ -157,8 +161,8 @@ - 17 - 17 + 8 + 8 UTF-8 diff --git a/pom.xml b/pom.xml index d975ad7..be4c70f 100644 --- a/pom.xml +++ b/pom.xml @@ -10,8 +10,8 @@ Nicko - 17 - 17 + 8 + 8 UTF-8 @@ -32,15 +32,19 @@ placeholderapi https://repo.extendedclip.com/content/repositories/placeholderapi/ + + dmulloy2-repo + https://repo.dmulloy2.net/repository/public/ + - - com.github.retrooper.packetevents - spigot - 2.0.0-SNAPSHOT - provided - + + com.comphenix.protocol + ProtocolLib + 5.0.0-SNAPSHOT + + me.clip diff --git a/src/main/java/net/artelnatif/nicko/NickoBukkit.java b/src/main/java/net/artelnatif/nicko/NickoBukkit.java index c8a798b..8310406 100644 --- a/src/main/java/net/artelnatif/nicko/NickoBukkit.java +++ b/src/main/java/net/artelnatif/nicko/NickoBukkit.java @@ -1,5 +1,7 @@ package net.artelnatif.nicko; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.ProtocolManager; import net.artelnatif.nicko.command.NickoCommand; import net.artelnatif.nicko.config.Configuration; import net.artelnatif.nicko.config.ConfigurationManager; @@ -37,6 +39,7 @@ public class NickoBukkit extends JavaPlugin { private Configuration configuration; private LocaleFileManager localeFileManager; private PlayerNameStore nameStore; + private ProtocolManager protocolManager; public NickoBukkit() { this.unitTesting = false; } @@ -76,6 +79,7 @@ public class NickoBukkit extends JavaPlugin { } if (!unitTesting) { + protocolManager = ProtocolLibrary.getProtocolManager(); localeFileManager = new LocaleFileManager(); if (configuration.isCustomLocale()) { if (localeFileManager.dumpFromLocale(Locale.ENGLISH)) { @@ -150,4 +154,6 @@ public class NickoBukkit extends JavaPlugin { public LocaleFileManager getLocaleFileManager() { return localeFileManager; } + + public ProtocolManager getProtocolManager() { return protocolManager; } } diff --git a/src/main/java/net/artelnatif/nicko/anvil/AnvilManager.java b/src/main/java/net/artelnatif/nicko/anvil/AnvilManager.java index b82d18d..6e53506 100644 --- a/src/main/java/net/artelnatif/nicko/anvil/AnvilManager.java +++ b/src/main/java/net/artelnatif/nicko/anvil/AnvilManager.java @@ -1,7 +1,7 @@ package net.artelnatif.nicko.anvil; import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.appearance.AppearanceManager; +import net.artelnatif.nicko.disguise.AppearanceManager; import net.artelnatif.nicko.disguise.ActionResult; import net.artelnatif.nicko.i18n.I18N; import net.artelnatif.nicko.i18n.I18NDict; diff --git a/src/main/java/net/artelnatif/nicko/command/sub/NickoCheckSubCmd.java b/src/main/java/net/artelnatif/nicko/command/sub/NickoCheckSubCmd.java index 848a87b..56a4614 100644 --- a/src/main/java/net/artelnatif/nicko/command/sub/NickoCheckSubCmd.java +++ b/src/main/java/net/artelnatif/nicko/command/sub/NickoCheckSubCmd.java @@ -1,7 +1,7 @@ package net.artelnatif.nicko.command.sub; import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.appearance.AppearanceManager; +import net.artelnatif.nicko.disguise.AppearanceManager; import net.artelnatif.nicko.i18n.I18N; import net.artelnatif.nicko.i18n.I18NDict; import net.artelnatif.nicko.mojang.MojangUtils; diff --git a/src/main/java/net/artelnatif/nicko/command/sub/NickoDebugSubCmd.java b/src/main/java/net/artelnatif/nicko/command/sub/NickoDebugSubCmd.java index b691de9..e7490ba 100644 --- a/src/main/java/net/artelnatif/nicko/command/sub/NickoDebugSubCmd.java +++ b/src/main/java/net/artelnatif/nicko/command/sub/NickoDebugSubCmd.java @@ -1,7 +1,7 @@ package net.artelnatif.nicko.command.sub; import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.appearance.AppearanceManager; +import net.artelnatif.nicko.disguise.AppearanceManager; import net.artelnatif.nicko.mojang.MojangUtils; import org.bukkit.Bukkit; import org.bukkit.Sound; diff --git a/src/main/java/net/artelnatif/nicko/appearance/AppearanceManager.java b/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java similarity index 57% rename from src/main/java/net/artelnatif/nicko/appearance/AppearanceManager.java rename to src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java index e182d64..2cde36d 100644 --- a/src/main/java/net/artelnatif/nicko/appearance/AppearanceManager.java +++ b/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java @@ -1,29 +1,20 @@ -package net.artelnatif.nicko.appearance; +package net.artelnatif.nicko.disguise; -import com.github.retrooper.packetevents.PacketEvents; -import com.github.retrooper.packetevents.protocol.player.TextureProperty; -import com.github.retrooper.packetevents.protocol.player.UserProfile; -import com.github.retrooper.packetevents.protocol.world.Difficulty; -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoRemove; -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate; -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerRespawn; -import io.github.retrooper.packetevents.util.SpigotConversionUtil; +import com.comphenix.protocol.wrappers.WrappedGameProfile; +import com.comphenix.protocol.wrappers.WrappedSignedProperty; import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; import net.artelnatif.nicko.i18n.I18NDict; import net.artelnatif.nicko.mojang.MojangAPI; import net.artelnatif.nicko.mojang.MojangSkin; import net.artelnatif.nicko.storage.PlayerDataStore; import net.artelnatif.nicko.storage.name.PlayerNameStore; -import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerTeleportEvent; import java.io.IOException; -import java.util.EnumSet; -import java.util.List; +import java.util.Collection; import java.util.Optional; import java.util.UUID; import java.util.concurrent.ExecutionException; @@ -105,16 +96,17 @@ public class AppearanceManager { public ActionResult updatePlayer(boolean skinChange) { final String displayName = profile.getName() == null ? player.getName() : profile.getName(); Bukkit.broadcastMessage("Building UserProfile"); - final UserProfile userProfile = new UserProfile(player.getUniqueId(), displayName); + final WrappedGameProfile gameProfile = new WrappedGameProfile(player.getUniqueId(), displayName); - final ActionResult result = updateGameProfileSkin(userProfile, skinChange); + final ActionResult result = updateGameProfileSkin(gameProfile, skinChange); if (!result.isError()) { - updateTabList(userProfile, displayName); + updateTabList(gameProfile, displayName); + respawnPlayer(); } return new ActionResult<>(); } - private ActionResult updateGameProfileSkin(UserProfile userProfile, boolean skinChange) { + private ActionResult updateGameProfileSkin(WrappedGameProfile gameProfile, boolean skinChange) { final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); if (skinChange || changeOnlyName) { @@ -126,14 +118,12 @@ public class AppearanceManager { skin = mojang.getSkin(uuid.get()); if (skin.isPresent()) { final MojangSkin skinResult = skin.get(); - final List properties = userProfile.getTextureProperties(); + final Collection properties = gameProfile.getProperties().values(); properties.clear(); - properties.add(new TextureProperty("textures", skinResult.getValue(), skinResult.getSignature())); + properties.add(new WrappedSignedProperty("textures", skinResult.getValue(), skinResult.getSignature())); Bukkit.broadcastMessage("Modified properties"); } } - Bukkit.broadcastMessage("Respawning player"); - respawnPlayer(); return new ActionResult<>(); } catch (ExecutionException e) { return new ActionResult<>(I18NDict.Error.SKIN_FAIL_CACHE); @@ -145,43 +135,16 @@ public class AppearanceManager { } private void respawnPlayer() { + Bukkit.broadcastMessage("Respawning player"); final World world = player.getWorld(); - final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn( - SpigotConversionUtil.fromBukkitWorld(world), - world.getName(), - Difficulty.getById(world.getDifficulty().ordinal()), - world.getSeed(), - SpigotConversionUtil.fromBukkitGameMode(player.getGameMode()), - null, - false, - false, - false, - null, - null - ); - PacketEvents.getAPI().getPlayerManager().sendPacket(player, respawn); + // TODO (Ineanto, 4/23/23): Respawn Packet + player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); } - private void updateTabList(UserProfile userProfile, String displayName) { - final WrapperPlayServerPlayerInfoUpdate infoAdd = new WrapperPlayServerPlayerInfoUpdate(EnumSet.of( - WrapperPlayServerPlayerInfoUpdate.Action.ADD_PLAYER, - WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_GAME_MODE, - WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_DISPLAY_NAME, - WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_LISTED, - WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_LATENCY - ), new WrapperPlayServerPlayerInfoUpdate.PlayerInfo( - userProfile, - true, - 0, - SpigotConversionUtil.fromBukkitGameMode(player.getGameMode()), - Component.text(displayName), - null - )); - - final WrapperPlayServerPlayerInfoRemove infoRemove = new WrapperPlayServerPlayerInfoRemove(player.getUniqueId()); + private void updateTabList(WrappedGameProfile gameProfile, String displayName) { + // TODO (Ineanto, 4/23/23): Update player info packet + // TODO (Ineanto, 4/23/23): Remove player info packet Bukkit.broadcastMessage("Updating tablist"); - PacketEvents.getAPI().getPlayerManager().sendPacket(player, infoRemove); - PacketEvents.getAPI().getPlayerManager().sendPacket(player, infoAdd); - + // TODO (Ineanto, 4/23/23): Send packets } } diff --git a/src/main/java/net/artelnatif/nicko/event/PlayerJoinListener.java b/src/main/java/net/artelnatif/nicko/event/PlayerJoinListener.java index fc1a3c4..d78ff18 100644 --- a/src/main/java/net/artelnatif/nicko/event/PlayerJoinListener.java +++ b/src/main/java/net/artelnatif/nicko/event/PlayerJoinListener.java @@ -1,7 +1,7 @@ package net.artelnatif.nicko.event; import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.appearance.AppearanceManager; +import net.artelnatif.nicko.disguise.AppearanceManager; import net.artelnatif.nicko.disguise.ActionResult; import net.artelnatif.nicko.disguise.NickoProfile; import net.artelnatif.nicko.i18n.I18N; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/main/ResetAppearance.java b/src/main/java/net/artelnatif/nicko/gui/items/main/ResetAppearance.java index 48fa0d6..3c1e8c1 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/main/ResetAppearance.java +++ b/src/main/java/net/artelnatif/nicko/gui/items/main/ResetAppearance.java @@ -1,6 +1,6 @@ package net.artelnatif.nicko.gui.items.main; -import net.artelnatif.nicko.appearance.AppearanceManager; +import net.artelnatif.nicko.disguise.AppearanceManager; import net.artelnatif.nicko.i18n.I18N; import net.artelnatif.nicko.i18n.I18NDict; import org.bukkit.Material; diff --git a/src/main/java/net/artelnatif/nicko/mojang/MojangAPI.java b/src/main/java/net/artelnatif/nicko/mojang/MojangAPI.java index 7c1f852..d8b3bf2 100644 --- a/src/main/java/net/artelnatif/nicko/mojang/MojangAPI.java +++ b/src/main/java/net/artelnatif/nicko/mojang/MojangAPI.java @@ -25,7 +25,7 @@ public class MojangAPI { private final Logger logger = Logger.getLogger("MojangAPI"); - private final CacheLoader> loader = new CacheLoader<>() { + private final CacheLoader> loader = new CacheLoader>() { @Nonnull public Optional load(@Nonnull String uuid) throws Exception { return getSkinFromMojang(uuid); diff --git a/src/main/java/net/artelnatif/nicko/wrapper/AbstractPacket.java b/src/main/java/net/artelnatif/nicko/wrapper/AbstractPacket.java new file mode 100644 index 0000000..f636bf3 --- /dev/null +++ b/src/main/java/net/artelnatif/nicko/wrapper/AbstractPacket.java @@ -0,0 +1,88 @@ +/** + * PacketWrapper - ProtocolLib wrappers for Minecraft packets + * Copyright (C) dmulloy2 + * Copyright (C) Kristian S. Strangeland + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.artelnatif.nicko.wrapper; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.PacketContainer; +import com.google.common.base.Objects; +import org.bukkit.entity.Player; + +public abstract class AbstractPacket { + protected PacketContainer handle; + + /** + * Constructs a new strongly typed wrapper for the given packet. + * + * @param handle - handle to the raw packet data. + * @param type - the packet type. + */ + protected AbstractPacket(PacketContainer handle, PacketType type) { + // Make sure we're given a valid packet + if (handle == null) + throw new IllegalArgumentException("Packet handle cannot be NULL."); + if (!Objects.equal(handle.getType(), type)) + throw new IllegalArgumentException(handle.getHandle() + + " is not a packet of type " + type); + + this.handle = handle; + } + + /** + * Retrieve a handle to the raw packet data. + * + * @return Raw packet data. + */ + public PacketContainer getHandle() { + return handle; + } + + /** + * Send the current packet to the given receiver. + * + * @param receiver - the receiver. + * @throws RuntimeException If the packet cannot be sent. + */ + public void sendPacket(Player receiver) { + ProtocolLibrary.getProtocolManager().sendServerPacket(receiver, + getHandle()); + } + + /** + * Send the current packet to all online players. + */ + public void broadcastPacket() { + ProtocolLibrary.getProtocolManager().broadcastServerPacket(getHandle()); + } + + /** + * Simulate receiving the current packet from the given sender. + * + * @param sender - the sender. + * @throws RuntimeException if the packet cannot be received. + */ + public void receivePacket(Player sender) { + try { + ProtocolLibrary.getProtocolManager().receiveClientPacket(sender, + getHandle()); + } catch (Exception e) { + throw new RuntimeException("Cannot receive packet.", e); + } + } +} \ No newline at end of file diff --git a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java new file mode 100644 index 0000000..c0cbf97 --- /dev/null +++ b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java @@ -0,0 +1,37 @@ +package net.artelnatif.nicko.wrapper; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import org.bukkit.World; + +import java.util.Optional; + +/** + * 1.19.4 compliant version of the WrapperPlayServerRespawn. + * + * @author ineanto, based on work from dmulloy2 and Kristian S. Strangeland + */ +public class WrapperPlayServerRespawn extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.RESPAWN; + + public WrapperPlayServerRespawn() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public Optional getDimension() { + return handle.getDimensionTypes().optionRead(0); + } + + public void setDimension(World value) { + handle.getDimensionTypes().write(0, value); + } + + public Optional getSeed() { + return handle.getLongs().optionRead(0); + } + + public void setSeed(long value) { + handle.getLongs().write(0, value); + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 9599f7a..26ba4b9 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -5,7 +5,6 @@ author: Ineanto api-version: 1.13 softdepend: [ PlaceholderAPI ] load: POSTWORLD -depend: [ packetevents ] commands: nicko: description: "Opens Nicko's GUI." diff --git a/v1_19_R3/pom.xml b/v1_19_R3/pom.xml new file mode 100644 index 0000000..eefd19d --- /dev/null +++ b/v1_19_R3/pom.xml @@ -0,0 +1,68 @@ + + + 4.0.0 + + + net.artelnatif + nicko-parent + 1.0-SNAPSHOT + + + v1_19_R3 + 1.0-SNAPSHOT + + + + + net.md-5 + specialsource-maven-plugin + 1.2.4 + + + package + + remap + + remap-obf + + org.spigotmc:minecraft-server:1.19.4-R0.1-SNAPSHOT:txt:maps-mojang + true + org.spigotmc:spigot:1.19.4-R0.1-SNAPSHOT:jar:remapped-mojang + true + remapped-obf + + + + package + + remap + + remap-spigot + + ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar + org.spigotmc:minecraft-server:1.19.4-R0.1-SNAPSHOT:csrg:maps-spigot + org.spigotmc:spigot:1.19.4-R0.1-SNAPSHOT:jar:remapped-obf + + + + + + + + + + org.spigotmc + spigot + 1.19.4-R0.1-SNAPSHOT + remapped-mojang + provided + + + net.artelnatif + core + 1.0-SNAPSHOT + + + \ No newline at end of file diff --git a/v1_19_R3/src/main/java/net/artelnatif/nicko/impl/v1_19_R3.java b/v1_19_R3/src/main/java/net/artelnatif/nicko/impl/v1_19_R3.java new file mode 100644 index 0000000..d0ef0eb --- /dev/null +++ b/v1_19_R3/src/main/java/net/artelnatif/nicko/impl/v1_19_R3.java @@ -0,0 +1,140 @@ +package net.artelnatif.nicko.impl; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; +import net.artelnatif.nicko.NickoBukkit; +import net.artelnatif.nicko.disguise.ActionResult; +import net.artelnatif.nicko.disguise.NickoProfile; +import net.artelnatif.nicko.mojang.MojangSkin; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.RemoteChatSession; +import net.minecraft.network.protocol.game.*; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.EntityDataSerializers; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.player.ProfilePublicKey; +import net.minecraft.world.level.Level; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerTeleportEvent; + +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.Optional; +import java.util.UUID; +import java.util.logging.Logger; + +public class v1_19_R3 implements Internals { + final Logger logger = Bukkit.getLogger(); + + @Override + public void updateSelf(Player player) { + final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + final ServerLevel level = serverPlayer.getLevel(); + final ResourceKey levelResourceKey = serverPlayer.getLevel().dimension(); + final ClientboundRespawnPacket respawn = new ClientboundRespawnPacket(serverPlayer.level.dimensionTypeId(), + levelResourceKey, level.getWorld().getSeed(), + serverPlayer.gameMode.getGameModeForPlayer(), serverPlayer.gameMode.getPreviousGameModeForPlayer(), + level.isDebug(), + level.isFlat(), + (byte) 0x00, + Optional.empty()); + + final boolean wasFlying = player.isFlying(); + serverPlayer.connection.send(respawn); + player.setFlying(wasFlying); + player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); + player.updateInventory(); + } + + @Override + public void updateOthers(Player player) { + final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + + final ClientboundRemoveEntitiesPacket remove = new ClientboundRemoveEntitiesPacket(serverPlayer.getBukkitEntity().getEntityId()); + final ClientboundAddEntityPacket add = new ClientboundAddEntityPacket(serverPlayer); + + final SynchedEntityData entityData = serverPlayer.getEntityData(); + final EntityDataAccessor skinPartAccessor = new EntityDataAccessor<>(17, EntityDataSerializers.BYTE); + entityData.set(skinPartAccessor, (byte) 0x7f); + final ClientboundSetEntityDataPacket entityMetadata = new ClientboundSetEntityDataPacket(serverPlayer.getBukkitEntity().getEntityId(), entityData.getNonDefaultValues()); + + Bukkit.getOnlinePlayers().forEach(online -> { + final ServerPlayer onlineServerPlayer = ((CraftPlayer) online).getHandle(); + if (onlineServerPlayer.getBukkitEntity().getUniqueId() != player.getUniqueId()) { + onlineServerPlayer.connection.send(remove); + onlineServerPlayer.connection.send(add); + } + onlineServerPlayer.connection.send(entityMetadata); + }); + } + + @Override + public ActionResult updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset) { + final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); + final String profileName = profile.getName() == null ? player.getName() : profile.getName(); + + final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + final GameProfile gameProfile = new GameProfile(player.getUniqueId(), profileName); + + if (skinChange || changeOnlyName) { + final ActionResult skinFetch = fetchSkinTextures(profile, reset); + if (!skinFetch.isError()) { + final MojangSkin skin = skinFetch.getResult(); + final PropertyMap properties = gameProfile.getProperties(); + properties.removeAll("textures"); + properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); + updateSelf(player); + } + } + + final ClientboundPlayerInfoUpdatePacket init = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(Collections.singletonList(serverPlayer)); + final ClientboundPlayerInfoRemovePacket remove = new ClientboundPlayerInfoRemovePacket(Collections.singletonList(player.getUniqueId())); + + RemoteChatSession chatSession; + if (serverPlayer.getChatSession() == null) { + NickoBukkit.getInstance().getLogger().warning("Chat Session of " + serverPlayer.displayName + " is null!"); + NickoBukkit.getInstance().getLogger().warning("If your server is in offline mode/under BungeeCord you can safely ignore this message."); + chatSession = null; + } else { + final UUID uuid = serverPlayer.getChatSession().sessionId(); + final ProfilePublicKey ppk = serverPlayer.getChatSession().profilePublicKey(); + chatSession = new RemoteChatSession(uuid, ppk); + } + + spoofPlayerInfoPacket(init, Collections.singletonList(new ClientboundPlayerInfoUpdatePacket.Entry( + player.getUniqueId(), + gameProfile, + true, + serverPlayer.latency, + serverPlayer.gameMode.getGameModeForPlayer(), + Component.literal(profileName), + chatSession == null ? null : chatSession.asData() + ))); + + + Bukkit.getOnlinePlayers().forEach(online -> { + final ServerPlayer onlinePlayer = ((CraftPlayer) online).getHandle(); + onlinePlayer.connection.send(remove); + onlinePlayer.connection.send(init); + }); + // TODO: 3/17/23 Update signature to avoid duplicate for loop + updateOthers(player); + return new ActionResult<>(); + } + + private void spoofPlayerInfoPacket(Object object, Object newValue) { + try { + final Field field = object.getClass().getDeclaredField("b"); + field.setAccessible(true); + field.set(object, newValue); + } catch (NoSuchFieldException | IllegalAccessException e) { + NickoBukkit.getInstance().getLogger().warning("Unable to spoof packet, that's bad! (" + e.getMessage() + ")"); + } + } +} From ebe539c6147356a586d090fb6d72aa45446559e9 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 25 Apr 2023 18:36:14 +0200 Subject: [PATCH 007/296] fix: remove dependency reduced pom --- dependency-reduced-pom.xml | 168 ------------------------------------- 1 file changed, 168 deletions(-) delete mode 100644 dependency-reduced-pom.xml diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml deleted file mode 100644 index 5f3a8ad..0000000 --- a/dependency-reduced-pom.xml +++ /dev/null @@ -1,168 +0,0 @@ - - - 4.0.0 - net.artelnatif - nicko - Nicko - 1.0-SNAPSHOT - - - - true - ${basedir}/src/main/resources/ - - - - - maven-surefire-plugin - 3.0.0-M7 - - - maven-shade-plugin - 3.4.1 - - - package - - shade - - - - - net.wesjd:anvilgui - xyz.xenondevs.invui:* - com.github.jsixface:* - com.fasterxml.jackson.dataformat - com.fasterxml.jackson.core - org.mariadb.jdbc - - - - - net.wesjd.anvilgui - net.artelnatif.libs.anvilgui - - - xyz.xenondevs.invui - net.artelnatif.libs.invui - - - com.github.jsixface - net.artelnatif.libs.yaml - - - com.fasterxml.jackson.dataformat - net.artelnatif.libs.jackson.yaml - - - com.fasterxml.jackson.core - net.artelnatif.libs.jackson.core - - - org.mariadb.jdbc - net.artelnatif.libs.mariadb - - - false - - - - - - - - - papermc - https://repo.papermc.io/repository/maven-public/ - - - spigot-repo - https://hub.spigotmc.org/nexus/content/groups/public/ - - - codemc-snapshots - https://repo.codemc.io/repository/maven-snapshots/ - - - placeholderapi - https://repo.extendedclip.com/content/repositories/placeholderapi/ - - - dmulloy2-repo - https://repo.dmulloy2.net/repository/public/ - - - - - com.comphenix.protocol - ProtocolLib - 5.0.0-SNAPSHOT - compile - - - me.clip - placeholderapi - 2.11.2 - provided - - - org.spigotmc - spigot-api - 1.19.4-R0.1-SNAPSHOT - provided - - - com.google.guava - guava - 31.1-jre - provided - - - com.github.seeseemelk - MockBukkit-v1.19 - 2.29.0 - test - - - paper-api - io.papermc.paper - - - junit-jupiter - org.junit.jupiter - - - hamcrest-library - org.hamcrest - - - adventure-platform-bungeecord - net.kyori - - - maven-resolver-provider - org.apache.maven - - - maven-resolver-connector-basic - org.apache.maven.resolver - - - maven-resolver-transport-http - org.apache.maven.resolver - - - - - redis.clients - jedis - 4.3.0 - compile - - - - 8 - 8 - UTF-8 - - From 94634f7bba87bbe7fea125568b085cdaad819710 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 25 Apr 2023 18:37:22 +0200 Subject: [PATCH 008/296] fix: remove nms folder --- .gitignore | 5 +- v1_19_R3/pom.xml | 68 --------- .../net/artelnatif/nicko/impl/v1_19_R3.java | 140 ------------------ 3 files changed, 4 insertions(+), 209 deletions(-) delete mode 100644 v1_19_R3/pom.xml delete mode 100644 v1_19_R3/src/main/java/net/artelnatif/nicko/impl/v1_19_R3.java diff --git a/.gitignore b/.gitignore index 67f8558..17d0f8a 100644 --- a/.gitignore +++ b/.gitignore @@ -46,4 +46,7 @@ v1_19_R1/target target # Maven Dependency Reduced Pom -dependency-reduced-pom.xml \ No newline at end of file +dependency-reduced-pom.xml + +# Kept for convenience +v1_19_R3 \ No newline at end of file diff --git a/v1_19_R3/pom.xml b/v1_19_R3/pom.xml deleted file mode 100644 index eefd19d..0000000 --- a/v1_19_R3/pom.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - 4.0.0 - - - net.artelnatif - nicko-parent - 1.0-SNAPSHOT - - - v1_19_R3 - 1.0-SNAPSHOT - - - - - net.md-5 - specialsource-maven-plugin - 1.2.4 - - - package - - remap - - remap-obf - - org.spigotmc:minecraft-server:1.19.4-R0.1-SNAPSHOT:txt:maps-mojang - true - org.spigotmc:spigot:1.19.4-R0.1-SNAPSHOT:jar:remapped-mojang - true - remapped-obf - - - - package - - remap - - remap-spigot - - ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar - org.spigotmc:minecraft-server:1.19.4-R0.1-SNAPSHOT:csrg:maps-spigot - org.spigotmc:spigot:1.19.4-R0.1-SNAPSHOT:jar:remapped-obf - - - - - - - - - - org.spigotmc - spigot - 1.19.4-R0.1-SNAPSHOT - remapped-mojang - provided - - - net.artelnatif - core - 1.0-SNAPSHOT - - - \ No newline at end of file diff --git a/v1_19_R3/src/main/java/net/artelnatif/nicko/impl/v1_19_R3.java b/v1_19_R3/src/main/java/net/artelnatif/nicko/impl/v1_19_R3.java deleted file mode 100644 index d0ef0eb..0000000 --- a/v1_19_R3/src/main/java/net/artelnatif/nicko/impl/v1_19_R3.java +++ /dev/null @@ -1,140 +0,0 @@ -package net.artelnatif.nicko.impl; - -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import com.mojang.authlib.properties.PropertyMap; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.mojang.MojangSkin; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.RemoteChatSession; -import net.minecraft.network.protocol.game.*; -import net.minecraft.network.syncher.EntityDataAccessor; -import net.minecraft.network.syncher.EntityDataSerializers; -import net.minecraft.network.syncher.SynchedEntityData; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.player.ProfilePublicKey; -import net.minecraft.world.level.Level; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerTeleportEvent; - -import java.lang.reflect.Field; -import java.util.Collections; -import java.util.Optional; -import java.util.UUID; -import java.util.logging.Logger; - -public class v1_19_R3 implements Internals { - final Logger logger = Bukkit.getLogger(); - - @Override - public void updateSelf(Player player) { - final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); - final ServerLevel level = serverPlayer.getLevel(); - final ResourceKey levelResourceKey = serverPlayer.getLevel().dimension(); - final ClientboundRespawnPacket respawn = new ClientboundRespawnPacket(serverPlayer.level.dimensionTypeId(), - levelResourceKey, level.getWorld().getSeed(), - serverPlayer.gameMode.getGameModeForPlayer(), serverPlayer.gameMode.getPreviousGameModeForPlayer(), - level.isDebug(), - level.isFlat(), - (byte) 0x00, - Optional.empty()); - - final boolean wasFlying = player.isFlying(); - serverPlayer.connection.send(respawn); - player.setFlying(wasFlying); - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.updateInventory(); - } - - @Override - public void updateOthers(Player player) { - final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); - - final ClientboundRemoveEntitiesPacket remove = new ClientboundRemoveEntitiesPacket(serverPlayer.getBukkitEntity().getEntityId()); - final ClientboundAddEntityPacket add = new ClientboundAddEntityPacket(serverPlayer); - - final SynchedEntityData entityData = serverPlayer.getEntityData(); - final EntityDataAccessor skinPartAccessor = new EntityDataAccessor<>(17, EntityDataSerializers.BYTE); - entityData.set(skinPartAccessor, (byte) 0x7f); - final ClientboundSetEntityDataPacket entityMetadata = new ClientboundSetEntityDataPacket(serverPlayer.getBukkitEntity().getEntityId(), entityData.getNonDefaultValues()); - - Bukkit.getOnlinePlayers().forEach(online -> { - final ServerPlayer onlineServerPlayer = ((CraftPlayer) online).getHandle(); - if (onlineServerPlayer.getBukkitEntity().getUniqueId() != player.getUniqueId()) { - onlineServerPlayer.connection.send(remove); - onlineServerPlayer.connection.send(add); - } - onlineServerPlayer.connection.send(entityMetadata); - }); - } - - @Override - public ActionResult updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset) { - final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); - final String profileName = profile.getName() == null ? player.getName() : profile.getName(); - - final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); - final GameProfile gameProfile = new GameProfile(player.getUniqueId(), profileName); - - if (skinChange || changeOnlyName) { - final ActionResult skinFetch = fetchSkinTextures(profile, reset); - if (!skinFetch.isError()) { - final MojangSkin skin = skinFetch.getResult(); - final PropertyMap properties = gameProfile.getProperties(); - properties.removeAll("textures"); - properties.put("textures", new Property("textures", skin.getValue(), skin.getSignature())); - updateSelf(player); - } - } - - final ClientboundPlayerInfoUpdatePacket init = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(Collections.singletonList(serverPlayer)); - final ClientboundPlayerInfoRemovePacket remove = new ClientboundPlayerInfoRemovePacket(Collections.singletonList(player.getUniqueId())); - - RemoteChatSession chatSession; - if (serverPlayer.getChatSession() == null) { - NickoBukkit.getInstance().getLogger().warning("Chat Session of " + serverPlayer.displayName + " is null!"); - NickoBukkit.getInstance().getLogger().warning("If your server is in offline mode/under BungeeCord you can safely ignore this message."); - chatSession = null; - } else { - final UUID uuid = serverPlayer.getChatSession().sessionId(); - final ProfilePublicKey ppk = serverPlayer.getChatSession().profilePublicKey(); - chatSession = new RemoteChatSession(uuid, ppk); - } - - spoofPlayerInfoPacket(init, Collections.singletonList(new ClientboundPlayerInfoUpdatePacket.Entry( - player.getUniqueId(), - gameProfile, - true, - serverPlayer.latency, - serverPlayer.gameMode.getGameModeForPlayer(), - Component.literal(profileName), - chatSession == null ? null : chatSession.asData() - ))); - - - Bukkit.getOnlinePlayers().forEach(online -> { - final ServerPlayer onlinePlayer = ((CraftPlayer) online).getHandle(); - onlinePlayer.connection.send(remove); - onlinePlayer.connection.send(init); - }); - // TODO: 3/17/23 Update signature to avoid duplicate for loop - updateOthers(player); - return new ActionResult<>(); - } - - private void spoofPlayerInfoPacket(Object object, Object newValue) { - try { - final Field field = object.getClass().getDeclaredField("b"); - field.setAccessible(true); - field.set(object, newValue); - } catch (NoSuchFieldException | IllegalAccessException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to spoof packet, that's bad! (" + e.getMessage() + ")"); - } - } -} From cee168e225a9c539e31815a5cd6ac9084c0fd389 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 25 Apr 2023 23:25:14 +0200 Subject: [PATCH 009/296] feat: wrappers --- .../net/artelnatif/nicko/NickoBukkit.java | 24 +++++ .../nicko/disguise/AppearanceManager.java | 49 +++++++--- .../wrapper/WrapperPlayServerRespawn.java | 94 +++++++++++++++++-- .../WrapperPlayerServerPlayerInfo.java | 46 +++++++++ .../WrapperPlayerServerPlayerInfoRemove.java | 35 +++++++ src/main/resources/plugin.yml | 2 + 6 files changed, 228 insertions(+), 22 deletions(-) create mode 100644 src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayerServerPlayerInfo.java create mode 100644 src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java diff --git a/src/main/java/net/artelnatif/nicko/NickoBukkit.java b/src/main/java/net/artelnatif/nicko/NickoBukkit.java index 8310406..7f94730 100644 --- a/src/main/java/net/artelnatif/nicko/NickoBukkit.java +++ b/src/main/java/net/artelnatif/nicko/NickoBukkit.java @@ -1,7 +1,9 @@ package net.artelnatif.nicko; +import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.*; import net.artelnatif.nicko.command.NickoCommand; import net.artelnatif.nicko.config.Configuration; import net.artelnatif.nicko.config.ConfigurationManager; @@ -27,6 +29,7 @@ import xyz.xenondevs.invui.item.impl.SimpleItem; import java.io.File; import java.io.IOException; +import java.lang.reflect.Field; public class NickoBukkit extends JavaPlugin { private static NickoBukkit plugin; @@ -104,6 +107,27 @@ public class NickoBukkit extends JavaPlugin { getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this); getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this); + protocolManager.addPacketListener(new PacketAdapter( + this, + ListenerPriority.NORMAL, + PacketType.Play.Server.PLAYER_INFO) { + @Override + public void onPacketReceiving(PacketEvent event) { + } + + @Override + public void onPacketSending(PacketEvent event) { + final PacketContainer packet = event.getPacket(); + packet.getStructures().getFields().forEach(fieldAccessor -> { + final Field field = fieldAccessor.getField(); + getLogger().info("field=[" + + "name=" + field.getName() + "," + + "type=" + field.getType().getSimpleName() + + "]"); + }); + } + }); + getLogger().info("Nicko (Bukkit) has been enabled."); } } diff --git a/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java b/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java index 2cde36d..afaf82e 100644 --- a/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java +++ b/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java @@ -1,20 +1,23 @@ package net.artelnatif.nicko.disguise; -import com.comphenix.protocol.wrappers.WrappedGameProfile; -import com.comphenix.protocol.wrappers.WrappedSignedProperty; +import com.comphenix.protocol.wrappers.*; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Multimap; import net.artelnatif.nicko.NickoBukkit; import net.artelnatif.nicko.i18n.I18NDict; import net.artelnatif.nicko.mojang.MojangAPI; import net.artelnatif.nicko.mojang.MojangSkin; import net.artelnatif.nicko.storage.PlayerDataStore; import net.artelnatif.nicko.storage.name.PlayerNameStore; +import net.artelnatif.nicko.wrapper.WrapperPlayServerRespawn; +import net.artelnatif.nicko.wrapper.WrapperPlayerServerPlayerInfo; +import net.artelnatif.nicko.wrapper.WrapperPlayerServerPlayerInfoRemove; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerTeleportEvent; import java.io.IOException; -import java.util.Collection; +import java.util.EnumSet; import java.util.Optional; import java.util.UUID; import java.util.concurrent.ExecutionException; @@ -95,9 +98,9 @@ public class AppearanceManager { public ActionResult updatePlayer(boolean skinChange) { final String displayName = profile.getName() == null ? player.getName() : profile.getName(); - Bukkit.broadcastMessage("Building UserProfile"); - final WrappedGameProfile gameProfile = new WrappedGameProfile(player.getUniqueId(), displayName); + Bukkit.broadcastMessage("Building UserProfile"); + final WrappedGameProfile gameProfile = WrappedGameProfile.fromPlayer(player).withName(displayName); final ActionResult result = updateGameProfileSkin(gameProfile, skinChange); if (!result.isError()) { updateTabList(gameProfile, displayName); @@ -118,9 +121,9 @@ public class AppearanceManager { skin = mojang.getSkin(uuid.get()); if (skin.isPresent()) { final MojangSkin skinResult = skin.get(); - final Collection properties = gameProfile.getProperties().values(); - properties.clear(); - properties.add(new WrappedSignedProperty("textures", skinResult.getValue(), skinResult.getSignature())); + final Multimap properties = gameProfile.getProperties(); + properties.get("textures").clear(); + properties.put("textures", new WrappedSignedProperty("textures", skinResult.getValue(), skinResult.getSignature())); Bukkit.broadcastMessage("Modified properties"); } } @@ -137,14 +140,32 @@ public class AppearanceManager { private void respawnPlayer() { Bukkit.broadcastMessage("Respawning player"); final World world = player.getWorld(); - // TODO (Ineanto, 4/23/23): Respawn Packet - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); + final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(); + respawn.setGameMode(player.getGameMode()); + respawn.setDifficulty(world.getDifficulty()); + respawn.setDimension(world); + respawn.setSeed(world.getSeed()); + respawn.sendPacket(player); } private void updateTabList(WrappedGameProfile gameProfile, String displayName) { - // TODO (Ineanto, 4/23/23): Update player info packet - // TODO (Ineanto, 4/23/23): Remove player info packet Bukkit.broadcastMessage("Updating tablist"); - // TODO (Ineanto, 4/23/23): Send packets + final WrapperPlayerServerPlayerInfoRemove remove = new WrapperPlayerServerPlayerInfoRemove(); + remove.setUUIDs(ImmutableList.of(player.getUniqueId())); + + final WrapperPlayerServerPlayerInfo update = new WrapperPlayerServerPlayerInfo(); + update.setActions(EnumSet.of(EnumWrappers.PlayerInfoAction.ADD_PLAYER, + EnumWrappers.PlayerInfoAction.UPDATE_LISTED, + EnumWrappers.PlayerInfoAction.UPDATE_DISPLAY_NAME, + EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE, + EnumWrappers.PlayerInfoAction.UPDATE_LATENCY)); + update.setData(ImmutableList.of(new PlayerInfoData( + gameProfile, + player.getPing(), + EnumWrappers.NativeGameMode.fromBukkit(player.getGameMode()), + WrappedChatComponent.fromText(displayName) + ))); + remove.sendPacket(player); + update.sendPacket(player); } } diff --git a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java index c0cbf97..26a1321 100644 --- a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java @@ -2,12 +2,17 @@ package net.artelnatif.nicko.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.utility.MinecraftReflection; +import com.comphenix.protocol.utility.MinecraftVersion; +import com.comphenix.protocol.wrappers.BukkitConverters; +import com.comphenix.protocol.wrappers.EnumWrappers; +import org.bukkit.Difficulty; +import org.bukkit.GameMode; import org.bukkit.World; -import java.util.Optional; - /** - * 1.19.4 compliant version of the WrapperPlayServerRespawn. + * Up-to-date version of the Wrapper class + * for the PacketPlayServerRespawn. * * @author ineanto, based on work from dmulloy2 and Kristian S. Strangeland */ @@ -19,19 +24,92 @@ public class WrapperPlayServerRespawn extends AbstractPacket { handle.getModifier().writeDefaults(); } - public Optional getDimension() { - return handle.getDimensionTypes().optionRead(0); + //............. + // Dimension Field (1.8 - Present) + // The dimension field has changed types, + // numerous times. Version 1.8 through 1.15 need an integer, + // 1.15 through 1.18 need a (NBT Tag) Identifier and + // 1.19.2 and beyond require a Holder of a DimensionManager Identifier (???). + // (Wiki.vg still refers this as an Identifier) + // + // n.b.: this field is a nightmare please mojang stop refactoring + // your code to change things that were working perfectly fine before + //............. + + public World getDimension() { + if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { + // 1.19 and above + return handle.getHolders( + MinecraftReflection.getDimensionManager(), + BukkitConverters.getDimensionConverter() + ).read(0); + } + + return handle.getDimensionTypes().read(0); } public void setDimension(World value) { + if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { + // 1.19 and above + handle.getWorldKeys().withParamType( + MinecraftReflection.getResourceKey(), + BukkitConverters.getWorldKeyConverter() + ).write(0, value); + return; + } + // 1.18 and below handle.getDimensionTypes().write(0, value); } - public Optional getSeed() { - return handle.getLongs().optionRead(0); + //............. + // GameMode Field + //............. + + public void getGameMode() { + // Present since 1.8, we're good! + handle.getGameModes().read(0); + } + + public void setGameMode(GameMode value) { + // Present since 1.8, we're good! + handle.getGameModes().write(0, EnumWrappers.NativeGameMode.fromBukkit(value)); + } + + //............. + // Seed Field + // Added in 1.15. + //............. + + public long getSeed() { + if (MinecraftVersion.BEE_UPDATE.atOrAbove()) { + return handle.getLongs().read(0); + } + return -1; } public void setSeed(long value) { - handle.getLongs().write(0, value); + if (MinecraftVersion.BEE_UPDATE.atOrAbove()) { + handle.getLongs().write(0, value); + } + } + + //............. + // Difficulty Field + // Removed in 1.14. + //............. + + public Difficulty getDifficulty() { + if (MinecraftVersion.VILLAGE_UPDATE.atOrAbove()) { + return null; + } + + final EnumWrappers.Difficulty difficulty = handle.getDifficulties().read(0); + return difficulty == null ? null : Difficulty.valueOf(difficulty.name()); + } + + public void setDifficulty(Difficulty difficulty) { + if (difficulty != null && !MinecraftVersion.VILLAGE_UPDATE.atOrAbove()) { + handle.getDifficulties().write(0, EnumWrappers.Difficulty.valueOf(difficulty.name())); + } } } diff --git a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayerServerPlayerInfo.java b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayerServerPlayerInfo.java new file mode 100644 index 0000000..fc64027 --- /dev/null +++ b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayerServerPlayerInfo.java @@ -0,0 +1,46 @@ +package net.artelnatif.nicko.wrapper; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers; +import com.comphenix.protocol.wrappers.PlayerInfoData; + +import java.util.List; +import java.util.Set; + +/** + * Up-to-date version of the Wrapper class + * for the PlayerServerPlayerInfo. + * + * @author ineanto, based on work from dmulloy2 and Kristian S. Strangeland + */ + +public class WrapperPlayerServerPlayerInfo extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.PLAYER_INFO; + + public WrapperPlayerServerPlayerInfo() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayerServerPlayerInfo(PacketContainer packet) { + super(packet, TYPE); + } + + public Set getActions() { + return handle.getPlayerInfoActions().read(0); + } + + public void setActions(Set value) { + handle.getPlayerInfoActions().write(0, value); + } + + public List getData() { + return handle.getPlayerInfoDataLists().read(0); + } + + public void setData(List value) { + //handle.getSets(PlayerInfoData.getConverter()).write(0, value); + handle.getPlayerInfoDataLists().write(1, value); + } +} diff --git a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java new file mode 100644 index 0000000..bc6e912 --- /dev/null +++ b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java @@ -0,0 +1,35 @@ +package net.artelnatif.nicko.wrapper; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; + +import java.util.List; +import java.util.UUID; + +/** + * Up-to-date version of the Wrapper class + * for the PlayerServerPlayerInfoRemove. + * + * @author ineanto, based on work from dmulloy2 and Kristian S. Strangeland + */ + +public class WrapperPlayerServerPlayerInfoRemove extends AbstractPacket { + public static final PacketType TYPE = PacketType.Play.Server.PLAYER_INFO_REMOVE; + + public WrapperPlayerServerPlayerInfoRemove() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + public WrapperPlayerServerPlayerInfoRemove(PacketContainer packet) { + super(packet, TYPE); + } + + public List getUUIDs() { + return handle.getUUIDLists().read(0); + } + + public void setUUIDs(List value) { + handle.getUUIDLists().write(0, value); + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 26ba4b9..66cda8f 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -4,6 +4,8 @@ version: 1.0-SNAPSHOT author: Ineanto api-version: 1.13 softdepend: [ PlaceholderAPI ] +depend: + - ProtocolLib load: POSTWORLD commands: nicko: From 0ad2c408a68882dcdd98bc25fdd714345be1eb33 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 25 Apr 2023 23:25:43 +0200 Subject: [PATCH 010/296] style: clarify code --- src/main/java/net/artelnatif/nicko/NickoBukkit.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/net/artelnatif/nicko/NickoBukkit.java b/src/main/java/net/artelnatif/nicko/NickoBukkit.java index 7f94730..bff91c4 100644 --- a/src/main/java/net/artelnatif/nicko/NickoBukkit.java +++ b/src/main/java/net/artelnatif/nicko/NickoBukkit.java @@ -107,6 +107,7 @@ public class NickoBukkit extends JavaPlugin { getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this); getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this); + // For debug purposes protocolManager.addPacketListener(new PacketAdapter( this, ListenerPriority.NORMAL, From 7392b8aad287f282a1801bd7d369f4a1293a131d Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 25 Apr 2023 23:26:56 +0200 Subject: [PATCH 011/296] style: documentation --- .../nicko/wrapper/WrapperPlayServerRespawn.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java index 26a1321..758fb77 100644 --- a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java @@ -26,11 +26,11 @@ public class WrapperPlayServerRespawn extends AbstractPacket { //............. // Dimension Field (1.8 - Present) - // The dimension field has changed types, - // numerous times. Version 1.8 through 1.15 need an integer, - // 1.15 through 1.18 need a (NBT Tag) Identifier and - // 1.19.2 and beyond require a Holder of a DimensionManager Identifier (???). - // (Wiki.vg still refers this as an Identifier) + // The dimension field has changed numerous times: + // - Version 1.8 through 1.15 need an integer, + // - 1.15 through 1.18 need a (NBT Tag) Identifier and + // - 1.19.2 and beyond require a Holder of a DimensionManager Identifier (???). + // (Wiki.vg still refers to this as an "Identifier") // // n.b.: this field is a nightmare please mojang stop refactoring // your code to change things that were working perfectly fine before From a01b564912b455eb7b2f08b5905ac0327102074d Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 28 Apr 2023 22:47:57 +0200 Subject: [PATCH 012/296] feat: update wrapper --- .../net/artelnatif/nicko/NickoBukkit.java | 2 +- .../nicko/disguise/AppearanceManager.java | 3 ++ .../wrapper/WrapperPlayServerRespawn.java | 31 +++++++++++++++---- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/artelnatif/nicko/NickoBukkit.java b/src/main/java/net/artelnatif/nicko/NickoBukkit.java index bff91c4..061ea72 100644 --- a/src/main/java/net/artelnatif/nicko/NickoBukkit.java +++ b/src/main/java/net/artelnatif/nicko/NickoBukkit.java @@ -111,7 +111,7 @@ public class NickoBukkit extends JavaPlugin { protocolManager.addPacketListener(new PacketAdapter( this, ListenerPriority.NORMAL, - PacketType.Play.Server.PLAYER_INFO) { + PacketType.Play.Server.RESPAWN) { @Override public void onPacketReceiving(PacketEvent event) { } diff --git a/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java b/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java index afaf82e..9c82225 100644 --- a/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java +++ b/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java @@ -145,6 +145,9 @@ public class AppearanceManager { respawn.setDifficulty(world.getDifficulty()); respawn.setDimension(world); respawn.setSeed(world.getSeed()); + respawn.setLastDeathLocation(player.getLocation()); + respawn.getHandle().getBooleans().write(0, false); // is debug + respawn.getHandle().getBooleans().write(1, false); // is flat respawn.sendPacket(player); } diff --git a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java index 758fb77..6ac26ee 100644 --- a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java @@ -4,12 +4,16 @@ import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; +import com.comphenix.protocol.wrappers.BlockPosition; import com.comphenix.protocol.wrappers.BukkitConverters; import com.comphenix.protocol.wrappers.EnumWrappers; import org.bukkit.Difficulty; import org.bukkit.GameMode; +import org.bukkit.Location; import org.bukkit.World; +import java.util.Optional; + /** * Up-to-date version of the Wrapper class * for the PacketPlayServerRespawn. @@ -51,10 +55,7 @@ public class WrapperPlayServerRespawn extends AbstractPacket { public void setDimension(World value) { if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { // 1.19 and above - handle.getWorldKeys().withParamType( - MinecraftReflection.getResourceKey(), - BukkitConverters.getWorldKeyConverter() - ).write(0, value); + handle.getWorldKeys().write(0, value); return; } // 1.18 and below @@ -66,15 +67,33 @@ public class WrapperPlayServerRespawn extends AbstractPacket { //............. public void getGameMode() { - // Present since 1.8, we're good! handle.getGameModes().read(0); } public void setGameMode(GameMode value) { - // Present since 1.8, we're good! handle.getGameModes().write(0, EnumWrappers.NativeGameMode.fromBukkit(value)); } + //............. + // Last death location Field + // Added in 1.19. + //............. + + public Optional getLastDeathLocation() { + if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { + return handle.getOptionals(BlockPosition.getConverter()).read(0); + } + return Optional.empty(); + } + + public void setLastDeathLocation(Location value) { + if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { + final BlockPosition locationToBlockPosition = BlockPosition.getConverter().getSpecific(value); + final Optional blockPosition = Optional.ofNullable(locationToBlockPosition); + handle.getOptionals(BlockPosition.getConverter()).write(0, blockPosition); + } + } + //............. // Seed Field // Added in 1.15. From 567184b07da579ec250a9564d9da2b19a7fef31e Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 28 Apr 2023 23:31:34 +0200 Subject: [PATCH 013/296] still trying to figure out why protocollib doesn't work. --- logs/2023-04-28-1.log.gz | Bin 0 -> 123 bytes logs/2023-04-28-2.log.gz | Bin 0 -> 124 bytes logs/2023-04-28-3.log.gz | Bin 0 -> 124 bytes logs/2023-04-28-4.log.gz | Bin 0 -> 124 bytes logs/2023-04-28-5.log.gz | Bin 0 -> 124 bytes logs/2023-04-28-6.log.gz | Bin 0 -> 124 bytes logs/2023-04-28-7.log.gz | Bin 0 -> 124 bytes logs/2023-04-28-8.log.gz | Bin 0 -> 124 bytes pom.xml | 2 +- .../net/artelnatif/nicko/NickoBukkit.java | 28 +++++++++----- .../nicko/disguise/AppearanceManager.java | 6 +++ .../wrapper/WrapperPlayServerRespawn.java | 36 ++++++++++++++---- 12 files changed, 54 insertions(+), 18 deletions(-) create mode 100644 logs/2023-04-28-1.log.gz create mode 100644 logs/2023-04-28-2.log.gz create mode 100644 logs/2023-04-28-3.log.gz create mode 100644 logs/2023-04-28-4.log.gz create mode 100644 logs/2023-04-28-5.log.gz create mode 100644 logs/2023-04-28-6.log.gz create mode 100644 logs/2023-04-28-7.log.gz create mode 100644 logs/2023-04-28-8.log.gz diff --git a/logs/2023-04-28-1.log.gz b/logs/2023-04-28-1.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..20d5077f7dc09d787c8b69aca2bf3e038e909942 GIT binary patch literal 123 zcmb2|=3oGW|Evc$avd@dV0&LcK3RDwPT^7Qwo<9-22TfX!vVNmt;}q))X7pjZuLXqLDGr(>x37x^?+( bU(Kq1D1EkW(M-cTWwY(KTI6eI0qq0;1)VlJ literal 0 HcmV?d00001 diff --git a/logs/2023-04-28-2.log.gz b/logs/2023-04-28-2.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..c9b7d6dc36bebfe5314af5addac817d00f8faa21 GIT binary patch literal 124 zcmV-?0E7P@iwFP!00000{{_LZ4uUWc2H@SN__yL-&9kb7AVZtryH6pUe3%+^2;xs){mdy0)jLBO=BSLNY^4C8vm|D0WK5i__yj{C>0ZPlMJqyus9HgrmfNhd*%+p z>+^l1yOML%HWS95&!v8MLq8FoA}oZ)wzrGBTWbkj2uT$&m7F3zEZ8&&j4-d}VHOU4 enORqZ)26w6@%O4bOC2000290X5eE literal 0 HcmV?d00001 diff --git a/logs/2023-04-28-5.log.gz b/logs/2023-04-28-5.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..454921fa172affc87b6922c83b9f78099a839a50 GIT binary patch literal 124 zcmV-?0E7P@iwFP!00000{{_Ll4uUWg2GHH7__oSmEcK7vNd{L;To?#L(^hDLz2;ts zukSg7JCVCmeH$@+d@jeneRU(@A;Lna?fG(WjkT80hLBVdQ^_gf&4NvnzzFkd?q=cO emzi}n*l(K4gs)fqu|z`mtag7>*qPUA0001f1UuRQ literal 0 HcmV?d00001 diff --git a/logs/2023-04-28-6.log.gz b/logs/2023-04-28-6.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..c0d0683e3e086851d5306755298111f0dccfc06c GIT binary patch literal 124 zcmV-?0E7P@iwFP!00000{{_LZ4uUWc2H>5i__yj{s0AarNd{L;TpS2P(^hDLJ#z=~ z_5HrlHRP_;HWS8=&!v9#&tW3mMOX-D+g?ttv(^&&5RxilDmg{GS+Hvo7-8Pb&8!^! ey0C5rhh1}-@%5@dmPi;L$LbF`@g~1&0002)kT-Au literal 0 HcmV?d00001 diff --git a/logs/2023-04-28-7.log.gz b/logs/2023-04-28-7.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..d1c0febd88a247bbe8ed703cdc72232fb258dd2b GIT binary patch literal 124 zcmV-?0E7P@iwFP!00000{{_LZ4uUWc2H@SN__yL=uwc_9Fv7f=yIDB+ eWoBIss!em5@bjuWOCBALj00016zB%Fm literal 0 HcmV?d00001 diff --git a/logs/2023-04-28-8.log.gz b/logs/2023-04-28-8.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..ffb6f05c8bd9b4aa8fc1ae797468eb06390398a9 GIT binary patch literal 124 zcmb2|=3oGW|Evc$@--O zq*lEXK6dqak>sv$dqFuRot9H^`RUgqvN>ZpJVgzs&QZFjbHkLg#~^>1DL4E6Gizoa cEW93L_oM2nytm4i^Oqm;SADH$$O2jl025F&UH||9 literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml index be4c70f..e88257a 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ org.spigotmc - spigot-api + spigot 1.19.4-R0.1-SNAPSHOT provided diff --git a/src/main/java/net/artelnatif/nicko/NickoBukkit.java b/src/main/java/net/artelnatif/nicko/NickoBukkit.java index 061ea72..641b86b 100644 --- a/src/main/java/net/artelnatif/nicko/NickoBukkit.java +++ b/src/main/java/net/artelnatif/nicko/NickoBukkit.java @@ -3,7 +3,10 @@ package net.artelnatif.nicko; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; -import com.comphenix.protocol.events.*; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; import net.artelnatif.nicko.command.NickoCommand; import net.artelnatif.nicko.config.Configuration; import net.artelnatif.nicko.config.ConfigurationManager; @@ -17,6 +20,7 @@ import net.artelnatif.nicko.mojang.MojangAPI; import net.artelnatif.nicko.placeholder.PlaceHolderHook; import net.artelnatif.nicko.storage.PlayerDataStore; import net.artelnatif.nicko.storage.name.PlayerNameStore; +import net.artelnatif.nicko.wrapper.WrapperPlayServerRespawn; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.command.PluginCommand; @@ -29,7 +33,6 @@ import xyz.xenondevs.invui.item.impl.SimpleItem; import java.io.File; import java.io.IOException; -import java.lang.reflect.Field; public class NickoBukkit extends JavaPlugin { private static NickoBukkit plugin; @@ -119,13 +122,20 @@ public class NickoBukkit extends JavaPlugin { @Override public void onPacketSending(PacketEvent event) { final PacketContainer packet = event.getPacket(); - packet.getStructures().getFields().forEach(fieldAccessor -> { - final Field field = fieldAccessor.getField(); - getLogger().info("field=[" + - "name=" + field.getName() + "," + - "type=" + field.getType().getSimpleName() + - "]"); - }); + final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(packet); + getLogger().info(respawn.getDimension().getName()); + getLogger().info(String.valueOf(respawn.isCopyMetadata())); + getLogger().info(String.valueOf(respawn.getSeed())); + getLogger().info(String.valueOf(respawn.getLastDeathLocation().isPresent())); + /** + * packet.getStructures().getFields().forEach(fieldAccessor -> { + * final Field field = fieldAccessor.getField(); + * getLogger().info("field=[" + + * "name=" + field.getName() + "," + + * "type=" + field.getType().getSimpleName() + + * "]"); + * }); + */ } }); diff --git a/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java b/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java index 9c82225..93e3841 100644 --- a/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java +++ b/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java @@ -139,16 +139,22 @@ public class AppearanceManager { private void respawnPlayer() { Bukkit.broadcastMessage("Respawning player"); + final World world = player.getWorld(); final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(); respawn.setGameMode(player.getGameMode()); + respawn.setPreviousGameMode(player.getGameMode()); respawn.setDifficulty(world.getDifficulty()); respawn.setDimension(world); respawn.setSeed(world.getSeed()); respawn.setLastDeathLocation(player.getLocation()); + respawn.setCopyMetadata(false); respawn.getHandle().getBooleans().write(0, false); // is debug respawn.getHandle().getBooleans().write(1, false); // is flat respawn.sendPacket(player); + /*final EntityPlayer cp = ((CraftPlayer) player).getHandle(); + final PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(cp.cG().Z(), cp.P(), player.getWorld().getSeed(), EnumGamemode.a, EnumGamemode.a, true, true, (byte) 0x00, Optional.empty()); + cp.b.a(respawn);*/ } private void updateTabList(WrappedGameProfile gameProfile, String displayName) { diff --git a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java index 6ac26ee..a8a855a 100644 --- a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java @@ -2,10 +2,8 @@ package net.artelnatif.nicko.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.wrappers.BlockPosition; -import com.comphenix.protocol.wrappers.BukkitConverters; import com.comphenix.protocol.wrappers.EnumWrappers; import org.bukkit.Difficulty; import org.bukkit.GameMode; @@ -28,6 +26,8 @@ public class WrapperPlayServerRespawn extends AbstractPacket { handle.getModifier().writeDefaults(); } + public WrapperPlayServerRespawn(PacketContainer container) { super(container, TYPE); } + //............. // Dimension Field (1.8 - Present) // The dimension field has changed numerous times: @@ -42,11 +42,7 @@ public class WrapperPlayServerRespawn extends AbstractPacket { public World getDimension() { if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { - // 1.19 and above - return handle.getHolders( - MinecraftReflection.getDimensionManager(), - BukkitConverters.getDimensionConverter() - ).read(0); + return handle.getWorldKeys().read(0); } return handle.getDimensionTypes().read(0); @@ -58,7 +54,7 @@ public class WrapperPlayServerRespawn extends AbstractPacket { handle.getWorldKeys().write(0, value); return; } - // 1.18 and below + handle.getDimensionTypes().write(0, value); } @@ -74,6 +70,30 @@ public class WrapperPlayServerRespawn extends AbstractPacket { handle.getGameModes().write(0, EnumWrappers.NativeGameMode.fromBukkit(value)); } + //............. + // Previous GameMode Field + //............. + + public void getPreviousGameMode() { + handle.getGameModes().read(1); + } + + public void setPreviousGameMode(GameMode value) { + handle.getGameModes().write(1, EnumWrappers.NativeGameMode.fromBukkit(value)); + } + + //............. + // Copy Metadata Field + //............. + + public boolean isCopyMetadata() { + return handle.getBytes().read(0) != 0; + } + + public void setCopyMetadata(boolean value) { + handle.getBytes().write(0, ((byte) (value ? 1 : 0))); + } + //............. // Last death location Field // Added in 1.19. From 562f9ea3e4061c304c03fda73de90dc7886a089b Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 28 Apr 2023 23:32:00 +0200 Subject: [PATCH 014/296] fix: remove logs??? --- logs/2023-04-28-1.log.gz | Bin 123 -> 0 bytes logs/2023-04-28-2.log.gz | Bin 124 -> 0 bytes logs/2023-04-28-3.log.gz | Bin 124 -> 0 bytes logs/2023-04-28-4.log.gz | Bin 124 -> 0 bytes logs/2023-04-28-5.log.gz | Bin 124 -> 0 bytes logs/2023-04-28-6.log.gz | Bin 124 -> 0 bytes logs/2023-04-28-7.log.gz | Bin 124 -> 0 bytes logs/2023-04-28-8.log.gz | Bin 124 -> 0 bytes 8 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 logs/2023-04-28-1.log.gz delete mode 100644 logs/2023-04-28-2.log.gz delete mode 100644 logs/2023-04-28-3.log.gz delete mode 100644 logs/2023-04-28-4.log.gz delete mode 100644 logs/2023-04-28-5.log.gz delete mode 100644 logs/2023-04-28-6.log.gz delete mode 100644 logs/2023-04-28-7.log.gz delete mode 100644 logs/2023-04-28-8.log.gz diff --git a/logs/2023-04-28-1.log.gz b/logs/2023-04-28-1.log.gz deleted file mode 100644 index 20d5077f7dc09d787c8b69aca2bf3e038e909942..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123 zcmb2|=3oGW|Evc$avd@dV0&LcK3RDwPT^7Qwo<9-22TfX!vVNmt;}q))X7pjZuLXqLDGr(>x37x^?+( bU(Kq1D1EkW(M-cTWwY(KTI6eI0qq0;1)VlJ diff --git a/logs/2023-04-28-2.log.gz b/logs/2023-04-28-2.log.gz deleted file mode 100644 index c9b7d6dc36bebfe5314af5addac817d00f8faa21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124 zcmV-?0E7P@iwFP!00000{{_LZ4uUWc2H@SN__yL-&9kb7AVZtryH6pUe3%+^2;xs){mdy0)jLBO=BSLNY^4C8vm|D0WK5i__yj{C>0ZPlMJqyus9HgrmfNhd*%+p z>+^l1yOML%HWS95&!v8MLq8FoA}oZ)wzrGBTWbkj2uT$&m7F3zEZ8&&j4-d}VHOU4 enORqZ)26w6@%O4bOC2000290X5eE diff --git a/logs/2023-04-28-5.log.gz b/logs/2023-04-28-5.log.gz deleted file mode 100644 index 454921fa172affc87b6922c83b9f78099a839a50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124 zcmV-?0E7P@iwFP!00000{{_Ll4uUWg2GHH7__oSmEcK7vNd{L;To?#L(^hDLz2;ts zukSg7JCVCmeH$@+d@jeneRU(@A;Lna?fG(WjkT80hLBVdQ^_gf&4NvnzzFkd?q=cO emzi}n*l(K4gs)fqu|z`mtag7>*qPUA0001f1UuRQ diff --git a/logs/2023-04-28-6.log.gz b/logs/2023-04-28-6.log.gz deleted file mode 100644 index c0d0683e3e086851d5306755298111f0dccfc06c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124 zcmV-?0E7P@iwFP!00000{{_LZ4uUWc2H>5i__yj{s0AarNd{L;TpS2P(^hDLJ#z=~ z_5HrlHRP_;HWS8=&!v9#&tW3mMOX-D+g?ttv(^&&5RxilDmg{GS+Hvo7-8Pb&8!^! ey0C5rhh1}-@%5@dmPi;L$LbF`@g~1&0002)kT-Au diff --git a/logs/2023-04-28-7.log.gz b/logs/2023-04-28-7.log.gz deleted file mode 100644 index d1c0febd88a247bbe8ed703cdc72232fb258dd2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124 zcmV-?0E7P@iwFP!00000{{_LZ4uUWc2H@SN__yL=uwc_9Fv7f=yIDB+ eWoBIss!em5@bjuWOCBALj00016zB%Fm diff --git a/logs/2023-04-28-8.log.gz b/logs/2023-04-28-8.log.gz deleted file mode 100644 index ffb6f05c8bd9b4aa8fc1ae797468eb06390398a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124 zcmb2|=3oGW|Evc$@--O zq*lEXK6dqak>sv$dqFuRot9H^`RUgqvN>ZpJVgzs&QZFjbHkLg#~^>1DL4E6Gizoa cEW93L_oM2nytm4i^Oqm;SADH$$O2jl025F&UH||9 From 1eb2af64435536e070b4aed74d44838da0d975c1 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 28 Apr 2023 23:52:50 +0200 Subject: [PATCH 015/296] why mojang? why? --- logs/2023-04-28-1.log.gz | Bin 0 -> 124 bytes logs/2023-04-28-2.log.gz | Bin 0 -> 124 bytes logs/2023-04-28-3.log.gz | Bin 0 -> 124 bytes logs/2023-04-28-4.log.gz | Bin 0 -> 124 bytes .../net/artelnatif/nicko/NickoBukkit.java | 35 ------------------ .../nicko/disguise/AppearanceManager.java | 7 ++-- .../wrapper/WrapperPlayServerRespawn.java | 11 +++--- 7 files changed, 8 insertions(+), 45 deletions(-) create mode 100644 logs/2023-04-28-1.log.gz create mode 100644 logs/2023-04-28-2.log.gz create mode 100644 logs/2023-04-28-3.log.gz create mode 100644 logs/2023-04-28-4.log.gz diff --git a/logs/2023-04-28-1.log.gz b/logs/2023-04-28-1.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..759f46fbeca47326703aefd30fbfc09ca76b77bb GIT binary patch literal 124 zcmV-?0E7P@iwFP!00000{{_LZ4uUWc2H@SN__xYntfeI8CK+5YVPPN)O=XzV^&4Vwd8~+3wF%{Bg~t*nU!N$ e->jR#ao18`_y*MkPb literal 0 HcmV?d00001 diff --git a/logs/2023-04-28-2.log.gz b/logs/2023-04-28-2.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..5236e1ca399a45b94bd4c6ef77c09d5aa71116d5 GIT binary patch literal 124 zcmV-?0E7P@iwFP!00000{{_LZ4uUWc2H@SN__yj{tVI%X6AZ4HxHu4ormfPX_RJlG z*Z2D-*HF`v>t;+}pX=o{Jja=E7hxe>?X5k#&RR-&9k({kH!O$+9a&*l6W?$g2;RYe&!U9P95BO=BSLNY^4C8vm|D0WK6 literal 0 HcmV?d00001 diff --git a/logs/2023-04-28-4.log.gz b/logs/2023-04-28-4.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..a6f5e76a2d21c295ccf47564184c7da70dfb0584 GIT binary patch literal 124 zcmb2|=3oGW|Evc$@--O4FumQ>9kC?jql4%U#t2>Q6=<9NKseC=7h^C28Z^{njLBJBQ-6S c_myw)&j-&#%cprr$hE)X*NHi!kp;9A03zErZvX%Q literal 0 HcmV?d00001 diff --git a/src/main/java/net/artelnatif/nicko/NickoBukkit.java b/src/main/java/net/artelnatif/nicko/NickoBukkit.java index 641b86b..8310406 100644 --- a/src/main/java/net/artelnatif/nicko/NickoBukkit.java +++ b/src/main/java/net/artelnatif/nicko/NickoBukkit.java @@ -1,12 +1,7 @@ package net.artelnatif.nicko; -import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; -import com.comphenix.protocol.events.ListenerPriority; -import com.comphenix.protocol.events.PacketAdapter; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.events.PacketEvent; import net.artelnatif.nicko.command.NickoCommand; import net.artelnatif.nicko.config.Configuration; import net.artelnatif.nicko.config.ConfigurationManager; @@ -20,7 +15,6 @@ import net.artelnatif.nicko.mojang.MojangAPI; import net.artelnatif.nicko.placeholder.PlaceHolderHook; import net.artelnatif.nicko.storage.PlayerDataStore; import net.artelnatif.nicko.storage.name.PlayerNameStore; -import net.artelnatif.nicko.wrapper.WrapperPlayServerRespawn; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.command.PluginCommand; @@ -110,35 +104,6 @@ public class NickoBukkit extends JavaPlugin { getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this); getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this); - // For debug purposes - protocolManager.addPacketListener(new PacketAdapter( - this, - ListenerPriority.NORMAL, - PacketType.Play.Server.RESPAWN) { - @Override - public void onPacketReceiving(PacketEvent event) { - } - - @Override - public void onPacketSending(PacketEvent event) { - final PacketContainer packet = event.getPacket(); - final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(packet); - getLogger().info(respawn.getDimension().getName()); - getLogger().info(String.valueOf(respawn.isCopyMetadata())); - getLogger().info(String.valueOf(respawn.getSeed())); - getLogger().info(String.valueOf(respawn.getLastDeathLocation().isPresent())); - /** - * packet.getStructures().getFields().forEach(fieldAccessor -> { - * final Field field = fieldAccessor.getField(); - * getLogger().info("field=[" + - * "name=" + field.getName() + "," + - * "type=" + field.getType().getSimpleName() + - * "]"); - * }); - */ - } - }); - getLogger().info("Nicko (Bukkit) has been enabled."); } } diff --git a/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java b/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java index 93e3841..c8f3ec2 100644 --- a/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java +++ b/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java @@ -142,16 +142,15 @@ public class AppearanceManager { final World world = player.getWorld(); final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(); + respawn.setDimension(world); + respawn.setSeed(world.getSeed()); respawn.setGameMode(player.getGameMode()); respawn.setPreviousGameMode(player.getGameMode()); respawn.setDifficulty(world.getDifficulty()); - respawn.setDimension(world); - respawn.setSeed(world.getSeed()); - respawn.setLastDeathLocation(player.getLocation()); respawn.setCopyMetadata(false); respawn.getHandle().getBooleans().write(0, false); // is debug respawn.getHandle().getBooleans().write(1, false); // is flat - respawn.sendPacket(player); + respawn.broadcastPacket(); /*final EntityPlayer cp = ((CraftPlayer) player).getHandle(); final PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(cp.cG().Z(), cp.P(), player.getWorld().getSeed(), EnumGamemode.a, EnumGamemode.a, true, true, (byte) 0x00, Optional.empty()); cp.b.a(respawn);*/ diff --git a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java index a8a855a..e43c6cb 100644 --- a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java @@ -26,8 +26,6 @@ public class WrapperPlayServerRespawn extends AbstractPacket { handle.getModifier().writeDefaults(); } - public WrapperPlayServerRespawn(PacketContainer container) { super(container, TYPE); } - //............. // Dimension Field (1.8 - Present) // The dimension field has changed numerous times: @@ -62,8 +60,8 @@ public class WrapperPlayServerRespawn extends AbstractPacket { // GameMode Field //............. - public void getGameMode() { - handle.getGameModes().read(0); + public GameMode getGameMode() { + return handle.getGameModes().read(0).toBukkit(); } public void setGameMode(GameMode value) { @@ -74,8 +72,8 @@ public class WrapperPlayServerRespawn extends AbstractPacket { // Previous GameMode Field //............. - public void getPreviousGameMode() { - handle.getGameModes().read(1); + public GameMode getPreviousGameMode() { + return handle.getGameModes().read(1).toBukkit(); } public void setPreviousGameMode(GameMode value) { @@ -97,6 +95,7 @@ public class WrapperPlayServerRespawn extends AbstractPacket { //............. // Last death location Field // Added in 1.19. + // (useless?) //............. public Optional getLastDeathLocation() { From 3037945729f89196279651693983bc7ea5511241 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 28 Apr 2023 23:53:10 +0200 Subject: [PATCH 016/296] fix: logs again --- logs/2023-04-28-1.log.gz | Bin 124 -> 0 bytes logs/2023-04-28-2.log.gz | Bin 124 -> 0 bytes logs/2023-04-28-3.log.gz | Bin 124 -> 0 bytes logs/2023-04-28-4.log.gz | Bin 124 -> 0 bytes 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 logs/2023-04-28-1.log.gz delete mode 100644 logs/2023-04-28-2.log.gz delete mode 100644 logs/2023-04-28-3.log.gz delete mode 100644 logs/2023-04-28-4.log.gz diff --git a/logs/2023-04-28-1.log.gz b/logs/2023-04-28-1.log.gz deleted file mode 100644 index 759f46fbeca47326703aefd30fbfc09ca76b77bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124 zcmV-?0E7P@iwFP!00000{{_LZ4uUWc2H@SN__xYntfeI8CK+5YVPPN)O=XzV^&4Vwd8~+3wF%{Bg~t*nU!N$ e->jR#ao18`_y*MkPb diff --git a/logs/2023-04-28-2.log.gz b/logs/2023-04-28-2.log.gz deleted file mode 100644 index 5236e1ca399a45b94bd4c6ef77c09d5aa71116d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124 zcmV-?0E7P@iwFP!00000{{_LZ4uUWc2H@SN__yj{tVI%X6AZ4HxHu4ormfPX_RJlG z*Z2D-*HF`v>t;+}pX=o{Jja=E7hxe>?X5k#&RR-&9k({kH!O$+9a&*l6W?$g2;RYe&!U9P95BO=BSLNY^4C8vm|D0WK6 diff --git a/logs/2023-04-28-4.log.gz b/logs/2023-04-28-4.log.gz deleted file mode 100644 index a6f5e76a2d21c295ccf47564184c7da70dfb0584..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124 zcmb2|=3oGW|Evc$@--O4FumQ>9kC?jql4%U#t2>Q6=<9NKseC=7h^C28Z^{njLBJBQ-6S c_myw)&j-&#%cprr$hE)X*NHi!kp;9A03zErZvX%Q From af7081a87a7c0e160bfeffcdbf06191ec338f250 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 29 Apr 2023 10:46:08 +0200 Subject: [PATCH 017/296] feat: still researching packets support --- .gitignore | 4 ++- .../nicko/disguise/AppearanceManager.java | 4 +-- .../wrapper/WrapperPlayServerRespawn.java | 29 ++++++++++++------- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 17d0f8a..a573eb1 100644 --- a/.gitignore +++ b/.gitignore @@ -49,4 +49,6 @@ target dependency-reduced-pom.xml # Kept for convenience -v1_19_R3 \ No newline at end of file +v1_19_R3 +# MockBukkit logs +logs \ No newline at end of file diff --git a/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java b/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java index c8f3ec2..22ea766 100644 --- a/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java +++ b/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java @@ -149,8 +149,8 @@ public class AppearanceManager { respawn.setDifficulty(world.getDifficulty()); respawn.setCopyMetadata(false); respawn.getHandle().getBooleans().write(0, false); // is debug - respawn.getHandle().getBooleans().write(1, false); // is flat - respawn.broadcastPacket(); + respawn.getHandle().getBooleans().write(1, true); // is flat + respawn.sendPacket(player); /*final EntityPlayer cp = ((CraftPlayer) player).getHandle(); final PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(cp.cG().Z(), cp.P(), player.getWorld().getSeed(), EnumGamemode.a, EnumGamemode.a, true, true, (byte) 0x00, Optional.empty()); cp.b.a(respawn);*/ diff --git a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java index e43c6cb..d7ac3e9 100644 --- a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java @@ -2,9 +2,12 @@ package net.artelnatif.nicko.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.wrappers.BlockPosition; +import com.comphenix.protocol.wrappers.BukkitConverters; import com.comphenix.protocol.wrappers.EnumWrappers; +import com.google.common.hash.Hashing; import org.bukkit.Difficulty; import org.bukkit.GameMode; import org.bukkit.Location; @@ -27,12 +30,11 @@ public class WrapperPlayServerRespawn extends AbstractPacket { } //............. - // Dimension Field (1.8 - Present) + // Dimension/World Field // The dimension field has changed numerous times: - // - Version 1.8 through 1.15 need an integer, - // - 1.15 through 1.18 need a (NBT Tag) Identifier and - // - 1.19.2 and beyond require a Holder of a DimensionManager Identifier (???). - // (Wiki.vg still refers to this as an "Identifier") + // - 1.8 through 1.17 (?) need an integer, + // - 1.18 need a Holder of a World ResourceKey, + // - 1.19.2 reverted 1.18 and simply need a World ResourceKey. // // n.b.: this field is a nightmare please mojang stop refactoring // your code to change things that were working perfectly fine before @@ -50,10 +52,16 @@ public class WrapperPlayServerRespawn extends AbstractPacket { if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { // 1.19 and above handle.getWorldKeys().write(0, value); - return; + } else if (MinecraftVersion.CAVES_CLIFFS_2.atOrAbove()) { + // 1.18 + handle.getHolders( + MinecraftReflection.getDimensionManager(), + BukkitConverters.getDimensionConverter() + ).write(0, value); + } else { + // 1.17 and below (untested) + handle.getDimensions().write(0, value.getEnvironment().ordinal()); } - - handle.getDimensionTypes().write(0, value); } //............. @@ -89,13 +97,12 @@ public class WrapperPlayServerRespawn extends AbstractPacket { } public void setCopyMetadata(boolean value) { - handle.getBytes().write(0, ((byte) (value ? 1 : 0))); + handle.getBytes().write(0, ((byte) (value ? 0x01 : 0x00))); } //............. // Last death location Field // Added in 1.19. - // (useless?) //............. public Optional getLastDeathLocation() { @@ -127,7 +134,7 @@ public class WrapperPlayServerRespawn extends AbstractPacket { public void setSeed(long value) { if (MinecraftVersion.BEE_UPDATE.atOrAbove()) { - handle.getLongs().write(0, value); + handle.getLongs().write(0, Hashing.sha256().hashLong(value).asLong()); } } From ac9af73fb6deda974c28a4e310a8656aef721506 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 29 Apr 2023 11:11:27 +0200 Subject: [PATCH 018/296] style: remove debugging statements --- .../artelnatif/nicko/disguise/AppearanceManager.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java b/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java index 22ea766..0075f05 100644 --- a/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java +++ b/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java @@ -99,7 +99,6 @@ public class AppearanceManager { public ActionResult updatePlayer(boolean skinChange) { final String displayName = profile.getName() == null ? player.getName() : profile.getName(); - Bukkit.broadcastMessage("Building UserProfile"); final WrappedGameProfile gameProfile = WrappedGameProfile.fromPlayer(player).withName(displayName); final ActionResult result = updateGameProfileSkin(gameProfile, skinChange); if (!result.isError()) { @@ -124,7 +123,6 @@ public class AppearanceManager { final Multimap properties = gameProfile.getProperties(); properties.get("textures").clear(); properties.put("textures", new WrappedSignedProperty("textures", skinResult.getValue(), skinResult.getSignature())); - Bukkit.broadcastMessage("Modified properties"); } } return new ActionResult<>(); @@ -138,8 +136,6 @@ public class AppearanceManager { } private void respawnPlayer() { - Bukkit.broadcastMessage("Respawning player"); - final World world = player.getWorld(); final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(); respawn.setDimension(world); @@ -149,15 +145,11 @@ public class AppearanceManager { respawn.setDifficulty(world.getDifficulty()); respawn.setCopyMetadata(false); respawn.getHandle().getBooleans().write(0, false); // is debug - respawn.getHandle().getBooleans().write(1, true); // is flat + respawn.getHandle().getBooleans().write(1, false); // is flat respawn.sendPacket(player); - /*final EntityPlayer cp = ((CraftPlayer) player).getHandle(); - final PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(cp.cG().Z(), cp.P(), player.getWorld().getSeed(), EnumGamemode.a, EnumGamemode.a, true, true, (byte) 0x00, Optional.empty()); - cp.b.a(respawn);*/ } private void updateTabList(WrappedGameProfile gameProfile, String displayName) { - Bukkit.broadcastMessage("Updating tablist"); final WrapperPlayerServerPlayerInfoRemove remove = new WrapperPlayerServerPlayerInfoRemove(); remove.setUUIDs(ImmutableList.of(player.getUniqueId())); From 3ad3da91791581a7af1fba3bdee54cbc4e58de07 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 17 May 2023 13:23:21 +0200 Subject: [PATCH 019/296] feat: player respawn support for 1.19 --- pom.xml | 30 ++++++++--------- .../nicko/disguise/AppearanceManager.java | 20 ++++++++--- .../wrapper/WrapperPlayServerRespawn.java | 33 +++++-------------- 3 files changed, 39 insertions(+), 44 deletions(-) diff --git a/pom.xml b/pom.xml index e88257a..1988940 100644 --- a/pom.xml +++ b/pom.xml @@ -39,12 +39,12 @@ - - com.comphenix.protocol - ProtocolLib - 5.0.0-SNAPSHOT - - + + + com.comphenix.protocol + ProtocolLib + 5.0.0-SNAPSHOT + me.clip @@ -52,13 +52,6 @@ 2.11.2 provided - - - org.spigotmc - spigot - 1.19.4-R0.1-SNAPSHOT - provided - xyz.xenondevs.invui @@ -97,15 +90,22 @@ yamlconfig 1.1.2 + com.fasterxml.jackson.core jackson-core - 2.13.3 + 2.14.2 + + + org.spigotmc + spigot-api + 1.19.4-R0.1-SNAPSHOT + provided com.fasterxml.jackson.dataformat jackson-dataformat-yaml - 2.13.3 + 2.14.2 diff --git a/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java b/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java index 0075f05..4659b9d 100644 --- a/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java +++ b/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java @@ -102,12 +102,14 @@ public class AppearanceManager { final WrappedGameProfile gameProfile = WrappedGameProfile.fromPlayer(player).withName(displayName); final ActionResult result = updateGameProfileSkin(gameProfile, skinChange); if (!result.isError()) { + updateMetadata(); updateTabList(gameProfile, displayName); respawnPlayer(); } return new ActionResult<>(); } + private ActionResult updateGameProfileSkin(WrappedGameProfile gameProfile, boolean skinChange) { final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); @@ -135,6 +137,11 @@ public class AppearanceManager { return new ActionResult<>(); } + private void updateMetadata() { + final WrappedDataWatcher entityWatcher = WrappedDataWatcher.getEntityWatcher(player); + entityWatcher.setObject(17, (byte) 0x7f, true); + } + private void respawnPlayer() { final World world = player.getWorld(); final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(); @@ -145,7 +152,7 @@ public class AppearanceManager { respawn.setDifficulty(world.getDifficulty()); respawn.setCopyMetadata(false); respawn.getHandle().getBooleans().write(0, false); // is debug - respawn.getHandle().getBooleans().write(1, false); // is flat + respawn.getHandle().getBooleans().write(0, false); // is flat respawn.sendPacket(player); } @@ -155,17 +162,22 @@ public class AppearanceManager { final WrapperPlayerServerPlayerInfo update = new WrapperPlayerServerPlayerInfo(); update.setActions(EnumSet.of(EnumWrappers.PlayerInfoAction.ADD_PLAYER, + EnumWrappers.PlayerInfoAction.INITIALIZE_CHAT, EnumWrappers.PlayerInfoAction.UPDATE_LISTED, EnumWrappers.PlayerInfoAction.UPDATE_DISPLAY_NAME, EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE, EnumWrappers.PlayerInfoAction.UPDATE_LATENCY)); update.setData(ImmutableList.of(new PlayerInfoData( - gameProfile, + player.getUniqueId(), player.getPing(), + true, EnumWrappers.NativeGameMode.fromBukkit(player.getGameMode()), - WrappedChatComponent.fromText(displayName) + gameProfile, + WrappedChatComponent.fromText(displayName), + new WrappedRemoteChatSessionData(UUID.randomUUID(), + WrappedProfilePublicKey.ofPlayer(player).getKeyData()) ))); remove.sendPacket(player); update.sendPacket(player); } -} +} \ No newline at end of file diff --git a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java index d7ac3e9..ace7147 100644 --- a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java @@ -1,20 +1,18 @@ package net.artelnatif.nicko.wrapper; import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.InternalStructure; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; -import com.comphenix.protocol.wrappers.BlockPosition; import com.comphenix.protocol.wrappers.BukkitConverters; import com.comphenix.protocol.wrappers.EnumWrappers; +import com.comphenix.protocol.wrappers.MinecraftKey; import com.google.common.hash.Hashing; import org.bukkit.Difficulty; import org.bukkit.GameMode; -import org.bukkit.Location; import org.bukkit.World; -import java.util.Optional; - /** * Up-to-date version of the Wrapper class * for the PacketPlayServerRespawn. @@ -50,7 +48,12 @@ public class WrapperPlayServerRespawn extends AbstractPacket { public void setDimension(World value) { if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { - // 1.19 and above + // 1.19 to 1.19.4 + // Thank you lukalt! + final InternalStructure dimensionType = handle.getStructures().read(0); + dimensionType.getMinecraftKeys().write(0, new MinecraftKey("minecraft", "dimension_type")); + dimensionType.getMinecraftKeys().write(1, new MinecraftKey("minecraft", "overworld")); + handle.getStructures().write(0, dimensionType); handle.getWorldKeys().write(0, value); } else if (MinecraftVersion.CAVES_CLIFFS_2.atOrAbove()) { // 1.18 @@ -100,26 +103,6 @@ public class WrapperPlayServerRespawn extends AbstractPacket { handle.getBytes().write(0, ((byte) (value ? 0x01 : 0x00))); } - //............. - // Last death location Field - // Added in 1.19. - //............. - - public Optional getLastDeathLocation() { - if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { - return handle.getOptionals(BlockPosition.getConverter()).read(0); - } - return Optional.empty(); - } - - public void setLastDeathLocation(Location value) { - if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { - final BlockPosition locationToBlockPosition = BlockPosition.getConverter().getSpecific(value); - final Optional blockPosition = Optional.ofNullable(locationToBlockPosition); - handle.getOptionals(BlockPosition.getConverter()).write(0, blockPosition); - } - } - //............. // Seed Field // Added in 1.15. From f3088fca8c3a0fdfce52438cc75ae2e2486f1068 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 17 May 2023 13:27:15 +0200 Subject: [PATCH 020/296] refactor: move package --- .gitignore | 7 +---- pom.xml | 2 +- .../atnrch}/nicko/NickoBukkit.java | 28 +++++++++---------- .../atnrch}/nicko/anvil/AnvilManager.java | 14 +++++----- .../atnrch}/nicko/command/NickoCommand.java | 10 +++---- .../nicko/command/sub/NickoCheckSubCmd.java | 12 ++++---- .../nicko/command/sub/NickoDebugSubCmd.java | 8 +++--- .../atnrch}/nicko/config/Configuration.java | 2 +- .../nicko/config/ConfigurationManager.java | 2 +- .../nicko/config/DataSourceConfiguration.java | 2 +- .../atnrch}/nicko/disguise/ActionResult.java | 4 +-- .../nicko/disguise/AppearanceManager.java | 20 ++++++------- .../atnrch}/nicko/disguise/NickoProfile.java | 4 +-- .../nicko/event/PlayerJoinListener.java | 18 ++++++------ .../nicko/event/PlayerQuitListener.java | 6 ++-- .../atnrch}/nicko/gui/AdminGUI.java | 6 ++-- .../atnrch}/nicko/gui/MainGUI.java | 14 +++++----- .../atnrch}/nicko/gui/SettingsGUI.java | 8 +++--- .../nicko/gui/admin/CacheManagementGUI.java | 12 ++++---- .../gui/admin/cache/CacheDetailedGUI.java | 16 +++++------ .../nicko/gui/items/admin/ManageCache.java | 4 +-- .../gui/items/admin/cache/CacheDetailed.java | 4 +-- .../items/admin/cache/CacheInvalidate.java | 8 +++--- .../gui/items/admin/cache/CacheOverview.java | 6 ++-- .../items/admin/cache/SkinPlaceholder.java | 2 +- .../nicko/gui/items/common/GoBack.java | 2 +- .../gui/items/common/OptionUnavailable.java | 2 +- .../nicko/gui/items/common/ScrollDown.java | 2 +- .../nicko/gui/items/common/ScrollUp.java | 2 +- .../nicko/gui/items/main/AdminSubGUI.java | 4 +-- .../atnrch}/nicko/gui/items/main/ExitGUI.java | 2 +- .../nicko/gui/items/main/ResetAppearance.java | 8 +++--- .../nicko/gui/items/main/SettingsSubGUI.java | 4 +-- .../gui/items/settings/BungeeCordCycling.java | 6 ++-- .../gui/items/settings/LanguageCycling.java | 8 +++--- .../nicko/gui/items/skin/ChangeName.java | 4 +-- .../gui/items/skin/ChangeNameAndSkin.java | 4 +-- .../nicko/gui/items/skin/ChangeSkin.java | 4 +-- .../atnrch}/nicko/i18n/I18N.java | 6 ++-- .../atnrch}/nicko/i18n/I18NDict.java | 2 +- .../atnrch}/nicko/i18n/Locale.java | 2 +- .../atnrch}/nicko/i18n/LocaleFileManager.java | 4 +-- .../atnrch}/nicko/mojang/MojangAPI.java | 2 +- .../atnrch}/nicko/mojang/MojangSkin.java | 2 +- .../atnrch}/nicko/mojang/MojangUtils.java | 2 +- .../nicko/placeholder/NickoExpansion.java | 6 ++-- .../nicko/placeholder/PlaceHolderHook.java | 4 +-- .../nicko/storage/PlayerDataStore.java | 22 +++++++-------- .../atnrch}/nicko/storage/Storage.java | 6 ++-- .../nicko/storage/StorageProvider.java | 2 +- .../atnrch}/nicko/storage/cache/Cache.java | 6 ++-- .../nicko/storage/cache/CacheProvider.java | 2 +- .../nicko/storage/cache/redis/RedisCache.java | 10 +++---- .../cache/redis/RedisCacheProvider.java | 4 +-- .../nicko/storage/json/JSONStorage.java | 14 +++++----- .../storage/json/JSONStorageProvider.java | 4 +-- .../nicko/storage/name/PlayerNameStore.java | 2 +- .../atnrch}/nicko/storage/sql/SQLStorage.java | 14 +++++----- .../nicko/storage/sql/SQLStorageProvider.java | 8 +++--- .../atnrch}/nicko/wrapper/AbstractPacket.java | 2 +- .../wrapper/WrapperPlayServerRespawn.java | 2 +- .../WrapperPlayerServerPlayerInfo.java | 2 +- .../WrapperPlayerServerPlayerInfoRemove.java | 2 +- src/main/resources/plugin.yml | 2 +- .../atnrch}/nicko/test/NickoPluginTest.java | 8 +++--- .../nicko/test/config/ConfigurationTest.java | 6 ++-- .../nicko/test/storage/BrokenSQLTest.java | 12 ++++---- .../nicko/test/storage/SQLStorageTest.java | 14 +++++----- .../test/storage/cache/CacheStorageTest.java | 10 +++---- 69 files changed, 225 insertions(+), 230 deletions(-) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/NickoBukkit.java (87%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/anvil/AnvilManager.java (92%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/command/NickoCommand.java (86%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/command/sub/NickoCheckSubCmd.java (82%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/command/sub/NickoDebugSubCmd.java (88%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/config/Configuration.java (97%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/config/ConfigurationManager.java (98%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/config/DataSourceConfiguration.java (96%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/disguise/ActionResult.java (88%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/disguise/AppearanceManager.java (92%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/disguise/NickoProfile.java (95%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/event/PlayerJoinListener.java (77%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/event/PlayerQuitListener.java (82%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/AdminGUI.java (85%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/MainGUI.java (76%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/SettingsGUI.java (83%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/admin/CacheManagementGUI.java (72%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/admin/cache/CacheDetailedGUI.java (82%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/items/admin/ManageCache.java (92%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/items/admin/cache/CacheDetailed.java (88%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/items/admin/cache/CacheInvalidate.java (88%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/items/admin/cache/CacheOverview.java (87%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/items/admin/cache/SkinPlaceholder.java (93%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/items/common/GoBack.java (94%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/items/common/OptionUnavailable.java (91%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/items/common/ScrollDown.java (93%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/items/common/ScrollUp.java (93%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/items/main/AdminSubGUI.java (92%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/items/main/ExitGUI.java (92%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/items/main/ResetAppearance.java (89%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/items/main/SettingsSubGUI.java (90%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/items/settings/BungeeCordCycling.java (92%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/items/settings/LanguageCycling.java (92%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/items/skin/ChangeName.java (90%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/items/skin/ChangeNameAndSkin.java (91%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/gui/items/skin/ChangeSkin.java (90%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/i18n/I18N.java (94%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/i18n/I18NDict.java (98%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/i18n/Locale.java (95%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/i18n/LocaleFileManager.java (94%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/mojang/MojangAPI.java (99%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/mojang/MojangSkin.java (95%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/mojang/MojangUtils.java (95%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/placeholder/NickoExpansion.java (92%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/placeholder/PlaceHolderHook.java (84%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/storage/PlayerDataStore.java (83%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/storage/Storage.java (78%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/storage/StorageProvider.java (67%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/storage/cache/Cache.java (77%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/storage/cache/CacheProvider.java (63%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/storage/cache/redis/RedisCache.java (65%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/storage/cache/redis/RedisCacheProvider.java (83%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/storage/json/JSONStorage.java (89%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/storage/json/JSONStorageProvider.java (79%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/storage/name/PlayerNameStore.java (93%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/storage/sql/SQLStorage.java (94%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/storage/sql/SQLStorageProvider.java (93%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/wrapper/AbstractPacket.java (98%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/wrapper/WrapperPlayServerRespawn.java (99%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/wrapper/WrapperPlayerServerPlayerInfo.java (97%) rename src/main/java/{net/artelnatif => xyz/atnrch}/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java (96%) rename src/test/java/{net/artelnatif => xyz/atnrch}/nicko/test/NickoPluginTest.java (81%) rename src/test/java/{net/artelnatif => xyz/atnrch}/nicko/test/config/ConfigurationTest.java (85%) rename src/test/java/{net/artelnatif => xyz/atnrch}/nicko/test/storage/BrokenSQLTest.java (85%) rename src/test/java/{net/artelnatif => xyz/atnrch}/nicko/test/storage/SQLStorageTest.java (92%) rename src/test/java/{net/artelnatif => xyz/atnrch}/nicko/test/storage/cache/CacheStorageTest.java (84%) diff --git a/.gitignore b/.gitignore index a573eb1..67f8558 100644 --- a/.gitignore +++ b/.gitignore @@ -46,9 +46,4 @@ v1_19_R1/target target # Maven Dependency Reduced Pom -dependency-reduced-pom.xml - -# Kept for convenience -v1_19_R3 -# MockBukkit logs -logs \ No newline at end of file +dependency-reduced-pom.xml \ No newline at end of file diff --git a/pom.xml b/pom.xml index 1988940..aba14d4 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - net.artelnatif + xyz.atnrch nicko 1.0-SNAPSHOT Nicko diff --git a/src/main/java/net/artelnatif/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java similarity index 87% rename from src/main/java/net/artelnatif/nicko/NickoBukkit.java rename to src/main/java/xyz/atnrch/nicko/NickoBukkit.java index 8310406..55b87f0 100644 --- a/src/main/java/net/artelnatif/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -1,20 +1,20 @@ -package net.artelnatif.nicko; +package xyz.atnrch.nicko; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; -import net.artelnatif.nicko.command.NickoCommand; -import net.artelnatif.nicko.config.Configuration; -import net.artelnatif.nicko.config.ConfigurationManager; -import net.artelnatif.nicko.event.PlayerJoinListener; -import net.artelnatif.nicko.event.PlayerQuitListener; -import net.artelnatif.nicko.gui.items.common.OptionUnavailable; -import net.artelnatif.nicko.gui.items.main.ExitGUI; -import net.artelnatif.nicko.i18n.Locale; -import net.artelnatif.nicko.i18n.LocaleFileManager; -import net.artelnatif.nicko.mojang.MojangAPI; -import net.artelnatif.nicko.placeholder.PlaceHolderHook; -import net.artelnatif.nicko.storage.PlayerDataStore; -import net.artelnatif.nicko.storage.name.PlayerNameStore; +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.OptionUnavailable; +import xyz.atnrch.nicko.gui.items.main.ExitGUI; +import xyz.atnrch.nicko.i18n.Locale; +import xyz.atnrch.nicko.i18n.LocaleFileManager; +import xyz.atnrch.nicko.mojang.MojangAPI; +import xyz.atnrch.nicko.placeholder.PlaceHolderHook; +import xyz.atnrch.nicko.storage.PlayerDataStore; +import xyz.atnrch.nicko.storage.name.PlayerNameStore; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.command.PluginCommand; diff --git a/src/main/java/net/artelnatif/nicko/anvil/AnvilManager.java b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java similarity index 92% rename from src/main/java/net/artelnatif/nicko/anvil/AnvilManager.java rename to src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java index 6e53506..b741fef 100644 --- a/src/main/java/net/artelnatif/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java @@ -1,11 +1,11 @@ -package net.artelnatif.nicko.anvil; +package xyz.atnrch.nicko.anvil; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.AppearanceManager; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.i18n.I18N; -import net.artelnatif.nicko.i18n.I18NDict; -import net.artelnatif.nicko.mojang.MojangUtils; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.disguise.AppearanceManager; +import xyz.atnrch.nicko.disguise.ActionResult; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.mojang.MojangUtils; import net.wesjd.anvilgui.AnvilGUI; import org.bukkit.Material; import org.bukkit.entity.Player; diff --git a/src/main/java/net/artelnatif/nicko/command/NickoCommand.java b/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java similarity index 86% rename from src/main/java/net/artelnatif/nicko/command/NickoCommand.java rename to src/main/java/xyz/atnrch/nicko/command/NickoCommand.java index e10d6c6..114da47 100644 --- a/src/main/java/net/artelnatif/nicko/command/NickoCommand.java +++ b/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java @@ -1,9 +1,9 @@ -package net.artelnatif.nicko.command; +package xyz.atnrch.nicko.command; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.command.sub.NickoCheckSubCmd; -import net.artelnatif.nicko.command.sub.NickoDebugSubCmd; -import net.artelnatif.nicko.gui.MainGUI; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.command.sub.NickoCheckSubCmd; +import xyz.atnrch.nicko.command.sub.NickoDebugSubCmd; +import xyz.atnrch.nicko.gui.MainGUI; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; diff --git a/src/main/java/net/artelnatif/nicko/command/sub/NickoCheckSubCmd.java b/src/main/java/xyz/atnrch/nicko/command/sub/NickoCheckSubCmd.java similarity index 82% rename from src/main/java/net/artelnatif/nicko/command/sub/NickoCheckSubCmd.java rename to src/main/java/xyz/atnrch/nicko/command/sub/NickoCheckSubCmd.java index 56a4614..438b5e8 100644 --- a/src/main/java/net/artelnatif/nicko/command/sub/NickoCheckSubCmd.java +++ b/src/main/java/xyz/atnrch/nicko/command/sub/NickoCheckSubCmd.java @@ -1,10 +1,10 @@ -package net.artelnatif.nicko.command.sub; +package xyz.atnrch.nicko.command.sub; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.AppearanceManager; -import net.artelnatif.nicko.i18n.I18N; -import net.artelnatif.nicko.i18n.I18NDict; -import net.artelnatif.nicko.mojang.MojangUtils; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.disguise.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; diff --git a/src/main/java/net/artelnatif/nicko/command/sub/NickoDebugSubCmd.java b/src/main/java/xyz/atnrch/nicko/command/sub/NickoDebugSubCmd.java similarity index 88% rename from src/main/java/net/artelnatif/nicko/command/sub/NickoDebugSubCmd.java rename to src/main/java/xyz/atnrch/nicko/command/sub/NickoDebugSubCmd.java index e7490ba..c416898 100644 --- a/src/main/java/net/artelnatif/nicko/command/sub/NickoDebugSubCmd.java +++ b/src/main/java/xyz/atnrch/nicko/command/sub/NickoDebugSubCmd.java @@ -1,8 +1,8 @@ -package net.artelnatif.nicko.command.sub; +package xyz.atnrch.nicko.command.sub; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.AppearanceManager; -import net.artelnatif.nicko.mojang.MojangUtils; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.disguise.AppearanceManager; +import xyz.atnrch.nicko.mojang.MojangUtils; import org.bukkit.Bukkit; import org.bukkit.Sound; import org.bukkit.command.CommandSender; diff --git a/src/main/java/net/artelnatif/nicko/config/Configuration.java b/src/main/java/xyz/atnrch/nicko/config/Configuration.java similarity index 97% rename from src/main/java/net/artelnatif/nicko/config/Configuration.java rename to src/main/java/xyz/atnrch/nicko/config/Configuration.java index 31016bb..848eba1 100644 --- a/src/main/java/net/artelnatif/nicko/config/Configuration.java +++ b/src/main/java/xyz/atnrch/nicko/config/Configuration.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.config; +package xyz.atnrch.nicko.config; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/net/artelnatif/nicko/config/ConfigurationManager.java b/src/main/java/xyz/atnrch/nicko/config/ConfigurationManager.java similarity index 98% rename from src/main/java/net/artelnatif/nicko/config/ConfigurationManager.java rename to src/main/java/xyz/atnrch/nicko/config/ConfigurationManager.java index 37c680b..f322668 100644 --- a/src/main/java/net/artelnatif/nicko/config/ConfigurationManager.java +++ b/src/main/java/xyz/atnrch/nicko/config/ConfigurationManager.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.config; +package xyz.atnrch.nicko.config; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/src/main/java/net/artelnatif/nicko/config/DataSourceConfiguration.java b/src/main/java/xyz/atnrch/nicko/config/DataSourceConfiguration.java similarity index 96% rename from src/main/java/net/artelnatif/nicko/config/DataSourceConfiguration.java rename to src/main/java/xyz/atnrch/nicko/config/DataSourceConfiguration.java index d180824..da4495f 100644 --- a/src/main/java/net/artelnatif/nicko/config/DataSourceConfiguration.java +++ b/src/main/java/xyz/atnrch/nicko/config/DataSourceConfiguration.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.config; +package xyz.atnrch.nicko.config; public class DataSourceConfiguration { public static final DataSourceConfiguration SQL_EMPTY = new DataSourceConfiguration("127.0.0.1", 3306, "root", ""); diff --git a/src/main/java/net/artelnatif/nicko/disguise/ActionResult.java b/src/main/java/xyz/atnrch/nicko/disguise/ActionResult.java similarity index 88% rename from src/main/java/net/artelnatif/nicko/disguise/ActionResult.java rename to src/main/java/xyz/atnrch/nicko/disguise/ActionResult.java index 83158b0..0e84447 100644 --- a/src/main/java/net/artelnatif/nicko/disguise/ActionResult.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/ActionResult.java @@ -1,6 +1,6 @@ -package net.artelnatif.nicko.disguise; +package xyz.atnrch.nicko.disguise; -import net.artelnatif.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.I18NDict; public class ActionResult { private final I18NDict errorMessage; diff --git a/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java similarity index 92% rename from src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java rename to src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java index 4659b9d..6b6ff82 100644 --- a/src/main/java/net/artelnatif/nicko/disguise/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java @@ -1,17 +1,17 @@ -package net.artelnatif.nicko.disguise; +package xyz.atnrch.nicko.disguise; import com.comphenix.protocol.wrappers.*; import com.google.common.collect.ImmutableList; import com.google.common.collect.Multimap; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.i18n.I18NDict; -import net.artelnatif.nicko.mojang.MojangAPI; -import net.artelnatif.nicko.mojang.MojangSkin; -import net.artelnatif.nicko.storage.PlayerDataStore; -import net.artelnatif.nicko.storage.name.PlayerNameStore; -import net.artelnatif.nicko.wrapper.WrapperPlayServerRespawn; -import net.artelnatif.nicko.wrapper.WrapperPlayerServerPlayerInfo; -import net.artelnatif.nicko.wrapper.WrapperPlayerServerPlayerInfoRemove; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.mojang.MojangAPI; +import xyz.atnrch.nicko.mojang.MojangSkin; +import xyz.atnrch.nicko.storage.PlayerDataStore; +import xyz.atnrch.nicko.storage.name.PlayerNameStore; +import xyz.atnrch.nicko.wrapper.WrapperPlayServerRespawn; +import xyz.atnrch.nicko.wrapper.WrapperPlayerServerPlayerInfo; +import xyz.atnrch.nicko.wrapper.WrapperPlayerServerPlayerInfoRemove; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.entity.Player; diff --git a/src/main/java/net/artelnatif/nicko/disguise/NickoProfile.java b/src/main/java/xyz/atnrch/nicko/disguise/NickoProfile.java similarity index 95% rename from src/main/java/net/artelnatif/nicko/disguise/NickoProfile.java rename to src/main/java/xyz/atnrch/nicko/disguise/NickoProfile.java index 926ad28..3652f90 100644 --- a/src/main/java/net/artelnatif/nicko/disguise/NickoProfile.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/NickoProfile.java @@ -1,6 +1,6 @@ -package net.artelnatif.nicko.disguise; +package xyz.atnrch.nicko.disguise; -import net.artelnatif.nicko.i18n.Locale; +import xyz.atnrch.nicko.i18n.Locale; public class NickoProfile implements Cloneable { public static final NickoProfile EMPTY_PROFILE = new NickoProfile(null, null, Locale.ENGLISH, true); diff --git a/src/main/java/net/artelnatif/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java similarity index 77% rename from src/main/java/net/artelnatif/nicko/event/PlayerJoinListener.java rename to src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java index d78ff18..4008add 100644 --- a/src/main/java/net/artelnatif/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java @@ -1,13 +1,13 @@ -package net.artelnatif.nicko.event; +package xyz.atnrch.nicko.event; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.AppearanceManager; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.i18n.I18N; -import net.artelnatif.nicko.i18n.I18NDict; -import net.artelnatif.nicko.storage.PlayerDataStore; -import net.artelnatif.nicko.storage.name.PlayerNameStore; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.disguise.AppearanceManager; +import xyz.atnrch.nicko.disguise.ActionResult; +import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.storage.PlayerDataStore; +import xyz.atnrch.nicko.storage.name.PlayerNameStore; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; diff --git a/src/main/java/net/artelnatif/nicko/event/PlayerQuitListener.java b/src/main/java/xyz/atnrch/nicko/event/PlayerQuitListener.java similarity index 82% rename from src/main/java/net/artelnatif/nicko/event/PlayerQuitListener.java rename to src/main/java/xyz/atnrch/nicko/event/PlayerQuitListener.java index 6d83949..3f89078 100644 --- a/src/main/java/net/artelnatif/nicko/event/PlayerQuitListener.java +++ b/src/main/java/xyz/atnrch/nicko/event/PlayerQuitListener.java @@ -1,7 +1,7 @@ -package net.artelnatif.nicko.event; +package xyz.atnrch.nicko.event; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.ActionResult; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.disguise.ActionResult; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; diff --git a/src/main/java/net/artelnatif/nicko/gui/AdminGUI.java b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java similarity index 85% rename from src/main/java/net/artelnatif/nicko/gui/AdminGUI.java rename to src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java index 6baa5a7..2ce2990 100644 --- a/src/main/java/net/artelnatif/nicko/gui/AdminGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java @@ -1,7 +1,7 @@ -package net.artelnatif.nicko.gui; +package xyz.atnrch.nicko.gui; -import net.artelnatif.nicko.gui.items.admin.ManageCache; -import net.artelnatif.nicko.gui.items.common.GoBack; +import xyz.atnrch.nicko.gui.items.admin.ManageCache; +import xyz.atnrch.nicko.gui.items.common.GoBack; import org.bukkit.entity.Player; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; diff --git a/src/main/java/net/artelnatif/nicko/gui/MainGUI.java b/src/main/java/xyz/atnrch/nicko/gui/MainGUI.java similarity index 76% rename from src/main/java/net/artelnatif/nicko/gui/MainGUI.java rename to src/main/java/xyz/atnrch/nicko/gui/MainGUI.java index e8afe54..aea1c50 100644 --- a/src/main/java/net/artelnatif/nicko/gui/MainGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/MainGUI.java @@ -1,11 +1,11 @@ -package net.artelnatif.nicko.gui; +package xyz.atnrch.nicko.gui; -import net.artelnatif.nicko.gui.items.main.AdminSubGUI; -import net.artelnatif.nicko.gui.items.main.ResetAppearance; -import net.artelnatif.nicko.gui.items.main.SettingsSubGUI; -import net.artelnatif.nicko.gui.items.skin.ChangeName; -import net.artelnatif.nicko.gui.items.skin.ChangeNameAndSkin; -import net.artelnatif.nicko.gui.items.skin.ChangeSkin; +import xyz.atnrch.nicko.gui.items.main.AdminSubGUI; +import xyz.atnrch.nicko.gui.items.main.ResetAppearance; +import xyz.atnrch.nicko.gui.items.main.SettingsSubGUI; +import xyz.atnrch.nicko.gui.items.skin.ChangeName; +import xyz.atnrch.nicko.gui.items.skin.ChangeNameAndSkin; +import xyz.atnrch.nicko.gui.items.skin.ChangeSkin; import org.bukkit.entity.Player; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; diff --git a/src/main/java/net/artelnatif/nicko/gui/SettingsGUI.java b/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java similarity index 83% rename from src/main/java/net/artelnatif/nicko/gui/SettingsGUI.java rename to src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java index eef7069..dc6fbc7 100644 --- a/src/main/java/net/artelnatif/nicko/gui/SettingsGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java @@ -1,8 +1,8 @@ -package net.artelnatif.nicko.gui; +package xyz.atnrch.nicko.gui; -import net.artelnatif.nicko.gui.items.common.GoBack; -import net.artelnatif.nicko.gui.items.settings.BungeeCordCycling; -import net.artelnatif.nicko.gui.items.settings.LanguageCycling; +import xyz.atnrch.nicko.gui.items.common.GoBack; +import xyz.atnrch.nicko.gui.items.settings.BungeeCordCycling; +import xyz.atnrch.nicko.gui.items.settings.LanguageCycling; import org.bukkit.entity.Player; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; diff --git a/src/main/java/net/artelnatif/nicko/gui/admin/CacheManagementGUI.java b/src/main/java/xyz/atnrch/nicko/gui/admin/CacheManagementGUI.java similarity index 72% rename from src/main/java/net/artelnatif/nicko/gui/admin/CacheManagementGUI.java rename to src/main/java/xyz/atnrch/nicko/gui/admin/CacheManagementGUI.java index 196ad40..58a2510 100644 --- a/src/main/java/net/artelnatif/nicko/gui/admin/CacheManagementGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/admin/CacheManagementGUI.java @@ -1,10 +1,10 @@ -package net.artelnatif.nicko.gui.admin; +package xyz.atnrch.nicko.gui.admin; -import net.artelnatif.nicko.gui.AdminGUI; -import net.artelnatif.nicko.gui.items.admin.cache.CacheDetailed; -import net.artelnatif.nicko.gui.items.admin.cache.CacheInvalidate; -import net.artelnatif.nicko.gui.items.admin.cache.CacheOverview; -import net.artelnatif.nicko.gui.items.common.GoBack; +import xyz.atnrch.nicko.gui.AdminGUI; +import xyz.atnrch.nicko.gui.items.admin.cache.CacheDetailed; +import xyz.atnrch.nicko.gui.items.admin.cache.CacheInvalidate; +import xyz.atnrch.nicko.gui.items.admin.cache.CacheOverview; +import xyz.atnrch.nicko.gui.items.common.GoBack; import org.bukkit.entity.Player; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; diff --git a/src/main/java/net/artelnatif/nicko/gui/admin/cache/CacheDetailedGUI.java b/src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java similarity index 82% rename from src/main/java/net/artelnatif/nicko/gui/admin/cache/CacheDetailedGUI.java rename to src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java index c02134c..d8b4c65 100644 --- a/src/main/java/net/artelnatif/nicko/gui/admin/cache/CacheDetailedGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java @@ -1,16 +1,16 @@ -package net.artelnatif.nicko.gui.admin.cache; +package xyz.atnrch.nicko.gui.admin.cache; +import xyz.atnrch.nicko.gui.items.common.GoBack; +import xyz.atnrch.nicko.gui.items.common.ScrollUp; +import xyz.atnrch.nicko.mojang.MojangSkin; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.gui.structure.Markers; import xyz.xenondevs.invui.item.Item; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.gui.items.admin.cache.SkinPlaceholder; -import net.artelnatif.nicko.gui.admin.CacheManagementGUI; -import net.artelnatif.nicko.gui.items.common.GoBack; -import net.artelnatif.nicko.gui.items.common.ScrollDown; -import net.artelnatif.nicko.gui.items.common.ScrollUp; -import net.artelnatif.nicko.mojang.MojangSkin; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.gui.items.admin.cache.SkinPlaceholder; +import xyz.atnrch.nicko.gui.admin.CacheManagementGUI; +import xyz.atnrch.nicko.gui.items.common.ScrollDown; import org.bukkit.entity.Player; import xyz.xenondevs.invui.window.Window; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/admin/ManageCache.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCache.java similarity index 92% rename from src/main/java/net/artelnatif/nicko/gui/items/admin/ManageCache.java rename to src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCache.java index ed814ec..5215caf 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/admin/ManageCache.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCache.java @@ -1,9 +1,9 @@ -package net.artelnatif.nicko.gui.items.admin; +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 net.artelnatif.nicko.gui.admin.CacheManagementGUI; +import xyz.atnrch.nicko.gui.admin.CacheManagementGUI; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheDetailed.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheDetailed.java similarity index 88% rename from src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheDetailed.java rename to src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheDetailed.java index 830a859..9a55797 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheDetailed.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheDetailed.java @@ -1,6 +1,6 @@ -package net.artelnatif.nicko.gui.items.admin.cache; +package xyz.atnrch.nicko.gui.items.admin.cache; -import net.artelnatif.nicko.gui.admin.cache.CacheDetailedGUI; +import xyz.atnrch.nicko.gui.admin.cache.CacheDetailedGUI; import org.bukkit.Material; import org.bukkit.event.inventory.ClickType; import xyz.xenondevs.invui.item.builder.ItemBuilder; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheInvalidate.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheInvalidate.java similarity index 88% rename from src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheInvalidate.java rename to src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheInvalidate.java index f454e92..7d3fa9a 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheInvalidate.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheInvalidate.java @@ -1,8 +1,8 @@ -package net.artelnatif.nicko.gui.items.admin.cache; +package xyz.atnrch.nicko.gui.items.admin.cache; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.i18n.I18N; -import net.artelnatif.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.NickoBukkit; +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; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheOverview.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheOverview.java similarity index 87% rename from src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheOverview.java rename to src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheOverview.java index b916b95..a4f0b70 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/CacheOverview.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheOverview.java @@ -1,9 +1,9 @@ -package net.artelnatif.nicko.gui.items.admin.cache; +package xyz.atnrch.nicko.gui.items.admin.cache; import com.google.common.cache.CacheStats; import com.google.common.cache.LoadingCache; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.mojang.MojangSkin; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.mojang.MojangSkin; import org.bukkit.Material; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/SkinPlaceholder.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/SkinPlaceholder.java similarity index 93% rename from src/main/java/net/artelnatif/nicko/gui/items/admin/cache/SkinPlaceholder.java rename to src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/SkinPlaceholder.java index 2984c53..6f94d63 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/admin/cache/SkinPlaceholder.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/SkinPlaceholder.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.gui.items.admin.cache; +package xyz.atnrch.nicko.gui.items.admin.cache; import org.bukkit.Material; import xyz.xenondevs.invui.item.builder.ItemBuilder; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/common/GoBack.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/GoBack.java similarity index 94% rename from src/main/java/net/artelnatif/nicko/gui/items/common/GoBack.java rename to src/main/java/xyz/atnrch/nicko/gui/items/common/GoBack.java index 5d44816..f840a6a 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/common/GoBack.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/GoBack.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.gui.items.common; +package xyz.atnrch.nicko.gui.items.common; import org.bukkit.Material; import xyz.xenondevs.invui.gui.Gui; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/common/OptionUnavailable.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/OptionUnavailable.java similarity index 91% rename from src/main/java/net/artelnatif/nicko/gui/items/common/OptionUnavailable.java rename to src/main/java/xyz/atnrch/nicko/gui/items/common/OptionUnavailable.java index 1f8e38a..97d42cb 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/common/OptionUnavailable.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/OptionUnavailable.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.gui.items.common; +package xyz.atnrch.nicko.gui.items.common; import org.bukkit.Material; import xyz.xenondevs.invui.item.builder.ItemBuilder; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/common/ScrollDown.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollDown.java similarity index 93% rename from src/main/java/net/artelnatif/nicko/gui/items/common/ScrollDown.java rename to src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollDown.java index 8cc8536..e8c5ade 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/common/ScrollDown.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollDown.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.gui.items.common; +package xyz.atnrch.nicko.gui.items.common; import org.bukkit.Material; import xyz.xenondevs.invui.gui.ScrollGui; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/common/ScrollUp.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollUp.java similarity index 93% rename from src/main/java/net/artelnatif/nicko/gui/items/common/ScrollUp.java rename to src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollUp.java index cd30663..a4f64bd 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/common/ScrollUp.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollUp.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.gui.items.common; +package xyz.atnrch.nicko.gui.items.common; import org.bukkit.Material; import xyz.xenondevs.invui.gui.ScrollGui; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/main/AdminSubGUI.java b/src/main/java/xyz/atnrch/nicko/gui/items/main/AdminSubGUI.java similarity index 92% rename from src/main/java/net/artelnatif/nicko/gui/items/main/AdminSubGUI.java rename to src/main/java/xyz/atnrch/nicko/gui/items/main/AdminSubGUI.java index 0ad8982..dedf06d 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/main/AdminSubGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/main/AdminSubGUI.java @@ -1,6 +1,6 @@ -package net.artelnatif.nicko.gui.items.main; +package xyz.atnrch.nicko.gui.items.main; -import net.artelnatif.nicko.gui.AdminGUI; +import xyz.atnrch.nicko.gui.AdminGUI; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; import org.bukkit.event.inventory.ClickType; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/main/ExitGUI.java b/src/main/java/xyz/atnrch/nicko/gui/items/main/ExitGUI.java similarity index 92% rename from src/main/java/net/artelnatif/nicko/gui/items/main/ExitGUI.java rename to src/main/java/xyz/atnrch/nicko/gui/items/main/ExitGUI.java index 3992b2a..438d137 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/main/ExitGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/main/ExitGUI.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.gui.items.main; +package xyz.atnrch.nicko.gui.items.main; import org.bukkit.Material; import org.bukkit.event.inventory.ClickType; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/main/ResetAppearance.java b/src/main/java/xyz/atnrch/nicko/gui/items/main/ResetAppearance.java similarity index 89% rename from src/main/java/net/artelnatif/nicko/gui/items/main/ResetAppearance.java rename to src/main/java/xyz/atnrch/nicko/gui/items/main/ResetAppearance.java index 3c1e8c1..fb380ec 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/main/ResetAppearance.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/main/ResetAppearance.java @@ -1,8 +1,8 @@ -package net.artelnatif.nicko.gui.items.main; +package xyz.atnrch.nicko.gui.items.main; -import net.artelnatif.nicko.disguise.AppearanceManager; -import net.artelnatif.nicko.i18n.I18N; -import net.artelnatif.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.disguise.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; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/main/SettingsSubGUI.java b/src/main/java/xyz/atnrch/nicko/gui/items/main/SettingsSubGUI.java similarity index 90% rename from src/main/java/net/artelnatif/nicko/gui/items/main/SettingsSubGUI.java rename to src/main/java/xyz/atnrch/nicko/gui/items/main/SettingsSubGUI.java index 52f9c28..26e0f40 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/main/SettingsSubGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/main/SettingsSubGUI.java @@ -1,6 +1,6 @@ -package net.artelnatif.nicko.gui.items.main; +package xyz.atnrch.nicko.gui.items.main; -import net.artelnatif.nicko.gui.SettingsGUI; +import xyz.atnrch.nicko.gui.SettingsGUI; import org.bukkit.Material; import org.bukkit.event.inventory.ClickType; import xyz.xenondevs.invui.item.builder.ItemBuilder; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/settings/BungeeCordCycling.java b/src/main/java/xyz/atnrch/nicko/gui/items/settings/BungeeCordCycling.java similarity index 92% rename from src/main/java/net/artelnatif/nicko/gui/items/settings/BungeeCordCycling.java rename to src/main/java/xyz/atnrch/nicko/gui/items/settings/BungeeCordCycling.java index 61a389b..76b20fc 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/settings/BungeeCordCycling.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/settings/BungeeCordCycling.java @@ -1,7 +1,7 @@ -package net.artelnatif.nicko.gui.items.settings; +package xyz.atnrch.nicko.gui.items.settings; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.disguise.NickoProfile; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/settings/LanguageCycling.java b/src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCycling.java similarity index 92% rename from src/main/java/net/artelnatif/nicko/gui/items/settings/LanguageCycling.java rename to src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCycling.java index abe1399..c6f6054 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/settings/LanguageCycling.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCycling.java @@ -1,8 +1,8 @@ -package net.artelnatif.nicko.gui.items.settings; +package xyz.atnrch.nicko.gui.items.settings; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.i18n.Locale; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.i18n.Locale; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeName.java b/src/main/java/xyz/atnrch/nicko/gui/items/skin/ChangeName.java similarity index 90% rename from src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeName.java rename to src/main/java/xyz/atnrch/nicko/gui/items/skin/ChangeName.java index c485e1a..82cc9de 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeName.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/skin/ChangeName.java @@ -1,6 +1,6 @@ -package net.artelnatif.nicko.gui.items.skin; +package xyz.atnrch.nicko.gui.items.skin; -import net.artelnatif.nicko.anvil.AnvilManager; +import xyz.atnrch.nicko.anvil.AnvilManager; import org.bukkit.Material; import org.bukkit.event.inventory.ClickType; import xyz.xenondevs.invui.item.builder.ItemBuilder; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeNameAndSkin.java b/src/main/java/xyz/atnrch/nicko/gui/items/skin/ChangeNameAndSkin.java similarity index 91% rename from src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeNameAndSkin.java rename to src/main/java/xyz/atnrch/nicko/gui/items/skin/ChangeNameAndSkin.java index 91fe0ff..fb3784f 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeNameAndSkin.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/skin/ChangeNameAndSkin.java @@ -1,6 +1,6 @@ -package net.artelnatif.nicko.gui.items.skin; +package xyz.atnrch.nicko.gui.items.skin; -import net.artelnatif.nicko.anvil.AnvilManager; +import xyz.atnrch.nicko.anvil.AnvilManager; import org.bukkit.Material; import org.bukkit.event.inventory.ClickType; import xyz.xenondevs.invui.item.builder.ItemBuilder; diff --git a/src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeSkin.java b/src/main/java/xyz/atnrch/nicko/gui/items/skin/ChangeSkin.java similarity index 90% rename from src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeSkin.java rename to src/main/java/xyz/atnrch/nicko/gui/items/skin/ChangeSkin.java index e3b96a3..cd61031 100644 --- a/src/main/java/net/artelnatif/nicko/gui/items/skin/ChangeSkin.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/skin/ChangeSkin.java @@ -1,6 +1,6 @@ -package net.artelnatif.nicko.gui.items.skin; +package xyz.atnrch.nicko.gui.items.skin; -import net.artelnatif.nicko.anvil.AnvilManager; +import xyz.atnrch.nicko.anvil.AnvilManager; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import xyz.xenondevs.invui.item.builder.SkullBuilder; diff --git a/src/main/java/net/artelnatif/nicko/i18n/I18N.java b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java similarity index 94% rename from src/main/java/net/artelnatif/nicko/i18n/I18N.java rename to src/main/java/xyz/atnrch/nicko/i18n/I18N.java index 40fe6ef..117f8c9 100644 --- a/src/main/java/net/artelnatif/nicko/i18n/I18N.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java @@ -1,8 +1,8 @@ -package net.artelnatif.nicko.i18n; +package xyz.atnrch.nicko.i18n; import com.github.jsixface.YamlConfig; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.disguise.NickoProfile; import org.bukkit.entity.Player; import java.io.InputStream; diff --git a/src/main/java/net/artelnatif/nicko/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java similarity index 98% rename from src/main/java/net/artelnatif/nicko/i18n/I18NDict.java rename to src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index 4997810..6c3bd2c 100644 --- a/src/main/java/net/artelnatif/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.i18n; +package xyz.atnrch.nicko.i18n; public class I18NDict { private final String key; diff --git a/src/main/java/net/artelnatif/nicko/i18n/Locale.java b/src/main/java/xyz/atnrch/nicko/i18n/Locale.java similarity index 95% rename from src/main/java/net/artelnatif/nicko/i18n/Locale.java rename to src/main/java/xyz/atnrch/nicko/i18n/Locale.java index 479e5cf..607b54c 100644 --- a/src/main/java/net/artelnatif/nicko/i18n/Locale.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/Locale.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.i18n; +package xyz.atnrch.nicko.i18n; import java.io.Serializable; diff --git a/src/main/java/net/artelnatif/nicko/i18n/LocaleFileManager.java b/src/main/java/xyz/atnrch/nicko/i18n/LocaleFileManager.java similarity index 94% rename from src/main/java/net/artelnatif/nicko/i18n/LocaleFileManager.java rename to src/main/java/xyz/atnrch/nicko/i18n/LocaleFileManager.java index ed7fe00..d2ff7e6 100644 --- a/src/main/java/net/artelnatif/nicko/i18n/LocaleFileManager.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/LocaleFileManager.java @@ -1,7 +1,7 @@ -package net.artelnatif.nicko.i18n; +package xyz.atnrch.nicko.i18n; import com.github.jsixface.YamlConfig; -import net.artelnatif.nicko.NickoBukkit; +import xyz.atnrch.nicko.NickoBukkit; import xyz.xenondevs.invui.util.IOUtils; import java.io.*; diff --git a/src/main/java/net/artelnatif/nicko/mojang/MojangAPI.java b/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java similarity index 99% rename from src/main/java/net/artelnatif/nicko/mojang/MojangAPI.java rename to src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java index d8b3bf2..46eb2f1 100644 --- a/src/main/java/net/artelnatif/nicko/mojang/MojangAPI.java +++ b/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.mojang; +package xyz.atnrch.nicko.mojang; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; diff --git a/src/main/java/net/artelnatif/nicko/mojang/MojangSkin.java b/src/main/java/xyz/atnrch/nicko/mojang/MojangSkin.java similarity index 95% rename from src/main/java/net/artelnatif/nicko/mojang/MojangSkin.java rename to src/main/java/xyz/atnrch/nicko/mojang/MojangSkin.java index 8980bcb..2033147 100644 --- a/src/main/java/net/artelnatif/nicko/mojang/MojangSkin.java +++ b/src/main/java/xyz/atnrch/nicko/mojang/MojangSkin.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.mojang; +package xyz.atnrch.nicko.mojang; import com.google.gson.JsonObject; diff --git a/src/main/java/net/artelnatif/nicko/mojang/MojangUtils.java b/src/main/java/xyz/atnrch/nicko/mojang/MojangUtils.java similarity index 95% rename from src/main/java/net/artelnatif/nicko/mojang/MojangUtils.java rename to src/main/java/xyz/atnrch/nicko/mojang/MojangUtils.java index 135c210..6845392 100644 --- a/src/main/java/net/artelnatif/nicko/mojang/MojangUtils.java +++ b/src/main/java/xyz/atnrch/nicko/mojang/MojangUtils.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.mojang; +package xyz.atnrch.nicko.mojang; import java.util.UUID; import java.util.regex.Pattern; diff --git a/src/main/java/net/artelnatif/nicko/placeholder/NickoExpansion.java b/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java similarity index 92% rename from src/main/java/net/artelnatif/nicko/placeholder/NickoExpansion.java rename to src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java index 7f3e39d..02a4cf7 100644 --- a/src/main/java/net/artelnatif/nicko/placeholder/NickoExpansion.java +++ b/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java @@ -1,8 +1,8 @@ -package net.artelnatif.nicko.placeholder; +package xyz.atnrch.nicko.placeholder; import me.clip.placeholderapi.expansion.PlaceholderExpansion; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.disguise.NickoProfile; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/net/artelnatif/nicko/placeholder/PlaceHolderHook.java b/src/main/java/xyz/atnrch/nicko/placeholder/PlaceHolderHook.java similarity index 84% rename from src/main/java/net/artelnatif/nicko/placeholder/PlaceHolderHook.java rename to src/main/java/xyz/atnrch/nicko/placeholder/PlaceHolderHook.java index c4d3750..b2900df 100644 --- a/src/main/java/net/artelnatif/nicko/placeholder/PlaceHolderHook.java +++ b/src/main/java/xyz/atnrch/nicko/placeholder/PlaceHolderHook.java @@ -1,6 +1,6 @@ -package net.artelnatif.nicko.placeholder; +package xyz.atnrch.nicko.placeholder; -import net.artelnatif.nicko.NickoBukkit; +import xyz.atnrch.nicko.NickoBukkit; import org.bukkit.Bukkit; public class PlaceHolderHook { diff --git a/src/main/java/net/artelnatif/nicko/storage/PlayerDataStore.java b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java similarity index 83% rename from src/main/java/net/artelnatif/nicko/storage/PlayerDataStore.java rename to src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java index 002c839..cae4147 100644 --- a/src/main/java/net/artelnatif/nicko/storage/PlayerDataStore.java +++ b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java @@ -1,15 +1,15 @@ -package net.artelnatif.nicko.storage; +package xyz.atnrch.nicko.storage; -import net.artelnatif.nicko.config.Configuration; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.i18n.I18NDict; -import net.artelnatif.nicko.mojang.MojangAPI; -import net.artelnatif.nicko.mojang.MojangUtils; -import net.artelnatif.nicko.storage.cache.Cache; -import net.artelnatif.nicko.storage.cache.redis.RedisCache; -import net.artelnatif.nicko.storage.json.JSONStorage; -import net.artelnatif.nicko.storage.sql.SQLStorage; +import xyz.atnrch.nicko.config.Configuration; +import xyz.atnrch.nicko.disguise.ActionResult; +import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.mojang.MojangAPI; +import xyz.atnrch.nicko.mojang.MojangUtils; +import xyz.atnrch.nicko.storage.cache.Cache; +import xyz.atnrch.nicko.storage.cache.redis.RedisCache; +import xyz.atnrch.nicko.storage.json.JSONStorage; +import xyz.atnrch.nicko.storage.sql.SQLStorage; import org.bukkit.entity.Player; import java.io.IOException; diff --git a/src/main/java/net/artelnatif/nicko/storage/Storage.java b/src/main/java/xyz/atnrch/nicko/storage/Storage.java similarity index 78% rename from src/main/java/net/artelnatif/nicko/storage/Storage.java rename to src/main/java/xyz/atnrch/nicko/storage/Storage.java index b23b1ef..830721b 100644 --- a/src/main/java/net/artelnatif/nicko/storage/Storage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/Storage.java @@ -1,7 +1,7 @@ -package net.artelnatif.nicko.storage; +package xyz.atnrch.nicko.storage; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.disguise.ActionResult; +import xyz.atnrch.nicko.disguise.NickoProfile; import java.util.Optional; import java.util.UUID; diff --git a/src/main/java/net/artelnatif/nicko/storage/StorageProvider.java b/src/main/java/xyz/atnrch/nicko/storage/StorageProvider.java similarity index 67% rename from src/main/java/net/artelnatif/nicko/storage/StorageProvider.java rename to src/main/java/xyz/atnrch/nicko/storage/StorageProvider.java index 41b66de..c12b930 100644 --- a/src/main/java/net/artelnatif/nicko/storage/StorageProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/StorageProvider.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.storage; +package xyz.atnrch.nicko.storage; public interface StorageProvider { boolean init(); diff --git a/src/main/java/net/artelnatif/nicko/storage/cache/Cache.java b/src/main/java/xyz/atnrch/nicko/storage/cache/Cache.java similarity index 77% rename from src/main/java/net/artelnatif/nicko/storage/cache/Cache.java rename to src/main/java/xyz/atnrch/nicko/storage/cache/Cache.java index 92d5b75..dfdc061 100644 --- a/src/main/java/net/artelnatif/nicko/storage/cache/Cache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/cache/Cache.java @@ -1,7 +1,7 @@ -package net.artelnatif.nicko.storage.cache; +package xyz.atnrch.nicko.storage.cache; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.disguise.ActionResult; +import xyz.atnrch.nicko.disguise.NickoProfile; import java.util.Optional; import java.util.UUID; diff --git a/src/main/java/net/artelnatif/nicko/storage/cache/CacheProvider.java b/src/main/java/xyz/atnrch/nicko/storage/cache/CacheProvider.java similarity index 63% rename from src/main/java/net/artelnatif/nicko/storage/cache/CacheProvider.java rename to src/main/java/xyz/atnrch/nicko/storage/cache/CacheProvider.java index e85fd3a..8c0d462 100644 --- a/src/main/java/net/artelnatif/nicko/storage/cache/CacheProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/cache/CacheProvider.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.storage.cache; +package xyz.atnrch.nicko.storage.cache; public interface CacheProvider { boolean init(); diff --git a/src/main/java/net/artelnatif/nicko/storage/cache/redis/RedisCache.java b/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCache.java similarity index 65% rename from src/main/java/net/artelnatif/nicko/storage/cache/redis/RedisCache.java rename to src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCache.java index 824cd72..1aeb8dd 100644 --- a/src/main/java/net/artelnatif/nicko/storage/cache/redis/RedisCache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCache.java @@ -1,9 +1,9 @@ -package net.artelnatif.nicko.storage.cache.redis; +package xyz.atnrch.nicko.storage.cache.redis; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.storage.cache.Cache; -import net.artelnatif.nicko.storage.cache.CacheProvider; +import xyz.atnrch.nicko.disguise.ActionResult; +import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.storage.cache.Cache; +import xyz.atnrch.nicko.storage.cache.CacheProvider; import java.util.Optional; import java.util.UUID; diff --git a/src/main/java/net/artelnatif/nicko/storage/cache/redis/RedisCacheProvider.java b/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCacheProvider.java similarity index 83% rename from src/main/java/net/artelnatif/nicko/storage/cache/redis/RedisCacheProvider.java rename to src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCacheProvider.java index 65347e3..343cc3a 100644 --- a/src/main/java/net/artelnatif/nicko/storage/cache/redis/RedisCacheProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCacheProvider.java @@ -1,6 +1,6 @@ -package net.artelnatif.nicko.storage.cache.redis; +package xyz.atnrch.nicko.storage.cache.redis; -import net.artelnatif.nicko.storage.cache.CacheProvider; +import xyz.atnrch.nicko.storage.cache.CacheProvider; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; diff --git a/src/main/java/net/artelnatif/nicko/storage/json/JSONStorage.java b/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java similarity index 89% rename from src/main/java/net/artelnatif/nicko/storage/json/JSONStorage.java rename to src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java index a0f6846..cdd7537 100644 --- a/src/main/java/net/artelnatif/nicko/storage/json/JSONStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java @@ -1,13 +1,13 @@ -package net.artelnatif.nicko.storage.json; +package xyz.atnrch.nicko.storage.json; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.i18n.I18NDict; -import net.artelnatif.nicko.storage.Storage; -import net.artelnatif.nicko.storage.StorageProvider; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.disguise.ActionResult; +import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.storage.Storage; +import xyz.atnrch.nicko.storage.StorageProvider; import java.io.*; import java.util.Optional; diff --git a/src/main/java/net/artelnatif/nicko/storage/json/JSONStorageProvider.java b/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorageProvider.java similarity index 79% rename from src/main/java/net/artelnatif/nicko/storage/json/JSONStorageProvider.java rename to src/main/java/xyz/atnrch/nicko/storage/json/JSONStorageProvider.java index ac2be77..2d58096 100644 --- a/src/main/java/net/artelnatif/nicko/storage/json/JSONStorageProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorageProvider.java @@ -1,6 +1,6 @@ -package net.artelnatif.nicko.storage.json; +package xyz.atnrch.nicko.storage.json; -import net.artelnatif.nicko.storage.StorageProvider; +import xyz.atnrch.nicko.storage.StorageProvider; import java.io.File; diff --git a/src/main/java/net/artelnatif/nicko/storage/name/PlayerNameStore.java b/src/main/java/xyz/atnrch/nicko/storage/name/PlayerNameStore.java similarity index 93% rename from src/main/java/net/artelnatif/nicko/storage/name/PlayerNameStore.java rename to src/main/java/xyz/atnrch/nicko/storage/name/PlayerNameStore.java index c439d4e..6dccd32 100644 --- a/src/main/java/net/artelnatif/nicko/storage/name/PlayerNameStore.java +++ b/src/main/java/xyz/atnrch/nicko/storage/name/PlayerNameStore.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.storage.name; +package xyz.atnrch.nicko.storage.name; import org.bukkit.entity.Player; diff --git a/src/main/java/net/artelnatif/nicko/storage/sql/SQLStorage.java b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java similarity index 94% rename from src/main/java/net/artelnatif/nicko/storage/sql/SQLStorage.java rename to src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java index 8dcea73..87e03e8 100644 --- a/src/main/java/net/artelnatif/nicko/storage/sql/SQLStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java @@ -1,11 +1,11 @@ -package net.artelnatif.nicko.storage.sql; +package xyz.atnrch.nicko.storage.sql; -import net.artelnatif.nicko.config.Configuration; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; -import net.artelnatif.nicko.i18n.I18NDict; -import net.artelnatif.nicko.i18n.Locale; -import net.artelnatif.nicko.storage.Storage; +import xyz.atnrch.nicko.config.Configuration; +import xyz.atnrch.nicko.disguise.ActionResult; +import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.i18n.Locale; +import xyz.atnrch.nicko.storage.Storage; import java.io.ByteArrayInputStream; import java.nio.ByteBuffer; diff --git a/src/main/java/net/artelnatif/nicko/storage/sql/SQLStorageProvider.java b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java similarity index 93% rename from src/main/java/net/artelnatif/nicko/storage/sql/SQLStorageProvider.java rename to src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java index 1a733e7..9888efd 100644 --- a/src/main/java/net/artelnatif/nicko/storage/sql/SQLStorageProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java @@ -1,8 +1,8 @@ -package net.artelnatif.nicko.storage.sql; +package xyz.atnrch.nicko.storage.sql; -import net.artelnatif.nicko.config.Configuration; -import net.artelnatif.nicko.config.DataSourceConfiguration; -import net.artelnatif.nicko.storage.StorageProvider; +import xyz.atnrch.nicko.config.Configuration; +import xyz.atnrch.nicko.config.DataSourceConfiguration; +import xyz.atnrch.nicko.storage.StorageProvider; import org.mariadb.jdbc.MariaDbDataSource; import java.sql.Connection; diff --git a/src/main/java/net/artelnatif/nicko/wrapper/AbstractPacket.java b/src/main/java/xyz/atnrch/nicko/wrapper/AbstractPacket.java similarity index 98% rename from src/main/java/net/artelnatif/nicko/wrapper/AbstractPacket.java rename to src/main/java/xyz/atnrch/nicko/wrapper/AbstractPacket.java index f636bf3..c1ff601 100644 --- a/src/main/java/net/artelnatif/nicko/wrapper/AbstractPacket.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/AbstractPacket.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.artelnatif.nicko.wrapper; +package xyz.atnrch.nicko.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; diff --git a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java similarity index 99% rename from src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java rename to src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java index ace7147..c8d46a1 100644 --- a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.wrapper; +package xyz.atnrch.nicko.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.InternalStructure; diff --git a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayerServerPlayerInfo.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java similarity index 97% rename from src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayerServerPlayerInfo.java rename to src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java index fc64027..dad7be6 100644 --- a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayerServerPlayerInfo.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.wrapper; +package xyz.atnrch.nicko.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.PacketContainer; diff --git a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java similarity index 96% rename from src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java rename to src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java index bc6e912..a218e67 100644 --- a/src/main/java/net/artelnatif/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java @@ -1,4 +1,4 @@ -package net.artelnatif.nicko.wrapper; +package xyz.atnrch.nicko.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.PacketContainer; diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 66cda8f..3ab1d56 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: Nicko -main: net.artelnatif.nicko.NickoBukkit +main: xyz.atnrch.nicko.NickoBukkit version: 1.0-SNAPSHOT author: Ineanto api-version: 1.13 diff --git a/src/test/java/net/artelnatif/nicko/test/NickoPluginTest.java b/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java similarity index 81% rename from src/test/java/net/artelnatif/nicko/test/NickoPluginTest.java rename to src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java index f71f9c6..0cfd752 100644 --- a/src/test/java/net/artelnatif/nicko/test/NickoPluginTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java @@ -1,9 +1,9 @@ -package net.artelnatif.nicko.test; +package xyz.atnrch.nicko.test; import be.seeseemelk.mockbukkit.MockBukkit; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.config.Configuration; -import net.artelnatif.nicko.config.DataSourceConfiguration; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.config.Configuration; +import xyz.atnrch.nicko.config.DataSourceConfiguration; import org.junit.jupiter.api.*; import static org.junit.jupiter.api.Assertions.assertNotNull; diff --git a/src/test/java/net/artelnatif/nicko/test/config/ConfigurationTest.java b/src/test/java/xyz/atnrch/nicko/test/config/ConfigurationTest.java similarity index 85% rename from src/test/java/net/artelnatif/nicko/test/config/ConfigurationTest.java rename to src/test/java/xyz/atnrch/nicko/test/config/ConfigurationTest.java index 8c461c8..fd44eb9 100644 --- a/src/test/java/net/artelnatif/nicko/test/config/ConfigurationTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/config/ConfigurationTest.java @@ -1,8 +1,8 @@ -package net.artelnatif.nicko.test.config; +package xyz.atnrch.nicko.test.config; import be.seeseemelk.mockbukkit.MockBukkit; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.config.Configuration; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.config.Configuration; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; diff --git a/src/test/java/net/artelnatif/nicko/test/storage/BrokenSQLTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java similarity index 85% rename from src/test/java/net/artelnatif/nicko/test/storage/BrokenSQLTest.java rename to src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java index 1b4f7c2..af1d913 100644 --- a/src/test/java/net/artelnatif/nicko/test/storage/BrokenSQLTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java @@ -1,13 +1,13 @@ -package net.artelnatif.nicko.test.storage; +package xyz.atnrch.nicko.test.storage; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; import be.seeseemelk.mockbukkit.entity.PlayerMock; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.config.Configuration; -import net.artelnatif.nicko.config.DataSourceConfiguration; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.config.Configuration; +import xyz.atnrch.nicko.config.DataSourceConfiguration; +import xyz.atnrch.nicko.disguise.ActionResult; +import xyz.atnrch.nicko.disguise.NickoProfile; import org.junit.jupiter.api.*; import java.util.Optional; diff --git a/src/test/java/net/artelnatif/nicko/test/storage/SQLStorageTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java similarity index 92% rename from src/test/java/net/artelnatif/nicko/test/storage/SQLStorageTest.java rename to src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java index 15f3b82..5f33ae9 100644 --- a/src/test/java/net/artelnatif/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java @@ -1,14 +1,14 @@ -package net.artelnatif.nicko.test.storage; +package xyz.atnrch.nicko.test.storage; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; import be.seeseemelk.mockbukkit.entity.PlayerMock; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.config.DataSourceConfiguration; -import net.artelnatif.nicko.i18n.Locale; -import net.artelnatif.nicko.config.Configuration; -import net.artelnatif.nicko.disguise.ActionResult; -import net.artelnatif.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.config.DataSourceConfiguration; +import xyz.atnrch.nicko.i18n.Locale; +import xyz.atnrch.nicko.config.Configuration; +import xyz.atnrch.nicko.disguise.ActionResult; +import xyz.atnrch.nicko.disguise.NickoProfile; import org.junit.jupiter.api.*; import java.util.Optional; diff --git a/src/test/java/net/artelnatif/nicko/test/storage/cache/CacheStorageTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/cache/CacheStorageTest.java similarity index 84% rename from src/test/java/net/artelnatif/nicko/test/storage/cache/CacheStorageTest.java rename to src/test/java/xyz/atnrch/nicko/test/storage/cache/CacheStorageTest.java index 1e039af..c5b1df0 100644 --- a/src/test/java/net/artelnatif/nicko/test/storage/cache/CacheStorageTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/cache/CacheStorageTest.java @@ -1,12 +1,12 @@ -package net.artelnatif.nicko.test.storage.cache; +package xyz.atnrch.nicko.test.storage.cache; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; import be.seeseemelk.mockbukkit.entity.PlayerMock; -import net.artelnatif.nicko.NickoBukkit; -import net.artelnatif.nicko.config.Configuration; -import net.artelnatif.nicko.config.DataSourceConfiguration; -import net.artelnatif.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.config.Configuration; +import xyz.atnrch.nicko.config.DataSourceConfiguration; +import xyz.atnrch.nicko.disguise.NickoProfile; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; From 4157c7152653efaff9a3e2165bce69b820d36fc4 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 17 May 2023 13:39:49 +0200 Subject: [PATCH 021/296] style(i18n): adjust some sentences --- src/main/resources/en.yml | 18 +++++++++--------- src/main/resources/fr.yml | 16 ++++++++-------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index b35b72c..3d65290 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -1,10 +1,10 @@ error: - couldnt_get_name_from_mojang: "Failed to get username from Mojang" - couldnt_get_skin_from_cache: "Failed to get skin from cache" - couldnt_get_skin_from_mojang: "Failed to get skin from Mojang" + couldnt_get_name_from_mojang: "Unable to get username from Mojang." + couldnt_get_skin_from_cache: "Unable to get skin from the cache." + couldnt_get_skin_from_mojang: "Unable to get skin from Mojang." generic: "Unknown error" - invalid_username: "§cThe specified username is not a valid Minecraft username." - player_offline: "§c{0} §fis offline, please try again." + invalid_username: "§cThis is not a valid Minecraft username." + player_offline: "§c{0} §fis offline!" sql: "SQL Error" json: "JSON Error" event: @@ -14,9 +14,9 @@ event: fail: "§cUnable to apply your disguise. §7§o({0})" success: "§aDisguise applied!" previous_skin_applied: - fail: "§cFailed to apply your previous disguise back. §7§o({0})" - success: "§aYour previous active disguise has been applied back." + fail: "§cUnable to apply your previous disguise back. §7§o({0})" + success: "§aYour previous active disguise has been applied." undisguise: - fail: "§cUnable to remove your disguise. It will be set back to default on your next login. Sorry!" - none: "§cYou do not have an active disguise." + fail: "§cUnable to remove your disguise. It will be reset on your next login." + none: "§cYou are not under a disguise." success: "§aDisguise removed." \ No newline at end of file diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index d4b346d..160b4b2 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -1,10 +1,10 @@ error: - couldnt_get_name_from_mojang: "Impossible de récupérer le nom d''utilisateur depuis Mojang" - couldnt_get_skin_from_cache: "Impossible de récupérer le skin depuis le cache" - couldnt_get_skin_from_mojang: "Impossible de récupérer le skin depuis Mojang" + couldnt_get_name_from_mojang: "Impossible de récupérer le nom d''utilisateur depuis Mojang." + couldnt_get_skin_from_cache: "Impossible de récupérer le skin depuis le cache." + couldnt_get_skin_from_mojang: "Impossible de récupérer le skin depuis Mojang." generic: "Erreur inconnue" - invalid_username: "§cLe pseudo spécifié n''est pas un pseudo Minecraft valide." - player_offline: "§c{0} §fest hors-ligne, veuillez réessayer." + invalid_username: "§cLe pseudo n''est pas un pseudo Minecraft valide." + player_offline: "§c{0} §fest hors-ligne!." sql: "Erreur SQL" json: "Erreur JSON" event: @@ -14,9 +14,9 @@ event: fail: "§cImpossible d''appliquer votre déguisement. §7§o({0})" success: "§aDéguisement appliqué !" previous_skin_applied: - fail: "§cImpossible d''appliquer votre déguisement précédent. §7§o({0})" - success: "§aVotre précédent déguisement a été réappliqué." + fail: "§cImpossible d''appliquer votre précédent déguisement. §7§o({0})" + success: "§aVotre précédent déguisement a été appliqué." undisguise: - fail: "§cImpossible de retier votre déguisement. Il sera remis par défaut à votre prochaine reconnexion. Désolé !" + fail: "§cImpossible de retier votre déguisement. Il sera réinitialisé à votre prochaine reconnexion." none: "§cVous n''avez pas de déguisement." success: "§aDéguisement retiré." \ No newline at end of file From fecfb7300b90d3de0f2300ae239fd301d5fa47d4 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 18 May 2023 18:49:04 +0200 Subject: [PATCH 022/296] feat: player reset for the time being, message signature is set to null, causing players beyond 1.19.2 to be kicked while being disguised, even after removing said one. look at the comment for further information. --- pom.xml | 1 + .../java/xyz/atnrch/nicko/NickoBukkit.java | 12 +++++----- .../nicko/disguise/AppearanceManager.java | 24 +++++++++---------- .../wrapper/WrapperPlayServerRespawn.java | 2 +- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/pom.xml b/pom.xml index aba14d4..31d2bc6 100644 --- a/pom.xml +++ b/pom.xml @@ -44,6 +44,7 @@ com.comphenix.protocol ProtocolLib 5.0.0-SNAPSHOT + provided diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index 55b87f0..7aa2ead 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -2,6 +2,12 @@ package xyz.atnrch.nicko; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; +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; @@ -15,12 +21,6 @@ import xyz.atnrch.nicko.mojang.MojangAPI; import xyz.atnrch.nicko.placeholder.PlaceHolderHook; import xyz.atnrch.nicko.storage.PlayerDataStore; import xyz.atnrch.nicko.storage.name.PlayerNameStore; -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.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SimpleItem; diff --git a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java index 6b6ff82..51fc7c7 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java @@ -3,6 +3,7 @@ package xyz.atnrch.nicko.disguise; import com.comphenix.protocol.wrappers.*; import com.google.common.collect.ImmutableList; import com.google.common.collect.Multimap; +import org.bukkit.event.player.PlayerTeleportEvent; import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.mojang.MojangAPI; @@ -85,17 +86,14 @@ public class AppearanceManager { final String defaultName = nameStore.getStoredName(player); this.profile.setName(defaultName); this.profile.setSkin(defaultName); - final ActionResult actionResult = resetPlayer(); - this.profile.setSkin(null); - this.profile.setName(null); + final ActionResult actionResult = updatePlayer(true); + if (!actionResult.isError()) { + this.profile.setSkin(null); + this.profile.setName(null); + } return actionResult; } - public ActionResult resetPlayer() { - // TODO: 4/3/23 Reset player - return new ActionResult<>(); - } - public ActionResult updatePlayer(boolean skinChange) { final String displayName = profile.getName() == null ? player.getName() : profile.getName(); @@ -106,6 +104,7 @@ public class AppearanceManager { updateTabList(gameProfile, displayName); respawnPlayer(); } + player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); return new ActionResult<>(); } @@ -159,7 +158,6 @@ public class AppearanceManager { private void updateTabList(WrappedGameProfile gameProfile, String displayName) { final WrapperPlayerServerPlayerInfoRemove remove = new WrapperPlayerServerPlayerInfoRemove(); remove.setUUIDs(ImmutableList.of(player.getUniqueId())); - final WrapperPlayerServerPlayerInfo update = new WrapperPlayerServerPlayerInfo(); update.setActions(EnumSet.of(EnumWrappers.PlayerInfoAction.ADD_PLAYER, EnumWrappers.PlayerInfoAction.INITIALIZE_CHAT, @@ -173,9 +171,11 @@ public class AppearanceManager { true, EnumWrappers.NativeGameMode.fromBukkit(player.getGameMode()), gameProfile, - WrappedChatComponent.fromText(displayName), - new WrappedRemoteChatSessionData(UUID.randomUUID(), - WrappedProfilePublicKey.ofPlayer(player).getKeyData()) + WrappedChatComponent.fromText(displayName) + // Yes, I skip providing chat session data. + // Yes, this will cause players to get kicked as soon as they send a message. + // No, I'll not waste another day fixing their mess. Go cry about it to Mojang. + // (Long live NoEncryption!) ))); remove.sendPacket(player); update.sendPacket(player); diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java index c8d46a1..817f8c1 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java @@ -32,7 +32,7 @@ public class WrapperPlayServerRespawn extends AbstractPacket { // The dimension field has changed numerous times: // - 1.8 through 1.17 (?) need an integer, // - 1.18 need a Holder of a World ResourceKey, - // - 1.19.2 reverted 1.18 and simply need a World ResourceKey. + // - 1.19 and beyond don't require a Holder. // // n.b.: this field is a nightmare please mojang stop refactoring // your code to change things that were working perfectly fine before From 87e998d5785a39fed400e2c4d301b6d214b53f28 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 20 May 2023 00:52:16 +0200 Subject: [PATCH 023/296] feat(cache): initial redis support --- .../nicko/storage/cache/redis/RedisCache.java | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCache.java b/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCache.java index 1aeb8dd..e833ae8 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCache.java @@ -1,5 +1,8 @@ package xyz.atnrch.nicko.storage.cache.redis; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import redis.clients.jedis.Jedis; import xyz.atnrch.nicko.disguise.ActionResult; import xyz.atnrch.nicko.disguise.NickoProfile; import xyz.atnrch.nicko.storage.cache.Cache; @@ -9,23 +12,36 @@ import java.util.Optional; import java.util.UUID; public class RedisCache extends Cache { + private final Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create(); + private RedisCacheProvider provider; + @Override public CacheProvider getProvider() { - return null; + if (provider == null) { + provider = new RedisCacheProvider(); + } + return provider; } @Override public ActionResult cache(UUID uuid, NickoProfile profile) { - return null; + final Jedis jedis = provider.getJedis(); + jedis.set("nicko:" + uuid.toString(), gson.toJson(profile)); + return new ActionResult<>(); } @Override public boolean isCached(UUID uuid) { - return false; + final Jedis jedis = provider.getJedis(); + return jedis.exists("nicko:" + uuid.toString()); } @Override public Optional retrieve(UUID uuid) { - return Optional.empty(); + final Jedis jedis = provider.getJedis(); + // 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); + return Optional.of(profile); } } From f0b9c62a1bcf29091a4731c621162da65d207052 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 20 May 2023 00:54:49 +0200 Subject: [PATCH 024/296] feat(cache): get address and port from configuration --- .../nicko/storage/cache/redis/RedisCache.java | 13 +++++++++++-- .../storage/cache/redis/RedisCacheProvider.java | 12 ++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCache.java b/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCache.java index e833ae8..b9dffe7 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCache.java @@ -3,6 +3,7 @@ package xyz.atnrch.nicko.storage.cache.redis; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import redis.clients.jedis.Jedis; +import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.disguise.ActionResult; import xyz.atnrch.nicko.disguise.NickoProfile; import xyz.atnrch.nicko.storage.cache.Cache; @@ -12,13 +13,21 @@ import java.util.Optional; import java.util.UUID; public class RedisCache extends Cache { - private final Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create(); + private final Gson gson = new GsonBuilder() + .serializeNulls() + .setPrettyPrinting() + .create(); + private final Configuration configuration; private RedisCacheProvider provider; + public RedisCache(Configuration configuration) { + this.configuration = configuration; + } + @Override public CacheProvider getProvider() { if (provider == null) { - provider = new RedisCacheProvider(); + provider = new RedisCacheProvider(configuration); } return provider; } diff --git a/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCacheProvider.java b/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCacheProvider.java index 343cc3a..6692a52 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCacheProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCacheProvider.java @@ -1,16 +1,24 @@ package xyz.atnrch.nicko.storage.cache.redis; +import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.storage.cache.CacheProvider; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; public class RedisCacheProvider implements CacheProvider { + private final Configuration configuration; private JedisPool pool; + public RedisCacheProvider(Configuration configuration) { + this.configuration = configuration; + } + @Override public boolean init() { - // TODO: 3/12/23 Get port from configuration - pool = new JedisPool("localhost", 6379); + pool = new JedisPool( + configuration.getRedisConfiguration().getAddress(), + configuration.getRedisConfiguration().getPort() + ); return !pool.isClosed() && pool.getResource() != null; } From 17fa5e81e7623d7ee1e2192c36948248d9c7c2e7 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 20 May 2023 14:03:01 +0200 Subject: [PATCH 025/296] feat(cache): reworked implementation --- .../java/xyz/atnrch/nicko/NickoBukkit.java | 16 ++++--- .../atnrch/nicko/config/Configuration.java | 13 ++---- .../nicko/config/DataSourceConfiguration.java | 14 ++++-- .../nicko/disguise/AppearanceManager.java | 21 ++++++--- .../nicko/event/PlayerJoinListener.java | 17 +++---- .../nicko/storage/{cache => }/Cache.java | 2 +- .../storage/{cache => }/CacheProvider.java | 2 +- .../atnrch/nicko/storage/PlayerDataStore.java | 41 +++++++---------- .../atnrch/nicko/storage/map/MapCache.java | 44 +++++++++++++++++++ .../nicko/storage/map/MapCacheProvider.java | 29 ++++++++++++ .../storage/{cache => }/redis/RedisCache.java | 6 +-- .../{cache => }/redis/RedisCacheProvider.java | 4 +- .../WrapperPlayerServerPlayerInfo.java | 1 - src/main/resources/config.yml | 39 ++++++++-------- .../atnrch/nicko/test/NickoPluginTest.java | 3 +- .../nicko/test/config/ConfigurationTest.java | 9 ++-- .../nicko/test/storage/BrokenSQLTest.java | 3 +- .../nicko/test/storage/SQLStorageTest.java | 3 +- .../test/storage/cache/CacheStorageTest.java | 5 +-- 19 files changed, 169 insertions(+), 103 deletions(-) rename src/main/java/xyz/atnrch/nicko/storage/{cache => }/Cache.java (93%) rename src/main/java/xyz/atnrch/nicko/storage/{cache => }/CacheProvider.java (66%) create mode 100644 src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java create mode 100644 src/main/java/xyz/atnrch/nicko/storage/map/MapCacheProvider.java rename src/main/java/xyz/atnrch/nicko/storage/{cache => }/redis/RedisCache.java (92%) rename src/main/java/xyz/atnrch/nicko/storage/{cache => }/redis/RedisCacheProvider.java (89%) diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index 7aa2ead..c45f335 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -70,12 +70,16 @@ public class NickoBukkit extends JavaPlugin { dataStore = new PlayerDataStore(mojangAPI, getNickoConfig()); nameStore = new PlayerNameStore(); - if (!dataStore.getStorage().isError()) { - getLogger().info("Loading persistence..."); - if (!dataStore.getStorage().getProvider().init()) { - dataStore.getStorage().setError(true); - getLogger().severe("Failed to open persistence, data will NOT be saved!"); - } + getLogger().info("Loading persistence..."); + if (!dataStore.getStorage().getProvider().init()) { + dataStore.getStorage().setError(true); + getLogger().severe("Failed to open persistence, data will NOT be saved!"); + } + + getLogger().info("Loading cache..."); + if (!dataStore.getCache().getProvider().init()) { + dataStore.getCache().setError(true); + getLogger().severe("Failed to open cache, data will NOT be saved!"); } if (!unitTesting) { diff --git a/src/main/java/xyz/atnrch/nicko/config/Configuration.java b/src/main/java/xyz/atnrch/nicko/config/Configuration.java index 848eba1..3a90a8b 100644 --- a/src/main/java/xyz/atnrch/nicko/config/Configuration.java +++ b/src/main/java/xyz/atnrch/nicko/config/Configuration.java @@ -12,23 +12,20 @@ public class Configuration { @JsonProperty("redis") private final DataSourceConfiguration redisConfiguration; private final String prefix; - private final Boolean local; private final Boolean customLocale; - public Configuration(DataSourceConfiguration sqlConfiguration, DataSourceConfiguration redisConfiguration, String prefix, Boolean local, Boolean customLocale) { + public Configuration(DataSourceConfiguration sqlConfiguration, DataSourceConfiguration redisConfiguration, String prefix, Boolean customLocale) { this.sqlConfiguration = sqlConfiguration; this.redisConfiguration = redisConfiguration; this.prefix = prefix; - this.local = local; this.customLocale = customLocale; } public Configuration() { this( - new DataSourceConfiguration("", 3306, "", ""), - new DataSourceConfiguration("", 6379, "", ""), + new DataSourceConfiguration(false, "", 3306, "", ""), + new DataSourceConfiguration(false, "", 6379, "", ""), "", - false, false ); } @@ -45,10 +42,6 @@ public class Configuration { return prefix; } - public Boolean isLocal() { - return local; - } - public Boolean isCustomLocale() { return customLocale; } diff --git a/src/main/java/xyz/atnrch/nicko/config/DataSourceConfiguration.java b/src/main/java/xyz/atnrch/nicko/config/DataSourceConfiguration.java index da4495f..a549ab4 100644 --- a/src/main/java/xyz/atnrch/nicko/config/DataSourceConfiguration.java +++ b/src/main/java/xyz/atnrch/nicko/config/DataSourceConfiguration.java @@ -1,22 +1,28 @@ package xyz.atnrch.nicko.config; public class DataSourceConfiguration { - public static final DataSourceConfiguration SQL_EMPTY = new DataSourceConfiguration("127.0.0.1", 3306, "root", ""); - public static final DataSourceConfiguration REDIS_EMPTY = new DataSourceConfiguration("127.0.0.1", 6379, "", ""); + public static final DataSourceConfiguration SQL_EMPTY = new DataSourceConfiguration(false, "127.0.0.1", 3306, "root", ""); + public static final DataSourceConfiguration REDIS_EMPTY = new DataSourceConfiguration(false, "127.0.0.1", 6379, "", ""); + private final boolean enabled; private final String address; private final Integer port; private final String username; private final String password; - public DataSourceConfiguration(String address, Integer port, String username, String password) { + public DataSourceConfiguration(boolean enabled, String address, Integer port, String username, String password) { + this.enabled = enabled; this.address = address; this.port = port; this.username = username; this.password = password; } - public DataSourceConfiguration() { this("", 0, "", ""); } + public DataSourceConfiguration() { this(false, "", 0, "", ""); } + + public boolean isEnabled() { + return enabled; + } public String getAddress() { return address; diff --git a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java index 51fc7c7..eab8a44 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java @@ -1,8 +1,12 @@ package xyz.atnrch.nicko.disguise; +import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.wrappers.*; import com.google.common.collect.ImmutableList; import com.google.common.collect.Multimap; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerTeleportEvent; import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.i18n.I18NDict; @@ -13,9 +17,6 @@ import xyz.atnrch.nicko.storage.name.PlayerNameStore; import xyz.atnrch.nicko.wrapper.WrapperPlayServerRespawn; import xyz.atnrch.nicko.wrapper.WrapperPlayerServerPlayerInfo; import xyz.atnrch.nicko.wrapper.WrapperPlayerServerPlayerInfoRemove; -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.entity.Player; import java.io.IOException; import java.util.EnumSet; @@ -157,14 +158,15 @@ public class AppearanceManager { private void updateTabList(WrappedGameProfile gameProfile, String displayName) { final WrapperPlayerServerPlayerInfoRemove remove = new WrapperPlayerServerPlayerInfoRemove(); - remove.setUUIDs(ImmutableList.of(player.getUniqueId())); final WrapperPlayerServerPlayerInfo update = new WrapperPlayerServerPlayerInfo(); - update.setActions(EnumSet.of(EnumWrappers.PlayerInfoAction.ADD_PLAYER, + final EnumSet actions = EnumSet.of( + EnumWrappers.PlayerInfoAction.REMOVE_PLAYER, // Necessary for 1.19.2 and below + EnumWrappers.PlayerInfoAction.ADD_PLAYER, EnumWrappers.PlayerInfoAction.INITIALIZE_CHAT, EnumWrappers.PlayerInfoAction.UPDATE_LISTED, EnumWrappers.PlayerInfoAction.UPDATE_DISPLAY_NAME, EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE, - EnumWrappers.PlayerInfoAction.UPDATE_LATENCY)); + EnumWrappers.PlayerInfoAction.UPDATE_LATENCY); update.setData(ImmutableList.of(new PlayerInfoData( player.getUniqueId(), player.getPing(), @@ -177,7 +179,12 @@ public class AppearanceManager { // No, I'll not waste another day fixing their mess. Go cry about it to Mojang. // (Long live NoEncryption!) ))); - remove.sendPacket(player); + if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) { + actions.remove(EnumWrappers.PlayerInfoAction.REMOVE_PLAYER); + remove.setUUIDs(ImmutableList.of(player.getUniqueId())); + remove.sendPacket(player); + } + update.setActions(actions); update.sendPacket(player); } } \ No newline at end of file diff --git a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java index 4008add..e56372e 100644 --- a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java @@ -1,18 +1,17 @@ package xyz.atnrch.nicko.event; -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.disguise.AppearanceManager; -import xyz.atnrch.nicko.disguise.ActionResult; -import xyz.atnrch.nicko.disguise.NickoProfile; -import xyz.atnrch.nicko.i18n.I18N; -import xyz.atnrch.nicko.i18n.I18NDict; -import xyz.atnrch.nicko.storage.PlayerDataStore; -import xyz.atnrch.nicko.storage.name.PlayerNameStore; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.disguise.ActionResult; +import xyz.atnrch.nicko.disguise.AppearanceManager; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.atnrch.nicko.storage.PlayerDataStore; +import xyz.atnrch.nicko.storage.name.PlayerNameStore; public class PlayerJoinListener implements Listener { @EventHandler @@ -25,8 +24,6 @@ public class PlayerJoinListener implements Listener { nameStore.storeName(player); // TODO: 2/20/23 BungeeCord transfer - - dataStore.performProfileUpdate(player.getUniqueId(), NickoProfile.EMPTY_PROFILE); Bukkit.getScheduler().runTaskLater(instance, () -> { final AppearanceManager appearanceManager = AppearanceManager.get(player); if (appearanceManager.hasData()) { diff --git a/src/main/java/xyz/atnrch/nicko/storage/cache/Cache.java b/src/main/java/xyz/atnrch/nicko/storage/Cache.java similarity index 93% rename from src/main/java/xyz/atnrch/nicko/storage/cache/Cache.java rename to src/main/java/xyz/atnrch/nicko/storage/Cache.java index dfdc061..7b818ae 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/cache/Cache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/Cache.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.storage.cache; +package xyz.atnrch.nicko.storage; import xyz.atnrch.nicko.disguise.ActionResult; import xyz.atnrch.nicko.disguise.NickoProfile; diff --git a/src/main/java/xyz/atnrch/nicko/storage/cache/CacheProvider.java b/src/main/java/xyz/atnrch/nicko/storage/CacheProvider.java similarity index 66% rename from src/main/java/xyz/atnrch/nicko/storage/cache/CacheProvider.java rename to src/main/java/xyz/atnrch/nicko/storage/CacheProvider.java index 8c0d462..e0f19cd 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/cache/CacheProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/CacheProvider.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.storage.cache; +package xyz.atnrch.nicko.storage; public interface CacheProvider { boolean init(); diff --git a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java index cae4147..b3e67f1 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java +++ b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java @@ -1,19 +1,18 @@ package xyz.atnrch.nicko.storage; +import org.bukkit.entity.Player; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.disguise.ActionResult; import xyz.atnrch.nicko.disguise.NickoProfile; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.mojang.MojangAPI; import xyz.atnrch.nicko.mojang.MojangUtils; -import xyz.atnrch.nicko.storage.cache.Cache; -import xyz.atnrch.nicko.storage.cache.redis.RedisCache; import xyz.atnrch.nicko.storage.json.JSONStorage; +import xyz.atnrch.nicko.storage.map.MapCache; +import xyz.atnrch.nicko.storage.redis.RedisCache; import xyz.atnrch.nicko.storage.sql.SQLStorage; -import org.bukkit.entity.Player; import java.io.IOException; -import java.util.HashMap; import java.util.Optional; import java.util.UUID; @@ -21,21 +20,11 @@ public class PlayerDataStore { private final Storage storage; private final Cache cache; private final MojangAPI mojangAPI; - private final HashMap profiles = new HashMap<>(); public PlayerDataStore(MojangAPI mojangAPI, Configuration configuration) { this.mojangAPI = mojangAPI; - this.storage = configuration.isLocal() ? new JSONStorage() : new SQLStorage(configuration); - this.cache = new RedisCache(); // The only option for now! - } - - public void performProfileUpdate(UUID uuid, NickoProfile profile) { - if (!profiles.containsKey(uuid)) { - profiles.put(uuid, profile); - return; - } - - profiles.replace(uuid, profile); + this.storage = configuration.getSqlConfiguration().isEnabled() ? new SQLStorage(configuration) : new JSONStorage(); + this.cache = configuration.getRedisConfiguration().isEnabled() ? new RedisCache(configuration) : new MapCache(); } public Optional getData(UUID uuid) { @@ -43,15 +32,15 @@ public class PlayerDataStore { return Optional.empty(); } - if (profiles.containsKey(uuid)) { - return Optional.of(profiles.get(uuid)); + if (cache.isCached(uuid)) { + return cache.retrieve(uuid); } else if (storage.isStored(uuid)) { final Optional retrievedProfile = storage.retrieve(uuid); - retrievedProfile.ifPresent(profile -> profiles.put(uuid, profile)); + retrievedProfile.ifPresent(profile -> cache.cache(uuid, profile)); return retrievedProfile; } else { final NickoProfile newProfile = NickoProfile.EMPTY_PROFILE.clone(); - profiles.put(uuid, newProfile); + cache.cache(uuid, newProfile); return Optional.of(newProfile); } } @@ -74,12 +63,14 @@ public class PlayerDataStore { } public ActionResult saveData(Player player) { - if (storage.isError()) { return new ActionResult<>(I18NDict.Error.UNEXPECTED_ERROR); } - if (!profiles.containsKey(player.getUniqueId())) { return new ActionResult<>(I18NDict.Error.UNEXPECTED_ERROR); } + if (storage.isError()) return new ActionResult<>(I18NDict.Error.UNEXPECTED_ERROR); + if (!cache.isCached(player.getUniqueId())) return new ActionResult<>(I18NDict.Error.UNEXPECTED_ERROR); + if (!cache.retrieve(player.getUniqueId()).isPresent()) + return new ActionResult<>(I18NDict.Error.UNEXPECTED_ERROR); - final ActionResult store = storage.store(player.getUniqueId(), profiles.get(player.getUniqueId())); - profiles.remove(player.getUniqueId()); - return store; + // TODO (Ineanto, 5/20/23): Remove value from cache + //profiles.remove(player.getUniqueId()); + return storage.store(player.getUniqueId(), cache.retrieve(player.getUniqueId()).get()); } public Storage getStorage() { diff --git a/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java b/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java new file mode 100644 index 0000000..5bca4cf --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java @@ -0,0 +1,44 @@ +package xyz.atnrch.nicko.storage.map; + +import xyz.atnrch.nicko.disguise.ActionResult; +import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.storage.Cache; +import xyz.atnrch.nicko.storage.CacheProvider; + +import java.util.HashMap; +import java.util.Optional; +import java.util.UUID; + +public class MapCache extends Cache { + private MapCacheProvider provider; + + @Override + public CacheProvider getProvider() { + if (provider == null) { + provider = new MapCacheProvider(); + } + return provider; + } + + @Override + public ActionResult cache(UUID uuid, NickoProfile profile) { + final HashMap profiles = provider.getMap(); + profiles.put(uuid, profile); + return new ActionResult<>(); + } + + @Override + public boolean isCached(UUID uuid) { + final HashMap profiles = provider.getMap(); + return profiles.containsKey(uuid); + } + + @Override + public Optional retrieve(UUID uuid) { + final HashMap profiles = provider.getMap(); + if (isCached(uuid)) { + return Optional.of(profiles.get(uuid)); + } + return Optional.empty(); + } +} diff --git a/src/main/java/xyz/atnrch/nicko/storage/map/MapCacheProvider.java b/src/main/java/xyz/atnrch/nicko/storage/map/MapCacheProvider.java new file mode 100644 index 0000000..7413007 --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/storage/map/MapCacheProvider.java @@ -0,0 +1,29 @@ +package xyz.atnrch.nicko.storage.map; + +import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.storage.CacheProvider; + +import java.util.HashMap; +import java.util.UUID; + +public class MapCacheProvider implements CacheProvider { + private HashMap profiles; + + @Override + public boolean init() { + if (profiles == null) { + profiles = new HashMap<>(); + } + return true; + } + + @Override + public boolean close() { + profiles = null; + return true; + } + + public HashMap getMap() { + return profiles; + } +} diff --git a/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCache.java b/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java similarity index 92% rename from src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCache.java rename to src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java index b9dffe7..29f4fce 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.storage.cache.redis; +package xyz.atnrch.nicko.storage.redis; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -6,8 +6,8 @@ import redis.clients.jedis.Jedis; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.disguise.ActionResult; import xyz.atnrch.nicko.disguise.NickoProfile; -import xyz.atnrch.nicko.storage.cache.Cache; -import xyz.atnrch.nicko.storage.cache.CacheProvider; +import xyz.atnrch.nicko.storage.Cache; +import xyz.atnrch.nicko.storage.CacheProvider; import java.util.Optional; import java.util.UUID; diff --git a/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCacheProvider.java b/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCacheProvider.java similarity index 89% rename from src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCacheProvider.java rename to src/main/java/xyz/atnrch/nicko/storage/redis/RedisCacheProvider.java index 6692a52..a935fb5 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/cache/redis/RedisCacheProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCacheProvider.java @@ -1,7 +1,7 @@ -package xyz.atnrch.nicko.storage.cache.redis; +package xyz.atnrch.nicko.storage.redis; import xyz.atnrch.nicko.config.Configuration; -import xyz.atnrch.nicko.storage.cache.CacheProvider; +import xyz.atnrch.nicko.storage.CacheProvider; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java index dad7be6..3befbe2 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java @@ -40,7 +40,6 @@ public class WrapperPlayerServerPlayerInfo extends AbstractPacket { } public void setData(List value) { - //handle.getSets(PlayerInfoData.getConverter()).write(0, value); handle.getPlayerInfoDataLists().write(1, value); } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 22f718a..0f162c9 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,16 +1,29 @@ # Nicko ${project.version} - Config: +############ +# LANGUAGE # +############ + +# Nicko's messages prefix. +# Accepted values: any string +prefix: "§6Nicko §8§l| §r" + +# Nicko will copy the English locale as "lang.yml" +# and will use the translations in that file when "Server Custom" +# is selected as the player's locale. +# Accepted values: false (Disabled), true (Enabled) +customLocale: false + ########### # STORAGE # ########### -# Indicates wherever the data will be stored -# locally through a .json file or a (My)SQL database. -# Accepted values: false (Disabled), true (Enabled) -local: true - # This configuration section manages SQL. sql: + # Indicates wherever the data will be stored locally + # inside a .json file or in a SQL database. + # Accepted values: false (Disabled), true (Enabled) + enabled: false # SQL database's address # Accepted values: valid IP address (e.g. localhost, 127.0.0.1) address: "localhost" @@ -42,18 +55,4 @@ redis: username: "username" # Redis server's password # Accepted values: any string - password: "password" - -########### -# DISPLAY # -########### - -# Nicko's messages prefix. -# Accepted values: any string -prefix: "§6Nicko §8§l| §r" - -# Nicko will copy the English locale as "lang.yml" -# and will use the translations in that file when "Server Custom" -# is selected as the player's locale. -# Accepted values: false (Disabled), true (Enabled) -customLocale: false \ No newline at end of file + password: "password" \ No newline at end of file diff --git a/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java b/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java index 0cfd752..a046898 100644 --- a/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java @@ -14,10 +14,9 @@ public class NickoPluginTest { @BeforeAll public static void setup() { final Configuration config = new Configuration( - DataSourceConfiguration.SQL_EMPTY, + new DataSourceConfiguration(true, "127.0.0.1", 3306, "root", "12345"), DataSourceConfiguration.REDIS_EMPTY, "", - true, false); MockBukkit.mock(); plugin = MockBukkit.load(NickoBukkit.class, config); diff --git a/src/test/java/xyz/atnrch/nicko/test/config/ConfigurationTest.java b/src/test/java/xyz/atnrch/nicko/test/config/ConfigurationTest.java index fd44eb9..647740a 100644 --- a/src/test/java/xyz/atnrch/nicko/test/config/ConfigurationTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/config/ConfigurationTest.java @@ -1,14 +1,14 @@ package xyz.atnrch.nicko.test.config; import be.seeseemelk.mockbukkit.MockBukkit; -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.config.Configuration; 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 static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertFalse; public class ConfigurationTest { private static NickoBukkit plugin; @@ -23,7 +23,8 @@ public class ConfigurationTest { @DisplayName("Read configuration") public void readConfiguration() { final Configuration configuration = plugin.getNickoConfig(); - assertTrue(configuration.isLocal()); + assertFalse(configuration.getSqlConfiguration().isEnabled()); + assertFalse(configuration.getRedisConfiguration().isEnabled()); } @AfterAll diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java index af1d913..4f204f4 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java @@ -23,10 +23,9 @@ public class BrokenSQLTest { @BeforeAll public static void setup() { final Configuration config = new Configuration( - DataSourceConfiguration.SQL_EMPTY, + new DataSourceConfiguration(true, "127.0.0.1", 3306, "root", ""), DataSourceConfiguration.REDIS_EMPTY, "", - false, false); server = MockBukkit.mock(); plugin = MockBukkit.load(NickoBukkit.class, config); 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 5f33ae9..39c4ad1 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java @@ -25,10 +25,9 @@ public class SQLStorageTest { @BeforeAll public static void setup() { final Configuration config = new Configuration( - new DataSourceConfiguration("127.0.0.1", 3306, "root", "12345"), + new DataSourceConfiguration(true, "127.0.0.1", 3306, "root", "12345"), DataSourceConfiguration.REDIS_EMPTY, "", - false, false); server = MockBukkit.mock(); plugin = MockBukkit.load(NickoBukkit.class, config); diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/cache/CacheStorageTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/cache/CacheStorageTest.java index c5b1df0..1b7af16 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/cache/CacheStorageTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/cache/CacheStorageTest.java @@ -24,10 +24,9 @@ public class CacheStorageTest { @BeforeAll public static void setup() { final Configuration config = new Configuration( - new DataSourceConfiguration("127.0.0.1", 3306, "root", "12345"), + new DataSourceConfiguration(false, "127.0.0.1", 3306, "root", "12345"), DataSourceConfiguration.REDIS_EMPTY, "", - false, false); server = MockBukkit.mock(); plugin = MockBukkit.load(NickoBukkit.class, config); @@ -39,7 +38,7 @@ public class CacheStorageTest { public void cachePlayerData() { final Optional optionalProfile = plugin.getDataStore().getData(player.getUniqueId()); assertTrue(optionalProfile.isPresent()); - //assertTrue(plugin.getDataStore().isCached(player.getUniqueId())); + assertTrue(plugin.getDataStore().getCache().isCached(player.getUniqueId())); } @AfterAll From 318c0ffefd7bcb30ffb9a0fe6e8b13aeba7da49a Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 22 May 2023 14:13:40 +0200 Subject: [PATCH 026/296] feat(redis): add test for redis cache --- .../nicko/config/DataSourceConfiguration.java | 11 +++++ .../nicko/storage/redis/RedisCache.java | 1 + .../storage/redis/RedisCacheProvider.java | 6 ++- .../nicko/storage/sql/SQLStorageProvider.java | 8 ++-- .../MapCacheTest.java} | 6 +-- .../test/storage/redis/RedisCacheTest.java | 48 +++++++++++++++++++ 6 files changed, 71 insertions(+), 9 deletions(-) rename src/test/java/xyz/atnrch/nicko/test/storage/{cache/CacheStorageTest.java => map/MapCacheTest.java} (89%) create mode 100644 src/test/java/xyz/atnrch/nicko/test/storage/redis/RedisCacheTest.java diff --git a/src/main/java/xyz/atnrch/nicko/config/DataSourceConfiguration.java b/src/main/java/xyz/atnrch/nicko/config/DataSourceConfiguration.java index a549ab4..291d242 100644 --- a/src/main/java/xyz/atnrch/nicko/config/DataSourceConfiguration.java +++ b/src/main/java/xyz/atnrch/nicko/config/DataSourceConfiguration.java @@ -39,4 +39,15 @@ public class DataSourceConfiguration { public String getPassword() { return password; } + + @Override + public String toString() { + return "DataSourceConfiguration{" + + "enabled=" + enabled + + ", address='" + address + '\'' + + ", port=" + port + + ", username='" + username + '\'' + + ", password='" + password + '\'' + + '}'; + } } 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 29f4fce..68482e8 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java @@ -21,6 +21,7 @@ public class RedisCache extends Cache { private RedisCacheProvider provider; public RedisCache(Configuration configuration) { + System.out.println("Loaded REDIS CACHE"); this.configuration = configuration; } 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 a935fb5..09a486d 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCacheProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCacheProvider.java @@ -1,6 +1,7 @@ package xyz.atnrch.nicko.storage.redis; import xyz.atnrch.nicko.config.Configuration; +import xyz.atnrch.nicko.config.DataSourceConfiguration; import xyz.atnrch.nicko.storage.CacheProvider; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; @@ -15,9 +16,10 @@ public class RedisCacheProvider implements CacheProvider { @Override public boolean init() { + final DataSourceConfiguration redisConfiguration = configuration.getRedisConfiguration(); pool = new JedisPool( - configuration.getRedisConfiguration().getAddress(), - configuration.getRedisConfiguration().getPort() + redisConfiguration.getAddress(), + redisConfiguration.getPort() ); return !pool.isClosed() && pool.getResource() != null; } diff --git a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java index 9888efd..7f0ed2d 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java @@ -26,10 +26,10 @@ public class SQLStorageProvider implements StorageProvider { public boolean init() { try { final MariaDbDataSource dataSource = new MariaDbDataSource(); - final DataSourceConfiguration dataSourceConfiguration = configuration.getSqlConfiguration(); - dataSource.setUrl("jdbc:mariadb://" + dataSourceConfiguration.getAddress() + ":" + dataSourceConfiguration.getPort()); - dataSource.setUser(dataSourceConfiguration.getUsername()); - dataSource.setPassword(dataSourceConfiguration.getPassword()); + final DataSourceConfiguration sqlConfiguration = configuration.getSqlConfiguration(); + dataSource.setUrl("jdbc:mariadb://" + sqlConfiguration.getAddress() + ":" + sqlConfiguration.getPort()); + dataSource.setUser(sqlConfiguration.getUsername()); + dataSource.setPassword(sqlConfiguration.getPassword()); connection = dataSource.getConnection(); final boolean initialized = connection != null && !connection.isClosed(); diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/cache/CacheStorageTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java similarity index 89% rename from src/test/java/xyz/atnrch/nicko/test/storage/cache/CacheStorageTest.java rename to src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java index 1b7af16..035227c 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/cache/CacheStorageTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.test.storage.cache; +package xyz.atnrch.nicko.test.storage.map; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; @@ -16,7 +16,7 @@ import java.util.Optional; import static org.junit.jupiter.api.Assertions.assertTrue; -public class CacheStorageTest { +public class MapCacheTest { private static ServerMock server; private static NickoBukkit plugin; private static PlayerMock player; @@ -24,7 +24,7 @@ public class CacheStorageTest { @BeforeAll public static void setup() { final Configuration config = new Configuration( - new DataSourceConfiguration(false, "127.0.0.1", 3306, "root", "12345"), + DataSourceConfiguration.SQL_EMPTY, DataSourceConfiguration.REDIS_EMPTY, "", false); 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 new file mode 100644 index 0000000..37bf788 --- /dev/null +++ b/src/test/java/xyz/atnrch/nicko/test/storage/redis/RedisCacheTest.java @@ -0,0 +1,48 @@ +package xyz.atnrch.nicko.test.storage.redis; + +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; +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.disguise.NickoProfile; + +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class RedisCacheTest { + private static ServerMock server; + private static NickoBukkit plugin; + private static PlayerMock player; + + @BeforeAll + public static void setup() { + final Configuration config = new Configuration( + DataSourceConfiguration.SQL_EMPTY, + new DataSourceConfiguration(true, "127.0.0.1", 6379, "", ""), + "", + false); + server = MockBukkit.mock(); + plugin = MockBukkit.load(NickoBukkit.class, config); + player = server.addPlayer(); + } + + @Test + @DisplayName("Cache Player Data") + public void cachePlayerData() { + final Optional optionalProfile = plugin.getDataStore().getData(player.getUniqueId()); + assertTrue(optionalProfile.isPresent()); + assertTrue(plugin.getDataStore().getCache().isCached(player.getUniqueId())); + } + + @AfterAll + public static void shutdown() { + MockBukkit.unmock(); + } +} From ec3ca218a56e97f9b09cf5c03f4da1dffcbca6de Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 22 May 2023 20:39:22 +0200 Subject: [PATCH 027/296] style: line wrapping --- .../xyz/atnrch/nicko/storage/redis/RedisCacheProvider.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) 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 09a486d..c655cfb 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCacheProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCacheProvider.java @@ -17,10 +17,7 @@ public class RedisCacheProvider implements CacheProvider { @Override public boolean init() { final DataSourceConfiguration redisConfiguration = configuration.getRedisConfiguration(); - pool = new JedisPool( - redisConfiguration.getAddress(), - redisConfiguration.getPort() - ); + pool = new JedisPool(redisConfiguration.getAddress(), redisConfiguration.getPort()); return !pool.isClosed() && pool.getResource() != null; } From 04fbcd99ba5ad38584c9d550bbaa2bac8308549e Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 22 May 2023 20:42:18 +0200 Subject: [PATCH 028/296] refractor(appearance manager): clarify issue --- src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java index eab8a44..7bdd742 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java @@ -175,7 +175,8 @@ public class AppearanceManager { gameProfile, WrappedChatComponent.fromText(displayName) // Yes, I skip providing chat session data. - // Yes, this will cause players to get kicked as soon as they send a message. + // Yes, this will cause players to get kicked + // as soon as they send a message on versions above 1.19.2. // No, I'll not waste another day fixing their mess. Go cry about it to Mojang. // (Long live NoEncryption!) ))); From 584b34fd51138fb90f47ea82187df2a4c2733cf3 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 29 May 2023 14:01:30 +0200 Subject: [PATCH 029/296] feat(wrapper): handle previous versions --- .../nicko/disguise/AppearanceManager.java | 44 ++++++++++--------- .../wrapper/WrapperPlayServerRespawn.java | 6 ++- .../WrapperPlayerServerPlayerInfo.java | 9 +++- 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java index 7bdd742..cc6f507 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java @@ -150,24 +150,32 @@ public class AppearanceManager { respawn.setGameMode(player.getGameMode()); respawn.setPreviousGameMode(player.getGameMode()); respawn.setDifficulty(world.getDifficulty()); - respawn.setCopyMetadata(false); - respawn.getHandle().getBooleans().write(0, false); // is debug - respawn.getHandle().getBooleans().write(0, false); // is flat + respawn.setCopyMetadata(true); respawn.sendPacket(player); } private void updateTabList(WrappedGameProfile gameProfile, String displayName) { - final WrapperPlayerServerPlayerInfoRemove remove = new WrapperPlayerServerPlayerInfoRemove(); - final WrapperPlayerServerPlayerInfo update = new WrapperPlayerServerPlayerInfo(); - final EnumSet actions = EnumSet.of( - EnumWrappers.PlayerInfoAction.REMOVE_PLAYER, // Necessary for 1.19.2 and below - EnumWrappers.PlayerInfoAction.ADD_PLAYER, - EnumWrappers.PlayerInfoAction.INITIALIZE_CHAT, - EnumWrappers.PlayerInfoAction.UPDATE_LISTED, - EnumWrappers.PlayerInfoAction.UPDATE_DISPLAY_NAME, - EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE, - EnumWrappers.PlayerInfoAction.UPDATE_LATENCY); - update.setData(ImmutableList.of(new PlayerInfoData( + final WrapperPlayerServerPlayerInfo add = new WrapperPlayerServerPlayerInfo(); + if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) { + final WrapperPlayerServerPlayerInfoRemove remove = new WrapperPlayerServerPlayerInfoRemove(); + final EnumSet actions = EnumSet.of( + EnumWrappers.PlayerInfoAction.ADD_PLAYER, + EnumWrappers.PlayerInfoAction.INITIALIZE_CHAT, + EnumWrappers.PlayerInfoAction.UPDATE_LISTED, + EnumWrappers.PlayerInfoAction.UPDATE_DISPLAY_NAME, + EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE, + EnumWrappers.PlayerInfoAction.UPDATE_LATENCY); + remove.setUUIDs(ImmutableList.of(player.getUniqueId())); + remove.sendPacket(player); + add.setActions(actions); + } else { + final WrapperPlayerServerPlayerInfo remove = new WrapperPlayerServerPlayerInfo(); + remove.setActions(EnumSet.of(EnumWrappers.PlayerInfoAction.REMOVE_PLAYER)); + add.setActions(EnumSet.of(EnumWrappers.PlayerInfoAction.ADD_PLAYER)); + remove.sendPacket(player); + } + + add.setData(ImmutableList.of(new PlayerInfoData( player.getUniqueId(), player.getPing(), true, @@ -180,12 +188,6 @@ public class AppearanceManager { // No, I'll not waste another day fixing their mess. Go cry about it to Mojang. // (Long live NoEncryption!) ))); - if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) { - actions.remove(EnumWrappers.PlayerInfoAction.REMOVE_PLAYER); - remove.setUUIDs(ImmutableList.of(player.getUniqueId())); - remove.sendPacket(player); - } - update.setActions(actions); - update.sendPacket(player); + add.sendPacket(player); } } \ No newline at end of file diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java index 817f8c1..9908724 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java @@ -100,7 +100,11 @@ public class WrapperPlayServerRespawn extends AbstractPacket { } public void setCopyMetadata(boolean value) { - handle.getBytes().write(0, ((byte) (value ? 0x01 : 0x00))); + if(MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) { + handle.getBytes().write(0, ((byte) (value ? 0x01 : 0x00))); + } else { + handle.getBooleans().write(0, value); + } } //............. diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java index 3befbe2..df989b4 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java @@ -2,6 +2,7 @@ package xyz.atnrch.nicko.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.wrappers.EnumWrappers; import com.comphenix.protocol.wrappers.PlayerInfoData; @@ -32,7 +33,11 @@ public class WrapperPlayerServerPlayerInfo extends AbstractPacket { } public void setActions(Set value) { - handle.getPlayerInfoActions().write(0, value); + if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) { + handle.getPlayerInfoActions().write(0, value); + } else { + handle.getPlayerInfoAction().write(0, value.stream().iterator().next()); // Get the first Value. + } } public List getData() { @@ -40,6 +45,6 @@ public class WrapperPlayerServerPlayerInfo extends AbstractPacket { } public void setData(List value) { - handle.getPlayerInfoDataLists().write(1, value); + handle.getPlayerInfoDataLists().write(0, value); } } From dee3f9b91c4c48aa9f6f9fa92705975ef4df3173 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 19 Jun 2023 15:08:23 +0200 Subject: [PATCH 030/296] maintenance and player info packet cast fix --- .gitignore | 12 ----- docker-compose.yml | 23 ++++++++++ pom.xml | 44 +++++++++---------- .../nicko/gui/admin/CacheManagementGUI.java | 8 ++-- .../gui/admin/cache/CacheDetailedGUI.java | 4 +- ...Placeholder.java => EntryPlaceholder.java} | 4 +- ...date.java => InvalidateCompleteCache.java} | 4 +- ...iled.java => InvalidateSpecificEntry.java} | 4 +- .../WrapperPlayerServerPlayerInfo.java | 4 +- .../nicko/test/storage/SQLStorageTest.java | 6 +-- 10 files changed, 61 insertions(+), 52 deletions(-) create mode 100644 docker-compose.yml rename src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/{SkinPlaceholder.java => EntryPlaceholder.java} (88%) rename src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/{CacheInvalidate.java => InvalidateCompleteCache.java} (93%) rename src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/{CacheDetailed.java => InvalidateSpecificEntry.java} (90%) diff --git a/.gitignore b/.gitignore index 67f8558..7055fba 100644 --- a/.gitignore +++ b/.gitignore @@ -27,18 +27,6 @@ replay_pid* # Idea files *.iml -# Nicko first pass build files -core/target -v1_14_R1/target -v1_15_R1/target -v1_16_R1/target -v1_16_R2/target -v1_16_R3/target -v1_17_R1/target -v1_18_R1/target -v1_18_R2/target -v1_19_R1/target - # Idea Folder .idea diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d2fa012 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,23 @@ +# Nicko's docker-compose.yml +# Used for debug and test purposes. +version: '3.1' + +services: + + db: + image: mariadb + restart: always + environment: + MARIADB_ROOT_PASSWORD: 12345 + + adminer: + image: adminer + restart: always + ports: + - "8080:8080" + + redis: + image: redis + restart: always + ports: + - "6379:6379" \ No newline at end of file diff --git a/pom.xml b/pom.xml index 31d2bc6..04e30ec 100644 --- a/pom.xml +++ b/pom.xml @@ -39,47 +39,52 @@ - + + + org.spigotmc + spigot-api + 1.19.4-R0.1-SNAPSHOT + provided + com.comphenix.protocol ProtocolLib 5.0.0-SNAPSHOT provided - me.clip placeholderapi 2.11.2 provided - xyz.xenondevs.invui invui 1.0-SNAPSHOT - net.wesjd anvilgui 1.6.3-SNAPSHOT - - - com.google.guava - guava - 31.1-jre - provided - - com.github.seeseemelk MockBukkit-v1.19 2.29.0 test - + + + + com.google.code.gson + gson + 2.10.1 + org.mariadb.jdbc mariadb-java-client @@ -95,24 +100,17 @@ com.fasterxml.jackson.core jackson-core - 2.14.2 - - - org.spigotmc - spigot-api - 1.19.4-R0.1-SNAPSHOT - provided + 2.15.2 com.fasterxml.jackson.dataformat jackson-dataformat-yaml - 2.14.2 + 2.15.2 - redis.clients jedis - 4.3.0 + 4.4.3 diff --git a/src/main/java/xyz/atnrch/nicko/gui/admin/CacheManagementGUI.java b/src/main/java/xyz/atnrch/nicko/gui/admin/CacheManagementGUI.java index 58a2510..77ca7d2 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/admin/CacheManagementGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/admin/CacheManagementGUI.java @@ -1,8 +1,8 @@ package xyz.atnrch.nicko.gui.admin; import xyz.atnrch.nicko.gui.AdminGUI; -import xyz.atnrch.nicko.gui.items.admin.cache.CacheDetailed; -import xyz.atnrch.nicko.gui.items.admin.cache.CacheInvalidate; +import xyz.atnrch.nicko.gui.items.admin.cache.InvalidateSpecificEntry; +import xyz.atnrch.nicko.gui.items.admin.cache.InvalidateCompleteCache; import xyz.atnrch.nicko.gui.items.admin.cache.CacheOverview; import xyz.atnrch.nicko.gui.items.common.GoBack; import org.bukkit.entity.Player; @@ -20,8 +20,8 @@ public class CacheManagementGUI { .setStructure("B # S A D") .addIngredient('B', new GoBack(new AdminGUI(player).getGUI())) .addIngredient('S', new CacheOverview()) - .addIngredient('A', new CacheInvalidate()) - .addIngredient('D', new CacheDetailed()) + .addIngredient('A', new InvalidateCompleteCache()) + .addIngredient('D', new InvalidateSpecificEntry()) .build(); this.player = player; } diff --git a/src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java b/src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java index d8b4c65..1b49726 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java @@ -8,7 +8,7 @@ import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.gui.structure.Markers; import xyz.xenondevs.invui.item.Item; import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.gui.items.admin.cache.SkinPlaceholder; +import xyz.atnrch.nicko.gui.items.admin.cache.EntryPlaceholder; import xyz.atnrch.nicko.gui.admin.CacheManagementGUI; import xyz.atnrch.nicko.gui.items.common.ScrollDown; import org.bukkit.entity.Player; @@ -34,7 +34,7 @@ public class CacheDetailedGUI { .collect(Collectors.toList()); final List items = loadedSkins.stream() - .map(SkinPlaceholder::new) + .map(EntryPlaceholder::new) .collect(Collectors.toList()); gui = ScrollGui.items(guiItemBuilder -> { diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/SkinPlaceholder.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/EntryPlaceholder.java similarity index 88% rename from src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/SkinPlaceholder.java rename to src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/EntryPlaceholder.java index 6f94d63..10b8c32 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/SkinPlaceholder.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/EntryPlaceholder.java @@ -7,8 +7,8 @@ import xyz.xenondevs.invui.item.impl.AsyncItem; import java.util.UUID; -public class SkinPlaceholder extends AsyncItem { - public SkinPlaceholder(String name) { +public class EntryPlaceholder extends AsyncItem { + public EntryPlaceholder(String name) { super(new ItemBuilder(Material.PAINTING).setDisplayName("§7§oLoading..."), () -> { final String stringUUID = name.replaceAll("(.{8})(.{4})(.{4})(.{4})(.+)", "$1-$2-$3-$4-$5"); final UUID uuid = UUID.fromString(stringUUID); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheInvalidate.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCompleteCache.java similarity index 93% rename from src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheInvalidate.java rename to src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCompleteCache.java index 7d3fa9a..5ec26d3 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheInvalidate.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCompleteCache.java @@ -9,8 +9,8 @@ import org.bukkit.event.inventory.ClickType; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class CacheInvalidate extends SuppliedItem { - public CacheInvalidate() { +public class InvalidateCompleteCache extends SuppliedItem { + public InvalidateCompleteCache() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.TNT); builder.setDisplayName("§fInvalidate §6skin cache"); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheDetailed.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateSpecificEntry.java similarity index 90% rename from src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheDetailed.java rename to src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateSpecificEntry.java index 9a55797..62bd5a0 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheDetailed.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateSpecificEntry.java @@ -6,8 +6,8 @@ import org.bukkit.event.inventory.ClickType; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class CacheDetailed extends SuppliedItem { - public CacheDetailed() { +public class InvalidateSpecificEntry extends SuppliedItem { + public InvalidateSpecificEntry() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.PAPER); builder.setDisplayName("§6Invalidate specific skin..."); diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java index df989b4..86ee3f5 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java @@ -41,10 +41,10 @@ public class WrapperPlayerServerPlayerInfo extends AbstractPacket { } public List getData() { - return handle.getPlayerInfoDataLists().read(0); + return handle.getPlayerInfoDataLists().read(1); } public void setData(List value) { - handle.getPlayerInfoDataLists().write(0, value); + handle.getPlayerInfoDataLists().write(1, value); } } 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 39c4ad1..c6c9380 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java @@ -3,13 +3,13 @@ package xyz.atnrch.nicko.test.storage; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; import be.seeseemelk.mockbukkit.entity.PlayerMock; +import org.junit.jupiter.api.*; import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.config.DataSourceConfiguration; -import xyz.atnrch.nicko.i18n.Locale; import xyz.atnrch.nicko.config.Configuration; +import xyz.atnrch.nicko.config.DataSourceConfiguration; import xyz.atnrch.nicko.disguise.ActionResult; import xyz.atnrch.nicko.disguise.NickoProfile; -import org.junit.jupiter.api.*; +import xyz.atnrch.nicko.i18n.Locale; import java.util.Optional; From f447abe963cab4c2f1e7ad7331b7a3996e0b6b30 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 19 Jun 2023 15:32:09 +0200 Subject: [PATCH 031/296] style: description and readme adjustements --- README.md | 2 +- src/main/resources/plugin.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 850d86b..c677c04 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # _Nicko_ -## The next-generation, most feature-packed disguise plugin for Minecraft. +## The next generation, feature packed disguise plugin for Minecraft. ### Download: diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 3ab1d56..979373c 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -2,6 +2,7 @@ name: Nicko main: xyz.atnrch.nicko.NickoBukkit version: 1.0-SNAPSHOT author: Ineanto +description: "In-game appearance manager." api-version: 1.13 softdepend: [ PlaceholderAPI ] depend: From f9513aa7517a5f81ccb491ffc524b6771883293d Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 19 Jun 2023 15:38:17 +0200 Subject: [PATCH 032/296] style: chat session data comment move --- .../xyz/atnrch/nicko/disguise/AppearanceManager.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java index cc6f507..4386823 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java @@ -175,6 +175,11 @@ public class AppearanceManager { remove.sendPacket(player); } + // Yes, I skip providing chat session data. + // Yes, this will cause players to get kicked + // as soon as they send a message on versions above 1.19.2. + // No, I'll not waste another day fixing their mess. Go cry about it to Mojang. + // (Long live NoEncryption!) add.setData(ImmutableList.of(new PlayerInfoData( player.getUniqueId(), player.getPing(), @@ -182,11 +187,6 @@ public class AppearanceManager { EnumWrappers.NativeGameMode.fromBukkit(player.getGameMode()), gameProfile, WrappedChatComponent.fromText(displayName) - // Yes, I skip providing chat session data. - // Yes, this will cause players to get kicked - // as soon as they send a message on versions above 1.19.2. - // No, I'll not waste another day fixing their mess. Go cry about it to Mojang. - // (Long live NoEncryption!) ))); add.sendPacket(player); } From 041700d070346ea9b5224a4cb5473a7c62b686f5 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 19 Jun 2023 15:38:47 +0200 Subject: [PATCH 033/296] style: wrap comment --- src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java index 4386823..1857003 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java @@ -178,7 +178,8 @@ public class AppearanceManager { // Yes, I skip providing chat session data. // Yes, this will cause players to get kicked // as soon as they send a message on versions above 1.19.2. - // No, I'll not waste another day fixing their mess. Go cry about it to Mojang. + // No, I'll not waste another day fixing their mess. + // Go cry about it to Mojang. // (Long live NoEncryption!) add.setData(ImmutableList.of(new PlayerInfoData( player.getUniqueId(), From f99d20ade34a4dcd17e4ad681fec6072a379e951 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 19 Jun 2023 15:51:37 +0200 Subject: [PATCH 034/296] refactor(wrappers): unused getters --- .../wrapper/WrapperPlayServerRespawn.java | 36 ------------------- .../WrapperPlayerServerPlayerInfo.java | 12 ------- .../WrapperPlayerServerPlayerInfoRemove.java | 8 ----- 3 files changed, 56 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java index 9908724..38f0a84 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java @@ -38,14 +38,6 @@ public class WrapperPlayServerRespawn extends AbstractPacket { // your code to change things that were working perfectly fine before //............. - public World getDimension() { - if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { - return handle.getWorldKeys().read(0); - } - - return handle.getDimensionTypes().read(0); - } - public void setDimension(World value) { if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { // 1.19 to 1.19.4 @@ -71,10 +63,6 @@ public class WrapperPlayServerRespawn extends AbstractPacket { // GameMode Field //............. - public GameMode getGameMode() { - return handle.getGameModes().read(0).toBukkit(); - } - public void setGameMode(GameMode value) { handle.getGameModes().write(0, EnumWrappers.NativeGameMode.fromBukkit(value)); } @@ -83,10 +71,6 @@ public class WrapperPlayServerRespawn extends AbstractPacket { // Previous GameMode Field //............. - public GameMode getPreviousGameMode() { - return handle.getGameModes().read(1).toBukkit(); - } - public void setPreviousGameMode(GameMode value) { handle.getGameModes().write(1, EnumWrappers.NativeGameMode.fromBukkit(value)); } @@ -95,10 +79,6 @@ public class WrapperPlayServerRespawn extends AbstractPacket { // Copy Metadata Field //............. - public boolean isCopyMetadata() { - return handle.getBytes().read(0) != 0; - } - public void setCopyMetadata(boolean value) { if(MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) { handle.getBytes().write(0, ((byte) (value ? 0x01 : 0x00))); @@ -112,13 +92,6 @@ public class WrapperPlayServerRespawn extends AbstractPacket { // Added in 1.15. //............. - public long getSeed() { - if (MinecraftVersion.BEE_UPDATE.atOrAbove()) { - return handle.getLongs().read(0); - } - return -1; - } - public void setSeed(long value) { if (MinecraftVersion.BEE_UPDATE.atOrAbove()) { handle.getLongs().write(0, Hashing.sha256().hashLong(value).asLong()); @@ -130,15 +103,6 @@ public class WrapperPlayServerRespawn extends AbstractPacket { // Removed in 1.14. //............. - public Difficulty getDifficulty() { - if (MinecraftVersion.VILLAGE_UPDATE.atOrAbove()) { - return null; - } - - final EnumWrappers.Difficulty difficulty = handle.getDifficulties().read(0); - return difficulty == null ? null : Difficulty.valueOf(difficulty.name()); - } - public void setDifficulty(Difficulty difficulty) { if (difficulty != null && !MinecraftVersion.VILLAGE_UPDATE.atOrAbove()) { handle.getDifficulties().write(0, EnumWrappers.Difficulty.valueOf(difficulty.name())); diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java index 86ee3f5..32d6f07 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java @@ -24,14 +24,6 @@ public class WrapperPlayerServerPlayerInfo extends AbstractPacket { handle.getModifier().writeDefaults(); } - public WrapperPlayerServerPlayerInfo(PacketContainer packet) { - super(packet, TYPE); - } - - public Set getActions() { - return handle.getPlayerInfoActions().read(0); - } - public void setActions(Set value) { if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) { handle.getPlayerInfoActions().write(0, value); @@ -40,10 +32,6 @@ public class WrapperPlayerServerPlayerInfo extends AbstractPacket { } } - public List getData() { - return handle.getPlayerInfoDataLists().read(1); - } - public void setData(List value) { handle.getPlayerInfoDataLists().write(1, value); } diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java index a218e67..5c48f9d 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java @@ -21,14 +21,6 @@ public class WrapperPlayerServerPlayerInfoRemove extends AbstractPacket { handle.getModifier().writeDefaults(); } - public WrapperPlayerServerPlayerInfoRemove(PacketContainer packet) { - super(packet, TYPE); - } - - public List getUUIDs() { - return handle.getUUIDLists().read(0); - } - public void setUUIDs(List value) { handle.getUUIDLists().write(0, value); } From bb6764af004dddab9723ff11feec2f6d63122acc Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 19 Jun 2023 15:54:31 +0200 Subject: [PATCH 035/296] feat: outdated comment --- src/main/java/xyz/atnrch/nicko/config/Configuration.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/config/Configuration.java b/src/main/java/xyz/atnrch/nicko/config/Configuration.java index 3a90a8b..e5ff073 100644 --- a/src/main/java/xyz/atnrch/nicko/config/Configuration.java +++ b/src/main/java/xyz/atnrch/nicko/config/Configuration.java @@ -2,10 +2,6 @@ package xyz.atnrch.nicko.config; import com.fasterxml.jackson.annotation.JsonProperty; -/** - * TODO: 4/2/23 Convert using Bukkit YAML API - * Link - **/ public class Configuration { @JsonProperty("sql") private final DataSourceConfiguration sqlConfiguration; From 7cab66a70e05294f907c514dfbb3b856ea57ea1a Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 19 Jun 2023 21:52:21 +0200 Subject: [PATCH 036/296] fix(docker): open mariadb port --- docker-compose.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index d2fa012..f06cc56 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,6 +9,8 @@ services: restart: always environment: MARIADB_ROOT_PASSWORD: 12345 + ports: + - "3306:3306" adminer: image: adminer From c3e10ae81d2cc9a6e9e4da9d986b481297549bfb Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 19 Jun 2023 21:52:46 +0200 Subject: [PATCH 037/296] feat(i18n): title update when going back --- README.md | 2 +- src/main/java/xyz/atnrch/nicko/NickoBukkit.java | 2 -- src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java | 12 ++++++++---- src/main/java/xyz/atnrch/nicko/gui/MainGUI.java | 7 ++++++- src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java | 3 ++- .../atnrch/nicko/gui/admin/CacheManagementGUI.java | 12 ++++++++---- .../nicko/gui/admin/cache/CacheDetailedGUI.java | 3 ++- .../xyz/atnrch/nicko/gui/items/common/GoBack.java | 5 ++--- src/main/resources/fr.yml | 12 ++++++++++-- 9 files changed, 39 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index c677c04..e723fb3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # _Nicko_ -## The next generation, feature packed disguise plugin for Minecraft. +## The feature packed, next generation disguise plugin for Minecraft. ### Download: diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index c45f335..ca4a53f 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -158,6 +158,4 @@ public class NickoBukkit extends JavaPlugin { public LocaleFileManager getLocaleFileManager() { return localeFileManager; } - - public ProtocolManager getProtocolManager() { return protocolManager; } } diff --git a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java index 2ce2990..5394c3f 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java @@ -7,12 +7,12 @@ import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; public class AdminGUI { - public static final String TITLE = "Nicko > Administration"; - + private final String title = "Nicko > Administration"; private final Player player; private final Gui gui; public AdminGUI(Player player) { + final MainGUI parent = new MainGUI(player); this.gui = Gui.normal() .setStructure( "# # # # # # # # #", @@ -20,7 +20,7 @@ public class AdminGUI { "B # # # # # # # #" ) .addIngredient('S', new ManageCache()) - .addIngredient('B', new GoBack(new MainGUI(player).getGUI())) + .addIngredient('B', new GoBack(parent.getGUI(), title)) .build(); this.player = player; } @@ -29,7 +29,11 @@ public class AdminGUI { return gui; } + public String getTitle() { + return title; + } + 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/MainGUI.java b/src/main/java/xyz/atnrch/nicko/gui/MainGUI.java index aea1c50..162518c 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/MainGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/MainGUI.java @@ -11,6 +11,7 @@ import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; public class MainGUI { + private final String title = "Nicko - Home"; private final Player player; private final Gui gui; @@ -40,7 +41,11 @@ public class MainGUI { return gui; } + public String getTitle() { + return title; + } + public void open() { - Window.single().setGui(gui).setTitle("Nicko - Home").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 dc6fbc7..8c48a0d 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java @@ -23,9 +23,10 @@ public class SettingsGUI { // TODO: 3/6/23 Replace when Redis is not enabled dynamicStructure[1] = dynamicStructure[1].replace("T", "U"); + final MainGUI parent = new MainGUI(player); this.gui = Gui.normal() .setStructure(dynamicStructure) - .addIngredient('B', new GoBack(new MainGUI(player).getGUI())) + .addIngredient('B', new GoBack(parent.getGUI(), parent.getTitle())) .addIngredient('L', new LanguageCycling().get(player)) .addIngredient('T', new BungeeCordCycling().get(player)) .build(); diff --git a/src/main/java/xyz/atnrch/nicko/gui/admin/CacheManagementGUI.java b/src/main/java/xyz/atnrch/nicko/gui/admin/CacheManagementGUI.java index 77ca7d2..1a3bd13 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/admin/CacheManagementGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/admin/CacheManagementGUI.java @@ -10,15 +10,15 @@ import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; public class CacheManagementGUI { - public static final String TITLE = "Nicko > Admin... > Cache"; - + private final String title = "Nicko > Admin... > Cache"; private final Player player; private final Gui gui; public CacheManagementGUI(Player player) { + final AdminGUI parent = new AdminGUI(player); this.gui = Gui.normal() .setStructure("B # S A D") - .addIngredient('B', new GoBack(new AdminGUI(player).getGUI())) + .addIngredient('B', new GoBack(parent.getGUI(), parent.getTitle())) .addIngredient('S', new CacheOverview()) .addIngredient('A', new InvalidateCompleteCache()) .addIngredient('D', new InvalidateSpecificEntry()) @@ -30,7 +30,11 @@ public class CacheManagementGUI { return gui; } + public String getTitle() { + return title; + } + 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/admin/cache/CacheDetailedGUI.java b/src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java index 1b49726..003e18b 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java @@ -37,6 +37,7 @@ public class CacheDetailedGUI { .map(EntryPlaceholder::new) .collect(Collectors.toList()); + final CacheManagementGUI parent = new CacheManagementGUI(player); gui = ScrollGui.items(guiItemBuilder -> { guiItemBuilder.setStructure( "# # # # # # # # #", @@ -48,7 +49,7 @@ public class CacheDetailedGUI { guiItemBuilder.addIngredient('x', Markers.CONTENT_LIST_SLOT_HORIZONTAL); guiItemBuilder.addIngredient('U', new ScrollUp()); guiItemBuilder.addIngredient('D', new ScrollDown()); - guiItemBuilder.addIngredient('B', new GoBack(new CacheManagementGUI(player).getGUI())); + guiItemBuilder.addIngredient('B', new GoBack(parent.getGUI(), parent.getTitle())); guiItemBuilder.setContent(items); }); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/GoBack.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/GoBack.java index f840a6a..1131ef1 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/GoBack.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/GoBack.java @@ -7,7 +7,7 @@ import xyz.xenondevs.invui.item.impl.SuppliedItem; import xyz.xenondevs.invui.window.Window; public class GoBack extends SuppliedItem { - public GoBack(Gui gui) { + public GoBack(Gui gui, String parentTitle) { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.ARROW); builder.setDisplayName("Go back"); @@ -15,8 +15,7 @@ public class GoBack extends SuppliedItem { return builder; }, click -> { click.getEvent().getView().close(); - // TODO: 4/1/23 Get title of parent GUI - Window.single().setGui(gui).setTitle("Nicko").open(click.getPlayer()); + Window.single().setGui(gui).setTitle(parentTitle).open(click.getPlayer()); return true; }); } diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 160b4b2..ee50336 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -17,6 +17,14 @@ event: fail: "§cImpossible d''appliquer votre précédent déguisement. §7§o({0})" success: "§aVotre précédent déguisement a été appliqué." undisguise: - fail: "§cImpossible de retier votre déguisement. Il sera réinitialisé à votre prochaine reconnexion." + fail: "§cImpossible de retirer votre déguisement. Il sera réinitialisé à votre prochaine reconnexion." none: "§cVous n''avez pas de déguisement." - success: "§aDéguisement retiré." \ No newline at end of file + success: "§aDéguisement retiré." +gui: + common: + exit: "Quitter" + back: "Retour" + l1_back: "Retournez à la fenêtre précédente." + not_available: "Option indisponible :(" + l1_not_available: "Ce bouton est désactivé." + From c66979133d7a80be66ad1c17933c503dda96526f Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 20 Jun 2023 10:38:06 +0200 Subject: [PATCH 038/296] fix(gui): title --- src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java index 5394c3f..470ee1b 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java @@ -20,7 +20,7 @@ public class AdminGUI { "B # # # # # # # #" ) .addIngredient('S', new ManageCache()) - .addIngredient('B', new GoBack(parent.getGUI(), title)) + .addIngredient('B', new GoBack(parent.getGUI(), parent.getTitle())) .build(); this.player = player; } From 50dd4c3adf2de47a5a2f27263a609fe81ff6bd14 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 28 Jun 2023 13:22:48 +0200 Subject: [PATCH 039/296] feat: 1.20/1.20.1 update --- README.md | 22 ++++++-- docker-compose.yml | 8 +-- pom.xml | 13 ++--- .../xyz/atnrch/nicko/anvil/AnvilManager.java | 53 +++++++++++-------- .../nicko/disguise/AppearanceManager.java | 5 ++ 5 files changed, 64 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index e723fb3..cd38263 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,25 @@ ## The feature packed, next generation disguise plugin for Minecraft. -### Download: +--- + +## Download: Coming soon! ⏳ +--- + +## Q/A + +Q: Players are getting kicked when they send a message on versions above 1.19.2! + +A: Install [NoEncryption](https://www.spigotmc.org/resources/noencryption.102902/). + +--- + #### Version compatibility table -| Version | Supported | -|-----------|----------------------------------------------------------------------------| -| < 1.12.2 | Use [NickReloaded](https://www.spigotmc.org/resources/nickreloaded.46335/) | -| \> 1.12.2 | Supported | \ No newline at end of file +| Version | Plugin | +|----------|----------------------------------------------------------------------------| +| < 1.12.2 | Use [NickReloaded](https://www.spigotmc.org/resources/nickreloaded.46335/) | +| > 1.12.2 | Use Nicko | diff --git a/docker-compose.yml b/docker-compose.yml index f06cc56..6bdf830 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,7 +6,7 @@ services: db: image: mariadb - restart: always + restart: no environment: MARIADB_ROOT_PASSWORD: 12345 ports: @@ -14,12 +14,12 @@ services: adminer: image: adminer - restart: always + restart: no ports: - "8080:8080" redis: image: redis - restart: always + restart: no ports: - - "6379:6379" \ No newline at end of file + - "6379:6379" diff --git a/pom.xml b/pom.xml index 04e30ec..f7515f3 100644 --- a/pom.xml +++ b/pom.xml @@ -17,12 +17,12 @@ - papermc - https://repo.papermc.io/repository/maven-public/ + xenondevs + https://repo.xenondevs.xyz/releases - spigot-repo - https://hub.spigotmc.org/nexus/content/groups/public/ + papermc + https://repo.papermc.io/repository/maven-public/ codemc-snapshots @@ -63,12 +63,13 @@ xyz.xenondevs.invui invui - 1.0-SNAPSHOT + 1.11 + pom net.wesjd anvilgui - 1.6.3-SNAPSHOT + 1.7.0-SNAPSHOT com.github.seeseemelk diff --git a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java index b741fef..5b53c5b 100644 --- a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java @@ -41,14 +41,17 @@ public class AnvilManager { .plugin(NickoBukkit.getInstance()) .itemLeft(getLeftItem(false)) .interactableSlots(AnvilGUI.Slot.OUTPUT) - .onComplete((completion) -> { - if (MojangUtils.isUsernameInvalid(completion.getText())) { - return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); - } else { - appearanceManager.setName(completion.getText()); - openSkinAnvil(); - return Collections.singletonList(AnvilGUI.ResponseAction.close()); + .onClick((slot, snapshot) -> { + if (slot == AnvilGUI.Slot.OUTPUT) { + if (MojangUtils.isUsernameInvalid(snapshot.getText())) { + return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); + } else { + appearanceManager.setName(snapshot.getText()); + openSkinAnvil(); + return Collections.singletonList(AnvilGUI.ResponseAction.close()); + } } + return Collections.emptyList(); }) .text("New name..."); } @@ -58,14 +61,17 @@ public class AnvilManager { .plugin(NickoBukkit.getInstance()) .itemLeft(getLeftItem(false)) .interactableSlots(AnvilGUI.Slot.OUTPUT) - .onComplete((completion) -> { - if (MojangUtils.isUsernameInvalid(completion.getText())) { - return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); - } else { - appearanceManager.setName(completion.getText()); - final ActionResult actionResult = appearanceManager.updatePlayer(false); - return sendResultAndClose(actionResult); + .onClick((slot, snapshot) -> { + if (slot == AnvilGUI.Slot.OUTPUT) { + if (MojangUtils.isUsernameInvalid(snapshot.getText())) { + return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); + } else { + appearanceManager.setName(snapshot.getText()); + final ActionResult actionResult = appearanceManager.updatePlayer(false); + return sendResultAndClose(actionResult); + } } + return Collections.emptyList(); }) .text("New name..."); } @@ -75,14 +81,17 @@ public class AnvilManager { .plugin(NickoBukkit.getInstance()) .itemLeft(getLeftItem(true)) .interactableSlots(AnvilGUI.Slot.OUTPUT) - .onComplete((completion) -> { - if (MojangUtils.isUsernameInvalid(completion.getText())) { - return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); - } else { - appearanceManager.setSkin(completion.getText()); - final ActionResult actionResult = appearanceManager.updatePlayer(true); - return sendResultAndClose(actionResult); + .onClick((slot, snapshot) -> { + if (slot == AnvilGUI.Slot.OUTPUT) { + if (MojangUtils.isUsernameInvalid(snapshot.getText())) { + return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); + } else { + appearanceManager.setSkin(snapshot.getText()); + final ActionResult actionResult = appearanceManager.updatePlayer(true); + return sendResultAndClose(actionResult); + } } + return Collections.emptyList(); }) .text("New skin..."); } @@ -99,7 +108,7 @@ public class AnvilManager { private ItemStack getLeftItem(boolean skin) { final ItemStack item = new ItemStack(Material.PAPER); final ItemMeta meta = item.getItemMeta(); - meta.setDisplayName("§0New " + (skin ? "skin" : "name") + "..."); + if (meta != null) meta.setDisplayName("§0New " + (skin ? "skin" : "name") + "..."); item.setItemMeta(meta); return item; } diff --git a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java index 1857003..282b3f5 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java @@ -144,6 +144,7 @@ public class AppearanceManager { private void respawnPlayer() { final World world = player.getWorld(); + final boolean wasFlying = player.isFlying(); final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(); respawn.setDimension(world); respawn.setSeed(world.getSeed()); @@ -152,8 +153,12 @@ 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(); } + @SuppressWarnings("deprecation") private void updateTabList(WrappedGameProfile gameProfile, String displayName) { final WrapperPlayerServerPlayerInfo add = new WrapperPlayerServerPlayerInfo(); if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) { From f3ebbd6a8d56d20a30d0f23bd124116cd8912e4e Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 28 Jun 2023 13:48:20 +0200 Subject: [PATCH 040/296] fix(anvilgui): update to 1.20/1.20.1 --- src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java | 2 ++ src/main/java/xyz/atnrch/nicko/gui/MainGUI.java | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java index 5b53c5b..312b255 100644 --- a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java @@ -39,6 +39,7 @@ public class AnvilManager { public AnvilGUI.Builder getNameThenSkinAnvil() { return new AnvilGUI.Builder() .plugin(NickoBukkit.getInstance()) + .preventClose() .itemLeft(getLeftItem(false)) .interactableSlots(AnvilGUI.Slot.OUTPUT) .onClick((slot, snapshot) -> { @@ -59,6 +60,7 @@ public class AnvilManager { public AnvilGUI.Builder getNameAnvil() { return new AnvilGUI.Builder() .plugin(NickoBukkit.getInstance()) + .preventClose() .itemLeft(getLeftItem(false)) .interactableSlots(AnvilGUI.Slot.OUTPUT) .onClick((slot, snapshot) -> { diff --git a/src/main/java/xyz/atnrch/nicko/gui/MainGUI.java b/src/main/java/xyz/atnrch/nicko/gui/MainGUI.java index 162518c..158d954 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/MainGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/MainGUI.java @@ -18,8 +18,8 @@ public class MainGUI { public MainGUI(Player player) { final String[] dynamicStructure = new String[]{ "# # # # # # # # #", - "# # # N B S # # #", - "E P A # # # # # R"}; + "A # # N B S # # #", + "E P # # # # # # R"}; if (!player.hasPermission("nicko.admin") || !player.isOp()) { dynamicStructure[2] = dynamicStructure[2].replace("A", "#"); From 2fbf3318f983da8c552c0884633c523d41508660 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 28 Jun 2023 23:22:50 +0200 Subject: [PATCH 041/296] feat(disguise): update others players + fixes/tweaks --- logs/2023-06-28-1.log.gz | Bin 0 -> 124 bytes logs/2023-06-28-2.log.gz | Bin 0 -> 125 bytes pom.xml | 4 +- .../java/xyz/atnrch/nicko/NickoBukkit.java | 6 +- .../xyz/atnrch/nicko/anvil/AnvilManager.java | 8 +- .../nicko/command/sub/NickoCheckSubCmd.java | 18 +- .../atnrch/nicko/disguise/ActionResult.java | 16 +- .../nicko/disguise/AppearanceManager.java | 26 ++- .../nicko/event/PlayerJoinListener.java | 12 +- .../admin/cache/InvalidateCompleteCache.java | 3 +- .../nicko/gui/items/main/ResetAppearance.java | 8 +- src/main/java/xyz/atnrch/nicko/i18n/I18N.java | 82 +++++---- .../java/xyz/atnrch/nicko/i18n/I18NDict.java | 40 ++-- .../xyz/atnrch/nicko/mojang/MojangAPI.java | 1 + .../WrapperPlayServerEntityDestroy.java | 41 +++++ .../WrapperPlayServerNamedEntitySpawn.java | 173 ++++++++++++++++++ src/main/resources/en.yml | 2 +- 17 files changed, 334 insertions(+), 106 deletions(-) create mode 100644 logs/2023-06-28-1.log.gz create mode 100644 logs/2023-06-28-2.log.gz create mode 100644 src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerEntityDestroy.java create mode 100644 src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerNamedEntitySpawn.java diff --git a/logs/2023-06-28-1.log.gz b/logs/2023-06-28-1.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..1423f84a184c8e6794848391df87a61973b73d93 GIT binary patch literal 124 zcmV-?0E7P@iwFP!00000{{_J@4#F@D1<;*S{4FpL?1+fU6CGHK#KKT@sG5K>G(k2M z*XO-41c^}sPZ-y^)YG$n43prd+El=Fj>pguk)U6eY=)F;$qBEf*eolYw)S;b$Cu!_ e^W@oKzgekod}gy>(ehF literal 0 HcmV?d00001 diff --git a/logs/2023-06-28-2.log.gz b/logs/2023-06-28-2.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..fe90cdd29d98b08a6a824c9cedf43de2c97a67c3 GIT binary patch literal 125 zcmV-@0D}J?iwFP!00000{{_LZ4uUWc2H@SN__yLx}8W org.spigotmc - spigot-api - 1.19.4-R0.1-SNAPSHOT + spigot + 1.20.1-R0.1-SNAPSHOT provided diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index ca4a53f..4b13b40 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -98,8 +98,10 @@ public class NickoBukkit extends JavaPlugin { command.setExecutor(new NickoCommand()); } - Structure.addGlobalIngredient('#', new SimpleItem(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setDisplayName(" "))); - Structure.addGlobalIngredient('%', new SimpleItem(new ItemBuilder(Material.ORANGE_STAINED_GLASS_PANE).setDisplayName(" "))); + //new SimpleItem(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setDisplayName(" ")) + //new SimpleItem(new ItemBuilder(Material.ORANGE_STAINED_GLASS_PANE).setDisplayName(" ")) + Structure.addGlobalIngredient('#', new SimpleItem(new ItemBuilder(Material.AIR))); + Structure.addGlobalIngredient('%', new SimpleItem(new ItemBuilder(Material.AIR))); Structure.addGlobalIngredient('U', new OptionUnavailable()); Structure.addGlobalIngredient('E', new ExitGUI()); diff --git a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java index 312b255..66f9611 100644 --- a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java @@ -39,7 +39,6 @@ public class AnvilManager { public AnvilGUI.Builder getNameThenSkinAnvil() { return new AnvilGUI.Builder() .plugin(NickoBukkit.getInstance()) - .preventClose() .itemLeft(getLeftItem(false)) .interactableSlots(AnvilGUI.Slot.OUTPUT) .onClick((slot, snapshot) -> { @@ -60,7 +59,6 @@ public class AnvilManager { public AnvilGUI.Builder getNameAnvil() { return new AnvilGUI.Builder() .plugin(NickoBukkit.getInstance()) - .preventClose() .itemLeft(getLeftItem(false)) .interactableSlots(AnvilGUI.Slot.OUTPUT) .onClick((slot, snapshot) -> { @@ -99,10 +97,12 @@ public class AnvilManager { } private List sendResultAndClose(ActionResult actionResult) { + final I18N i18n = new I18N(player); if (!actionResult.isError()) { - player.sendMessage(I18N.translate(player, I18NDict.Event.Disguise.SUCCESS)); + player.sendMessage(i18n.translate(I18NDict.Event.Disguise.SUCCESS)); } else { - player.sendMessage(I18N.translate(player, I18NDict.Event.Disguise.FAIL, I18N.translateWithoutPrefix(player, actionResult.getErrorMessage()))); + // TODO (Ineanto, 6/28/23): Check weirdness with error message not being translated sometimes + player.sendMessage(i18n.translate(I18NDict.Event.Disguise.FAIL, i18n.translateWithoutPrefix(actionResult.getErrorKey()))); } return Collections.singletonList(AnvilGUI.ResponseAction.close()); } diff --git a/src/main/java/xyz/atnrch/nicko/command/sub/NickoCheckSubCmd.java b/src/main/java/xyz/atnrch/nicko/command/sub/NickoCheckSubCmd.java index 438b5e8..451677f 100644 --- a/src/main/java/xyz/atnrch/nicko/command/sub/NickoCheckSubCmd.java +++ b/src/main/java/xyz/atnrch/nicko/command/sub/NickoCheckSubCmd.java @@ -14,10 +14,11 @@ 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(player, I18NDict.Error.INVALID_USERNAME)); + player.sendMessage(i18n.translate(I18NDict.Error.INVALID_USERNAME)); return; } @@ -28,15 +29,16 @@ public class NickoCheckSubCmd { } final StringJoiner builder = new StringJoiner("\n"); - builder.add("§c" + NickoBukkit.getInstance().getNickoConfig().getPrefix() + "§6Check for: §f§o" + targetName); - if (!appearanceManager.hasData()) { - builder.add("§cThis player has not data."); + 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("§7- §fNicked: §a✔"); - builder.add("§7- §fName: §6" + appearanceManager.getName()); - builder.add("§7- §fSkin: §6" + appearanceManager.getSkin()); + 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/disguise/ActionResult.java b/src/main/java/xyz/atnrch/nicko/disguise/ActionResult.java index 0e84447..7906963 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/ActionResult.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/ActionResult.java @@ -1,24 +1,22 @@ package xyz.atnrch.nicko.disguise; -import xyz.atnrch.nicko.i18n.I18NDict; - public class ActionResult { - private final I18NDict errorMessage; + private final String errorKey; private boolean error = false; private R result; public ActionResult() { - this.errorMessage = null; + this.errorKey = null; } - public ActionResult(I18NDict errorMessage) { - this.errorMessage = errorMessage; + public ActionResult(String errorMessage) { + this.errorKey = errorMessage; this.error = true; this.result = null; } public ActionResult(R result) { - this.errorMessage = null; + this.errorKey = null; this.result = result; } @@ -30,7 +28,7 @@ public class ActionResult { return error; } - public I18NDict getErrorMessage() { - return errorMessage; + public String getErrorKey() { + return errorKey; } } diff --git a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java index 282b3f5..6ad5e63 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java @@ -4,6 +4,7 @@ import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.wrappers.*; import com.google.common.collect.ImmutableList; import com.google.common.collect.Multimap; +import it.unimi.dsi.fastutil.ints.IntList; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.entity.Player; @@ -14,9 +15,7 @@ import xyz.atnrch.nicko.mojang.MojangAPI; import xyz.atnrch.nicko.mojang.MojangSkin; import xyz.atnrch.nicko.storage.PlayerDataStore; import xyz.atnrch.nicko.storage.name.PlayerNameStore; -import xyz.atnrch.nicko.wrapper.WrapperPlayServerRespawn; -import xyz.atnrch.nicko.wrapper.WrapperPlayerServerPlayerInfo; -import xyz.atnrch.nicko.wrapper.WrapperPlayerServerPlayerInfoRemove; +import xyz.atnrch.nicko.wrapper.*; import java.io.IOException; import java.util.EnumSet; @@ -104,11 +103,25 @@ public class AppearanceManager { updateMetadata(); updateTabList(gameProfile, displayName); respawnPlayer(); + updateOthers(); } player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); return new ActionResult<>(); } + public void updateOthers() { + WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy(); + WrapperPlayServerNamedEntitySpawn spawn = new WrapperPlayServerNamedEntitySpawn(); + destroy.setEntityIds(IntList.of(player.getEntityId())); + spawn.setEntityId(player.getEntityId()); + spawn.setLocation(player.getLocation()); + spawn.setPlayerId(player.getUniqueId()); + Bukkit.getOnlinePlayers().stream().filter(receiver -> receiver.getUniqueId() != player.getUniqueId()).forEach(receiver -> { + destroy.sendPacket(receiver); + spawn.sendPacket(receiver); + }); + } + private ActionResult updateGameProfileSkin(WrappedGameProfile gameProfile, boolean skinChange) { final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); @@ -154,7 +167,6 @@ public class AppearanceManager { respawn.setCopyMetadata(true); respawn.sendPacket(player); player.setFlying(wasFlying); - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); player.updateInventory(); } @@ -171,13 +183,13 @@ public class AppearanceManager { EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE, EnumWrappers.PlayerInfoAction.UPDATE_LATENCY); remove.setUUIDs(ImmutableList.of(player.getUniqueId())); - remove.sendPacket(player); + remove.broadcastPacket(); add.setActions(actions); } else { final WrapperPlayerServerPlayerInfo remove = new WrapperPlayerServerPlayerInfo(); remove.setActions(EnumSet.of(EnumWrappers.PlayerInfoAction.REMOVE_PLAYER)); add.setActions(EnumSet.of(EnumWrappers.PlayerInfoAction.ADD_PLAYER)); - remove.sendPacket(player); + remove.broadcastPacket(); } // Yes, I skip providing chat session data. @@ -194,6 +206,6 @@ public class AppearanceManager { gameProfile, WrappedChatComponent.fromText(displayName) ))); - add.sendPacket(player); + add.broadcastPacket(); } } \ No newline at end of file diff --git a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java index e56372e..1d09488 100644 --- a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java @@ -10,7 +10,6 @@ import xyz.atnrch.nicko.disguise.ActionResult; import xyz.atnrch.nicko.disguise.AppearanceManager; import xyz.atnrch.nicko.i18n.I18N; import xyz.atnrch.nicko.i18n.I18NDict; -import xyz.atnrch.nicko.storage.PlayerDataStore; import xyz.atnrch.nicko.storage.name.PlayerNameStore; public class PlayerJoinListener implements Listener { @@ -18,20 +17,19 @@ public class PlayerJoinListener implements Listener { public void onPlayerJoin(PlayerJoinEvent event) { final Player player = event.getPlayer(); final NickoBukkit instance = NickoBukkit.getInstance(); - - final PlayerDataStore dataStore = instance.getDataStore(); + final I18N i18n = new I18N(player); final PlayerNameStore nameStore = instance.getNameStore(); - nameStore.storeName(player); - // TODO: 2/20/23 BungeeCord transfer + // 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()); if (!actionResult.isError()) { - player.sendMessage(I18N.translate(player, I18NDict.Event.PreviousSkin.SUCCESS)); + player.sendMessage(i18n.translate(I18NDict.Event.PreviousSkin.SUCCESS)); } else { - player.sendMessage(I18N.translate(player, I18NDict.Event.PreviousSkin.FAIL, I18N.translateWithoutPrefix(player, actionResult.getErrorMessage()))); + player.sendMessage(i18n.translate(I18NDict.Event.PreviousSkin.FAIL, i18n.translateWithoutPrefix(actionResult.getErrorKey()))); } } }, 20L); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCompleteCache.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCompleteCache.java index 5ec26d3..9fef719 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCompleteCache.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCompleteCache.java @@ -25,8 +25,9 @@ public class InvalidateCompleteCache extends SuppliedItem { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { final Player player = click.getPlayer(); + final I18N i18n = new I18N(player); click.getEvent().getView().close(); - player.sendMessage(I18N.translate(player, I18NDict.Event.Admin.CACHE_CLEAN)); + player.sendMessage(i18n.translate(I18NDict.Event.Admin.CACHE_CLEAN)); NickoBukkit.getInstance().getMojangAPI().getCache().invalidateAll(); return true; } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/main/ResetAppearance.java b/src/main/java/xyz/atnrch/nicko/gui/items/main/ResetAppearance.java index fb380ec..eeb4246 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/main/ResetAppearance.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/main/ResetAppearance.java @@ -18,21 +18,23 @@ public class ResetAppearance extends SuppliedItem { 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); if (!appearanceManager.hasData()) { - player.sendMessage(I18N.translate(player, I18NDict.Event.Undisguise.NONE)); + player.sendMessage(i18n.translate(I18NDict.Event.Undisguise.NONE)); event.getEvent().getView().close(); return true; } if (!appearanceManager.reset().isError()) { - player.sendMessage(I18N.translate(player, I18NDict.Event.Undisguise.SUCCESS)); + player.sendMessage(i18n.translate(I18NDict.Event.Undisguise.SUCCESS)); return true; } else { - player.sendMessage(I18N.translate(player, I18NDict.Event.Undisguise.FAIL)); + player.sendMessage(i18n.translate(I18NDict.Event.Undisguise.FAIL)); return false; } } diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java index 117f8c9..be3d1c7 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java @@ -11,8 +11,51 @@ import java.util.Optional; public class I18N { private final static MessageFormat formatter = new MessageFormat(""); + private final Player player; + private final Locale playerLocale; - private static Locale getLocale(Player player) { + public I18N(Player player) { + this.player = player; + this.playerLocale = getPlayerLocale(); + } + + public String translate(String key, Object... arguments) { + final NickoBukkit instance = NickoBukkit.getInstance(); + final String string = readString(key); + + try { + formatter.applyPattern(string); + return instance.getNickoConfig().getPrefix() + formatter.format(arguments); + } catch (Exception e) { + return instance.getNickoConfig().getPrefix() + key; + } + } + + public String translateWithoutPrefix(String key, Object... arguments) { + final String translation = readString(key); + try { + formatter.applyPattern(translation); + return formatter.format(arguments); + } catch (Exception e) { + return key; + } + } + + private String readString(String key) { + final NickoBukkit instance = NickoBukkit.getInstance(); + String string; + if (playerLocale == Locale.CUSTOM) { + string = instance.getLocaleFileManager().get(key); + } else { + final InputStream resource = instance.getResource(playerLocale.getCode() + ".yml"); + final YamlConfig yamlConfig = YamlConfig.load(resource); + string = yamlConfig.getString(key); + } + + return string; + } + + private Locale getPlayerLocale() { final NickoBukkit instance = NickoBukkit.getInstance(); try { final Optional profile = instance.getDataStore().getData(player.getUniqueId()); @@ -22,41 +65,4 @@ public class I18N { return Locale.FALLBACK_LOCALE; } } - - public static String translate(Player player, I18NDict key, Object... arguments) { - final NickoBukkit instance = NickoBukkit.getInstance(); - final String translation = findTranslation(player, key); - - try { - formatter.applyPattern(translation); - return instance.getNickoConfig().getPrefix() + formatter.format(arguments); - } catch (Exception e) { - return instance.getNickoConfig().getPrefix() + key.key(); - } - } - - public static String translateWithoutPrefix(Player player, I18NDict key, Object... arguments) { - final String translation = findTranslation(player, key); - try { - formatter.applyPattern(translation); - return formatter.format(arguments); - } catch (Exception e) { - return key.key(); - } - } - - private static String findTranslation(Player player, I18NDict key) { - final NickoBukkit instance = NickoBukkit.getInstance(); - final Locale locale = getLocale(player); - String translation; - if (locale == Locale.CUSTOM) { - translation = instance.getLocaleFileManager().get(key.key()); - } else { - final InputStream resource = instance.getResource(locale.getCode() + ".yml"); - final YamlConfig yamlConfig = YamlConfig.load(resource); - translation = yamlConfig.getString(key.key()); - } - - return translation; - } } diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index 6c3bd2c..894f129 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -1,44 +1,36 @@ package xyz.atnrch.nicko.i18n; public class I18NDict { - private final String key; - - public I18NDict(String key) { this.key = key; } - public static class Event { public static class Admin { - public static final I18NDict CACHE_CLEAN = new I18NDict("event.admin.cache_clear"); + public static final String CACHE_CLEAN = "event.admin.cache_clear"; } public static class Disguise { - public static final I18NDict SUCCESS = new I18NDict("event.disguise.success"); - public static final I18NDict FAIL = new I18NDict("event.disguise.fail"); + public static final String SUCCESS = "event.disguise.success"; + public static final String FAIL = "event.disguise.fail"; } public static class Undisguise { - public static final I18NDict SUCCESS = new I18NDict("event.undisguise.success"); - public static final I18NDict FAIL = new I18NDict("event.undisguise.fail"); - public static final I18NDict NONE = new I18NDict("event.undisguise.none"); + public static final String SUCCESS = "event.undisguise.success"; + public static final String FAIL = "event.undisguise.fail"; + public static final String NONE = "event.undisguise.none"; } public static class PreviousSkin { - public static final I18NDict SUCCESS = new I18NDict("event.previous_skin_applied.success"); - public static final I18NDict FAIL = new I18NDict("event.previous_skin_applied.fail"); + public static final String SUCCESS = "event.previous_skin_applied.success"; + public static final String FAIL = "event.previous_skin_applied.fail"; } } public static class Error { - public static final I18NDict PLAYER_OFFLINE = new I18NDict("error.player_offline"); - public static final I18NDict SKIN_FAIL_MOJANG = new I18NDict("error.couldnt_get_skin_from_mojang"); - public static final I18NDict SKIN_FAIL_CACHE = new I18NDict("error.couldnt_get_skin_from_cache"); - public static final I18NDict NAME_FAIL_MOJANG = new I18NDict("error.couldnt_get_name_from_mojang"); - public static final I18NDict INVALID_USERNAME = new I18NDict("error.invalid_username"); - public static final I18NDict UNEXPECTED_ERROR = new I18NDict("error.generic"); - public static final I18NDict SQL_ERROR = new I18NDict("error.sql"); - public static final I18NDict JSON_ERROR = new I18NDict("error.json"); - } - - public String key() { - return key; + public static final String UNEXPECTED_ERROR = "error.invalid_name"; + public static final String PLAYER_OFFLINE = "error.player_offline"; + public static final String SKIN_FAIL_MOJANG = "error.couldnt_get_skin_from_mojang"; + public static final String SKIN_FAIL_CACHE = "error.couldnt_get_skin_from_cache"; + public static final String NAME_FAIL_MOJANG = "error.couldnt_get_name_from_mojang"; + 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"; } } diff --git a/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java b/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java index 46eb2f1..f5689fe 100644 --- a/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java +++ b/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java @@ -73,6 +73,7 @@ public class MojangAPI { con.setRequestMethod("GET"); switch (con.getResponseCode()) { + case 404: case 400: logger.warning("Failed to parse request: Invalid Name"); return getErrorObject(); diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerEntityDestroy.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerEntityDestroy.java new file mode 100644 index 0000000..38f9067 --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerEntityDestroy.java @@ -0,0 +1,41 @@ +package xyz.atnrch.nicko.wrapper; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.Converters; +import it.unimi.dsi.fastutil.ints.IntList; + +/** + * Sent by the server to the client to remove one or more entities. + */ +public class WrapperPlayServerEntityDestroy extends AbstractPacket { + + /** + * The packet type that is wrapped by this wrapper. + */ + public static final PacketType TYPE = PacketType.Play.Server.ENTITY_DESTROY; + + public WrapperPlayServerEntityDestroy() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + /** + * Gets a list of entity ids to remove + * + * @return 'entityIds' to remove + */ + public IntList getEntityIds() { + return this.handle.getModifier().withType(IntList.class, Converters.passthrough(IntList.class)).read(0); + } + + /** + * Sets the list of entity ids to remove + * + * @param value New value for field 'entityIds' + */ + public void setEntityIds(IntList value) { + this.handle.getModifier().withType(IntList.class, Converters.passthrough(IntList.class)).write(0, value); + } + +} \ No newline at end of file diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerNamedEntitySpawn.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerNamedEntitySpawn.java new file mode 100644 index 0000000..baa5bb9 --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerNamedEntitySpawn.java @@ -0,0 +1,173 @@ +package xyz.atnrch.nicko.wrapper; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import org.bukkit.Location; +import org.bukkit.World; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.UUID; + +/** + * This packet is sent by the server when a player comes into visible range, not when a player joins. + */ +public class WrapperPlayServerNamedEntitySpawn extends AbstractPacket { + /** + * The packet type that is wrapped by this wrapper. + */ + public static final PacketType TYPE = PacketType.Play.Server.NAMED_ENTITY_SPAWN; + + /** + * Constructors a new wrapper for the specified packet + */ + public WrapperPlayServerNamedEntitySpawn() { + super(new PacketContainer(TYPE), TYPE); + handle.getModifier().writeDefaults(); + } + + /** + * Retrieves entity id of the player + * + * @return 'entityId' + */ + public int getEntityId() { + return this.handle.getIntegers().read(0); + } + + /** + * Sets the entity id of the player + * + * @param value New value for field 'entityId' + */ + public void setEntityId(int value) { + this.handle.getIntegers().write(0, value); + } + + /** + * Retrieves the unique id of the player + * + * @return 'playerId' + */ + public UUID getPlayerId() { + return this.handle.getUUIDs().read(0); + } + + /** + * Sets the unique id of the player + * + * @param value New value for field 'playerId' + */ + public void setPlayerId(UUID value) { + this.handle.getUUIDs().write(0, value); + } + + /** + * Retrieves the value of field 'x' + * + * @return 'x' + */ + public double getX() { + return this.handle.getDoubles().read(0); + } + + /** + * Sets the value of field 'x' + * + * @param value New value for field 'x' + */ + public void setX(double value) { + this.handle.getDoubles().write(0, value); + } + + /** + * Retrieves the value of field 'y' + * + * @return 'y' + */ + public double getY() { + return this.handle.getDoubles().read(1); + } + + /** + * Sets the value of field 'y' + * + * @param value New value for field 'y' + */ + public void setY(double value) { + this.handle.getDoubles().write(1, value); + } + + /** + * Retrieves the value of field 'z' + * + * @return 'z' + */ + public double getZ() { + return this.handle.getDoubles().read(2); + } + + /** + * Sets the value of field 'z' + * + * @param value New value for field 'z' + */ + public void setZ(double value) { + this.handle.getDoubles().write(2, value); + } + + /** + * Retrieves the discrete rotation around the y-axis (yaw) + * + * @return 'yRot' + */ + public byte getYRotRaw() { + return this.handle.getBytes().read(0); + } + + /** + * Sets the discrete rotation around the y-axis (yaw) + * + * @param value New value for field 'yRot' + */ + public void setYRotRaw(byte value) { + this.handle.getBytes().write(0, value); + } + + /** + * Retrieves the value of field 'xRot' + * + * @return 'xRot' + */ + public byte getXRotRaw() { + return this.handle.getBytes().read(1); + } + + /** + * Sets the discrete rotation around the x-axis (pitch) + * + * @param value New value for field 'xRot' + */ + public void setXRotRaw(byte value) { + this.handle.getBytes().write(1, value); + } + + public Location getLocation(@Nullable World world) { + return new Location(world, getX(), getY(), getZ(), angleToDegrees(getYRotRaw()), angleToDegrees(getXRotRaw())); + } + public void setLocation(@Nonnull Location location) { + setX(location.getX()); + setY(location.getY()); + setZ(location.getZ()); + setYRotRaw(degreesToAngle(location.getYaw())); + setXRotRaw(degreesToAngle(location.getPitch())); + } + + private float angleToDegrees(byte rawAngle) { + return rawAngle / 256.0F * 360.0F; + } + + private byte degreesToAngle(float degree) { + return (byte)((int)(degree * 256.0F / 360.0F)); + } +} \ No newline at end of file diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 3d65290..a0d4833 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -1,5 +1,5 @@ error: - couldnt_get_name_from_mojang: "Unable to get username from Mojang." + invalid_name: "Unable to get username from Mojang." couldnt_get_skin_from_cache: "Unable to get skin from the cache." couldnt_get_skin_from_mojang: "Unable to get skin from Mojang." generic: "Unknown error" From 7eacc92a22ca9445909b4ab3a16b447de5b163b9 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 28 Jun 2023 23:23:34 +0200 Subject: [PATCH 042/296] remove logs --- logs/2023-06-28-1.log.gz | Bin 124 -> 0 bytes logs/2023-06-28-2.log.gz | Bin 125 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 logs/2023-06-28-1.log.gz delete mode 100644 logs/2023-06-28-2.log.gz diff --git a/logs/2023-06-28-1.log.gz b/logs/2023-06-28-1.log.gz deleted file mode 100644 index 1423f84a184c8e6794848391df87a61973b73d93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124 zcmV-?0E7P@iwFP!00000{{_J@4#F@D1<;*S{4FpL?1+fU6CGHK#KKT@sG5K>G(k2M z*XO-41c^}sPZ-y^)YG$n43prd+El=Fj>pguk)U6eY=)F;$qBEf*eolYw)S;b$Cu!_ e^W@oKzgekod}gy>(ehF diff --git a/logs/2023-06-28-2.log.gz b/logs/2023-06-28-2.log.gz deleted file mode 100644 index fe90cdd29d98b08a6a824c9cedf43de2c97a67c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 125 zcmV-@0D}J?iwFP!00000{{_LZ4uUWc2H@SN__yLx}8W Date: Thu, 29 Jun 2023 11:06:54 +0200 Subject: [PATCH 043/296] refactor(i18n): unnecessary static field --- src/main/java/xyz/atnrch/nicko/i18n/I18N.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java index be3d1c7..84fb429 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java @@ -10,7 +10,7 @@ import java.text.MessageFormat; import java.util.Optional; public class I18N { - private final static MessageFormat formatter = new MessageFormat(""); + private final MessageFormat formatter = new MessageFormat(""); private final Player player; private final Locale playerLocale; From 02e03794e4c42b0e7e55fc0f500b674a3344d7b2 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 29 Jun 2023 11:13:16 +0200 Subject: [PATCH 044/296] refactor(i18n): shorter keys --- .../xyz/atnrch/nicko/disguise/AppearanceManager.java | 4 ++-- src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java | 10 +++++----- .../java/xyz/atnrch/nicko/storage/PlayerDataStore.java | 6 +++--- src/main/resources/en.yml | 8 ++++---- src/main/resources/fr.yml | 10 +++++----- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java index 6ad5e63..8522c8a 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java @@ -142,9 +142,9 @@ public class AppearanceManager { } return new ActionResult<>(); } catch (ExecutionException e) { - return new ActionResult<>(I18NDict.Error.SKIN_FAIL_CACHE); + return new ActionResult<>(I18NDict.Error.CACHE); } catch (IOException e) { - return new ActionResult<>(I18NDict.Error.NAME_FAIL_MOJANG); + return new ActionResult<>(I18NDict.Error.MOJANG_NAME); } } return new ActionResult<>(); diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index 894f129..3c40364 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -24,11 +24,11 @@ public class I18NDict { } public static class Error { - public static final String UNEXPECTED_ERROR = "error.invalid_name"; - public static final String PLAYER_OFFLINE = "error.player_offline"; - public static final String SKIN_FAIL_MOJANG = "error.couldnt_get_skin_from_mojang"; - public static final String SKIN_FAIL_CACHE = "error.couldnt_get_skin_from_cache"; - public static final String NAME_FAIL_MOJANG = "error.couldnt_get_name_from_mojang"; + public static final String GENERIC = "error.generic"; + public static final String PLAYER_OFFLINE = "error.offline"; + 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"; diff --git a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java index b3e67f1..2cceb9f 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java +++ b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java @@ -63,10 +63,10 @@ public class PlayerDataStore { } public ActionResult saveData(Player player) { - if (storage.isError()) return new ActionResult<>(I18NDict.Error.UNEXPECTED_ERROR); - if (!cache.isCached(player.getUniqueId())) return new ActionResult<>(I18NDict.Error.UNEXPECTED_ERROR); + if (storage.isError()) return new ActionResult<>(I18NDict.Error.GENERIC); + if (!cache.isCached(player.getUniqueId())) return new ActionResult<>(I18NDict.Error.GENERIC); if (!cache.retrieve(player.getUniqueId()).isPresent()) - return new ActionResult<>(I18NDict.Error.UNEXPECTED_ERROR); + return new ActionResult<>(I18NDict.Error.GENERIC); // TODO (Ineanto, 5/20/23): Remove value from cache //profiles.remove(player.getUniqueId()); diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index a0d4833..ac2de53 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -1,10 +1,10 @@ error: - invalid_name: "Unable to get username from Mojang." - couldnt_get_skin_from_cache: "Unable to get skin from the cache." - couldnt_get_skin_from_mojang: "Unable to get skin from Mojang." generic: "Unknown error" invalid_username: "§cThis is not a valid Minecraft username." - player_offline: "§c{0} §fis offline!" + mojang_name: "Unable to get username from Mojang." + mojang_skin: "Unable to get skin from Mojang." + offline: "§c{0} §fis offline!" + cache: "Unable to get skin from the cache." sql: "SQL Error" json: "JSON Error" event: diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index ee50336..4471e6c 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -1,10 +1,10 @@ error: - couldnt_get_name_from_mojang: "Impossible de récupérer le nom d''utilisateur depuis Mojang." - couldnt_get_skin_from_cache: "Impossible de récupérer le skin depuis le cache." - couldnt_get_skin_from_mojang: "Impossible de récupérer le skin depuis Mojang." - generic: "Erreur inconnue" + generic: Erreur inconnue" invalid_username: "§cLe pseudo n''est pas un pseudo Minecraft valide." - player_offline: "§c{0} §fest hors-ligne!." + mojang_name: "Impossible de récupérer le nom d''utilisateur depuis Mojang." + mojang_skin: "Impossible de récupérer le skin depuis Mojang." + offline: "§c{0} §fest hors-ligne!" + cache: "Impossible de récupérer le skin depuis le cache." sql: "Erreur SQL" json: "Erreur JSON" event: From 3ec2e7a584ed242d05286054a824275afbd2de47 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 29 Jun 2023 11:13:40 +0200 Subject: [PATCH 045/296] fix(wrapper): packets are final --- .../java/xyz/atnrch/nicko/disguise/AppearanceManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java index 8522c8a..2f40ae2 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java @@ -110,8 +110,8 @@ public class AppearanceManager { } public void updateOthers() { - WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy(); - WrapperPlayServerNamedEntitySpawn spawn = new WrapperPlayServerNamedEntitySpawn(); + final WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy(); + final WrapperPlayServerNamedEntitySpawn spawn = new WrapperPlayServerNamedEntitySpawn(); destroy.setEntityIds(IntList.of(player.getEntityId())); spawn.setEntityId(player.getEntityId()); spawn.setLocation(player.getLocation()); From 15b02ff390f4040ef1b3e06920596ccf40214b34 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 29 Jun 2023 11:14:46 +0200 Subject: [PATCH 046/296] refactor(disguise): update player after disguise --- .../java/xyz/atnrch/nicko/disguise/AppearanceManager.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java index 2f40ae2..475fbb6 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java @@ -99,6 +99,7 @@ public class AppearanceManager { final WrappedGameProfile gameProfile = WrappedGameProfile.fromPlayer(player).withName(displayName); final ActionResult result = updateGameProfileSkin(gameProfile, skinChange); + final boolean wasFlying = player.isFlying(); if (!result.isError()) { updateMetadata(); updateTabList(gameProfile, displayName); @@ -106,6 +107,8 @@ public class AppearanceManager { updateOthers(); } player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); + player.setFlying(wasFlying); + player.updateInventory(); return new ActionResult<>(); } @@ -157,7 +160,6 @@ public class AppearanceManager { private void respawnPlayer() { final World world = player.getWorld(); - final boolean wasFlying = player.isFlying(); final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(); respawn.setDimension(world); respawn.setSeed(world.getSeed()); @@ -166,8 +168,6 @@ public class AppearanceManager { respawn.setDifficulty(world.getDifficulty()); respawn.setCopyMetadata(true); respawn.sendPacket(player); - player.setFlying(wasFlying); - player.updateInventory(); } @SuppressWarnings("deprecation") From 51ab123eaf323d783c55c0e7f129ba7f2988d032 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 29 Jun 2023 11:42:37 +0200 Subject: [PATCH 047/296] feat: throw error skin not found --- src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java index 475fbb6..a8c4645 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java @@ -141,6 +141,8 @@ public class AppearanceManager { final Multimap properties = gameProfile.getProperties(); properties.get("textures").clear(); properties.put("textures", new WrappedSignedProperty("textures", skinResult.getValue(), skinResult.getSignature())); + } else { + return new ActionResult<>(I18NDict.Error.MOJANG_SKIN); } } return new ActionResult<>(); From 82c210459e5090d18b4cdaef3d887eacc8cb7807 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 29 Jun 2023 11:55:02 +0200 Subject: [PATCH 048/296] style: space --- .../xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java index 32d6f07..432019c 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java @@ -15,7 +15,6 @@ import java.util.Set; * * @author ineanto, based on work from dmulloy2 and Kristian S. Strangeland */ - public class WrapperPlayerServerPlayerInfo extends AbstractPacket { public static final PacketType TYPE = PacketType.Play.Server.PLAYER_INFO; From 5cf35e5b9836477aa354b05f75ce006259c3927d Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 29 Jun 2023 12:20:19 +0200 Subject: [PATCH 049/296] refactor(placeholder): streamline --- .../java/xyz/atnrch/nicko/NickoBukkit.java | 7 +++++-- .../nicko/placeholder/PlaceHolderHook.java | 19 ------------------- 2 files changed, 5 insertions(+), 21 deletions(-) delete mode 100644 src/main/java/xyz/atnrch/nicko/placeholder/PlaceHolderHook.java diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index 4b13b40..c3f67cc 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -18,7 +18,7 @@ import xyz.atnrch.nicko.gui.items.main.ExitGUI; import xyz.atnrch.nicko.i18n.Locale; import xyz.atnrch.nicko.i18n.LocaleFileManager; import xyz.atnrch.nicko.mojang.MojangAPI; -import xyz.atnrch.nicko.placeholder.PlaceHolderHook; +import xyz.atnrch.nicko.placeholder.NickoExpansion; import xyz.atnrch.nicko.storage.PlayerDataStore; import xyz.atnrch.nicko.storage.name.PlayerNameStore; import xyz.xenondevs.invui.gui.structure.Structure; @@ -105,7 +105,10 @@ public class NickoBukkit extends JavaPlugin { Structure.addGlobalIngredient('U', new OptionUnavailable()); Structure.addGlobalIngredient('E', new ExitGUI()); - new PlaceHolderHook(this).hook(); + if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { + getLogger().info("Enabling PlaceHolderAPI support..."); + new NickoExpansion(this).register(); + } getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this); getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this); diff --git a/src/main/java/xyz/atnrch/nicko/placeholder/PlaceHolderHook.java b/src/main/java/xyz/atnrch/nicko/placeholder/PlaceHolderHook.java deleted file mode 100644 index b2900df..0000000 --- a/src/main/java/xyz/atnrch/nicko/placeholder/PlaceHolderHook.java +++ /dev/null @@ -1,19 +0,0 @@ -package xyz.atnrch.nicko.placeholder; - -import xyz.atnrch.nicko.NickoBukkit; -import org.bukkit.Bukkit; - -public class PlaceHolderHook { - private final NickoBukkit instance; - - public PlaceHolderHook(NickoBukkit instance) { - this.instance = instance; - } - - public void hook() { - if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { - instance.getLogger().info("Enabling PlaceHolderAPI support..."); - new NickoExpansion(instance).register(); - } - } -} From de9904df529aa79e88892ad2ed3ef3c88c6f123d Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 29 Jun 2023 12:23:40 +0200 Subject: [PATCH 050/296] refactor(placeholder): update author --- src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java b/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java index 02a4cf7..e7d5fc6 100644 --- a/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java +++ b/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java @@ -24,7 +24,7 @@ public class NickoExpansion extends PlaceholderExpansion { @Override public @NotNull String getAuthor() { - return "Aro"; + return "Ineanto"; } @Override From c6f037a24dc3f148ff00836b379f87eed45839bc Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 1 Jul 2023 17:35:46 +0200 Subject: [PATCH 051/296] style: gui adjustements --- src/main/java/xyz/atnrch/nicko/NickoBukkit.java | 8 +------- .../atnrch/nicko/gui/admin/CacheManagementGUI.java | 6 +++++- .../nicko/gui/admin/cache/CacheDetailedGUI.java | 14 +++++++------- .../gui/items/admin/cache/EntryPlaceholder.java | 11 +++++++++++ 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index c3f67cc..61c9618 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -1,7 +1,5 @@ package xyz.atnrch.nicko; -import com.comphenix.protocol.ProtocolLibrary; -import com.comphenix.protocol.ProtocolManager; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.command.PluginCommand; @@ -39,7 +37,6 @@ public class NickoBukkit extends JavaPlugin { private Configuration configuration; private LocaleFileManager localeFileManager; private PlayerNameStore nameStore; - private ProtocolManager protocolManager; public NickoBukkit() { this.unitTesting = false; } @@ -83,7 +80,6 @@ public class NickoBukkit extends JavaPlugin { } if (!unitTesting) { - protocolManager = ProtocolLibrary.getProtocolManager(); localeFileManager = new LocaleFileManager(); if (configuration.isCustomLocale()) { if (localeFileManager.dumpFromLocale(Locale.ENGLISH)) { @@ -98,10 +94,8 @@ public class NickoBukkit extends JavaPlugin { command.setExecutor(new NickoCommand()); } - //new SimpleItem(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setDisplayName(" ")) - //new SimpleItem(new ItemBuilder(Material.ORANGE_STAINED_GLASS_PANE).setDisplayName(" ")) Structure.addGlobalIngredient('#', new SimpleItem(new ItemBuilder(Material.AIR))); - Structure.addGlobalIngredient('%', new SimpleItem(new ItemBuilder(Material.AIR))); + Structure.addGlobalIngredient('%', new SimpleItem(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setDisplayName(" "))); Structure.addGlobalIngredient('U', new OptionUnavailable()); Structure.addGlobalIngredient('E', new ExitGUI()); diff --git a/src/main/java/xyz/atnrch/nicko/gui/admin/CacheManagementGUI.java b/src/main/java/xyz/atnrch/nicko/gui/admin/CacheManagementGUI.java index 1a3bd13..298e622 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/admin/CacheManagementGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/admin/CacheManagementGUI.java @@ -17,7 +17,11 @@ public class CacheManagementGUI { public CacheManagementGUI(Player player) { final AdminGUI parent = new AdminGUI(player); this.gui = Gui.normal() - .setStructure("B # S A D") + .setStructure( + "# # # # # # # # #", + "# # # S A D # # #", + "B # # # # # # # #" + ) .addIngredient('B', new GoBack(parent.getGUI(), parent.getTitle())) .addIngredient('S', new CacheOverview()) .addIngredient('A', new InvalidateCompleteCache()) diff --git a/src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java b/src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java index 003e18b..901d479 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java @@ -22,7 +22,7 @@ import java.util.stream.Collectors; public class CacheDetailedGUI { public static final String TITLE = "... > Cache > Invalidate"; - + private final Player player; private final Gui gui; @@ -40,12 +40,12 @@ public class CacheDetailedGUI { final CacheManagementGUI parent = new CacheManagementGUI(player); gui = ScrollGui.items(guiItemBuilder -> { guiItemBuilder.setStructure( - "# # # # # # # # #", - "# x x x x x x U #", - "# x x x x x x # #", - "# x x x x x x # #", - "# x x x x x x D #", - "B # # # # # # # #"); + "x x x x x x x x U", + "x x x x x x x x #", + "x x x x x x x x #", + "x x x x x x x x #", + "x x x x x x x x D", + "B % % % % % % % %"); guiItemBuilder.addIngredient('x', Markers.CONTENT_LIST_SLOT_HORIZONTAL); guiItemBuilder.addIngredient('U', new ScrollUp()); guiItemBuilder.addIngredient('D', new ScrollDown()); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/EntryPlaceholder.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/EntryPlaceholder.java index 10b8c32..077321f 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/EntryPlaceholder.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/EntryPlaceholder.java @@ -1,6 +1,10 @@ package xyz.atnrch.nicko.gui.items.admin.cache; 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.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.builder.SkullBuilder; import xyz.xenondevs.invui.item.impl.AsyncItem; @@ -18,4 +22,11 @@ public class EntryPlaceholder extends AsyncItem { return skull; }); } + + @Override + public void handleClick(@NotNull ClickType click, @NotNull Player player, @NotNull InventoryClickEvent event) { + if (click.isLeftClick() || click.isRightClick()) { + event.getView().close(); + } + } } From 18d73224067a2a205f04f582307cbe2b7e53aa57 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 1 Jul 2023 17:55:53 +0200 Subject: [PATCH 052/296] feat: don't cache reset skin --- .../xyz/atnrch/nicko/disguise/AppearanceManager.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java index a8c4645..839aeb9 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java @@ -79,14 +79,14 @@ public class AppearanceManager { public void setNameAndSkin(String name, String skin) { this.profile.setName(name); this.profile.setSkin(skin); - updatePlayer(true); + updatePlayer(true, false); } public ActionResult reset() { final String defaultName = nameStore.getStoredName(player); this.profile.setName(defaultName); this.profile.setSkin(defaultName); - final ActionResult actionResult = updatePlayer(true); + final ActionResult actionResult = updatePlayer(true, true); if (!actionResult.isError()) { this.profile.setSkin(null); this.profile.setName(null); @@ -94,11 +94,11 @@ public class AppearanceManager { return actionResult; } - public ActionResult updatePlayer(boolean skinChange) { + public ActionResult updatePlayer(boolean skinChange, boolean reset) { final String displayName = profile.getName() == null ? player.getName() : profile.getName(); final WrappedGameProfile gameProfile = WrappedGameProfile.fromPlayer(player).withName(displayName); - final ActionResult result = updateGameProfileSkin(gameProfile, skinChange); + final ActionResult result = updateGameProfileSkin(gameProfile, skinChange, reset); final boolean wasFlying = player.isFlying(); if (!result.isError()) { updateMetadata(); @@ -126,7 +126,7 @@ public class AppearanceManager { } - private ActionResult updateGameProfileSkin(WrappedGameProfile gameProfile, boolean skinChange) { + private ActionResult updateGameProfileSkin(WrappedGameProfile gameProfile, boolean skinChange, boolean reset) { final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); if (skinChange || changeOnlyName) { @@ -135,7 +135,7 @@ public class AppearanceManager { final MojangAPI mojang = NickoBukkit.getInstance().getMojangAPI(); final Optional uuid = mojang.getUUID(profile.getSkin()); if (uuid.isPresent()) { - skin = mojang.getSkin(uuid.get()); + skin = reset ? mojang.getSkinWithoutCaching(uuid.get()) : mojang.getSkin(uuid.get()); if (skin.isPresent()) { final MojangSkin skinResult = skin.get(); final Multimap properties = gameProfile.getProperties(); From a91d039dd268711803eebc2140afb96d768e2c38 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 1 Jul 2023 18:01:58 +0200 Subject: [PATCH 053/296] refactor: remove generic from actionresult --- .../atnrch/nicko/disguise/ActionResult.java | 25 ++++++++----------- .../nicko/disguise/AppearanceManager.java | 22 ++++++++-------- .../nicko/event/PlayerJoinListener.java | 2 +- .../nicko/event/PlayerQuitListener.java | 2 +- .../java/xyz/atnrch/nicko/storage/Cache.java | 2 +- .../atnrch/nicko/storage/PlayerDataStore.java | 8 +++--- .../xyz/atnrch/nicko/storage/Storage.java | 2 +- .../nicko/storage/json/JSONStorage.java | 8 +++--- .../atnrch/nicko/storage/map/MapCache.java | 4 +-- .../nicko/storage/redis/RedisCache.java | 4 +-- .../atnrch/nicko/storage/sql/SQLStorage.java | 8 +++--- 11 files changed, 42 insertions(+), 45 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/disguise/ActionResult.java b/src/main/java/xyz/atnrch/nicko/disguise/ActionResult.java index 7906963..a3ed415 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/ActionResult.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/ActionResult.java @@ -1,27 +1,24 @@ package xyz.atnrch.nicko.disguise; -public class ActionResult { +public class ActionResult { private final String errorKey; private boolean error = false; - private R result; - public ActionResult() { + public static ActionResult ok() { + return new ActionResult(); + } + + public static ActionResult error(String errorMessage) { + return new ActionResult(errorMessage); + } + + private ActionResult() { this.errorKey = null; } - public ActionResult(String errorMessage) { + private ActionResult(String errorMessage) { this.errorKey = errorMessage; this.error = true; - this.result = null; - } - - public ActionResult(R result) { - this.errorKey = null; - this.result = result; - } - - public R getResult() { - return result; } public boolean isError() { diff --git a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java index 839aeb9..ca541a2 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java @@ -82,11 +82,11 @@ public class AppearanceManager { updatePlayer(true, false); } - public ActionResult reset() { + public ActionResult reset() { final String defaultName = nameStore.getStoredName(player); this.profile.setName(defaultName); this.profile.setSkin(defaultName); - final ActionResult actionResult = updatePlayer(true, true); + final ActionResult actionResult = updatePlayer(true, true); if (!actionResult.isError()) { this.profile.setSkin(null); this.profile.setName(null); @@ -94,11 +94,11 @@ public class AppearanceManager { return actionResult; } - public ActionResult updatePlayer(boolean skinChange, boolean reset) { + public ActionResult updatePlayer(boolean skinChange, boolean reset) { 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); + final ActionResult result = updateGameProfileSkin(gameProfile, skinChange, reset); final boolean wasFlying = player.isFlying(); if (!result.isError()) { updateMetadata(); @@ -109,7 +109,7 @@ public class AppearanceManager { player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); player.setFlying(wasFlying); player.updateInventory(); - return new ActionResult<>(); + return ActionResult.ok(); } public void updateOthers() { @@ -126,7 +126,7 @@ public class AppearanceManager { } - private ActionResult updateGameProfileSkin(WrappedGameProfile gameProfile, boolean skinChange, boolean reset) { + private ActionResult updateGameProfileSkin(WrappedGameProfile gameProfile, boolean skinChange, boolean reset) { final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); if (skinChange || changeOnlyName) { @@ -142,17 +142,17 @@ public class AppearanceManager { properties.get("textures").clear(); properties.put("textures", new WrappedSignedProperty("textures", skinResult.getValue(), skinResult.getSignature())); } else { - return new ActionResult<>(I18NDict.Error.MOJANG_SKIN); + return ActionResult.error(I18NDict.Error.MOJANG_SKIN); } } - return new ActionResult<>(); + return ActionResult.ok(); } catch (ExecutionException e) { - return new ActionResult<>(I18NDict.Error.CACHE); + return ActionResult.error(I18NDict.Error.CACHE); } catch (IOException e) { - return new ActionResult<>(I18NDict.Error.MOJANG_NAME); + return ActionResult.error(I18NDict.Error.MOJANG_NAME); } } - return new ActionResult<>(); + return ActionResult.ok(); } private void updateMetadata() { diff --git a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java index 1d09488..c2a05a3 100644 --- a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java @@ -25,7 +25,7 @@ public class PlayerJoinListener implements Listener { Bukkit.getScheduler().runTaskLater(instance, () -> { final AppearanceManager appearanceManager = AppearanceManager.get(player); if (appearanceManager.hasData()) { - final ActionResult actionResult = appearanceManager.updatePlayer(appearanceManager.needsASkinChange()); + final ActionResult actionResult = appearanceManager.updatePlayer(appearanceManager.needsASkinChange(), true); if (!actionResult.isError()) { player.sendMessage(i18n.translate(I18NDict.Event.PreviousSkin.SUCCESS)); } else { diff --git a/src/main/java/xyz/atnrch/nicko/event/PlayerQuitListener.java b/src/main/java/xyz/atnrch/nicko/event/PlayerQuitListener.java index 3f89078..20fa8d5 100644 --- a/src/main/java/xyz/atnrch/nicko/event/PlayerQuitListener.java +++ b/src/main/java/xyz/atnrch/nicko/event/PlayerQuitListener.java @@ -11,7 +11,7 @@ public class PlayerQuitListener implements Listener { @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { final Player player = event.getPlayer(); - final ActionResult result = NickoBukkit.getInstance().getDataStore().saveData(player); + final ActionResult result = NickoBukkit.getInstance().getDataStore().saveData(player); if (result.isError()) { NickoBukkit.getInstance().getLogger().warning("Failed to save data for " + player.getName()); } diff --git a/src/main/java/xyz/atnrch/nicko/storage/Cache.java b/src/main/java/xyz/atnrch/nicko/storage/Cache.java index 7b818ae..65b8000 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/Cache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/Cache.java @@ -11,7 +11,7 @@ public abstract class Cache { public abstract CacheProvider getProvider(); - public abstract ActionResult cache(UUID uuid, NickoProfile profile); + public abstract ActionResult cache(UUID uuid, NickoProfile profile); public abstract boolean isCached(UUID uuid); diff --git a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java index 2cceb9f..640816a 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java +++ b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java @@ -62,11 +62,11 @@ public class PlayerDataStore { } } - public ActionResult saveData(Player player) { - if (storage.isError()) return new ActionResult<>(I18NDict.Error.GENERIC); - if (!cache.isCached(player.getUniqueId())) return new ActionResult<>(I18NDict.Error.GENERIC); + public ActionResult saveData(Player player) { + if (storage.isError()) return ActionResult.error(I18NDict.Error.GENERIC); + if (!cache.isCached(player.getUniqueId())) return ActionResult.error(I18NDict.Error.GENERIC); if (!cache.retrieve(player.getUniqueId()).isPresent()) - return new ActionResult<>(I18NDict.Error.GENERIC); + return ActionResult.error(I18NDict.Error.GENERIC); // TODO (Ineanto, 5/20/23): Remove value from cache //profiles.remove(player.getUniqueId()); diff --git a/src/main/java/xyz/atnrch/nicko/storage/Storage.java b/src/main/java/xyz/atnrch/nicko/storage/Storage.java index 830721b..d50970f 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/Storage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/Storage.java @@ -11,7 +11,7 @@ public abstract class Storage { public abstract StorageProvider getProvider(); - public abstract ActionResult store(UUID uuid, NickoProfile profile); + public abstract ActionResult store(UUID uuid, NickoProfile profile); public abstract boolean isStored(UUID uuid); diff --git a/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java b/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java index cdd7537..00763e8 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java @@ -30,7 +30,7 @@ public class JSONStorage extends Storage { } @Override - public ActionResult store(UUID uuid, NickoProfile profile) { + public ActionResult store(UUID uuid, NickoProfile profile) { final String profileToJson = gson.toJson(profile); final File file = new File(directory, uuid.toString() + ".json"); @@ -42,15 +42,15 @@ public class JSONStorage extends Storage { } } catch (IOException e) { logger.warning("Could not write to file."); - return new ActionResult<>(I18NDict.Error.JSON_ERROR); + return ActionResult.error(I18NDict.Error.JSON_ERROR); } } } catch (IOException e) { logger.warning("Could not create file."); - return new ActionResult<>(I18NDict.Error.JSON_ERROR); + return ActionResult.error(I18NDict.Error.JSON_ERROR); } - return new ActionResult<>(); + return ActionResult.ok(); } @Override diff --git a/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java b/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java index 5bca4cf..a913ee6 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java @@ -21,10 +21,10 @@ public class MapCache extends Cache { } @Override - public ActionResult cache(UUID uuid, NickoProfile profile) { + public ActionResult cache(UUID uuid, NickoProfile profile) { final HashMap profiles = provider.getMap(); profiles.put(uuid, profile); - return new ActionResult<>(); + return ActionResult.ok(); } @Override 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 68482e8..19e4924 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java @@ -34,10 +34,10 @@ public class RedisCache extends Cache { } @Override - public ActionResult cache(UUID uuid, NickoProfile profile) { + public ActionResult cache(UUID uuid, NickoProfile profile) { final Jedis jedis = provider.getJedis(); jedis.set("nicko:" + uuid.toString(), gson.toJson(profile)); - return new ActionResult<>(); + return ActionResult.ok(); } @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 87e03e8..069b040 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java @@ -36,18 +36,18 @@ public class SQLStorage extends Storage { } @Override - public ActionResult store(UUID uuid, NickoProfile profile) { + public ActionResult store(UUID uuid, NickoProfile profile) { final Connection connection = getProvider().getConnection(); - if (connection == null) return new ActionResult<>(I18NDict.Error.SQL_ERROR); + if (connection == null) return ActionResult.error(I18NDict.Error.SQL_ERROR); try { final PreparedStatement statement = isStored(uuid) ? getUpdateStatement(connection, uuid, profile) : getInsertStatement(connection, uuid, profile); statement.executeUpdate(); - return new ActionResult<>(); + return ActionResult.ok(); } catch (SQLException e) { logger.warning("Couldn't send SQL Request: " + e.getMessage()); - return new ActionResult<>(I18NDict.Error.SQL_ERROR); + return ActionResult.error(I18NDict.Error.SQL_ERROR); } } From f419f62f6c5ae7b6f71e3ed240489b2354fc1cda Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 1 Jul 2023 18:03:43 +0200 Subject: [PATCH 054/296] refactor: missed some more actionresults --- logs/2023-07-01-1.log.gz | Bin 0 -> 124 bytes .../java/xyz/atnrch/nicko/anvil/AnvilManager.java | 6 +++--- .../atnrch/nicko/event/PlayerJoinListener.java | 2 +- .../atnrch/nicko/test/storage/BrokenSQLTest.java | 2 +- .../atnrch/nicko/test/storage/SQLStorageTest.java | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 logs/2023-07-01-1.log.gz diff --git a/logs/2023-07-01-1.log.gz b/logs/2023-07-01-1.log.gz new file mode 100644 index 0000000000000000000000000000000000000000..7245b8e0a8b2d01e0b5aa458a73c2859163d3c15 GIT binary patch literal 124 zcmV-?0E7P@iwFP!00000{{_LZ4uUWc2H@SN__yL)bA literal 0 HcmV?d00001 diff --git a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java index 66f9611..b8610da 100644 --- a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java @@ -67,7 +67,7 @@ public class AnvilManager { return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); } else { appearanceManager.setName(snapshot.getText()); - final ActionResult actionResult = appearanceManager.updatePlayer(false); + final ActionResult actionResult = appearanceManager.updatePlayer(false, false); return sendResultAndClose(actionResult); } } @@ -87,7 +87,7 @@ public class AnvilManager { return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); } else { appearanceManager.setSkin(snapshot.getText()); - final ActionResult actionResult = appearanceManager.updatePlayer(true); + final ActionResult actionResult = appearanceManager.updatePlayer(true, false); return sendResultAndClose(actionResult); } } @@ -96,7 +96,7 @@ public class AnvilManager { .text("New skin..."); } - private List sendResultAndClose(ActionResult actionResult) { + private List sendResultAndClose(ActionResult actionResult) { final I18N i18n = new I18N(player); if (!actionResult.isError()) { player.sendMessage(i18n.translate(I18NDict.Event.Disguise.SUCCESS)); diff --git a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java index c2a05a3..cf21834 100644 --- a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java @@ -25,7 +25,7 @@ public class PlayerJoinListener implements Listener { Bukkit.getScheduler().runTaskLater(instance, () -> { final AppearanceManager appearanceManager = AppearanceManager.get(player); if (appearanceManager.hasData()) { - final ActionResult actionResult = appearanceManager.updatePlayer(appearanceManager.needsASkinChange(), true); + final ActionResult actionResult = appearanceManager.updatePlayer(appearanceManager.needsASkinChange(), false); if (!actionResult.isError()) { player.sendMessage(i18n.translate(I18NDict.Event.PreviousSkin.SUCCESS)); } else { diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java index 4f204f4..ac19e25 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java @@ -43,7 +43,7 @@ public class BrokenSQLTest { public void storePlayer() { final Optional optionalProfile = plugin.getDataStore().getData(player.getUniqueId()); assertFalse(optionalProfile.isPresent()); - ActionResult result = plugin.getDataStore().saveData(player); + ActionResult result = plugin.getDataStore().saveData(player); assertTrue(result.isError()); } 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 c6c9380..ba05003 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java @@ -75,7 +75,7 @@ public class SQLStorageTest { profile.setLocale(Locale.FRENCH); profile.setBungeecordTransfer(false); - final ActionResult result = plugin.getDataStore().saveData(player); + final ActionResult result = plugin.getDataStore().saveData(player); assertFalse(result.isError()); final Optional optionalUpdatedProfile = plugin.getDataStore().getData(player.getUniqueId()); @@ -99,7 +99,7 @@ public class SQLStorageTest { profile.setName(null); profile.setSkin(null); - final ActionResult result = plugin.getDataStore().saveData(player); + final ActionResult result = plugin.getDataStore().saveData(player); assertFalse(result.isError()); final Optional optionalUpdatedProfile = plugin.getDataStore().getData(player.getUniqueId()); From 4fa7082bf5754d43a6e9eb28798c8fffe49e7831 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 1 Jul 2023 18:04:25 +0200 Subject: [PATCH 055/296] build: ignore build logs --- .gitignore | 5 ++++- logs/2023-07-01-1.log.gz | Bin 124 -> 0 bytes 2 files changed, 4 insertions(+), 1 deletion(-) delete mode 100644 logs/2023-07-01-1.log.gz diff --git a/.gitignore b/.gitignore index 7055fba..2b2c724 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,7 @@ replay_pid* target # Maven Dependency Reduced Pom -dependency-reduced-pom.xml \ No newline at end of file +dependency-reduced-pom.xml + +# Logs +logs/ \ No newline at end of file diff --git a/logs/2023-07-01-1.log.gz b/logs/2023-07-01-1.log.gz deleted file mode 100644 index 7245b8e0a8b2d01e0b5aa458a73c2859163d3c15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124 zcmV-?0E7P@iwFP!00000{{_LZ4uUWc2H@SN__yL)bA From c8c55611a0f050e1d95ee8cc8f0704079dcc702d Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 1 Jul 2023 18:30:24 +0200 Subject: [PATCH 056/296] fix: mojangapi returns --- .../nicko/command/sub/NickoDebugSubCmd.java | 23 +++++++++++++++---- .../nicko/disguise/AppearanceManager.java | 11 +++++---- .../xyz/atnrch/nicko/mojang/MojangAPI.java | 2 +- src/main/resources/en.yml | 4 ++-- src/main/resources/fr.yml | 4 ++-- 5 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/command/sub/NickoDebugSubCmd.java b/src/main/java/xyz/atnrch/nicko/command/sub/NickoDebugSubCmd.java index c416898..aac6b71 100644 --- a/src/main/java/xyz/atnrch/nicko/command/sub/NickoDebugSubCmd.java +++ b/src/main/java/xyz/atnrch/nicko/command/sub/NickoDebugSubCmd.java @@ -1,7 +1,9 @@ package xyz.atnrch.nicko.command.sub; import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.disguise.ActionResult; import xyz.atnrch.nicko.disguise.AppearanceManager; +import xyz.atnrch.nicko.i18n.I18N; import xyz.atnrch.nicko.mojang.MojangUtils; import org.bukkit.Bukkit; import org.bukkit.Sound; @@ -35,14 +37,25 @@ public class NickoDebugSubCmd { } } - final AppearanceManager appearanceManager = AppearanceManager.get(target.getPlayer()); - - if (MojangUtils.isUsernameInvalid(name) || MojangUtils.isUsernameInvalid(skin)) { + if (MojangUtils.isUsernameInvalid(name)) { sender.sendMessage(prefix + "§cSpecified username is invalid."); + return; } + if (MojangUtils.isUsernameInvalid(skin)) { + sender.sendMessage(prefix + "§cSpecified skin is invalid."); + return; + } + + final AppearanceManager appearanceManager = AppearanceManager.get(target.getPlayer()); appearanceManager.setNameAndSkin(name, skin); - target.sendMessage(prefix + "§aWhoosh!"); - target.playSound(target.getLocation(), Sound.ENTITY_ITEM_FRAME_PLACE, 1, 1); + 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.translateWithoutPrefix(result.getErrorKey())); + } } } diff --git a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java index ca541a2..e85359e 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java @@ -79,7 +79,6 @@ public class AppearanceManager { public void setNameAndSkin(String name, String skin) { this.profile.setName(name); this.profile.setSkin(skin); - updatePlayer(true, false); } public ActionResult reset() { @@ -105,11 +104,11 @@ public class AppearanceManager { updateTabList(gameProfile, displayName); respawnPlayer(); updateOthers(); + player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); + player.setFlying(wasFlying); + player.updateInventory(); } - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.setFlying(wasFlying); - player.updateInventory(); - return ActionResult.ok(); + return result; } public void updateOthers() { @@ -144,6 +143,8 @@ public class AppearanceManager { } else { return ActionResult.error(I18NDict.Error.MOJANG_SKIN); } + } else { + return ActionResult.error(I18NDict.Error.MOJANG_NAME); } return ActionResult.ok(); } catch (ExecutionException e) { diff --git a/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java b/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java index f5689fe..fac38e2 100644 --- a/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java +++ b/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java @@ -62,7 +62,7 @@ public class MojangAPI { final MojangSkin skin = MojangSkin.buildFromJson(object); return Optional.of(skin); } - + System.out.println("got empty optional !!!"); return Optional.empty(); } diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index ac2de53..d60b361 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -1,8 +1,8 @@ error: generic: "Unknown error" invalid_username: "§cThis is not a valid Minecraft username." - mojang_name: "Unable to get username from Mojang." - mojang_skin: "Unable to get skin from Mojang." + mojang_name: "There is no Minecraft account with this name." + mojang_skin: "This Minecraft account has no skin." offline: "§c{0} §fis offline!" cache: "Unable to get skin from the cache." sql: "SQL Error" diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 4471e6c..70d597a 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -1,8 +1,8 @@ error: generic: Erreur inconnue" invalid_username: "§cLe pseudo n''est pas un pseudo Minecraft valide." - mojang_name: "Impossible de récupérer le nom d''utilisateur depuis Mojang." - mojang_skin: "Impossible de récupérer le skin depuis Mojang." + mojang_name: "Un compte Minecraft avec ce nom n'existe pas." + mojang_skin: "Ce compte Minecraft n'a pas de skin." offline: "§c{0} §fest hors-ligne!" cache: "Impossible de récupérer le skin depuis le cache." sql: "Erreur SQL" From 228e3c43746e9fef48ce96c086c9a09d65d7a6ce Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 1 Jul 2023 22:39:31 +0200 Subject: [PATCH 057/296] feat: confirm cache entry delete --- .../java/xyz/atnrch/nicko/gui/ConfirmGUI.java | 34 +++++++++++++++++++ .../gui/admin/cache/CacheDetailedGUI.java | 4 +-- ...{EntryPlaceholder.java => CacheEntry.java} | 21 ++++++++++-- .../gui/items/confirm/ActionCallback.java | 7 ++++ .../nicko/gui/items/confirm/Cancel.java | 19 +++++++++++ .../nicko/gui/items/confirm/Confirm.java | 19 +++++++++++ 6 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 src/main/java/xyz/atnrch/nicko/gui/ConfirmGUI.java rename src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/{EntryPlaceholder.java => CacheEntry.java} (63%) create mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/confirm/ActionCallback.java create mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/confirm/Cancel.java create mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/confirm/Confirm.java diff --git a/src/main/java/xyz/atnrch/nicko/gui/ConfirmGUI.java b/src/main/java/xyz/atnrch/nicko/gui/ConfirmGUI.java new file mode 100644 index 0000000..b761bc2 --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/gui/ConfirmGUI.java @@ -0,0 +1,34 @@ +package xyz.atnrch.nicko.gui; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import xyz.atnrch.nicko.gui.items.confirm.ActionCallback; +import xyz.atnrch.nicko.gui.items.confirm.Cancel; +import xyz.atnrch.nicko.gui.items.confirm.Confirm; +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, ActionCallback callback) { + this.gui = Gui.normal() + .setStructure( + "@ @ @ @ % & & & &", + "@ @ @ @ I & & & &", + "@ @ @ @ % & & & &" + ) + .addIngredient('@', new Confirm(callback)) + .addIngredient('&', new Cancel(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/admin/cache/CacheDetailedGUI.java b/src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java index 901d479..cfe413e 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java @@ -8,7 +8,7 @@ import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.gui.structure.Markers; import xyz.xenondevs.invui.item.Item; import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.gui.items.admin.cache.EntryPlaceholder; +import xyz.atnrch.nicko.gui.items.admin.cache.CacheEntry; import xyz.atnrch.nicko.gui.admin.CacheManagementGUI; import xyz.atnrch.nicko.gui.items.common.ScrollDown; import org.bukkit.entity.Player; @@ -34,7 +34,7 @@ public class CacheDetailedGUI { .collect(Collectors.toList()); final List items = loadedSkins.stream() - .map(EntryPlaceholder::new) + .map(CacheEntry::new) .collect(Collectors.toList()); final CacheManagementGUI parent = new CacheManagementGUI(player); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/EntryPlaceholder.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntry.java similarity index 63% rename from src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/EntryPlaceholder.java rename to src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntry.java index 077321f..cbf8ee9 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/EntryPlaceholder.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntry.java @@ -5,14 +5,19 @@ 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.ConfirmGUI; +import xyz.atnrch.nicko.gui.admin.cache.CacheDetailedGUI; +import xyz.atnrch.nicko.gui.items.confirm.ActionCallback; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.builder.SkullBuilder; import xyz.xenondevs.invui.item.impl.AsyncItem; import java.util.UUID; -public class EntryPlaceholder extends AsyncItem { - public EntryPlaceholder(String name) { +public class CacheEntry extends AsyncItem { + private final String name; + + public CacheEntry(String name) { super(new ItemBuilder(Material.PAINTING).setDisplayName("§7§oLoading..."), () -> { final String stringUUID = name.replaceAll("(.{8})(.{4})(.{4})(.{4})(.+)", "$1-$2-$3-$4-$5"); final UUID uuid = UUID.fromString(stringUUID); @@ -21,12 +26,24 @@ public class EntryPlaceholder extends AsyncItem { skull.addLoreLines("§7Click to invalidate skin"); return skull; }); + this.name = name; } @Override public void handleClick(@NotNull ClickType click, @NotNull Player player, @NotNull InventoryClickEvent event) { if (click.isLeftClick() || click.isRightClick()) { event.getView().close(); + new ConfirmGUI(player, new ActionCallback() { + @Override + public void onConfirm() { + player.sendMessage(name + " cleared"); + } + + @Override + public void onCancel() { + new CacheDetailedGUI(player).open(); + } + }).open(); } } } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/confirm/ActionCallback.java b/src/main/java/xyz/atnrch/nicko/gui/items/confirm/ActionCallback.java new file mode 100644 index 0000000..bebd9a0 --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/gui/items/confirm/ActionCallback.java @@ -0,0 +1,7 @@ +package xyz.atnrch.nicko.gui.items.confirm; + +public interface ActionCallback { + void onConfirm(); + + void onCancel(); +} diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/confirm/Cancel.java b/src/main/java/xyz/atnrch/nicko/gui/items/confirm/Cancel.java new file mode 100644 index 0000000..d3cdb28 --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/gui/items/confirm/Cancel.java @@ -0,0 +1,19 @@ +package xyz.atnrch.nicko.gui.items.confirm; + +import org.bukkit.Material; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.SuppliedItem; + +public class Cancel extends SuppliedItem { + public Cancel(ActionCallback 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/confirm/Confirm.java b/src/main/java/xyz/atnrch/nicko/gui/items/confirm/Confirm.java new file mode 100644 index 0000000..f381afb --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/gui/items/confirm/Confirm.java @@ -0,0 +1,19 @@ +package xyz.atnrch.nicko.gui.items.confirm; + +import org.bukkit.Material; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.SuppliedItem; + +public class Confirm extends SuppliedItem { + public Confirm(ActionCallback 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; + }); + } +} From 4aa9b239522e3bcd5aa9d891ad466357b3ae321c Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 3 Jul 2023 15:25:02 +0200 Subject: [PATCH 058/296] feat wip(skin): skin entry name --- .../gui/items/admin/cache/CacheEntry.java | 20 ++++++++++++------- .../xyz/atnrch/nicko/mojang/MojangAPI.java | 17 +++++++++++++++- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntry.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntry.java index cbf8ee9..cf53a1d 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntry.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntry.java @@ -5,9 +5,11 @@ 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.NickoBukkit; import xyz.atnrch.nicko.gui.ConfirmGUI; import xyz.atnrch.nicko.gui.admin.cache.CacheDetailedGUI; import xyz.atnrch.nicko.gui.items.confirm.ActionCallback; +import xyz.atnrch.nicko.mojang.MojangAPI; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.builder.SkullBuilder; import xyz.xenondevs.invui.item.impl.AsyncItem; @@ -16,17 +18,20 @@ import java.util.UUID; public class CacheEntry extends AsyncItem { private final String name; + private final String uuid; + private final MojangAPI mojangAPI = NickoBukkit.getInstance().getMojangAPI(); - public CacheEntry(String name) { + public CacheEntry(String uuid) { super(new ItemBuilder(Material.PAINTING).setDisplayName("§7§oLoading..."), () -> { - final String stringUUID = name.replaceAll("(.{8})(.{4})(.{4})(.{4})(.+)", "$1-$2-$3-$4-$5"); - final UUID uuid = UUID.fromString(stringUUID); - final SkullBuilder skull = new SkullBuilder(uuid); - skull.setDisplayName("§6Skin Entry"); + final String dashedUuid = uuid.replaceAll("(.{8})(.{4})(.{4})(.{4})(.+)", "$1-$2-$3-$4-$5"); + final UUID uuidObject = UUID.fromString(dashedUuid); + final SkullBuilder skull = new SkullBuilder(uuidObject); + skull.setDisplayName("§6" + NickoBukkit.getInstance().getMojangAPI().getUUIDName(uuid)); skull.addLoreLines("§7Click to invalidate skin"); return skull; }); - this.name = name; + this.uuid = uuid; + this.name = mojangAPI.getUUIDName(uuid); } @Override @@ -36,7 +41,8 @@ public class CacheEntry extends AsyncItem { new ConfirmGUI(player, new ActionCallback() { @Override public void onConfirm() { - player.sendMessage(name + " cleared"); + mojangAPI.eraseFromCache(uuid); + player.sendMessage(name + " has been erased from the cache."); } @Override diff --git a/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java b/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java index fac38e2..3d9cf4b 100644 --- a/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java +++ b/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java @@ -14,6 +14,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; +import java.util.HashMap; import java.util.Optional; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -25,6 +26,8 @@ public class MojangAPI { private final Logger logger = Logger.getLogger("MojangAPI"); + private final HashMap uuidToName = new HashMap<>(); + private final CacheLoader> loader = new CacheLoader>() { @Nonnull public Optional load(@Nonnull String uuid) throws Exception { @@ -50,11 +53,19 @@ public class MojangAPI { final String parametrizedUrl = URL_NAME.replace("{name}", name); final JsonObject object = getRequestToUrl(parametrizedUrl); if (hasNoError(object)) { - return Optional.of(object.get("id").getAsString()); + final JsonElement idObject = object.get("id"); + final String id = idObject.getAsString(); + uuidToName.put(id, name); + return Optional.of(id); } return Optional.empty(); } + public void eraseFromCache(String uuid) { + cache.invalidate(uuid); + uuidToName.remove(uuid); + } + private Optional getSkinFromMojang(String uuid) throws IOException { final String parametrizedUrl = URL_SKIN.replace("{uuid}", uuid); final JsonObject object = getRequestToUrl(parametrizedUrl); @@ -66,6 +77,10 @@ public class MojangAPI { return Optional.empty(); } + public String getUUIDName(String uuid) { + return uuidToName.get(uuid); + } + private JsonObject getRequestToUrl(String parametrizedUrl) throws IOException { final URL url = new URL(parametrizedUrl); final HttpsURLConnection con = (HttpsURLConnection) url.openConnection(); From 856f5504620464abf035792d5dd3678fd147f4e2 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 3 Jul 2023 15:34:56 +0200 Subject: [PATCH 059/296] style(wrapper): missing space --- .../atnrch/nicko/wrapper/WrapperPlayServerNamedEntitySpawn.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerNamedEntitySpawn.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerNamedEntitySpawn.java index baa5bb9..fb82152 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerNamedEntitySpawn.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerNamedEntitySpawn.java @@ -155,6 +155,7 @@ public class WrapperPlayServerNamedEntitySpawn extends AbstractPacket { public Location getLocation(@Nullable World world) { return new Location(world, getX(), getY(), getZ(), angleToDegrees(getYRotRaw()), angleToDegrees(getXRotRaw())); } + public void setLocation(@Nonnull Location location) { setX(location.getX()); setY(location.getY()); From a254d3ed9b34705b8a7fdc9e06b776e289fb306e Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 3 Jul 2023 17:51:13 +0200 Subject: [PATCH 060/296] fix(lang): missing " char --- src/main/resources/fr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 70d597a..2069579 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -1,5 +1,5 @@ error: - generic: Erreur inconnue" + generic: "Erreur inconnue" 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." From 48257e20287af2df81546b21ffd4b04d13f260cb Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 3 Jul 2023 17:51:37 +0200 Subject: [PATCH 061/296] fix: flying after respawn --- .../xyz/atnrch/nicko/disguise/AppearanceManager.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java index e85359e..16bb8d7 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java @@ -95,18 +95,13 @@ public class AppearanceManager { public ActionResult updatePlayer(boolean skinChange, boolean reset) { 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); - final boolean wasFlying = player.isFlying(); if (!result.isError()) { updateMetadata(); updateTabList(gameProfile, displayName); respawnPlayer(); updateOthers(); - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.setFlying(wasFlying); - player.updateInventory(); } return result; } @@ -163,6 +158,7 @@ public class AppearanceManager { private void respawnPlayer() { final World world = player.getWorld(); + final boolean wasFlying = player.isFlying(); final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(); respawn.setDimension(world); respawn.setSeed(world.getSeed()); @@ -171,6 +167,9 @@ 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(); } @SuppressWarnings("deprecation") From 4abcf7647f745fb9e9bf0ad8dda7b84d824e5c03 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 3 Jul 2023 18:20:42 +0200 Subject: [PATCH 062/296] feat(global): rename, restructure in prepartion for the I18N of the GUI. --- .../java/xyz/atnrch/nicko/NickoBukkit.java | 14 +++---- .../xyz/atnrch/nicko/anvil/AnvilManager.java | 8 ++-- .../ActionResult.java | 2 +- .../AppearanceManager.java | 2 +- .../NickoProfile.java | 2 +- .../atnrch/nicko/command/NickoCommand.java | 4 +- .../nicko/command/sub/NickoCheckSubCmd.java | 2 +- .../nicko/command/sub/NickoDebugSubCmd.java | 4 +- .../nicko/event/PlayerJoinListener.java | 8 ++-- .../nicko/event/PlayerQuitListener.java | 2 +- .../java/xyz/atnrch/nicko/gui/AdminGUI.java | 10 ++--- .../{admin/cache => }/CacheDetailedGUI.java | 19 +++++---- .../gui/{admin => }/CacheManagementGUI.java | 19 +++++---- .../java/xyz/atnrch/nicko/gui/ConfirmGUI.java | 12 +++--- .../nicko/gui/{MainGUI.java => HomeGUI.java} | 30 +++++++------- .../xyz/atnrch/nicko/gui/SettingsGUI.java | 14 +++---- ...{ManageCache.java => ManageCacheItem.java} | 6 +-- .../{CacheEntry.java => CacheEntryItem.java} | 10 ++--- ...heOverview.java => CacheOverviewItem.java} | 4 +- ...eteCache.java => InvalidateCacheItem.java} | 4 +- ...ficEntry.java => InvalidateEntryItem.java} | 6 +-- .../ChangeBothItem.java} | 6 +-- .../ChangeNameItem.java} | 6 +-- .../ChangeSkinItem.java} | 6 +-- .../common/{GoBack.java => GoBackItem.java} | 4 +- .../{ScrollDown.java => ScrollDownItem.java} | 4 +- .../{ScrollUp.java => ScrollUpItem.java} | 4 +- ...nUnavailable.java => UnavailableItem.java} | 4 +- .../confirm/CancelItem.java} | 6 +-- .../items/common/confirm/ChoiceCallback.java | 7 ++++ .../confirm/ConfirmItem.java} | 6 +-- .../gui/items/confirm/ActionCallback.java | 7 ---- .../AdminAccessItem.java} | 6 +-- .../{main/ExitGUI.java => home/ExitItem.java} | 6 +-- .../ResetItem.java} | 14 +++---- .../SettingsAccessItem.java} | 6 +-- ...ycling.java => BungeeCordCyclingItem.java} | 4 +- ...eCycling.java => LanguageCyclingItem.java} | 4 +- src/main/java/xyz/atnrch/nicko/i18n/I18N.java | 2 +- .../java/xyz/atnrch/nicko/i18n/I18NDict.java | 40 +++++++++++++------ .../nicko/placeholder/NickoExpansion.java | 2 +- .../java/xyz/atnrch/nicko/storage/Cache.java | 4 +- .../atnrch/nicko/storage/PlayerDataStore.java | 4 +- .../xyz/atnrch/nicko/storage/Storage.java | 4 +- .../nicko/storage/json/JSONStorage.java | 4 +- .../atnrch/nicko/storage/map/MapCache.java | 4 +- .../nicko/storage/map/MapCacheProvider.java | 2 +- .../nicko/storage/redis/RedisCache.java | 4 +- .../atnrch/nicko/storage/sql/SQLStorage.java | 4 +- src/main/resources/en.yml | 24 ++++++----- src/main/resources/fr.yml | 34 +++++++--------- .../nicko/test/storage/BrokenSQLTest.java | 4 +- .../nicko/test/storage/SQLStorageTest.java | 4 +- .../nicko/test/storage/map/MapCacheTest.java | 2 +- .../test/storage/redis/RedisCacheTest.java | 2 +- 55 files changed, 218 insertions(+), 208 deletions(-) rename src/main/java/xyz/atnrch/nicko/{disguise => appearance}/ActionResult.java (94%) rename src/main/java/xyz/atnrch/nicko/{disguise => appearance}/AppearanceManager.java (99%) rename src/main/java/xyz/atnrch/nicko/{disguise => appearance}/NickoProfile.java (97%) rename src/main/java/xyz/atnrch/nicko/gui/{admin/cache => }/CacheDetailedGUI.java (76%) rename src/main/java/xyz/atnrch/nicko/gui/{admin => }/CacheManagementGUI.java (58%) rename src/main/java/xyz/atnrch/nicko/gui/{MainGUI.java => HomeGUI.java} (51%) rename src/main/java/xyz/atnrch/nicko/gui/items/admin/{ManageCache.java => ManageCacheItem.java} (90%) rename src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/{CacheEntry.java => CacheEntryItem.java} (88%) rename src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/{CacheOverview.java => CacheOverviewItem.java} (92%) rename src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/{InvalidateCompleteCache.java => InvalidateCacheItem.java} (93%) rename src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/{InvalidateSpecificEntry.java => InvalidateEntryItem.java} (84%) rename src/main/java/xyz/atnrch/nicko/gui/items/{skin/ChangeNameAndSkin.java => appearance/ChangeBothItem.java} (87%) rename src/main/java/xyz/atnrch/nicko/gui/items/{skin/ChangeName.java => appearance/ChangeNameItem.java} (87%) rename src/main/java/xyz/atnrch/nicko/gui/items/{skin/ChangeSkin.java => appearance/ChangeSkinItem.java} (85%) rename src/main/java/xyz/atnrch/nicko/gui/items/common/{GoBack.java => GoBackItem.java} (87%) rename src/main/java/xyz/atnrch/nicko/gui/items/common/{ScrollDown.java => ScrollDownItem.java} (88%) rename src/main/java/xyz/atnrch/nicko/gui/items/common/{ScrollUp.java => ScrollUpItem.java} (89%) rename src/main/java/xyz/atnrch/nicko/gui/items/common/{OptionUnavailable.java => UnavailableItem.java} (84%) rename src/main/java/xyz/atnrch/nicko/gui/items/{confirm/Cancel.java => common/confirm/CancelItem.java} (76%) create mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/ChoiceCallback.java rename src/main/java/xyz/atnrch/nicko/gui/items/{confirm/Confirm.java => common/confirm/ConfirmItem.java} (76%) delete mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/confirm/ActionCallback.java rename src/main/java/xyz/atnrch/nicko/gui/items/{main/AdminSubGUI.java => home/AdminAccessItem.java} (89%) rename src/main/java/xyz/atnrch/nicko/gui/items/{main/ExitGUI.java => home/ExitItem.java} (81%) rename src/main/java/xyz/atnrch/nicko/gui/items/{main/ResetAppearance.java => home/ResetItem.java} (84%) rename src/main/java/xyz/atnrch/nicko/gui/items/{main/SettingsSubGUI.java => home/SettingsAccessItem.java} (86%) rename src/main/java/xyz/atnrch/nicko/gui/items/settings/{BungeeCordCycling.java => BungeeCordCyclingItem.java} (95%) rename src/main/java/xyz/atnrch/nicko/gui/items/settings/{LanguageCycling.java => LanguageCyclingItem.java} (96%) diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index 61c9618..db07808 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -11,8 +11,7 @@ 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.OptionUnavailable; -import xyz.atnrch.nicko.gui.items.main.ExitGUI; +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; @@ -38,7 +37,9 @@ public class NickoBukkit extends JavaPlugin { private LocaleFileManager localeFileManager; private PlayerNameStore nameStore; - public NickoBukkit() { this.unitTesting = false; } + public NickoBukkit() { + this.unitTesting = false; + } /** * Used by MockBukkit @@ -96,8 +97,7 @@ 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 OptionUnavailable()); - Structure.addGlobalIngredient('E', new ExitGUI()); + Structure.addGlobalIngredient('U', new UnavailableItem()); if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { getLogger().info("Enabling PlaceHolderAPI support..."); @@ -106,9 +106,9 @@ public class NickoBukkit extends JavaPlugin { getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this); getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this); - - getLogger().info("Nicko (Bukkit) has been enabled."); } + + getLogger().info("Nicko (Bukkit) has been enabled."); } @Override diff --git a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java index b8610da..879131e 100644 --- a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java @@ -1,8 +1,8 @@ package xyz.atnrch.nicko.anvil; import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.disguise.AppearanceManager; -import xyz.atnrch.nicko.disguise.ActionResult; +import xyz.atnrch.nicko.appearance.AppearanceManager; +import xyz.atnrch.nicko.appearance.ActionResult; import xyz.atnrch.nicko.i18n.I18N; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.mojang.MojangUtils; @@ -99,10 +99,10 @@ public class AnvilManager { private List sendResultAndClose(ActionResult actionResult) { final I18N i18n = new I18N(player); if (!actionResult.isError()) { - player.sendMessage(i18n.translate(I18NDict.Event.Disguise.SUCCESS)); + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.OK)); } else { // TODO (Ineanto, 6/28/23): Check weirdness with error message not being translated sometimes - player.sendMessage(i18n.translate(I18NDict.Event.Disguise.FAIL, i18n.translateWithoutPrefix(actionResult.getErrorKey()))); + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.ERROR, i18n.translateWithoutPrefix(actionResult.getErrorKey()))); } return Collections.singletonList(AnvilGUI.ResponseAction.close()); } diff --git a/src/main/java/xyz/atnrch/nicko/disguise/ActionResult.java b/src/main/java/xyz/atnrch/nicko/appearance/ActionResult.java similarity index 94% rename from src/main/java/xyz/atnrch/nicko/disguise/ActionResult.java rename to src/main/java/xyz/atnrch/nicko/appearance/ActionResult.java index a3ed415..c527832 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/ActionResult.java +++ b/src/main/java/xyz/atnrch/nicko/appearance/ActionResult.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.disguise; +package xyz.atnrch.nicko.appearance; public class ActionResult { private final String errorKey; diff --git a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java similarity index 99% rename from src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java rename to src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java index 16bb8d7..a61c3b8 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.disguise; +package xyz.atnrch.nicko.appearance; import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.wrappers.*; diff --git a/src/main/java/xyz/atnrch/nicko/disguise/NickoProfile.java b/src/main/java/xyz/atnrch/nicko/appearance/NickoProfile.java similarity index 97% rename from src/main/java/xyz/atnrch/nicko/disguise/NickoProfile.java rename to src/main/java/xyz/atnrch/nicko/appearance/NickoProfile.java index 3652f90..93222e0 100644 --- a/src/main/java/xyz/atnrch/nicko/disguise/NickoProfile.java +++ b/src/main/java/xyz/atnrch/nicko/appearance/NickoProfile.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.disguise; +package xyz.atnrch.nicko.appearance; import xyz.atnrch.nicko.i18n.Locale; diff --git a/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java b/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java index 114da47..59bd685 100644 --- a/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java +++ b/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java @@ -3,7 +3,7 @@ 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.MainGUI; +import xyz.atnrch.nicko.gui.HomeGUI; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -33,7 +33,7 @@ public class NickoCommand implements CommandExecutor { return false; } - new MainGUI(player).open(); + new HomeGUI(player).open(); return false; } diff --git a/src/main/java/xyz/atnrch/nicko/command/sub/NickoCheckSubCmd.java b/src/main/java/xyz/atnrch/nicko/command/sub/NickoCheckSubCmd.java index 451677f..6b70a01 100644 --- a/src/main/java/xyz/atnrch/nicko/command/sub/NickoCheckSubCmd.java +++ b/src/main/java/xyz/atnrch/nicko/command/sub/NickoCheckSubCmd.java @@ -1,7 +1,7 @@ package xyz.atnrch.nicko.command.sub; import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.disguise.AppearanceManager; +import xyz.atnrch.nicko.appearance.AppearanceManager; import xyz.atnrch.nicko.i18n.I18N; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.mojang.MojangUtils; diff --git a/src/main/java/xyz/atnrch/nicko/command/sub/NickoDebugSubCmd.java b/src/main/java/xyz/atnrch/nicko/command/sub/NickoDebugSubCmd.java index aac6b71..eee712d 100644 --- a/src/main/java/xyz/atnrch/nicko/command/sub/NickoDebugSubCmd.java +++ b/src/main/java/xyz/atnrch/nicko/command/sub/NickoDebugSubCmd.java @@ -1,8 +1,8 @@ package xyz.atnrch.nicko.command.sub; import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.disguise.ActionResult; -import xyz.atnrch.nicko.disguise.AppearanceManager; +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; diff --git a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java index cf21834..02698f5 100644 --- a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java @@ -6,8 +6,8 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.disguise.ActionResult; -import xyz.atnrch.nicko.disguise.AppearanceManager; +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.storage.name.PlayerNameStore; @@ -27,9 +27,9 @@ public class PlayerJoinListener implements Listener { if (appearanceManager.hasData()) { final ActionResult actionResult = appearanceManager.updatePlayer(appearanceManager.needsASkinChange(), false); if (!actionResult.isError()) { - player.sendMessage(i18n.translate(I18NDict.Event.PreviousSkin.SUCCESS)); + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Restore.OK)); } else { - player.sendMessage(i18n.translate(I18NDict.Event.PreviousSkin.FAIL, i18n.translateWithoutPrefix(actionResult.getErrorKey()))); + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Restore.ERROR, i18n.translateWithoutPrefix(actionResult.getErrorKey()))); } } }, 20L); diff --git a/src/main/java/xyz/atnrch/nicko/event/PlayerQuitListener.java b/src/main/java/xyz/atnrch/nicko/event/PlayerQuitListener.java index 20fa8d5..6da9607 100644 --- a/src/main/java/xyz/atnrch/nicko/event/PlayerQuitListener.java +++ b/src/main/java/xyz/atnrch/nicko/event/PlayerQuitListener.java @@ -1,7 +1,7 @@ package xyz.atnrch.nicko.event; import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.disguise.ActionResult; +import xyz.atnrch.nicko.appearance.ActionResult; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; diff --git a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java index 470ee1b..015ad69 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java @@ -1,7 +1,7 @@ package xyz.atnrch.nicko.gui; -import xyz.atnrch.nicko.gui.items.admin.ManageCache; -import xyz.atnrch.nicko.gui.items.common.GoBack; +import xyz.atnrch.nicko.gui.items.admin.ManageCacheItem; +import xyz.atnrch.nicko.gui.items.common.GoBackItem; import org.bukkit.entity.Player; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; @@ -12,15 +12,15 @@ public class AdminGUI { private final Gui gui; public AdminGUI(Player player) { - final MainGUI parent = new MainGUI(player); + final HomeGUI parent = new HomeGUI(player); this.gui = Gui.normal() .setStructure( "# # # # # # # # #", "# # # S U U # # #", "B # # # # # # # #" ) - .addIngredient('S', new ManageCache()) - .addIngredient('B', new GoBack(parent.getGUI(), parent.getTitle())) + .addIngredient('S', new ManageCacheItem()) + .addIngredient('B', new GoBackItem(parent.getGUI(), parent.getTitle())) .build(); this.player = player; } diff --git a/src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java b/src/main/java/xyz/atnrch/nicko/gui/CacheDetailedGUI.java similarity index 76% rename from src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java rename to src/main/java/xyz/atnrch/nicko/gui/CacheDetailedGUI.java index cfe413e..f021e7c 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/admin/cache/CacheDetailedGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/CacheDetailedGUI.java @@ -1,16 +1,15 @@ -package xyz.atnrch.nicko.gui.admin.cache; +package xyz.atnrch.nicko.gui; -import xyz.atnrch.nicko.gui.items.common.GoBack; -import xyz.atnrch.nicko.gui.items.common.ScrollUp; +import xyz.atnrch.nicko.gui.items.common.GoBackItem; +import xyz.atnrch.nicko.gui.items.common.ScrollUpItem; import xyz.atnrch.nicko.mojang.MojangSkin; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.gui.structure.Markers; import xyz.xenondevs.invui.item.Item; import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.gui.items.admin.cache.CacheEntry; -import xyz.atnrch.nicko.gui.admin.CacheManagementGUI; -import xyz.atnrch.nicko.gui.items.common.ScrollDown; +import xyz.atnrch.nicko.gui.items.admin.cache.CacheEntryItem; +import xyz.atnrch.nicko.gui.items.common.ScrollDownItem; import org.bukkit.entity.Player; import xyz.xenondevs.invui.window.Window; @@ -34,7 +33,7 @@ public class CacheDetailedGUI { .collect(Collectors.toList()); final List items = loadedSkins.stream() - .map(CacheEntry::new) + .map(CacheEntryItem::new) .collect(Collectors.toList()); final CacheManagementGUI parent = new CacheManagementGUI(player); @@ -47,9 +46,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 ScrollUp()); - guiItemBuilder.addIngredient('D', new ScrollDown()); - guiItemBuilder.addIngredient('B', new GoBack(parent.getGUI(), parent.getTitle())); + guiItemBuilder.addIngredient('U', new ScrollUpItem()); + guiItemBuilder.addIngredient('D', new ScrollDownItem()); + guiItemBuilder.addIngredient('B', new GoBackItem(parent.getGUI(), parent.getTitle())); guiItemBuilder.setContent(items); }); diff --git a/src/main/java/xyz/atnrch/nicko/gui/admin/CacheManagementGUI.java b/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java similarity index 58% rename from src/main/java/xyz/atnrch/nicko/gui/admin/CacheManagementGUI.java rename to src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java index 298e622..07f150a 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/admin/CacheManagementGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java @@ -1,11 +1,10 @@ -package xyz.atnrch.nicko.gui.admin; +package xyz.atnrch.nicko.gui; -import xyz.atnrch.nicko.gui.AdminGUI; -import xyz.atnrch.nicko.gui.items.admin.cache.InvalidateSpecificEntry; -import xyz.atnrch.nicko.gui.items.admin.cache.InvalidateCompleteCache; -import xyz.atnrch.nicko.gui.items.admin.cache.CacheOverview; -import xyz.atnrch.nicko.gui.items.common.GoBack; import org.bukkit.entity.Player; +import xyz.atnrch.nicko.gui.items.admin.cache.CacheOverviewItem; +import xyz.atnrch.nicko.gui.items.admin.cache.InvalidateCacheItem; +import xyz.atnrch.nicko.gui.items.admin.cache.InvalidateEntryItem; +import xyz.atnrch.nicko.gui.items.common.GoBackItem; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; @@ -22,10 +21,10 @@ public class CacheManagementGUI { "# # # S A D # # #", "B # # # # # # # #" ) - .addIngredient('B', new GoBack(parent.getGUI(), parent.getTitle())) - .addIngredient('S', new CacheOverview()) - .addIngredient('A', new InvalidateCompleteCache()) - .addIngredient('D', new InvalidateSpecificEntry()) + .addIngredient('B', new GoBackItem(parent.getGUI(), parent.getTitle())) + .addIngredient('S', new CacheOverviewItem()) + .addIngredient('A', new InvalidateCacheItem()) + .addIngredient('D', new InvalidateEntryItem()) .build(); this.player = player; } diff --git a/src/main/java/xyz/atnrch/nicko/gui/ConfirmGUI.java b/src/main/java/xyz/atnrch/nicko/gui/ConfirmGUI.java index b761bc2..a857a37 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/ConfirmGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/ConfirmGUI.java @@ -2,9 +2,9 @@ package xyz.atnrch.nicko.gui; import org.bukkit.Material; import org.bukkit.entity.Player; -import xyz.atnrch.nicko.gui.items.confirm.ActionCallback; -import xyz.atnrch.nicko.gui.items.confirm.Cancel; -import xyz.atnrch.nicko.gui.items.confirm.Confirm; +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; @@ -14,15 +14,15 @@ public class ConfirmGUI { private final Player player; private final Gui gui; - public ConfirmGUI(Player player, ActionCallback callback) { + public ConfirmGUI(Player player, ChoiceCallback callback) { this.gui = Gui.normal() .setStructure( "@ @ @ @ % & & & &", "@ @ @ @ I & & & &", "@ @ @ @ % & & & &" ) - .addIngredient('@', new Confirm(callback)) - .addIngredient('&', new Cancel(callback)) + .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; diff --git a/src/main/java/xyz/atnrch/nicko/gui/MainGUI.java b/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java similarity index 51% rename from src/main/java/xyz/atnrch/nicko/gui/MainGUI.java rename to src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java index 158d954..a2c5f22 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/MainGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java @@ -1,21 +1,22 @@ package xyz.atnrch.nicko.gui; -import xyz.atnrch.nicko.gui.items.main.AdminSubGUI; -import xyz.atnrch.nicko.gui.items.main.ResetAppearance; -import xyz.atnrch.nicko.gui.items.main.SettingsSubGUI; -import xyz.atnrch.nicko.gui.items.skin.ChangeName; -import xyz.atnrch.nicko.gui.items.skin.ChangeNameAndSkin; -import xyz.atnrch.nicko.gui.items.skin.ChangeSkin; import org.bukkit.entity.Player; +import xyz.atnrch.nicko.gui.items.appearance.ChangeBothItem; +import xyz.atnrch.nicko.gui.items.appearance.ChangeNameItem; +import xyz.atnrch.nicko.gui.items.appearance.ChangeSkinItem; +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.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; -public class MainGUI { +public class HomeGUI { private final String title = "Nicko - Home"; private final Player player; private final Gui gui; - public MainGUI(Player player) { + public HomeGUI(Player player) { final String[] dynamicStructure = new String[]{ "# # # # # # # # #", "A # # N B S # # #", @@ -27,12 +28,13 @@ public class MainGUI { this.gui = Gui.normal() .setStructure(dynamicStructure) - .addIngredient('R', new ResetAppearance()) - .addIngredient('N', new ChangeName()) - .addIngredient('B', new ChangeNameAndSkin()) - .addIngredient('S', new ChangeSkin(player)) - .addIngredient('P', new SettingsSubGUI()) - .addIngredient('A', new AdminSubGUI()) + .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()) .build(); this.player = player; } diff --git a/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java b/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java index 8c48a0d..3917d31 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java @@ -1,8 +1,8 @@ package xyz.atnrch.nicko.gui; -import xyz.atnrch.nicko.gui.items.common.GoBack; -import xyz.atnrch.nicko.gui.items.settings.BungeeCordCycling; -import xyz.atnrch.nicko.gui.items.settings.LanguageCycling; +import xyz.atnrch.nicko.gui.items.common.GoBackItem; +import xyz.atnrch.nicko.gui.items.settings.BungeeCordCyclingItem; +import xyz.atnrch.nicko.gui.items.settings.LanguageCyclingItem; import org.bukkit.entity.Player; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; @@ -23,12 +23,12 @@ public class SettingsGUI { // TODO: 3/6/23 Replace when Redis is not enabled dynamicStructure[1] = dynamicStructure[1].replace("T", "U"); - final MainGUI parent = new MainGUI(player); + final HomeGUI parent = new HomeGUI(player); this.gui = Gui.normal() .setStructure(dynamicStructure) - .addIngredient('B', new GoBack(parent.getGUI(), parent.getTitle())) - .addIngredient('L', new LanguageCycling().get(player)) - .addIngredient('T', new BungeeCordCycling().get(player)) + .addIngredient('B', new GoBackItem(parent.getGUI(), parent.getTitle())) + .addIngredient('L', new LanguageCyclingItem().get(player)) + .addIngredient('T', new BungeeCordCyclingItem().get(player)) .build(); this.player = player; } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCache.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCacheItem.java similarity index 90% rename from src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCache.java rename to src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCacheItem.java index 5215caf..b4c290c 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCache.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCacheItem.java @@ -3,15 +3,15 @@ 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.admin.CacheManagementGUI; +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; -public class ManageCache extends AsyncItem { - public ManageCache() { +public class ManageCacheItem extends AsyncItem { + public ManageCacheItem() { super(new ItemBuilder(Material.PAINTING) .setDisplayName("§fManage §6skin §fcache...") .addLoreLines("§7Access the skin cache management panel."), diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntry.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntryItem.java similarity index 88% rename from src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntry.java rename to src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntryItem.java index cf53a1d..71af311 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntry.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntryItem.java @@ -7,8 +7,8 @@ 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.admin.cache.CacheDetailedGUI; -import xyz.atnrch.nicko.gui.items.confirm.ActionCallback; +import xyz.atnrch.nicko.gui.CacheDetailedGUI; +import xyz.atnrch.nicko.gui.items.common.confirm.ChoiceCallback; import xyz.atnrch.nicko.mojang.MojangAPI; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.builder.SkullBuilder; @@ -16,12 +16,12 @@ import xyz.xenondevs.invui.item.impl.AsyncItem; import java.util.UUID; -public class CacheEntry extends AsyncItem { +public class CacheEntryItem extends AsyncItem { private final String name; private final String uuid; private final MojangAPI mojangAPI = NickoBukkit.getInstance().getMojangAPI(); - public CacheEntry(String uuid) { + public CacheEntryItem(String uuid) { super(new ItemBuilder(Material.PAINTING).setDisplayName("§7§oLoading..."), () -> { final String dashedUuid = uuid.replaceAll("(.{8})(.{4})(.{4})(.{4})(.+)", "$1-$2-$3-$4-$5"); final UUID uuidObject = UUID.fromString(dashedUuid); @@ -38,7 +38,7 @@ public class CacheEntry 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 ActionCallback() { + new ConfirmGUI(player, new ChoiceCallback() { @Override public void onConfirm() { mojangAPI.eraseFromCache(uuid); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheOverview.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheOverviewItem.java similarity index 92% rename from src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheOverview.java rename to src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheOverviewItem.java index a4f0b70..1048051 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheOverview.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheOverviewItem.java @@ -10,8 +10,8 @@ import xyz.xenondevs.invui.item.impl.SuppliedItem; import java.util.Optional; -public class CacheOverview extends SuppliedItem { - public CacheOverview() { +public class CacheOverviewItem extends SuppliedItem { + public CacheOverviewItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.OAK_SIGN); final LoadingCache> cache = NickoBukkit.getInstance().getMojangAPI().getCache(); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCompleteCache.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCacheItem.java similarity index 93% rename from src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCompleteCache.java rename to src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCacheItem.java index 9fef719..a9f5762 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCompleteCache.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCacheItem.java @@ -9,8 +9,8 @@ import org.bukkit.event.inventory.ClickType; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class InvalidateCompleteCache extends SuppliedItem { - public InvalidateCompleteCache() { +public class InvalidateCacheItem extends SuppliedItem { + public InvalidateCacheItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.TNT); builder.setDisplayName("§fInvalidate §6skin cache"); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateSpecificEntry.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateEntryItem.java similarity index 84% rename from src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateSpecificEntry.java rename to src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateEntryItem.java index 62bd5a0..1214ee7 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateSpecificEntry.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateEntryItem.java @@ -1,13 +1,13 @@ package xyz.atnrch.nicko.gui.items.admin.cache; -import xyz.atnrch.nicko.gui.admin.cache.CacheDetailedGUI; +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 InvalidateSpecificEntry extends SuppliedItem { - public InvalidateSpecificEntry() { +public class InvalidateEntryItem extends SuppliedItem { + public InvalidateEntryItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.PAPER); builder.setDisplayName("§6Invalidate specific skin..."); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/skin/ChangeNameAndSkin.java b/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeBothItem.java similarity index 87% rename from src/main/java/xyz/atnrch/nicko/gui/items/skin/ChangeNameAndSkin.java rename to src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeBothItem.java index fb3784f..c81676d 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/skin/ChangeNameAndSkin.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeBothItem.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.gui.items.skin; +package xyz.atnrch.nicko.gui.items.appearance; import xyz.atnrch.nicko.anvil.AnvilManager; import org.bukkit.Material; @@ -6,8 +6,8 @@ import org.bukkit.event.inventory.ClickType; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class ChangeNameAndSkin extends SuppliedItem { - public ChangeNameAndSkin() { +public class ChangeBothItem extends SuppliedItem { + public ChangeBothItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.END_PORTAL_FRAME); builder.setDisplayName("§6Skin §fand §6name §fchange"); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/skin/ChangeName.java b/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeNameItem.java similarity index 87% rename from src/main/java/xyz/atnrch/nicko/gui/items/skin/ChangeName.java rename to src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeNameItem.java index 82cc9de..c8cfa71 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/skin/ChangeName.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeNameItem.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.gui.items.skin; +package xyz.atnrch.nicko.gui.items.appearance; import xyz.atnrch.nicko.anvil.AnvilManager; import org.bukkit.Material; @@ -6,8 +6,8 @@ import org.bukkit.event.inventory.ClickType; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class ChangeName extends SuppliedItem { - public ChangeName() { +public class ChangeNameItem extends SuppliedItem { + public ChangeNameItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.NAME_TAG); builder.setDisplayName("§fChange §6name"); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/skin/ChangeSkin.java b/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeSkinItem.java similarity index 85% rename from src/main/java/xyz/atnrch/nicko/gui/items/skin/ChangeSkin.java rename to src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeSkinItem.java index cd61031..74c3a6a 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/skin/ChangeSkin.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeSkinItem.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.gui.items.skin; +package xyz.atnrch.nicko.gui.items.appearance; import xyz.atnrch.nicko.anvil.AnvilManager; import org.bukkit.entity.Player; @@ -6,8 +6,8 @@ import org.bukkit.event.inventory.ClickType; import xyz.xenondevs.invui.item.builder.SkullBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class ChangeSkin extends SuppliedItem { - public ChangeSkin(Player player) { +public class ChangeSkinItem extends SuppliedItem { + public ChangeSkinItem(Player player) { super(() -> { final SkullBuilder builder = new SkullBuilder(player.getName()); builder.setDisplayName("§fChange §6skin"); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/GoBack.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/GoBackItem.java similarity index 87% rename from src/main/java/xyz/atnrch/nicko/gui/items/common/GoBack.java rename to src/main/java/xyz/atnrch/nicko/gui/items/common/GoBackItem.java index 1131ef1..e7a28ac 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/GoBack.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/GoBackItem.java @@ -6,8 +6,8 @@ import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; import xyz.xenondevs.invui.window.Window; -public class GoBack extends SuppliedItem { - public GoBack(Gui gui, String parentTitle) { +public class GoBackItem extends SuppliedItem { + public GoBackItem(Gui gui, String parentTitle) { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.ARROW); builder.setDisplayName("Go back"); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollDown.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollDownItem.java similarity index 88% rename from src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollDown.java rename to src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollDownItem.java index e8c5ade..4c4d7f4 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollDown.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollDownItem.java @@ -6,9 +6,9 @@ import xyz.xenondevs.invui.item.ItemProvider; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.controlitem.ScrollItem; -public class ScrollDown extends ScrollItem { +public class ScrollDownItem extends ScrollItem { - public ScrollDown() { + public ScrollDownItem() { super(1); } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollUp.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollUpItem.java similarity index 89% rename from src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollUp.java rename to src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollUpItem.java index a4f64bd..c41201f 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollUp.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollUpItem.java @@ -6,9 +6,9 @@ import xyz.xenondevs.invui.item.ItemProvider; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.controlitem.ScrollItem; -public class ScrollUp extends ScrollItem { +public class ScrollUpItem extends ScrollItem { - public ScrollUp() { + public ScrollUpItem() { super(-1); } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/OptionUnavailable.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/UnavailableItem.java similarity index 84% rename from src/main/java/xyz/atnrch/nicko/gui/items/common/OptionUnavailable.java rename to src/main/java/xyz/atnrch/nicko/gui/items/common/UnavailableItem.java index 97d42cb..56486fc 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/OptionUnavailable.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/UnavailableItem.java @@ -4,8 +4,8 @@ import org.bukkit.Material; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class OptionUnavailable extends SuppliedItem { - public OptionUnavailable() { +public class UnavailableItem extends SuppliedItem { + public UnavailableItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.RED_TERRACOTTA); builder.setDisplayName("§cFeature unavailable :("); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/confirm/Cancel.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/CancelItem.java similarity index 76% rename from src/main/java/xyz/atnrch/nicko/gui/items/confirm/Cancel.java rename to src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/CancelItem.java index d3cdb28..eb654be 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/confirm/Cancel.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/CancelItem.java @@ -1,11 +1,11 @@ -package xyz.atnrch.nicko.gui.items.confirm; +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 Cancel extends SuppliedItem { - public Cancel(ActionCallback callback) { +public class CancelItem extends SuppliedItem { + public CancelItem(ChoiceCallback callback) { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE); builder.setDisplayName("§cCancel"); 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/confirm/ChoiceCallback.java new file mode 100644 index 0000000..c1d5c0c --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/ChoiceCallback.java @@ -0,0 +1,7 @@ +package xyz.atnrch.nicko.gui.items.common.confirm; + +public interface ChoiceCallback { + void onConfirm(); + + void onCancel(); +} diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/confirm/Confirm.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/ConfirmItem.java similarity index 76% rename from src/main/java/xyz/atnrch/nicko/gui/items/confirm/Confirm.java rename to src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/ConfirmItem.java index f381afb..d32fbb3 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/confirm/Confirm.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/ConfirmItem.java @@ -1,11 +1,11 @@ -package xyz.atnrch.nicko.gui.items.confirm; +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 Confirm extends SuppliedItem { - public Confirm(ActionCallback callback) { +public class ConfirmItem extends SuppliedItem { + public ConfirmItem(ChoiceCallback callback) { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); builder.setDisplayName("§aConfirm"); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/confirm/ActionCallback.java b/src/main/java/xyz/atnrch/nicko/gui/items/confirm/ActionCallback.java deleted file mode 100644 index bebd9a0..0000000 --- a/src/main/java/xyz/atnrch/nicko/gui/items/confirm/ActionCallback.java +++ /dev/null @@ -1,7 +0,0 @@ -package xyz.atnrch.nicko.gui.items.confirm; - -public interface ActionCallback { - void onConfirm(); - - void onCancel(); -} diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/main/AdminSubGUI.java b/src/main/java/xyz/atnrch/nicko/gui/items/home/AdminAccessItem.java similarity index 89% rename from src/main/java/xyz/atnrch/nicko/gui/items/main/AdminSubGUI.java rename to src/main/java/xyz/atnrch/nicko/gui/items/home/AdminAccessItem.java index dedf06d..0d691bc 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/main/AdminSubGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/home/AdminAccessItem.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.gui.items.main; +package xyz.atnrch.nicko.gui.items.home; import xyz.atnrch.nicko.gui.AdminGUI; import org.bukkit.Material; @@ -8,8 +8,8 @@ import org.bukkit.inventory.ItemFlag; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class AdminSubGUI extends SuppliedItem { - public AdminSubGUI() { +public class AdminAccessItem extends SuppliedItem { + public AdminAccessItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.COMMAND_BLOCK); builder.addEnchantment(Enchantment.DAMAGE_ALL, 1, false); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/main/ExitGUI.java b/src/main/java/xyz/atnrch/nicko/gui/items/home/ExitItem.java similarity index 81% rename from src/main/java/xyz/atnrch/nicko/gui/items/main/ExitGUI.java rename to src/main/java/xyz/atnrch/nicko/gui/items/home/ExitItem.java index 438d137..2e459e3 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/main/ExitGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/home/ExitItem.java @@ -1,12 +1,12 @@ -package xyz.atnrch.nicko.gui.items.main; +package xyz.atnrch.nicko.gui.items.home; import org.bukkit.Material; import org.bukkit.event.inventory.ClickType; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SimpleItem; -public class ExitGUI extends SimpleItem { - public ExitGUI() { +public class ExitItem extends SimpleItem { + public ExitItem() { super(new ItemBuilder(Material.OAK_DOOR).setDisplayName("§fExit"), click -> { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/main/ResetAppearance.java b/src/main/java/xyz/atnrch/nicko/gui/items/home/ResetItem.java similarity index 84% rename from src/main/java/xyz/atnrch/nicko/gui/items/main/ResetAppearance.java rename to src/main/java/xyz/atnrch/nicko/gui/items/home/ResetItem.java index eeb4246..2cff18d 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/main/ResetAppearance.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/home/ResetItem.java @@ -1,6 +1,6 @@ -package xyz.atnrch.nicko.gui.items.main; +package xyz.atnrch.nicko.gui.items.home; -import xyz.atnrch.nicko.disguise.AppearanceManager; +import xyz.atnrch.nicko.appearance.AppearanceManager; import xyz.atnrch.nicko.i18n.I18N; import xyz.atnrch.nicko.i18n.I18NDict; import org.bukkit.Material; @@ -9,8 +9,8 @@ import org.bukkit.event.inventory.ClickType; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class ResetAppearance extends SuppliedItem { - public ResetAppearance() { +public class ResetItem extends SuppliedItem { + public ResetItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.TNT); builder.setDisplayName("§fReset"); @@ -25,16 +25,16 @@ public class ResetAppearance extends SuppliedItem { final AppearanceManager appearanceManager = AppearanceManager.get(player); if (!appearanceManager.hasData()) { - player.sendMessage(i18n.translate(I18NDict.Event.Undisguise.NONE)); + 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.Undisguise.SUCCESS)); + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.OK)); return true; } else { - player.sendMessage(i18n.translate(I18NDict.Event.Undisguise.FAIL)); + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.ERROR)); return false; } } diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/main/SettingsSubGUI.java b/src/main/java/xyz/atnrch/nicko/gui/items/home/SettingsAccessItem.java similarity index 86% rename from src/main/java/xyz/atnrch/nicko/gui/items/main/SettingsSubGUI.java rename to src/main/java/xyz/atnrch/nicko/gui/items/home/SettingsAccessItem.java index 26e0f40..8263c28 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/main/SettingsSubGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/home/SettingsAccessItem.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.gui.items.main; +package xyz.atnrch.nicko.gui.items.home; import xyz.atnrch.nicko.gui.SettingsGUI; import org.bukkit.Material; @@ -6,8 +6,8 @@ import org.bukkit.event.inventory.ClickType; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -public class SettingsSubGUI extends SuppliedItem { - public SettingsSubGUI() { +public class SettingsAccessItem extends SuppliedItem { + public SettingsAccessItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.COMPARATOR); builder.setDisplayName("§fSettings..."); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/settings/BungeeCordCycling.java b/src/main/java/xyz/atnrch/nicko/gui/items/settings/BungeeCordCyclingItem.java similarity index 95% rename from src/main/java/xyz/atnrch/nicko/gui/items/settings/BungeeCordCycling.java rename to src/main/java/xyz/atnrch/nicko/gui/items/settings/BungeeCordCyclingItem.java index 76b20fc..1093422 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/settings/BungeeCordCycling.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/settings/BungeeCordCyclingItem.java @@ -1,7 +1,7 @@ package xyz.atnrch.nicko.gui.items.settings; import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.appearance.NickoProfile; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; @@ -13,7 +13,7 @@ import xyz.xenondevs.invui.item.impl.SimpleItem; import java.util.Optional; -public class BungeeCordCycling { +public class BungeeCordCyclingItem { private final ItemProvider[] providers = new ItemProvider[]{ getItemProviderForValue(true), getItemProviderForValue(false) diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCycling.java b/src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCyclingItem.java similarity index 96% rename from src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCycling.java rename to src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCyclingItem.java index c6f6054..611e0fa 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCycling.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCyclingItem.java @@ -1,7 +1,7 @@ package xyz.atnrch.nicko.gui.items.settings; import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.appearance.NickoProfile; import xyz.atnrch.nicko.i18n.Locale; import org.bukkit.Material; import org.bukkit.Sound; @@ -17,7 +17,7 @@ import java.util.Collections; import java.util.List; import java.util.Optional; -public class LanguageCycling { +public class LanguageCyclingItem { private final ItemProvider[] providers = getItems(); public AbstractItem get(Player player) { diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java index 84fb429..e6a3e22 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java @@ -2,7 +2,7 @@ package xyz.atnrch.nicko.i18n; import com.github.jsixface.YamlConfig; import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.appearance.NickoProfile; import org.bukkit.entity.Player; import java.io.InputStream; diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index 3c40364..f912ded 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -2,24 +2,38 @@ package xyz.atnrch.nicko.i18n; public class I18NDict { public static class Event { + public static final String EVENT_KEY = "event."; + public static class Admin { - public static final String CACHE_CLEAN = "event.admin.cache_clear"; + public static final String ADMIN_KEY = "admin."; + + public static final String CACHE_CLEAN = ADMIN_KEY + "cache_clear"; } - public static class Disguise { - public static final String SUCCESS = "event.disguise.success"; - public static final String FAIL = "event.disguise.fail"; - } + public static class Appearance { + public static final String APPEARANCE_KEY = EVENT_KEY + "appearance."; - public static class Undisguise { - public static final String SUCCESS = "event.undisguise.success"; - public static final String FAIL = "event.undisguise.fail"; - public static final String NONE = "event.undisguise.none"; - } + public static class Set { + public static final String SET_KEY = APPEARANCE_KEY + "set."; - public static class PreviousSkin { - public static final String SUCCESS = "event.previous_skin_applied.success"; - public static final String FAIL = "event.previous_skin_applied.fail"; + public static final String OK = SET_KEY + "ok"; + public static final String ERROR = SET_KEY + "error"; + } + + public static class Remove { + public static final String REMOVE_KEY = APPEARANCE_KEY + "remove."; + + public static final String OK = REMOVE_KEY + "ok"; + public static final String MISSING = REMOVE_KEY + "missing"; + public static final String ERROR = REMOVE_KEY + "error"; + } + + public static class Restore { + public static final String RESTORE_KEY = APPEARANCE_KEY + "restore."; + + public static final String OK = RESTORE_KEY + "success"; + public static final String ERROR = RESTORE_KEY + "fail"; + } } } diff --git a/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java b/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java index e7d5fc6..ea82f20 100644 --- a/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java +++ b/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java @@ -2,7 +2,7 @@ package xyz.atnrch.nicko.placeholder; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.appearance.NickoProfile; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/xyz/atnrch/nicko/storage/Cache.java b/src/main/java/xyz/atnrch/nicko/storage/Cache.java index 65b8000..c92a214 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/Cache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/Cache.java @@ -1,7 +1,7 @@ package xyz.atnrch.nicko.storage; -import xyz.atnrch.nicko.disguise.ActionResult; -import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.appearance.ActionResult; +import xyz.atnrch.nicko.appearance.NickoProfile; import java.util.Optional; import java.util.UUID; diff --git a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java index 640816a..080f647 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java +++ b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java @@ -2,8 +2,8 @@ package xyz.atnrch.nicko.storage; import org.bukkit.entity.Player; import xyz.atnrch.nicko.config.Configuration; -import xyz.atnrch.nicko.disguise.ActionResult; -import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.appearance.ActionResult; +import xyz.atnrch.nicko.appearance.NickoProfile; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.mojang.MojangAPI; import xyz.atnrch.nicko.mojang.MojangUtils; diff --git a/src/main/java/xyz/atnrch/nicko/storage/Storage.java b/src/main/java/xyz/atnrch/nicko/storage/Storage.java index d50970f..0f2dc41 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/Storage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/Storage.java @@ -1,7 +1,7 @@ package xyz.atnrch.nicko.storage; -import xyz.atnrch.nicko.disguise.ActionResult; -import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.appearance.ActionResult; +import xyz.atnrch.nicko.appearance.NickoProfile; import java.util.Optional; import java.util.UUID; diff --git a/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java b/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java index 00763e8..7608c22 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java @@ -3,8 +3,8 @@ package xyz.atnrch.nicko.storage.json; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.disguise.ActionResult; -import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.appearance.ActionResult; +import xyz.atnrch.nicko.appearance.NickoProfile; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.storage.Storage; import xyz.atnrch.nicko.storage.StorageProvider; diff --git a/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java b/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java index a913ee6..3c15fef 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java @@ -1,7 +1,7 @@ package xyz.atnrch.nicko.storage.map; -import xyz.atnrch.nicko.disguise.ActionResult; -import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.appearance.ActionResult; +import xyz.atnrch.nicko.appearance.NickoProfile; import xyz.atnrch.nicko.storage.Cache; import xyz.atnrch.nicko.storage.CacheProvider; 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 7413007..fa8367f 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/map/MapCacheProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/map/MapCacheProvider.java @@ -1,6 +1,6 @@ package xyz.atnrch.nicko.storage.map; -import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.appearance.NickoProfile; import xyz.atnrch.nicko.storage.CacheProvider; import java.util.HashMap; 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 19e4924..c8967f6 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java @@ -4,8 +4,8 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import redis.clients.jedis.Jedis; import xyz.atnrch.nicko.config.Configuration; -import xyz.atnrch.nicko.disguise.ActionResult; -import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.appearance.ActionResult; +import xyz.atnrch.nicko.appearance.NickoProfile; import xyz.atnrch.nicko.storage.Cache; import xyz.atnrch.nicko.storage.CacheProvider; 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 069b040..baaea0b 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java @@ -1,8 +1,8 @@ package xyz.atnrch.nicko.storage.sql; import xyz.atnrch.nicko.config.Configuration; -import xyz.atnrch.nicko.disguise.ActionResult; -import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.appearance.ActionResult; +import xyz.atnrch.nicko.appearance.NickoProfile; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.i18n.Locale; import xyz.atnrch.nicko.storage.Storage; diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index d60b361..488f418 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -7,16 +7,18 @@ error: cache: "Unable to get skin from the cache." sql: "SQL Error" json: "JSON Error" + event: + appearance: + set: + error: "§cUnable to apply your disguise. §7§o({0})" + ok: "§aDisguise applied!" + restore: + error: "§cUnable to apply your previous disguise back. §7§o({0})" + ok: "§aYour previous active disguise has been applied." + remove: + error: "§cUnable to remove your disguise. It will be reset on your next login." + missing: "§cYou are not under a disguise." + ok: "§aDisguise removed." admin: - cache_clear: "§aSkin cache cleaned." - disguise: - fail: "§cUnable to apply your disguise. §7§o({0})" - success: "§aDisguise applied!" - previous_skin_applied: - fail: "§cUnable to apply your previous disguise back. §7§o({0})" - success: "§aYour previous active disguise has been applied." - undisguise: - fail: "§cUnable to remove your disguise. It will be reset on your next login." - none: "§cYou are not under a disguise." - success: "§aDisguise removed." \ No newline at end of file + cache_clear: "§aSkin cache cleaned." \ No newline at end of file diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 2069579..2820091 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -7,24 +7,18 @@ error: cache: "Impossible de récupérer le skin depuis le cache." sql: "Erreur SQL" json: "Erreur JSON" -event: - admin: - cache_clear: "§aCache des skins nettoyé." - disguise: - fail: "§cImpossible d''appliquer votre déguisement. §7§o({0})" - success: "§aDéguisement appliqué !" - previous_skin_applied: - fail: "§cImpossible d''appliquer votre précédent déguisement. §7§o({0})" - success: "§aVotre précédent déguisement a été appliqué." - undisguise: - fail: "§cImpossible de retirer votre déguisement. Il sera réinitialisé à votre prochaine reconnexion." - none: "§cVous n''avez pas de déguisement." - success: "§aDéguisement retiré." -gui: - common: - exit: "Quitter" - back: "Retour" - l1_back: "Retournez à la fenêtre précédente." - not_available: "Option indisponible :(" - l1_not_available: "Ce bouton est désactivé." +event: + appearance: + set: + error: "§cImpossible d''appliquer votre déguisement. §7§o({0})" + ok: "§aDéguisement appliqué !" + restore: + error: "§cImpossible d''appliquer votre précédent déguisement. §7§o({0})" + ok: "§aVotre précédent déguisement a été appliqué." + remove: + error: "§cImpossible de retirer votre déguisement. Il sera réinitialisé à votre prochaine reconnexion." + missing: "§cVous n''avez pas de déguisement." + ok: "§aDéguisement retiré." + admin: + cache_clear: "§aCache des skins nettoyé." \ No newline at end of file diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java index ac19e25..1712cd7 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java @@ -6,8 +6,8 @@ import be.seeseemelk.mockbukkit.entity.PlayerMock; import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.DataSourceConfiguration; -import xyz.atnrch.nicko.disguise.ActionResult; -import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.appearance.ActionResult; +import xyz.atnrch.nicko.appearance.NickoProfile; import org.junit.jupiter.api.*; import java.util.Optional; 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 ba05003..2cd6880 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java @@ -7,8 +7,8 @@ import org.junit.jupiter.api.*; import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.DataSourceConfiguration; -import xyz.atnrch.nicko.disguise.ActionResult; -import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.appearance.ActionResult; +import xyz.atnrch.nicko.appearance.NickoProfile; import xyz.atnrch.nicko.i18n.Locale; import java.util.Optional; diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java index 035227c..6fa5cdb 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java @@ -6,7 +6,7 @@ import be.seeseemelk.mockbukkit.entity.PlayerMock; import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.DataSourceConfiguration; -import xyz.atnrch.nicko.disguise.NickoProfile; +import xyz.atnrch.nicko.appearance.NickoProfile; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; 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 37bf788..e439d11 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 @@ -10,7 +10,7 @@ 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.disguise.NickoProfile; +import xyz.atnrch.nicko.appearance.NickoProfile; import java.util.Optional; From b8a52da87e903b53eca830458b2b02cf3cea5c5d Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 3 Jul 2023 18:30:55 +0200 Subject: [PATCH 063/296] perf: merge instance --- src/main/java/xyz/atnrch/nicko/i18n/I18N.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java index e6a3e22..068d99f 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java @@ -11,6 +11,7 @@ import java.util.Optional; public class I18N { private final MessageFormat formatter = new MessageFormat(""); + private final NickoBukkit instance = NickoBukkit.getInstance(); private final Player player; private final Locale playerLocale; @@ -20,7 +21,6 @@ public class I18N { } public String translate(String key, Object... arguments) { - final NickoBukkit instance = NickoBukkit.getInstance(); final String string = readString(key); try { @@ -42,7 +42,6 @@ public class I18N { } private String readString(String key) { - final NickoBukkit instance = NickoBukkit.getInstance(); String string; if (playerLocale == Locale.CUSTOM) { string = instance.getLocaleFileManager().get(key); @@ -56,7 +55,6 @@ public class I18N { } private Locale getPlayerLocale() { - final NickoBukkit instance = NickoBukkit.getInstance(); try { final Optional profile = instance.getDataStore().getData(player.getUniqueId()); return !profile.isPresent() ? Locale.FALLBACK_LOCALE : profile.get().getLocale(); From 31c8c8f695a6478858e025772f6202453919df0b Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 3 Jul 2023 18:35:51 +0200 Subject: [PATCH 064/296] feat(storage): check for cache status --- src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java index 080f647..b4ed89d 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java +++ b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java @@ -64,6 +64,7 @@ public class PlayerDataStore { public ActionResult saveData(Player player) { 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); From 29a557c42d382976d6010152b2d113a38d959952 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 4 Jul 2023 19:36:08 +0200 Subject: [PATCH 065/296] refactor: titles among other things --- .../xyz/atnrch/nicko/gui/CacheManagementGUI.java | 4 ++-- .../nicko/gui/items/admin/ManageCacheItem.java | 2 +- .../gui/items/admin/cache/CacheEntryItem.java | 5 ++++- ...OverviewItem.java => CacheStatisticsItem.java} | 15 +++++++-------- .../items/admin/cache/InvalidateCacheItem.java | 7 ++++--- .../items/admin/cache/InvalidateEntryItem.java | 2 +- .../gui/items/appearance/ChangeBothItem.java | 2 +- .../gui/items/appearance/ChangeNameItem.java | 2 +- .../gui/items/appearance/ChangeSkinItem.java | 2 +- .../atnrch/nicko/gui/items/common/GoBackItem.java | 2 +- .../nicko/gui/items/common/ScrollDownItem.java | 4 ++-- .../nicko/gui/items/common/ScrollUpItem.java | 4 ++-- .../nicko/gui/items/common/UnavailableItem.java | 4 ++-- .../nicko/gui/items/home/AdminAccessItem.java | 4 ++-- .../atnrch/nicko/gui/items/home/ResetItem.java | 4 ++-- .../nicko/gui/items/home/SettingsAccessItem.java | 4 ++-- .../gui/items/settings/BungeeCordCyclingItem.java | 2 +- .../gui/items/settings/LanguageCyclingItem.java | 2 +- src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java | 14 ++++++++++---- src/main/resources/en.yml | 8 +++++--- src/main/resources/fr.yml | 8 +++++--- 21 files changed, 57 insertions(+), 44 deletions(-) rename src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/{CacheOverviewItem.java => CacheStatisticsItem.java} (64%) diff --git a/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java b/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java index 07f150a..c32227d 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java @@ -1,7 +1,7 @@ package xyz.atnrch.nicko.gui; import org.bukkit.entity.Player; -import xyz.atnrch.nicko.gui.items.admin.cache.CacheOverviewItem; +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.common.GoBackItem; @@ -22,7 +22,7 @@ public class CacheManagementGUI { "B # # # # # # # #" ) .addIngredient('B', new GoBackItem(parent.getGUI(), parent.getTitle())) - .addIngredient('S', new CacheOverviewItem()) + .addIngredient('S', new CacheStatisticsItem()) .addIngredient('A', new InvalidateCacheItem()) .addIngredient('D', new InvalidateEntryItem()) .build(); 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 b4c290c..ba536bc 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 @@ -13,7 +13,7 @@ import org.jetbrains.annotations.NotNull; public class ManageCacheItem extends AsyncItem { public ManageCacheItem() { super(new ItemBuilder(Material.PAINTING) - .setDisplayName("§fManage §6skin §fcache...") + .setDisplayName("§fManage skin cache...") .addLoreLines("§7Access the skin cache management panel."), () -> { final SkullBuilder builder = new SkullBuilder("Notch"); 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 71af311..a66f206 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 @@ -9,6 +9,8 @@ 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.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.mojang.MojangAPI; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.builder.SkullBuilder; @@ -41,8 +43,9 @@ public class CacheEntryItem extends AsyncItem { new ConfirmGUI(player, new ChoiceCallback() { @Override public void onConfirm() { + final I18N i18n = new I18N(player); + player.sendMessage(i18n.translate(I18NDict.Event.Admin.Cache.INVALIDATE_ENTRY, name)); mojangAPI.eraseFromCache(uuid); - player.sendMessage(name + " has been erased from the cache."); } @Override diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheOverviewItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheStatisticsItem.java similarity index 64% rename from src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheOverviewItem.java rename to src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheStatisticsItem.java index 1048051..0b3a6d1 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheOverviewItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheStatisticsItem.java @@ -10,18 +10,17 @@ import xyz.xenondevs.invui.item.impl.SuppliedItem; import java.util.Optional; -public class CacheOverviewItem extends SuppliedItem { - public CacheOverviewItem() { +public class CacheStatisticsItem extends SuppliedItem { + public CacheStatisticsItem() { super(() -> { - final ItemBuilder builder = new ItemBuilder(Material.OAK_SIGN); + final ItemBuilder builder = new ItemBuilder(Material.BOOK); final LoadingCache> cache = NickoBukkit.getInstance().getMojangAPI().getCache(); final CacheStats stats = cache.stats(); - builder.setDisplayName("§6Skin cache §foverview:"); + builder.setDisplayName("§fStatistics"); builder.addLoreLines( - "Request Count: §2" + stats.requestCount(), - "Skin Cached: §2" + Math.round(cache.size()), - "§7§oCache is cleared every 24 hours.", - "§7§o(Click to refresh)"); + "Request Count: §b" + stats.requestCount(), + "Skin Cached: §b" + Math.round(cache.size()), + "§8§oCache is cleared every 24 hours."); 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 a9f5762..20ea606 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 @@ -13,7 +13,7 @@ public class InvalidateCacheItem extends SuppliedItem { public InvalidateCacheItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.TNT); - builder.setDisplayName("§fInvalidate §6skin cache"); + builder.setDisplayName("§fInvalidate cache"); builder.addLoreLines( "§c§oNOT RECOMMENDED", "§7Invalidates every skin entry present in the cache.", @@ -24,10 +24,11 @@ public class InvalidateCacheItem extends SuppliedItem { }, (click) -> { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { + click.getEvent().getView().close(); + final Player player = click.getPlayer(); final I18N i18n = new I18N(player); - click.getEvent().getView().close(); - player.sendMessage(i18n.translate(I18NDict.Event.Admin.CACHE_CLEAN)); + player.sendMessage(i18n.translate(I18NDict.Event.Admin.Cache.INVALIDATE_ALL)); NickoBukkit.getInstance().getMojangAPI().getCache().invalidateAll(); return true; } 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 index 1214ee7..71ba35b 100644 --- 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 @@ -10,7 +10,7 @@ public class InvalidateEntryItem extends SuppliedItem { public InvalidateEntryItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.PAPER); - builder.setDisplayName("§6Invalidate specific skin..."); + builder.setDisplayName("§fInvalidate specific entry"); builder.addLoreLines("§7Select a specific skin to invalidate."); return builder; }, (click) -> { 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 c81676d..e85ebe8 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 @@ -11,7 +11,7 @@ public class ChangeBothItem extends SuppliedItem { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.END_PORTAL_FRAME); builder.setDisplayName("§6Skin §fand §6name §fchange"); - builder.addLoreLines("§7Change both your skin and name."); + builder.addLoreLines("§7Will open a GUI to change both your name and your skin."); 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 c8cfa71..2cf925b 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 @@ -11,7 +11,7 @@ public class ChangeNameItem extends SuppliedItem { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.NAME_TAG); builder.setDisplayName("§fChange §6name"); - builder.addLoreLines("§7Only change your name."); + builder.addLoreLines("§7Will open a GUI to change your name only."); 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 74c3a6a..681a980 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 @@ -11,7 +11,7 @@ public class ChangeSkinItem extends SuppliedItem { super(() -> { final SkullBuilder builder = new SkullBuilder(player.getName()); builder.setDisplayName("§fChange §6skin"); - builder.addLoreLines("§7Only change your skin."); + builder.addLoreLines("§7Will open a GUI to change your skin only."); 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..184322d 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 @@ -10,7 +10,7 @@ public class GoBackItem extends SuppliedItem { public GoBackItem(Gui gui, String parentTitle) { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.ARROW); - builder.setDisplayName("Go back"); + builder.setDisplayName("§fGo back"); builder.addLoreLines("§7Return to the previous window."); return builder; }, click -> { 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 4c4d7f4..094ec30 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 @@ -15,9 +15,9 @@ public class ScrollDownItem extends ScrollItem { @Override public ItemProvider getItemProvider(ScrollGui gui) { ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); - builder.setDisplayName("§7Scroll down"); + builder.setDisplayName("§fScroll down"); if (!gui.canScroll(1)) - builder.addLoreLines("§cYou can't scroll further down"); + builder.addLoreLines("§7§o(You can't scroll further down.)"); 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 c41201f..268bf96 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 @@ -15,9 +15,9 @@ public class ScrollUpItem extends ScrollItem { @Override public ItemProvider getItemProvider(ScrollGui gui) { ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE); - builder.setDisplayName("§7Scroll up"); + builder.setDisplayName("§fScroll up"); if (!gui.canScroll(-1)) - builder.addLoreLines("§cYou've reached the top"); + builder.addLoreLines("§7§o(You've reached the top.)"); 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 56486fc..2d50018 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 @@ -8,8 +8,8 @@ public class UnavailableItem extends SuppliedItem { public UnavailableItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.RED_TERRACOTTA); - builder.setDisplayName("§cFeature unavailable :("); - builder.addLoreLines("§7This button is disabled."); + builder.setDisplayName("§fUnavailable"); + builder.addLoreLines("§7§oThis button is disabled."); return builder; }, click -> 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 0d691bc..f5ab12a 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 @@ -14,8 +14,8 @@ public class AdminAccessItem extends SuppliedItem { final ItemBuilder builder = new ItemBuilder(Material.COMMAND_BLOCK); builder.addEnchantment(Enchantment.DAMAGE_ALL, 1, false); builder.addItemFlags(ItemFlag.HIDE_ENCHANTS); - builder.setDisplayName("§cAdministration panel..."); - builder.addLoreLines("§7Access the administration panel."); + builder.setDisplayName("§cAdministration panel"); + builder.addLoreLines("§7Configure and and manage Nicko."); return builder; }, click -> { final ClickType clickType = click.getClickType(); 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 2cff18d..824a1ce 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 @@ -13,8 +13,8 @@ public class ResetItem extends SuppliedItem { public ResetItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.TNT); - builder.setDisplayName("§fReset"); - builder.addLoreLines("§7Get rid of your disguise."); + builder.setDisplayName("§fReset appearance"); + builder.addLoreLines("§7Completely remove your disguise."); return builder; }, (event) -> { final Player player = event.getPlayer(); 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 8263c28..1ebac80 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 @@ -10,8 +10,8 @@ public class SettingsAccessItem extends SuppliedItem { public SettingsAccessItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.COMPARATOR); - builder.setDisplayName("§fSettings..."); - builder.addLoreLines("§7Adjust your preferences."); + builder.setDisplayName("§fSettings"); + builder.addLoreLines("§7Configure your experience."); 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 1093422..2ef37bd 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 @@ -35,7 +35,7 @@ public class BungeeCordCyclingItem { private ItemProvider getItemProviderForValue(boolean enabled) { final ItemBuilder builder = new ItemBuilder(Material.COMPASS); - builder.setDisplayName("§6BungeeCord transfer:"); + builder.setDisplayName("§fBungeeCord transfer"); if (enabled) { builder.addLoreLines("§7> §cDisabled"); builder.addLoreLines("§6§l> §a§lEnabled"); 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 611e0fa..2ff073e 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 @@ -36,7 +36,7 @@ public class LanguageCyclingItem { private ItemProvider generateItem(Locale locale, List locales) { final ItemBuilder builder = new ItemBuilder(Material.OAK_SIGN); - builder.setDisplayName("§6Select your language:"); + builder.setDisplayName("§fLanguage"); for (Locale value : locales) { if (locale != value) { builder.addLoreLines("§7> " + value.getName()); diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index f912ded..931cd28 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -5,9 +5,15 @@ public class I18NDict { public static final String EVENT_KEY = "event."; public static class Admin { - public static final String ADMIN_KEY = "admin."; + public static final String ADMIN_KEY = EVENT_KEY + "admin."; - public static final String CACHE_CLEAN = ADMIN_KEY + "cache_clear"; + public static class Cache { + public static final String CACHE_KEY = ADMIN_KEY + "cache."; + + public static final String INVALIDATE_ALL = CACHE_KEY + "invalidate_all"; + public static final String INVALIDATE_ENTRY = CACHE_KEY + "invalidate_entry"; + + } } public static class Appearance { @@ -31,8 +37,8 @@ public class I18NDict { public static class Restore { public static final String RESTORE_KEY = APPEARANCE_KEY + "restore."; - public static final String OK = RESTORE_KEY + "success"; - public static final String ERROR = RESTORE_KEY + "fail"; + public static final String OK = RESTORE_KEY + "ok"; + public static final String ERROR = RESTORE_KEY + "error"; } } } diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 488f418..18500a0 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -12,13 +12,15 @@ event: appearance: set: error: "§cUnable to apply your disguise. §7§o({0})" - ok: "§aDisguise applied!" + ok: "§fDisguise applied." restore: error: "§cUnable to apply your previous disguise back. §7§o({0})" ok: "§aYour previous active disguise has been applied." remove: error: "§cUnable to remove your disguise. It will be reset on your next login." missing: "§cYou are not under a disguise." - ok: "§aDisguise removed." + ok: "§fDisguise removed." admin: - cache_clear: "§aSkin cache cleaned." \ No newline at end of file + cache: + invalidate_cache: "§fComplete cache invalidated." + invalidate_entry: "§6{0} §fhas been invalidated." \ No newline at end of file diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 2820091..bec98ea 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -12,13 +12,15 @@ event: appearance: set: error: "§cImpossible d''appliquer votre déguisement. §7§o({0})" - ok: "§aDéguisement appliqué !" + ok: "§fDéguisement appliqué." restore: error: "§cImpossible d''appliquer votre précédent déguisement. §7§o({0})" ok: "§aVotre précédent déguisement a été appliqué." remove: error: "§cImpossible de retirer votre déguisement. Il sera réinitialisé à votre prochaine reconnexion." missing: "§cVous n''avez pas de déguisement." - ok: "§aDéguisement retiré." + ok: "§fDéguisement retiré." admin: - cache_clear: "§aCache des skins nettoyé." \ No newline at end of file + cache: + invalidate_cache: "§fCache complet invalidé." + invalidate_entry: "§6{0} §fa été invalidé." \ No newline at end of file From da8c7e91ce4a1a1e7f7a875c96bede17aad9cfc4 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 4 Jul 2023 19:36:40 +0200 Subject: [PATCH 066/296] fix: remove debug statement --- src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java b/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java index 3d9cf4b..1a90cab 100644 --- a/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java +++ b/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java @@ -73,7 +73,6 @@ public class MojangAPI { final MojangSkin skin = MojangSkin.buildFromJson(object); return Optional.of(skin); } - System.out.println("got empty optional !!!"); return Optional.empty(); } From 37b1d5bd0ce5229363a5f68f7e854c454f805234 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 8 Jul 2023 16:09:37 +0200 Subject: [PATCH 067/296] feat: cache uuids --- .../atnrch/nicko/gui/CacheDetailedGUI.java | 2 +- .../admin/cache/CacheStatisticsItem.java | 2 +- .../admin/cache/InvalidateCacheItem.java | 6 ++-- .../admin/cache/InvalidateEntryItem.java | 4 ++- .../xyz/atnrch/nicko/mojang/MojangAPI.java | 34 ++++++++++++++----- .../atnrch/nicko/storage/PlayerDataStore.java | 3 +- 6 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/gui/CacheDetailedGUI.java b/src/main/java/xyz/atnrch/nicko/gui/CacheDetailedGUI.java index f021e7c..8d5935a 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/CacheDetailedGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/CacheDetailedGUI.java @@ -26,7 +26,7 @@ public class CacheDetailedGUI { private final Gui gui; public CacheDetailedGUI(Player player) { - final ConcurrentMap> skins = NickoBukkit.getInstance().getMojangAPI().getCache().asMap(); + final ConcurrentMap> skins = NickoBukkit.getInstance().getMojangAPI().getSkinCache().asMap(); final List loadedSkins = skins.entrySet().stream() .filter(entry -> entry.getValue().isPresent()) .map(Map.Entry::getKey) 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 0b3a6d1..3471302 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 @@ -14,7 +14,7 @@ public class CacheStatisticsItem extends SuppliedItem { public CacheStatisticsItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.BOOK); - final LoadingCache> cache = NickoBukkit.getInstance().getMojangAPI().getCache(); + final LoadingCache> cache = NickoBukkit.getInstance().getMojangAPI().getSkinCache(); final CacheStats stats = cache.stats(); builder.setDisplayName("§fStatistics"); builder.addLoreLines( 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 20ea606..9cd81df 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 @@ -17,9 +17,7 @@ public class InvalidateCacheItem extends SuppliedItem { builder.addLoreLines( "§c§oNOT RECOMMENDED", "§7Invalidates every skin entry present in the cache.", - "§7Does not reset player disguises.", - "§7Could be useful if a skin has been updated", - "§7recently and the cache is now outdated."); + "§7Does not reset player disguises."); return builder; }, (click) -> { final ClickType clickType = click.getClickType(); @@ -29,7 +27,7 @@ public class InvalidateCacheItem extends SuppliedItem { final Player player = click.getPlayer(); final I18N i18n = new I18N(player); player.sendMessage(i18n.translate(I18NDict.Event.Admin.Cache.INVALIDATE_ALL)); - NickoBukkit.getInstance().getMojangAPI().getCache().invalidateAll(); + NickoBukkit.getInstance().getMojangAPI().getSkinCache().invalidateAll(); return true; } return false; 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 index 71ba35b..c3f0a5d 100644 --- 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 @@ -11,7 +11,9 @@ public class InvalidateEntryItem extends SuppliedItem { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.PAPER); builder.setDisplayName("§fInvalidate specific entry"); - builder.addLoreLines("§7Select a specific skin to invalidate."); + 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(); diff --git a/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java b/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java index 1a90cab..2abf04f 100644 --- a/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java +++ b/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java @@ -25,31 +25,47 @@ public class MojangAPI { public static final String URL_SKIN = "https://sessionserver.mojang.com/session/minecraft/profile/{uuid}?unsigned=false"; private final Logger logger = Logger.getLogger("MojangAPI"); - private final HashMap uuidToName = new HashMap<>(); - private final CacheLoader> loader = new CacheLoader>() { + private final CacheLoader> skinLoader = new CacheLoader>() { @Nonnull public Optional load(@Nonnull String uuid) throws Exception { return getSkinFromMojang(uuid); } }; - private final LoadingCache> cache = CacheBuilder + private final LoadingCache> skinCache = CacheBuilder .newBuilder() .recordStats() .expireAfterWrite(24, TimeUnit.HOURS) - .build(loader); + .build(skinLoader); + + private final CacheLoader> uuidLoader = new CacheLoader>() { + @Nonnull + public Optional load(@Nonnull String name) throws Exception { + return getUUIDFromMojang(name); + } + }; + + private final LoadingCache> uuidCache = CacheBuilder + .newBuilder() + .expireAfterWrite(2, TimeUnit.DAYS) + .build(uuidLoader); public Optional getSkin(String uuid) throws IOException, ExecutionException { - return cache.get(uuid); + return skinCache.get(uuid); } public Optional getSkinWithoutCaching(String uuid) throws IOException { return getSkinFromMojang(uuid); } - public Optional getUUID(String name) throws IOException { + public Optional getUUID(String name) throws IOException, ExecutionException { + return uuidCache.get(name); + } + + private Optional getUUIDFromMojang(String name) throws IOException { + // TODO (Ineanto, 7/6/23): store uuid final String parametrizedUrl = URL_NAME.replace("{name}", name); final JsonObject object = getRequestToUrl(parametrizedUrl); if (hasNoError(object)) { @@ -62,7 +78,7 @@ public class MojangAPI { } public void eraseFromCache(String uuid) { - cache.invalidate(uuid); + skinCache.invalidate(uuid); uuidToName.remove(uuid); } @@ -125,7 +141,7 @@ public class MojangAPI { return object.get("error") == null; } - public LoadingCache> getCache() { - return cache; + public LoadingCache> getSkinCache() { + return skinCache; } } diff --git a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java index b4ed89d..d94eb0b 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java +++ b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java @@ -15,6 +15,7 @@ import xyz.atnrch.nicko.storage.sql.SQLStorage; import java.io.IOException; import java.util.Optional; import java.util.UUID; +import java.util.concurrent.ExecutionException; public class PlayerDataStore { private final Storage storage; @@ -57,7 +58,7 @@ public class PlayerDataStore { return getData(uuid); } return Optional.empty(); - } catch (IOException e) { + } catch (IOException | ExecutionException e) { return Optional.empty(); } } From 571ed1d31dc2750ee92bdf36ced5dd16ad1569a3 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 8 Jul 2023 16:12:20 +0200 Subject: [PATCH 068/296] fix: store uuid --- src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java b/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java index 2abf04f..5630015 100644 --- a/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java +++ b/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java @@ -65,14 +65,15 @@ public class MojangAPI { } private Optional getUUIDFromMojang(String name) throws IOException { - // TODO (Ineanto, 7/6/23): store uuid final String parametrizedUrl = URL_NAME.replace("{name}", name); final JsonObject object = getRequestToUrl(parametrizedUrl); if (hasNoError(object)) { final JsonElement idObject = object.get("id"); - final String id = idObject.getAsString(); - uuidToName.put(id, name); - return Optional.of(id); + final String uuid = idObject.getAsString(); + final Optional uuidOptional = Optional.of(uuid); + uuidCache.put(name, uuidOptional); + uuidToName.put(uuid, name); + return uuidOptional; } return Optional.empty(); } @@ -80,6 +81,7 @@ public class MojangAPI { public void eraseFromCache(String uuid) { skinCache.invalidate(uuid); uuidToName.remove(uuid); + uuidCache.invalidate(uuid); } private Optional getSkinFromMojang(String uuid) throws IOException { From 57d09f65c2b17506adee14f1f2cea11e2350c9fa Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 8 Jul 2023 16:15:12 +0200 Subject: [PATCH 069/296] fix(i18n): translation --- src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java index 879131e..a318c20 100644 --- a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java @@ -101,7 +101,6 @@ public class AnvilManager { if (!actionResult.isError()) { player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.OK)); } else { - // TODO (Ineanto, 6/28/23): Check weirdness with error message not being translated sometimes player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.ERROR, i18n.translateWithoutPrefix(actionResult.getErrorKey()))); } return Collections.singletonList(AnvilGUI.ResponseAction.close()); From 92f88a1b923d05b1f86b87ad262dfe3e7974c118 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 10 Jul 2023 17:36:59 +0200 Subject: [PATCH 070/296] feat: translations --- src/main/resources/en.yml | 1 + src/main/resources/fr.yml | 1 + src/main/resources/plugin.yml | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 18500a0..fe5d422 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -1,5 +1,6 @@ error: generic: "Unknown error" + permission: "§cYou do not have the required permission." invalid_username: "§cThis is not a valid Minecraft username." mojang_name: "There is no Minecraft account with this name." mojang_skin: "This Minecraft account has no skin." diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index bec98ea..a9b4998 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -1,5 +1,6 @@ error: generic: "Erreur inconnue" + permission: "§cVous ne possédez pas la permission." 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." diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 979373c..d43e165 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -11,11 +11,11 @@ load: POSTWORLD commands: nicko: description: "Opens Nicko's GUI." - permission: nicko.admin + permission: nicko.use permissions: nicko.*: default: op children: - nicko.use nicko.use: - default: op \ No newline at end of file + default: false \ No newline at end of file From 00168c03a7655b8f018302bd325ab204f2a9af08 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 10 Jul 2023 17:38:03 +0200 Subject: [PATCH 071/296] feat: permission message and items --- .../java/xyz/atnrch/nicko/command/NickoCommand.java | 11 +++++++++-- src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java | 8 ++++---- .../nicko/gui/items/appearance/ChangeBothItem.java | 2 +- .../atnrch/nicko/gui/items/home/AdminAccessItem.java | 12 ++++-------- src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java | 1 + 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java b/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java index 59bd685..d8429c2 100644 --- a/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java +++ b/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java @@ -8,6 +8,8 @@ import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; public class NickoCommand implements CommandExecutor { private String helpMessage = "§cNicko §8§o[{version}] §f- §2Help:\n" + @@ -17,7 +19,7 @@ public class NickoCommand implements CommandExecutor { @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { if (sender instanceof Player) { - Player player = (Player) sender; + final Player player = (Player) sender; if (args.length >= 1) { switch (args[0]) { case "debug": @@ -33,7 +35,12 @@ public class NickoCommand implements CommandExecutor { return false; } - new HomeGUI(player).open(); + if(player.isOp() || player.hasPermission("nicko.use") || player.hasPermission("nicko.*")) { + new HomeGUI(player).open(); + } else { + final I18N i18N = new I18N(player); + player.sendMessage(i18N.translate(I18NDict.Error.PERMISSION)); + } return false; } diff --git a/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java b/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java index a2c5f22..ba2475b 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java @@ -18,11 +18,11 @@ public class HomeGUI { public HomeGUI(Player player) { final String[] dynamicStructure = new String[]{ - "# # # # # # # # #", - "A # # N B S # # #", - "E P # # # # # # R"}; + "# # # # # # # # P", + "# # # N B S # # #", + "E A # # # # # # R"}; - if (!player.hasPermission("nicko.admin") || !player.isOp()) { + if (!player.isOp() || !player.hasPermission("nicko.admin")) { dynamicStructure[2] = dynamicStructure[2].replace("A", "#"); } 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 e85ebe8..2da2968 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 @@ -9,7 +9,7 @@ import xyz.xenondevs.invui.item.impl.SuppliedItem; public class ChangeBothItem extends SuppliedItem { public ChangeBothItem() { super(() -> { - final ItemBuilder builder = new ItemBuilder(Material.END_PORTAL_FRAME); + 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."); return builder; 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 f5ab12a..298ebe4 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,21 +1,17 @@ package xyz.atnrch.nicko.gui.items.home; -import xyz.atnrch.nicko.gui.AdminGUI; import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.ItemFlag; +import xyz.atnrch.nicko.gui.AdminGUI; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; public class AdminAccessItem extends SuppliedItem { public AdminAccessItem() { super(() -> { - final ItemBuilder builder = new ItemBuilder(Material.COMMAND_BLOCK); - builder.addEnchantment(Enchantment.DAMAGE_ALL, 1, false); - builder.addItemFlags(ItemFlag.HIDE_ENCHANTS); - builder.setDisplayName("§cAdministration panel"); - builder.addLoreLines("§7Configure and and manage Nicko."); + final ItemBuilder builder = new ItemBuilder(Material.COMMAND_BLOCK_MINECART); + builder.setDisplayName("Administration panel"); + builder.addLoreLines("§7Configure and manage Nicko."); return builder; }, click -> { final ClickType clickType = click.getClickType(); diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index 931cd28..ce30a0a 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -45,6 +45,7 @@ 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 PLAYER_OFFLINE = "error.offline"; public static final String CACHE = "error.cache"; public static final String MOJANG_NAME = "error.mojang_name"; From cbc4c748caf04dcd1a677c4603461639b32537a8 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 10 Jul 2023 17:51:12 +0200 Subject: [PATCH 072/296] fix: item names --- .../xyz/atnrch/nicko/gui/items/admin/ManageCacheItem.java | 4 ++-- .../nicko/gui/items/admin/cache/CacheStatisticsItem.java | 2 +- .../nicko/gui/items/admin/cache/InvalidateCacheItem.java | 2 +- .../nicko/gui/items/admin/cache/InvalidateEntryItem.java | 2 +- .../atnrch/nicko/gui/items/appearance/ChangeNameItem.java | 2 +- .../atnrch/nicko/gui/items/appearance/ChangeSkinItem.java | 2 +- .../java/xyz/atnrch/nicko/gui/items/common/GoBackItem.java | 2 +- .../xyz/atnrch/nicko/gui/items/common/ScrollDownItem.java | 2 +- .../xyz/atnrch/nicko/gui/items/common/ScrollUpItem.java | 2 +- .../xyz/atnrch/nicko/gui/items/common/UnavailableItem.java | 2 +- src/main/java/xyz/atnrch/nicko/gui/items/home/ExitItem.java | 6 +++++- .../java/xyz/atnrch/nicko/gui/items/home/ResetItem.java | 2 +- .../xyz/atnrch/nicko/gui/items/home/SettingsAccessItem.java | 2 +- .../nicko/gui/items/settings/BungeeCordCyclingItem.java | 2 +- .../nicko/gui/items/settings/LanguageCyclingItem.java | 2 +- 15 files changed, 20 insertions(+), 16 deletions(-) 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 ba536bc..0a65cc9 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 @@ -13,11 +13,11 @@ import org.jetbrains.annotations.NotNull; public class ManageCacheItem extends AsyncItem { public ManageCacheItem() { super(new ItemBuilder(Material.PAINTING) - .setDisplayName("§fManage skin cache...") + .setDisplayName("Manage §6skin §fcache...") .addLoreLines("§7Access the skin cache management panel."), () -> { final SkullBuilder builder = new SkullBuilder("Notch"); - builder.setDisplayName("§fManage §6skin §fcache..."); + builder.setDisplayName("Manage §6skin §fcache..."); builder.addLoreLines("§7Access the skin cache management panel."); return builder; }); 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 3471302..9398e7a 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 @@ -16,7 +16,7 @@ public class CacheStatisticsItem extends SuppliedItem { final ItemBuilder builder = new ItemBuilder(Material.BOOK); final LoadingCache> cache = NickoBukkit.getInstance().getMojangAPI().getSkinCache(); final CacheStats stats = cache.stats(); - builder.setDisplayName("§fStatistics"); + builder.setDisplayName("Statistics"); builder.addLoreLines( "Request Count: §b" + stats.requestCount(), "Skin Cached: §b" + Math.round(cache.size()), 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 9cd81df..fdd518d 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 @@ -13,7 +13,7 @@ public class InvalidateCacheItem extends SuppliedItem { public InvalidateCacheItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.TNT); - builder.setDisplayName("§fInvalidate cache"); + builder.setDisplayName("Invalidate cache"); builder.addLoreLines( "§c§oNOT RECOMMENDED", "§7Invalidates every skin entry present in the cache.", 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 index c3f0a5d..71627b8 100644 --- 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 @@ -10,7 +10,7 @@ public class InvalidateEntryItem extends SuppliedItem { public InvalidateEntryItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.PAPER); - builder.setDisplayName("§fInvalidate specific entry"); + 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."); 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 2cf925b..985ebe4 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 @@ -10,7 +10,7 @@ public class ChangeNameItem extends SuppliedItem { public ChangeNameItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.NAME_TAG); - builder.setDisplayName("§fChange §6name"); + builder.setDisplayName("Change §6name"); builder.addLoreLines("§7Will open a GUI to change your name only."); return builder; }, click -> { 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 681a980..58b90b1 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 @@ -10,7 +10,7 @@ public class ChangeSkinItem extends SuppliedItem { public ChangeSkinItem(Player player) { super(() -> { final SkullBuilder builder = new SkullBuilder(player.getName()); - builder.setDisplayName("§fChange §6skin"); + builder.setDisplayName("Change §6skin"); builder.addLoreLines("§7Will open a GUI to change your skin only."); return builder; }, click -> { 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 184322d..e7a28ac 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 @@ -10,7 +10,7 @@ public class GoBackItem extends SuppliedItem { public GoBackItem(Gui gui, String parentTitle) { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.ARROW); - builder.setDisplayName("§fGo back"); + builder.setDisplayName("Go back"); builder.addLoreLines("§7Return to the previous window."); return builder; }, click -> { 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 094ec30..e39dad1 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 @@ -15,7 +15,7 @@ public class ScrollDownItem extends ScrollItem { @Override public ItemProvider getItemProvider(ScrollGui gui) { ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); - builder.setDisplayName("§fScroll down"); + builder.setDisplayName("Scroll down"); if (!gui.canScroll(1)) builder.addLoreLines("§7§o(You can't scroll further down.)"); 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 268bf96..b02f05b 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 @@ -15,7 +15,7 @@ public class ScrollUpItem extends ScrollItem { @Override public ItemProvider getItemProvider(ScrollGui gui) { ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE); - builder.setDisplayName("§fScroll up"); + builder.setDisplayName("Scroll up"); if (!gui.canScroll(-1)) builder.addLoreLines("§7§o(You've reached the top.)"); 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 2d50018..1eb4928 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 @@ -8,7 +8,7 @@ public class UnavailableItem extends SuppliedItem { public UnavailableItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.RED_TERRACOTTA); - builder.setDisplayName("§fUnavailable"); + builder.setDisplayName("Unavailable"); builder.addLoreLines("§7§oThis button is disabled."); return builder; }, click -> true); 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 2e459e3..f4ca6f4 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,5 +1,6 @@ package xyz.atnrch.nicko.gui.items.home; +import com.comphenix.protocol.utility.MinecraftVersion; import org.bukkit.Material; import org.bukkit.event.inventory.ClickType; import xyz.xenondevs.invui.item.builder.ItemBuilder; @@ -7,7 +8,10 @@ import xyz.xenondevs.invui.item.impl.SimpleItem; public class ExitItem extends SimpleItem { public ExitItem() { - super(new ItemBuilder(Material.OAK_DOOR).setDisplayName("§fExit"), click -> { + super(new ItemBuilder(Material.OAK_DOOR).setDisplayName("Exit"), click -> { + if(MinecraftVersion.BEE_UPDATE.atOrAbove()) { + + } final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { click.getEvent().getView().close(); 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 824a1ce..4b46e9c 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 @@ -13,7 +13,7 @@ public class ResetItem extends SuppliedItem { public ResetItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.TNT); - builder.setDisplayName("§fReset appearance"); + builder.setDisplayName("Reset appearance"); builder.addLoreLines("§7Completely remove your disguise."); return builder; }, (event) -> { 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 1ebac80..c4a27ce 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 @@ -10,7 +10,7 @@ public class SettingsAccessItem extends SuppliedItem { public SettingsAccessItem() { super(() -> { final ItemBuilder builder = new ItemBuilder(Material.COMPARATOR); - builder.setDisplayName("§fSettings"); + builder.setDisplayName("Settings"); builder.addLoreLines("§7Configure your experience."); return builder; }, click -> { 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 2ef37bd..7101cbd 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 @@ -35,7 +35,7 @@ public class BungeeCordCyclingItem { private ItemProvider getItemProviderForValue(boolean enabled) { final ItemBuilder builder = new ItemBuilder(Material.COMPASS); - builder.setDisplayName("§fBungeeCord transfer"); + builder.setDisplayName("BungeeCord transfer"); if (enabled) { builder.addLoreLines("§7> §cDisabled"); builder.addLoreLines("§6§l> §a§lEnabled"); 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 2ff073e..7ce31db 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 @@ -36,7 +36,7 @@ public class LanguageCyclingItem { private ItemProvider generateItem(Locale locale, List locales) { final ItemBuilder builder = new ItemBuilder(Material.OAK_SIGN); - builder.setDisplayName("§fLanguage"); + builder.setDisplayName("Language"); for (Locale value : locales) { if (locale != value) { builder.addLoreLines("§7> " + value.getName()); From 7c70ebf9b628136c1a765fef1a4e88857509b6ed Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 10 Jul 2023 17:54:13 +0200 Subject: [PATCH 073/296] fix(i18n): key mismatch --- .../atnrch/nicko/gui/items/admin/cache/InvalidateCacheItem.java | 2 +- src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 fdd518d..7c1c04f 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 @@ -26,7 +26,7 @@ public class InvalidateCacheItem extends SuppliedItem { final Player player = click.getPlayer(); final I18N i18n = new I18N(player); - player.sendMessage(i18n.translate(I18NDict.Event.Admin.Cache.INVALIDATE_ALL)); + player.sendMessage(i18n.translate(I18NDict.Event.Admin.Cache.INVALIDATE_CACHE)); NickoBukkit.getInstance().getMojangAPI().getSkinCache().invalidateAll(); return true; } diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index ce30a0a..f8dbab5 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -10,7 +10,7 @@ public class I18NDict { public static class Cache { public static final String CACHE_KEY = ADMIN_KEY + "cache."; - public static final String INVALIDATE_ALL = CACHE_KEY + "invalidate_all"; + public static final String INVALIDATE_CACHE = CACHE_KEY + "invalidate_cache"; public static final String INVALIDATE_ENTRY = CACHE_KEY + "invalidate_entry"; } From f795d42564615b9bac9a0782e970b54400592a0a Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 14 Jul 2023 10:11:48 +0200 Subject: [PATCH 074/296] refactor(redis): removed debug message --- .../nicko/appearance/AppearanceManager.java | 32 ++++++++++++++----- .../{appearance => profile}/NickoProfile.java | 0 .../nicko/storage/redis/RedisCache.java | 28 ++++++++-------- 3 files changed, 39 insertions(+), 21 deletions(-) rename src/main/java/xyz/atnrch/nicko/{appearance => profile}/NickoProfile.java (100%) diff --git a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java index a61c3b8..3229307 100644 --- a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.appearance; +package xyz.atnrch.nicko.profile; import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.wrappers.*; @@ -11,6 +11,7 @@ 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.storage.PlayerDataStore; @@ -23,29 +24,32 @@ import java.util.Optional; import java.util.UUID; import java.util.concurrent.ExecutionException; -public class AppearanceManager { +public class ProfileManager { 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) { + private ProfileManager(UUID uuid) { this.player = Bukkit.getPlayer(uuid); + this.uuid = uuid; this.profile = dataStore.getData(uuid).orElse(NickoProfile.EMPTY_PROFILE.clone()); } - private AppearanceManager(String name) { + private ProfileManager(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 ProfileManager get(Player player) { + return new ProfileManager(player.getUniqueId()); } - public static AppearanceManager get(String name) { - return new AppearanceManager(name); + public static ProfileManager get(String name) { + return new ProfileManager(name); } public boolean hasData() { @@ -54,6 +58,7 @@ public class AppearanceManager { public void setSkin(String skin) { profile.setSkin(skin); + dataStore.getCache().cache(uuid, profile); } public String getSkin() { @@ -66,12 +71,22 @@ public class AppearanceManager { 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; } @@ -79,6 +94,7 @@ public class AppearanceManager { public void setNameAndSkin(String name, String skin) { this.profile.setName(name); this.profile.setSkin(skin); + dataStore.getCache().cache(uuid, profile); } public ActionResult reset() { diff --git a/src/main/java/xyz/atnrch/nicko/appearance/NickoProfile.java b/src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java similarity index 100% rename from src/main/java/xyz/atnrch/nicko/appearance/NickoProfile.java rename to src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java 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 c8967f6..642fb9b 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java @@ -3,9 +3,9 @@ package xyz.atnrch.nicko.storage.redis; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import redis.clients.jedis.Jedis; -import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.appearance.NickoProfile; +import xyz.atnrch.nicko.profile.NickoProfile; +import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.storage.Cache; import xyz.atnrch.nicko.storage.CacheProvider; @@ -21,7 +21,6 @@ public class RedisCache extends Cache { private RedisCacheProvider provider; public RedisCache(Configuration configuration) { - System.out.println("Loaded REDIS CACHE"); this.configuration = configuration; } @@ -35,23 +34,26 @@ public class RedisCache extends Cache { @Override public ActionResult cache(UUID uuid, NickoProfile profile) { - final Jedis jedis = provider.getJedis(); - jedis.set("nicko:" + uuid.toString(), gson.toJson(profile)); - return ActionResult.ok(); + try (Jedis jedis = provider.getJedis()) { + jedis.set("nicko:" + uuid.toString(), gson.toJson(profile)); + return ActionResult.ok(); + } } @Override public boolean isCached(UUID uuid) { - final Jedis jedis = provider.getJedis(); - return jedis.exists("nicko:" + uuid.toString()); + try (Jedis jedis = provider.getJedis()) { + return jedis.exists("nicko:" + uuid.toString()); + } } @Override public Optional retrieve(UUID uuid) { - final Jedis jedis = provider.getJedis(); - // 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); - return Optional.of(profile); + try (Jedis jedis = provider.getJedis()) { + // 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); + return Optional.of(profile); + } } } From 69bae936d6691b8f672d6b96a8541b375cd7b3e7 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 14 Jul 2023 11:01:35 +0200 Subject: [PATCH 075/296] feat: update cache --- pom.xml | 16 +++++++++++++--- .../xyz/atnrch/nicko/anvil/AnvilManager.java | 18 ++++++++++++------ .../nicko/appearance/AppearanceManager.java | 17 +++++++++-------- .../items/settings/BungeeCordCyclingItem.java | 2 +- .../items/settings/LanguageCyclingItem.java | 17 +++++++++++++---- src/main/java/xyz/atnrch/nicko/i18n/I18N.java | 9 ++++----- .../java/xyz/atnrch/nicko/i18n/I18NDict.java | 19 ++++++++++++------- .../nicko/placeholder/NickoExpansion.java | 4 ++-- .../atnrch/nicko/profile/NickoProfile.java | 2 +- .../java/xyz/atnrch/nicko/storage/Cache.java | 2 +- .../atnrch/nicko/storage/PlayerDataStore.java | 13 +++++++++++-- .../xyz/atnrch/nicko/storage/Storage.java | 2 +- .../nicko/storage/json/JSONStorage.java | 2 +- .../atnrch/nicko/storage/map/MapCache.java | 2 +- .../nicko/storage/map/MapCacheProvider.java | 2 +- .../atnrch/nicko/storage/sql/SQLStorage.java | 2 +- src/main/resources/en.yml | 5 +++-- src/main/resources/fr.yml | 3 +-- .../nicko/test/storage/BrokenSQLTest.java | 2 +- .../nicko/test/storage/SQLStorageTest.java | 2 +- .../nicko/test/storage/map/MapCacheTest.java | 2 +- .../test/storage/redis/RedisCacheTest.java | 2 +- 22 files changed, 92 insertions(+), 53 deletions(-) diff --git a/pom.xml b/pom.xml index 13c384a..d936797 100644 --- a/pom.xml +++ b/pom.xml @@ -138,9 +138,11 @@ net.wesjd:anvilgui xyz.xenondevs.invui:* com.github.jsixface:* - com.fasterxml.jackson.dataformat - com.fasterxml.jackson.core - org.mariadb.jdbc + com.fasterxml.jackson.dataformat:* + com.fasterxml.jackson.core:* + org.mariadb.jdbc:* + redis.clients:* + org.apache.commons:commons-pool2 @@ -168,6 +170,14 @@ org.mariadb.jdbc net.artelnatif.libs.mariadb + + redis.clients + net.artelnatif.libs.redis + + + org.apache.commons.pool2 + net.artelnatif.libs.pool2 + false diff --git a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java index a318c20..2e9f13f 100644 --- a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java @@ -1,16 +1,17 @@ package xyz.atnrch.nicko.anvil; -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.appearance.AppearanceManager; -import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.i18n.I18N; -import xyz.atnrch.nicko.i18n.I18NDict; -import xyz.atnrch.nicko.mojang.MojangUtils; import net.wesjd.anvilgui.AnvilGUI; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +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.i18n.I18NDict; +import xyz.atnrch.nicko.mojang.MojangUtils; +import xyz.atnrch.nicko.storage.PlayerDataStore; import java.util.Collections; import java.util.List; @@ -18,10 +19,12 @@ import java.util.List; public class AnvilManager { private final Player player; private final AppearanceManager appearanceManager; + private final PlayerDataStore dataStore; public AnvilManager(Player player) { this.player = player; this.appearanceManager = AppearanceManager.get(player); + this.dataStore = NickoBukkit.getInstance().getDataStore(); } public void openNameThenSkinAnvil() { @@ -47,6 +50,7 @@ public class AnvilManager { return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); } else { appearanceManager.setName(snapshot.getText()); + dataStore.updateCache(player.getUniqueId(), appearanceManager.getProfile()); openSkinAnvil(); return Collections.singletonList(AnvilGUI.ResponseAction.close()); } @@ -67,6 +71,7 @@ public class AnvilManager { return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); } else { appearanceManager.setName(snapshot.getText()); + dataStore.updateCache(player.getUniqueId(), appearanceManager.getProfile()); final ActionResult actionResult = appearanceManager.updatePlayer(false, false); return sendResultAndClose(actionResult); } @@ -87,6 +92,7 @@ public class AnvilManager { return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); } else { appearanceManager.setSkin(snapshot.getText()); + dataStore.updateCache(player.getUniqueId(), appearanceManager.getProfile()); 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 3229307..2b51e6d 100644 --- a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.profile; +package xyz.atnrch.nicko.appearance; import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.wrappers.*; @@ -14,6 +14,7 @@ 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; import xyz.atnrch.nicko.storage.PlayerDataStore; import xyz.atnrch.nicko.storage.name.PlayerNameStore; import xyz.atnrch.nicko.wrapper.*; @@ -24,7 +25,7 @@ import java.util.Optional; import java.util.UUID; import java.util.concurrent.ExecutionException; -public class ProfileManager { +public class AppearanceManager { private final NickoProfile profile; private final Player player; private final UUID uuid; @@ -32,24 +33,24 @@ public class ProfileManager { private final PlayerDataStore dataStore = instance.getDataStore(); private final PlayerNameStore nameStore = instance.getNameStore(); - private ProfileManager(UUID uuid) { + private AppearanceManager(UUID uuid) { this.player = Bukkit.getPlayer(uuid); this.uuid = uuid; this.profile = dataStore.getData(uuid).orElse(NickoProfile.EMPTY_PROFILE.clone()); } - private ProfileManager(String name) { + private AppearanceManager(String name) { this.player = null; this.uuid = null; this.profile = dataStore.getOfflineData(name).orElse(NickoProfile.EMPTY_PROFILE.clone()); } - public static ProfileManager get(Player player) { - return new ProfileManager(player.getUniqueId()); + public static AppearanceManager get(Player player) { + return new AppearanceManager(player.getUniqueId()); } - public static ProfileManager get(String name) { - return new ProfileManager(name); + public static AppearanceManager get(String name) { + return new AppearanceManager(name); } public boolean hasData() { 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 7101cbd..ef2ca6b 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,7 +1,7 @@ package xyz.atnrch.nicko.gui.items.settings; import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.appearance.NickoProfile; +import xyz.atnrch.nicko.profile.NickoProfile; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; 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 7ce31db..01a3c41 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,11 +1,14 @@ package xyz.atnrch.nicko.gui.items.settings; -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.appearance.NickoProfile; -import xyz.atnrch.nicko.i18n.Locale; 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.Locale; +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; @@ -21,13 +24,19 @@ public class LanguageCyclingItem { private final ItemProvider[] providers = getItems(); public AbstractItem get(Player player) { - 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 localeOrdinal = nickoProfile.getLocale().ordinal(); return CycleItem.withStateChangeHandler((observer, integer) -> { nickoProfile.setLocale(Locale.values()[integer]); observer.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 0.707107f); // 0.707107 ~= C + if (dataStore.updateCache(player.getUniqueId(), nickoProfile).isError()) { + final I18N i18n = new I18N(player); + player.sendMessage(i18n.translate(I18NDict.Event.Settings.ERROR)); + player.getOpenInventory().close(); + } }, localeOrdinal, providers); } diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java index 068d99f..18f76bb 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java @@ -1,13 +1,12 @@ package xyz.atnrch.nicko.i18n; import com.github.jsixface.YamlConfig; -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.appearance.NickoProfile; import org.bukkit.entity.Player; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.appearance.AppearanceManager; import java.io.InputStream; import java.text.MessageFormat; -import java.util.Optional; public class I18N { private final MessageFormat formatter = new MessageFormat(""); @@ -56,8 +55,8 @@ public class I18N { private Locale getPlayerLocale() { try { - final Optional profile = instance.getDataStore().getData(player.getUniqueId()); - return !profile.isPresent() ? Locale.FALLBACK_LOCALE : profile.get().getLocale(); + 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() + "."); 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 f8dbab5..79489f0 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -2,13 +2,13 @@ package xyz.atnrch.nicko.i18n; public class I18NDict { public static class Event { - public static final String EVENT_KEY = "event."; + private static final String EVENT_KEY = "event."; public static class Admin { - public static final String ADMIN_KEY = EVENT_KEY + "admin."; + private static final String ADMIN_KEY = EVENT_KEY + "admin."; public static class Cache { - public static final String CACHE_KEY = ADMIN_KEY + "cache."; + private static final String CACHE_KEY = ADMIN_KEY + "cache."; public static final String INVALIDATE_CACHE = CACHE_KEY + "invalidate_cache"; public static final String INVALIDATE_ENTRY = CACHE_KEY + "invalidate_entry"; @@ -16,8 +16,14 @@ public class I18NDict { } } + public static class Settings { + private static final String SETTINGS_KEY = EVENT_KEY + "settings."; + + public static final String ERROR = SETTINGS_KEY + "error"; + } + public static class Appearance { - public static final String APPEARANCE_KEY = EVENT_KEY + "appearance."; + private static final String APPEARANCE_KEY = EVENT_KEY + "appearance."; public static class Set { public static final String SET_KEY = APPEARANCE_KEY + "set."; @@ -27,7 +33,7 @@ public class I18NDict { } public static class Remove { - public static final String REMOVE_KEY = APPEARANCE_KEY + "remove."; + private static final String REMOVE_KEY = APPEARANCE_KEY + "remove."; public static final String OK = REMOVE_KEY + "ok"; public static final String MISSING = REMOVE_KEY + "missing"; @@ -35,7 +41,7 @@ public class I18NDict { } public static class Restore { - public static final String RESTORE_KEY = APPEARANCE_KEY + "restore."; + private static final String RESTORE_KEY = APPEARANCE_KEY + "restore."; public static final String OK = RESTORE_KEY + "ok"; public static final String ERROR = RESTORE_KEY + "error"; @@ -46,7 +52,6 @@ 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 PLAYER_OFFLINE = "error.offline"; 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"; diff --git a/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java b/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java index ea82f20..770de6e 100644 --- a/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java +++ b/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java @@ -1,11 +1,11 @@ package xyz.atnrch.nicko.placeholder; import me.clip.placeholderapi.expansion.PlaceholderExpansion; -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.appearance.NickoProfile; 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.NickoProfile; import java.util.Optional; diff --git a/src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java b/src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java index 93222e0..eabad4f 100644 --- a/src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java +++ b/src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.appearance; +package xyz.atnrch.nicko.profile; import xyz.atnrch.nicko.i18n.Locale; diff --git a/src/main/java/xyz/atnrch/nicko/storage/Cache.java b/src/main/java/xyz/atnrch/nicko/storage/Cache.java index c92a214..cf48f79 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/Cache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/Cache.java @@ -1,7 +1,7 @@ package xyz.atnrch.nicko.storage; import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.appearance.NickoProfile; +import xyz.atnrch.nicko.profile.NickoProfile; import java.util.Optional; import java.util.UUID; diff --git a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java index d94eb0b..1b6c0ce 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java +++ b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java @@ -3,7 +3,7 @@ package xyz.atnrch.nicko.storage; import org.bukkit.entity.Player; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.appearance.NickoProfile; +import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.mojang.MojangAPI; import xyz.atnrch.nicko.mojang.MojangUtils; @@ -28,8 +28,17 @@ public class PlayerDataStore { this.cache = configuration.getRedisConfiguration().isEnabled() ? new RedisCache(configuration) : new MapCache(); } + public ActionResult updateCache(UUID uuid, NickoProfile profile) { + final Optional retrieved = getData(uuid); + if (retrieved.isPresent()) { + getCache().cache(uuid, profile); + return ActionResult.ok(); + } + return ActionResult.error(I18NDict.Error.CACHE); + } + public Optional getData(UUID uuid) { - if (storage.isError()) { + if (storage.isError() || cache.isError()) { return Optional.empty(); } diff --git a/src/main/java/xyz/atnrch/nicko/storage/Storage.java b/src/main/java/xyz/atnrch/nicko/storage/Storage.java index 0f2dc41..ed1d0a9 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/Storage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/Storage.java @@ -1,7 +1,7 @@ package xyz.atnrch.nicko.storage; import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.appearance.NickoProfile; +import xyz.atnrch.nicko.profile.NickoProfile; import java.util.Optional; import java.util.UUID; diff --git a/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java b/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java index 7608c22..22e27c3 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java @@ -4,7 +4,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.appearance.NickoProfile; +import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.storage.Storage; import xyz.atnrch.nicko.storage.StorageProvider; diff --git a/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java b/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java index 3c15fef..7b566e5 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java @@ -1,7 +1,7 @@ package xyz.atnrch.nicko.storage.map; import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.appearance.NickoProfile; +import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.Cache; import xyz.atnrch.nicko.storage.CacheProvider; 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 fa8367f..ba57607 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/map/MapCacheProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/map/MapCacheProvider.java @@ -1,6 +1,6 @@ package xyz.atnrch.nicko.storage.map; -import xyz.atnrch.nicko.appearance.NickoProfile; +import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.CacheProvider; import java.util.HashMap; 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 baaea0b..36c67e3 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java @@ -2,7 +2,7 @@ package xyz.atnrch.nicko.storage.sql; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.appearance.NickoProfile; +import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.i18n.Locale; import xyz.atnrch.nicko.storage.Storage; diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index fe5d422..7087dd6 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -1,15 +1,16 @@ error: - generic: "Unknown error" + generic: "An unknown error occurred." permission: "§cYou do not have the required permission." invalid_username: "§cThis is not a valid Minecraft username." mojang_name: "There is no Minecraft account with this name." mojang_skin: "This Minecraft account has no skin." - offline: "§c{0} §fis offline!" cache: "Unable to get skin from the cache." sql: "SQL Error" json: "JSON Error" event: + settings: + error: "§cUnable to update your settings. §7§o({0})" appearance: set: error: "§cUnable to apply your disguise. §7§o({0})" diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index a9b4998..6904949 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -1,10 +1,9 @@ error: - generic: "Erreur inconnue" + 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." mojang_name: "Un compte Minecraft avec ce nom n'existe pas." mojang_skin: "Ce compte Minecraft n'a pas de skin." - offline: "§c{0} §fest hors-ligne!" cache: "Impossible de récupérer le skin depuis le cache." sql: "Erreur SQL" json: "Erreur JSON" diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java index 1712cd7..899ef00 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java @@ -7,7 +7,7 @@ import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.DataSourceConfiguration; import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.appearance.NickoProfile; +import xyz.atnrch.nicko.profile.NickoProfile; import org.junit.jupiter.api.*; import java.util.Optional; 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 2cd6880..1ddc95d 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java @@ -8,7 +8,7 @@ import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.DataSourceConfiguration; import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.appearance.NickoProfile; +import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.i18n.Locale; import java.util.Optional; diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java index 6fa5cdb..61a361f 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java @@ -6,7 +6,7 @@ import be.seeseemelk.mockbukkit.entity.PlayerMock; import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.DataSourceConfiguration; -import xyz.atnrch.nicko.appearance.NickoProfile; +import xyz.atnrch.nicko.profile.NickoProfile; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; 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 e439d11..524e2c2 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 @@ -10,7 +10,7 @@ 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.appearance.NickoProfile; +import xyz.atnrch.nicko.profile.NickoProfile; import java.util.Optional; From 86e65043e1baf0b85dec7d2fbc085a347400810d Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 14 Jul 2023 13:39:20 +0200 Subject: [PATCH 076/296] feat(persistence): delete --- .../items/settings/LanguageCyclingItem.java | 1 + .../java/xyz/atnrch/nicko/storage/Cache.java | 2 ++ .../xyz/atnrch/nicko/storage/Storage.java | 2 ++ .../nicko/storage/json/JSONStorage.java | 10 ++++++++ .../atnrch/nicko/storage/map/MapCache.java | 7 ++++++ .../nicko/storage/redis/RedisCache.java | 10 +++++++- .../atnrch/nicko/storage/sql/SQLStorage.java | 21 ++++++++++++++-- .../test/storage/redis/RedisCacheTest.java | 25 ++++++++++++++----- 8 files changed, 69 insertions(+), 9 deletions(-) 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 01a3c41..d15b8b7 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 @@ -32,6 +32,7 @@ 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 + // 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)); diff --git a/src/main/java/xyz/atnrch/nicko/storage/Cache.java b/src/main/java/xyz/atnrch/nicko/storage/Cache.java index cf48f79..e771324 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/Cache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/Cache.java @@ -17,6 +17,8 @@ public abstract class Cache { public abstract Optional retrieve(UUID uuid); + public abstract ActionResult delete(UUID uuid); + public boolean isError() { return error; } diff --git a/src/main/java/xyz/atnrch/nicko/storage/Storage.java b/src/main/java/xyz/atnrch/nicko/storage/Storage.java index ed1d0a9..d9c6743 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/Storage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/Storage.java @@ -17,6 +17,8 @@ public abstract class Storage { public abstract Optional retrieve(UUID uuid); + public abstract ActionResult delete(UUID uuid); + public boolean isError() { return error; } diff --git a/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java b/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java index 22e27c3..747a739 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java @@ -74,6 +74,16 @@ public class JSONStorage extends Storage { } } + @Override + public ActionResult delete(UUID uuid) { + final File directory = new File(NickoBukkit.getInstance().getDataFolder() + "/players/"); + final File file = new File(directory, uuid.toString() + ".json"); + if (file.delete() || !file.exists()) { + return ActionResult.ok(); + } + return ActionResult.error(I18NDict.Error.JSON_ERROR); + } + private boolean checkFileExists(File file) throws IOException { if (!file.exists()) { return file.createNewFile(); diff --git a/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java b/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java index 7b566e5..c573457 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java @@ -41,4 +41,11 @@ public class MapCache extends Cache { } return Optional.empty(); } + + @Override + public ActionResult delete(UUID uuid) { + final HashMap profiles = provider.getMap(); + profiles.remove(uuid); + return ActionResult.ok(); + } } 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 642fb9b..a8d532c 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java @@ -4,8 +4,8 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import redis.clients.jedis.Jedis; import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.config.Configuration; +import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.Cache; import xyz.atnrch.nicko.storage.CacheProvider; @@ -56,4 +56,12 @@ public class RedisCache extends Cache { return Optional.of(profile); } } + + @Override + public ActionResult delete(UUID uuid) { + try (Jedis jedis = provider.getJedis()) { + jedis.del("nicko:" + uuid.toString()); + return ActionResult.ok(); + } + } } 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 36c67e3..27abb9a 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java @@ -1,10 +1,10 @@ package xyz.atnrch.nicko.storage.sql; -import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.profile.NickoProfile; +import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.i18n.Locale; +import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.Storage; import java.io.ByteArrayInputStream; @@ -101,6 +101,23 @@ public class SQLStorage extends Storage { } } + @Override + public ActionResult delete(UUID uuid) { + final Connection connection = getProvider().getConnection(); + if (connection == null) return ActionResult.error(I18NDict.Error.SQL_ERROR); + + try { + final String sql = "DELETE FROM nicko.DATA WHERE uuid = ?"; + final PreparedStatement statement = connection.prepareStatement(sql); + statement.setBinaryStream(1, uuidToBin(uuid)); + statement.executeUpdate(); + return ActionResult.ok(); + } catch (SQLException e) { + logger.warning("Couldn't fetch profile: " + e.getMessage()); + return ActionResult.error(I18NDict.Error.SQL_ERROR); + } + } + 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); 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 524e2c2..b8bf8b7 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 @@ -3,17 +3,17 @@ package xyz.atnrch.nicko.test.storage.redis; 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; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.*; import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.appearance.AppearanceManager; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.DataSourceConfiguration; import xyz.atnrch.nicko.profile.NickoProfile; +import xyz.atnrch.nicko.storage.PlayerDataStore; import java.util.Optional; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; public class RedisCacheTest { @@ -34,13 +34,26 @@ public class RedisCacheTest { } @Test - @DisplayName("Cache Player Data") - public void cachePlayerData() { + @DisplayName("Cache Profile") + public void cacheProfile() { final Optional optionalProfile = plugin.getDataStore().getData(player.getUniqueId()); assertTrue(optionalProfile.isPresent()); assertTrue(plugin.getDataStore().getCache().isCached(player.getUniqueId())); } + @Test + @DisplayName("Update Cache Profile") + public void updatePlayerCache() { + final PlayerDataStore dataStore = plugin.getDataStore(); + final AppearanceManager appearanceManager = AppearanceManager.get(player); + appearanceManager.setName("Notch"); + dataStore.updateCache(player.getUniqueId(), appearanceManager.getProfile()); + final Optional retrieve = dataStore.getCache().retrieve(player.getUniqueId()); + assertTrue(retrieve.isPresent()); + final NickoProfile retrieved = retrieve.get(); + assertEquals(retrieved.getName(), "Notch"); + } + @AfterAll public static void shutdown() { MockBukkit.unmock(); From 87a256c9c581242a53a25c9e31ec576422855d25 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 14 Jul 2023 13:50:59 +0200 Subject: [PATCH 077/296] fix: make tests run in order --- .../test/storage/redis/RedisCacheTest.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) 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 b8bf8b7..18eb313 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 @@ -5,6 +5,7 @@ import be.seeseemelk.mockbukkit.ServerMock; 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; @@ -13,9 +14,9 @@ import xyz.atnrch.nicko.storage.PlayerDataStore; import java.util.Optional; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class RedisCacheTest { private static ServerMock server; private static NickoBukkit plugin; @@ -35,6 +36,7 @@ public class RedisCacheTest { @Test @DisplayName("Cache Profile") + @Order(1) public void cacheProfile() { final Optional optionalProfile = plugin.getDataStore().getData(player.getUniqueId()); assertTrue(optionalProfile.isPresent()); @@ -43,7 +45,8 @@ public class RedisCacheTest { @Test @DisplayName("Update Cache Profile") - public void updatePlayerCache() { + @Order(2) + public void updateCache() { final PlayerDataStore dataStore = plugin.getDataStore(); final AppearanceManager appearanceManager = AppearanceManager.get(player); appearanceManager.setName("Notch"); @@ -54,6 +57,15 @@ public class RedisCacheTest { assertEquals(retrieved.getName(), "Notch"); } + @Test + @DisplayName("Delete Cache Profile") + @Order(3) + public void deleteCache() { + final PlayerDataStore dataStore = plugin.getDataStore(); + final ActionResult cacheDelete = dataStore.getCache().delete(player.getUniqueId()); + assertFalse(cacheDelete.isError()); + } + @AfterAll public static void shutdown() { MockBukkit.unmock(); From 8464909b6db4ae186c57279c173085f87d8a4240 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 14 Jul 2023 16:53:24 +0200 Subject: [PATCH 078/296] refactor(sql): delete --- docker-compose.yml | 8 +- .../atnrch/nicko/storage/sql/SQLStorage.java | 20 +++-- .../nicko/storage/sql/SQLStorageProvider.java | 2 +- .../nicko/test/storage/SQLStorageTest.java | 73 +++++++------------ 4 files changed, 46 insertions(+), 57 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 6bdf830..cc20182 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,11 +12,13 @@ services: ports: - "3306:3306" - adminer: - image: adminer + phpmyadmin: + image: phpmyadmin restart: no + links: + - db ports: - - "8080:8080" + - "8080:80" redis: image: redis 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 27abb9a..0a30a51 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java @@ -44,6 +44,7 @@ public class SQLStorage extends Storage { final PreparedStatement statement = isStored(uuid) ? getUpdateStatement(connection, uuid, profile) : getInsertStatement(connection, uuid, profile); statement.executeUpdate(); + statement.close(); return ActionResult.ok(); } catch (SQLException e) { logger.warning("Couldn't send SQL Request: " + e.getMessage()); @@ -60,9 +61,10 @@ public class SQLStorage extends Storage { final String sql = "SELECT * FROM nicko.DATA WHERE uuid = ?"; final PreparedStatement statement = connection.prepareStatement(sql); - statement.setBinaryStream(1, uuidToBin(uuid)); + statement.setString(1, uuid.toString()); final ResultSet resultSet = statement.executeQuery(); + statement.close(); return resultSet.next(); } catch (SQLException e) { logger.warning("Couldn't check if data is present: " + e.getMessage()); @@ -79,7 +81,7 @@ public class SQLStorage extends Storage { final String sql = "SELECT * FROM nicko.DATA WHERE uuid = ?"; final PreparedStatement statement = connection.prepareStatement(sql); - statement.setBinaryStream(1, uuidToBin(uuid)); + statement.setString(1, uuid.toString()); final ResultSet resultSet = statement.executeQuery(); String name = ""; @@ -92,6 +94,7 @@ public class SQLStorage extends Storage { locale = resultSet.getString("locale"); bungeecord = resultSet.getBoolean("bungeecord"); } + statement.close(); final NickoProfile profile = new NickoProfile(name, skin, Locale.fromCode(locale), bungeecord); return Optional.of(profile); @@ -109,11 +112,12 @@ public class SQLStorage extends Storage { try { final String sql = "DELETE FROM nicko.DATA WHERE uuid = ?"; final PreparedStatement statement = connection.prepareStatement(sql); - statement.setBinaryStream(1, uuidToBin(uuid)); - statement.executeUpdate(); - return ActionResult.ok(); + statement.setString(1, uuid.toString()); + int rows = statement.executeUpdate(); + statement.close(); + return (rows == 1 ? ActionResult.ok() : ActionResult.error(I18NDict.Error.SQL_ERROR)); } catch (SQLException e) { - logger.warning("Couldn't fetch profile: " + e.getMessage()); + logger.warning("Couldn't delete profile: " + e.getMessage()); return ActionResult.error(I18NDict.Error.SQL_ERROR); } } @@ -121,7 +125,7 @@ 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); - statement.setBinaryStream(1, uuidToBin(uuid)); + 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(4, profile.getLocale().getCode()); @@ -136,7 +140,7 @@ public class SQLStorage extends Storage { statement.setString(2, profile.getSkin() == null ? null : profile.getSkin()); statement.setString(3, profile.getLocale().getCode()); statement.setBoolean(4, profile.isBungeecordTransfer()); - statement.setBinaryStream(5, uuidToBin(uuid)); + statement.setString(5, uuid.toString()); return statement; } diff --git a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java index 7f0ed2d..b899526 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java @@ -59,7 +59,7 @@ public class SQLStorageProvider implements StorageProvider { final Connection connection = getConnection(); String query = "CREATE TABLE IF NOT EXISTS %s.DATA " + - "(uuid binary(16) NOT NULL," + + "(uuid varchar(36) NOT NULL," + "name varchar(16)," + "skin varchar(16)," + "locale char(2) NOT NULL," + 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 1ddc95d..e92dbe2 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java @@ -10,11 +10,11 @@ import xyz.atnrch.nicko.config.DataSourceConfiguration; import xyz.atnrch.nicko.appearance.ActionResult; import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.i18n.Locale; +import xyz.atnrch.nicko.storage.PlayerDataStore; import java.util.Optional; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class SQLStorageTest { @@ -35,39 +35,29 @@ public class SQLStorageTest { } @Test - @DisplayName("Create SQL Tables") + @DisplayName("Create tables") @Order(1) - public void createSQLTables() { + public void createTables() { assertFalse(plugin.getDataStore().getStorage().isError()); } @Test - @DisplayName("Store Player Via SQL") + @DisplayName("Store empty profile") @Order(2) - public void storePlayer() { + public void storeEmptyProfile() { final Optional optionalProfile = plugin.getDataStore().getData(player.getUniqueId()); assertTrue(optionalProfile.isPresent()); } @Test - @DisplayName("Retrieve Player Via SQL") + @DisplayName("Update profile") @Order(3) - public void retrievePlayer() { - final Optional storeAction = plugin.getDataStore().getData(player.getUniqueId()); - assertTrue(storeAction.isPresent()); - } - - @Test - @DisplayName("Update Player Via SQL") - @Order(4) - public void updatePlayer() { + public void updateProfile() { final Optional optionalProfile = plugin.getDataStore().getData(player.getUniqueId()); - assertTrue(optionalProfile.isPresent()); - final NickoProfile profile = optionalProfile.get(); - Assertions.assertNull(profile.getName()); - Assertions.assertNull(profile.getSkin()); - Assertions.assertEquals(profile.getLocale(), Locale.ENGLISH); + assertNull(profile.getName()); + assertNull(profile.getSkin()); + assertEquals(profile.getLocale(), Locale.ENGLISH); assertTrue(profile.isBungeecordTransfer()); profile.setName("Notch"); @@ -77,36 +67,29 @@ public class SQLStorageTest { final ActionResult result = plugin.getDataStore().saveData(player); assertFalse(result.isError()); + } - final Optional optionalUpdatedProfile = plugin.getDataStore().getData(player.getUniqueId()); - assertTrue(optionalUpdatedProfile.isPresent()); - final NickoProfile updatedProfile = optionalProfile.get(); - Assertions.assertEquals(updatedProfile.getName(), "Notch"); - Assertions.assertEquals(updatedProfile.getSkin(), "Notch"); - Assertions.assertEquals(updatedProfile.getLocale(), Locale.FRENCH); + @Test + @DisplayName("Get updated profile") + @Order(4) + public void hasProfileBeenUpdated() { + final Optional profile = plugin.getDataStore().getData(player.getUniqueId()); + assertTrue(profile.isPresent()); + + final NickoProfile updatedProfile = profile.get(); + assertEquals(updatedProfile.getName(), "Notch"); + assertEquals(updatedProfile.getSkin(), "Notch"); + assertEquals(updatedProfile.getLocale(), Locale.FRENCH); assertFalse(updatedProfile.isBungeecordTransfer()); } @Test - @DisplayName("Remove Player Disguise Via SQL") + @DisplayName("Delete profile") @Order(5) - public void removePlayerDisguise() { - final Optional optionalProfile = plugin.getDataStore().getData(player.getUniqueId()); - assertTrue(optionalProfile.isPresent()); - - final NickoProfile profile = optionalProfile.get(); - - profile.setName(null); - profile.setSkin(null); - - final ActionResult result = plugin.getDataStore().saveData(player); - assertFalse(result.isError()); - - final Optional optionalUpdatedProfile = plugin.getDataStore().getData(player.getUniqueId()); - assertTrue(optionalUpdatedProfile.isPresent()); - final NickoProfile updatedProfile = optionalProfile.get(); - Assertions.assertNull(updatedProfile.getName()); - Assertions.assertNull(updatedProfile.getSkin()); + public void deleteProfile() { + final PlayerDataStore dataStore = plugin.getDataStore(); + final ActionResult sqlDelete = dataStore.getStorage().delete(player.getUniqueId()); + assertFalse(sqlDelete.isError()); } @AfterAll From 3a7da4b3d695835c4e9e5042bf158e6d07bccab1 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 14 Jul 2023 22:54:01 +0200 Subject: [PATCH 079/296] sql: delete is not deleting wtf --- docker-compose.yml | 8 +++++++- .../xyz/atnrch/nicko/storage/sql/SQLStorage.java | 11 ++--------- .../nicko/storage/sql/SQLStorageProvider.java | 5 ++--- .../atnrch/nicko/test/storage/SQLStorageTest.java | 13 +++++++------ 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index cc20182..28db8fc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,10 +5,13 @@ version: '3.1' services: db: - image: mariadb + image: mariadb:latest restart: no environment: + MARIADB_DB: db MARIADB_ROOT_PASSWORD: 12345 + volumes: + - mysql:/var/lib/mysql ports: - "3306:3306" @@ -25,3 +28,6 @@ services: restart: no ports: - "6379:6379" + +volumes: + mysql: \ No newline at end of file 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 0a30a51..b26fd76 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java @@ -9,10 +9,7 @@ import xyz.atnrch.nicko.storage.Storage; import java.io.ByteArrayInputStream; import java.nio.ByteBuffer; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; +import java.sql.*; import java.util.Optional; import java.util.UUID; import java.util.logging.Logger; @@ -44,7 +41,6 @@ public class SQLStorage extends Storage { final PreparedStatement statement = isStored(uuid) ? getUpdateStatement(connection, uuid, profile) : getInsertStatement(connection, uuid, profile); statement.executeUpdate(); - statement.close(); return ActionResult.ok(); } catch (SQLException e) { logger.warning("Couldn't send SQL Request: " + e.getMessage()); @@ -64,7 +60,6 @@ public class SQLStorage extends Storage { statement.setString(1, uuid.toString()); final ResultSet resultSet = statement.executeQuery(); - statement.close(); return resultSet.next(); } catch (SQLException e) { logger.warning("Couldn't check if data is present: " + e.getMessage()); @@ -94,7 +89,6 @@ public class SQLStorage extends Storage { locale = resultSet.getString("locale"); bungeecord = resultSet.getBoolean("bungeecord"); } - statement.close(); final NickoProfile profile = new NickoProfile(name, skin, Locale.fromCode(locale), bungeecord); return Optional.of(profile); @@ -110,11 +104,10 @@ public class SQLStorage extends Storage { if (connection == null) return ActionResult.error(I18NDict.Error.SQL_ERROR); try { - final String sql = "DELETE FROM nicko.DATA WHERE uuid = ?"; + final String sql = "DELETE FROM nicko.DATA WHERE uuid = ? LIMIT 1"; final PreparedStatement statement = connection.prepareStatement(sql); statement.setString(1, uuid.toString()); int rows = statement.executeUpdate(); - statement.close(); return (rows == 1 ? ActionResult.ok() : ActionResult.error(I18NDict.Error.SQL_ERROR)); } catch (SQLException e) { logger.warning("Couldn't delete profile: " + e.getMessage()); diff --git a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java index b899526..b01a3ec 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java @@ -1,9 +1,9 @@ package xyz.atnrch.nicko.storage.sql; +import org.mariadb.jdbc.MariaDbDataSource; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.DataSourceConfiguration; import xyz.atnrch.nicko.storage.StorageProvider; -import org.mariadb.jdbc.MariaDbDataSource; import java.sql.Connection; import java.sql.PreparedStatement; @@ -31,6 +31,7 @@ public class SQLStorageProvider implements StorageProvider { dataSource.setUser(sqlConfiguration.getUsername()); dataSource.setPassword(sqlConfiguration.getPassword()); connection = dataSource.getConnection(); + connection.setAutoCommit(true); final boolean initialized = connection != null && !connection.isClosed(); if (!initialized) return false; @@ -69,7 +70,6 @@ public class SQLStorageProvider implements StorageProvider { final PreparedStatement statement = connection.prepareStatement(query); statement.executeUpdate(); - statement.close(); } private void createDatabase() throws SQLException { @@ -80,7 +80,6 @@ public class SQLStorageProvider implements StorageProvider { final PreparedStatement statement = connection.prepareStatement(query); statement.executeUpdate(); - statement.close(); } public Connection getConnection() { 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 e92dbe2..1493c60 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java @@ -21,6 +21,7 @@ public class SQLStorageTest { private static ServerMock server; private static NickoBukkit plugin; private static PlayerMock player; + private static PlayerDataStore dataStore; @BeforeAll public static void setup() { @@ -31,6 +32,7 @@ public class SQLStorageTest { false); server = MockBukkit.mock(); plugin = MockBukkit.load(NickoBukkit.class, config); + dataStore = plugin.getDataStore(); player = server.addPlayer(); } @@ -38,14 +40,14 @@ public class SQLStorageTest { @DisplayName("Create tables") @Order(1) public void createTables() { - assertFalse(plugin.getDataStore().getStorage().isError()); + assertFalse(dataStore.getStorage().isError()); } @Test @DisplayName("Store empty profile") @Order(2) public void storeEmptyProfile() { - final Optional optionalProfile = plugin.getDataStore().getData(player.getUniqueId()); + final Optional optionalProfile = dataStore.getData(player.getUniqueId()); assertTrue(optionalProfile.isPresent()); } @@ -53,7 +55,7 @@ public class SQLStorageTest { @DisplayName("Update profile") @Order(3) public void updateProfile() { - final Optional optionalProfile = plugin.getDataStore().getData(player.getUniqueId()); + final Optional optionalProfile = dataStore.getData(player.getUniqueId()); final NickoProfile profile = optionalProfile.get(); assertNull(profile.getName()); assertNull(profile.getSkin()); @@ -65,7 +67,7 @@ public class SQLStorageTest { profile.setLocale(Locale.FRENCH); profile.setBungeecordTransfer(false); - final ActionResult result = plugin.getDataStore().saveData(player); + final ActionResult result = dataStore.saveData(player); assertFalse(result.isError()); } @@ -73,7 +75,7 @@ public class SQLStorageTest { @DisplayName("Get updated profile") @Order(4) public void hasProfileBeenUpdated() { - final Optional profile = plugin.getDataStore().getData(player.getUniqueId()); + final Optional profile = dataStore.getData(player.getUniqueId()); assertTrue(profile.isPresent()); final NickoProfile updatedProfile = profile.get(); @@ -87,7 +89,6 @@ public class SQLStorageTest { @DisplayName("Delete profile") @Order(5) public void deleteProfile() { - final PlayerDataStore dataStore = plugin.getDataStore(); final ActionResult sqlDelete = dataStore.getStorage().delete(player.getUniqueId()); assertFalse(sqlDelete.isError()); } From 7d07834bf71642eb368019d264dc297145f6c6a0 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 15 Jul 2023 10:29:59 +0200 Subject: [PATCH 080/296] fix(sql): mockbukkit is the issue --- .../atnrch/nicko/storage/sql/SQLStorage.java | 23 +++++++-------- .../nicko/storage/sql/SQLStorageProvider.java | 2 +- .../nicko/test/storage/SQLStorageTest.java | 29 +++++++++---------- 3 files changed, 25 insertions(+), 29 deletions(-) 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 b26fd76..903328d 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java @@ -7,9 +7,10 @@ import xyz.atnrch.nicko.i18n.Locale; import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.Storage; -import java.io.ByteArrayInputStream; -import java.nio.ByteBuffer; -import java.sql.*; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.Optional; import java.util.UUID; import java.util.logging.Logger; @@ -54,7 +55,7 @@ public class SQLStorage extends Storage { if (connection == null) return false; try { - final String sql = "SELECT * FROM nicko.DATA WHERE uuid = ?"; + final String sql = "SELECT uuid FROM nicko.DATA WHERE uuid = ?"; final PreparedStatement statement = connection.prepareStatement(sql); statement.setString(1, uuid.toString()); @@ -71,6 +72,7 @@ public class SQLStorage extends Storage { public Optional retrieve(UUID uuid) { final Connection connection = getProvider().getConnection(); if (connection == null) return Optional.empty(); + if (!isStored(uuid)) return Optional.empty(); try { final String sql = "SELECT * FROM nicko.DATA WHERE uuid = ?"; @@ -89,6 +91,9 @@ 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); @@ -104,7 +109,7 @@ public class SQLStorage extends Storage { if (connection == null) return ActionResult.error(I18NDict.Error.SQL_ERROR); try { - final String sql = "DELETE FROM nicko.DATA WHERE uuid = ? LIMIT 1"; + final String sql = "DELETE FROM nicko.DATA WHERE uuid = ?"; final PreparedStatement statement = connection.prepareStatement(sql); statement.setString(1, uuid.toString()); int rows = statement.executeUpdate(); @@ -136,12 +141,4 @@ public class SQLStorage extends Storage { statement.setString(5, uuid.toString()); return statement; } - - private ByteArrayInputStream uuidToBin(UUID uuid) { - byte[] bytes = new byte[16]; - ByteBuffer.wrap(bytes) - .putLong(uuid.getMostSignificantBits()) - .putLong(uuid.getLeastSignificantBits()); - return new ByteArrayInputStream(bytes); - } } diff --git a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java index b01a3ec..473fd77 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java @@ -65,7 +65,7 @@ public class SQLStorageProvider implements StorageProvider { "skin varchar(16)," + "locale char(2) NOT NULL," + "bungeecord boolean NOT NULL," + - "PRIMARY KEY (UUID))"; + "PRIMARY KEY (uuid))"; query = query.replace("%s", schemaName); final PreparedStatement statement = connection.prepareStatement(query); 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 1493c60..04585a3 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java @@ -1,27 +1,24 @@ package xyz.atnrch.nicko.test.storage; import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -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.config.Configuration; import xyz.atnrch.nicko.config.DataSourceConfiguration; -import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.i18n.Locale; +import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.PlayerDataStore; import java.util.Optional; +import java.util.UUID; import static org.junit.jupiter.api.Assertions.*; @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class SQLStorageTest { - private static ServerMock server; - private static NickoBukkit plugin; - private static PlayerMock player; private static PlayerDataStore dataStore; + private static UUID uuid; @BeforeAll public static void setup() { @@ -30,10 +27,12 @@ public class SQLStorageTest { DataSourceConfiguration.REDIS_EMPTY, "", false); - server = MockBukkit.mock(); - plugin = MockBukkit.load(NickoBukkit.class, config); + + MockBukkit.mock(); + + final NickoBukkit plugin = MockBukkit.load(NickoBukkit.class, config); dataStore = plugin.getDataStore(); - player = server.addPlayer(); + uuid = UUID.randomUUID(); } @Test @@ -47,7 +46,7 @@ public class SQLStorageTest { @DisplayName("Store empty profile") @Order(2) public void storeEmptyProfile() { - final Optional optionalProfile = dataStore.getData(player.getUniqueId()); + final Optional optionalProfile = dataStore.getData(uuid); assertTrue(optionalProfile.isPresent()); } @@ -55,7 +54,7 @@ public class SQLStorageTest { @DisplayName("Update profile") @Order(3) public void updateProfile() { - final Optional optionalProfile = dataStore.getData(player.getUniqueId()); + final Optional optionalProfile = dataStore.getData(uuid); final NickoProfile profile = optionalProfile.get(); assertNull(profile.getName()); assertNull(profile.getSkin()); @@ -67,7 +66,7 @@ public class SQLStorageTest { profile.setLocale(Locale.FRENCH); profile.setBungeecordTransfer(false); - final ActionResult result = dataStore.saveData(player); + final ActionResult result = dataStore.getStorage().store(uuid, profile); assertFalse(result.isError()); } @@ -75,7 +74,7 @@ public class SQLStorageTest { @DisplayName("Get updated profile") @Order(4) public void hasProfileBeenUpdated() { - final Optional profile = dataStore.getData(player.getUniqueId()); + final Optional profile = dataStore.getData(uuid); assertTrue(profile.isPresent()); final NickoProfile updatedProfile = profile.get(); @@ -89,7 +88,7 @@ public class SQLStorageTest { @DisplayName("Delete profile") @Order(5) public void deleteProfile() { - final ActionResult sqlDelete = dataStore.getStorage().delete(player.getUniqueId()); + final ActionResult sqlDelete = dataStore.getStorage().delete(uuid); assertFalse(sqlDelete.isError()); } From 378813c829c71d13f5f0418fc4e88c3c790bb26d Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 15 Jul 2023 10:32:22 +0200 Subject: [PATCH 081/296] refactor: don't set variable --- src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java | 3 +-- .../java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java | 3 +-- .../xyz/atnrch/nicko/test/storage/redis/RedisCacheTest.java | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java index 899ef00..120e5fc 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java @@ -16,7 +16,6 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; public class BrokenSQLTest { - private static ServerMock server; private static NickoBukkit plugin; private static PlayerMock player; @@ -27,7 +26,7 @@ public class BrokenSQLTest { DataSourceConfiguration.REDIS_EMPTY, "", false); - server = MockBukkit.mock(); + final ServerMock server = MockBukkit.mock(); plugin = MockBukkit.load(NickoBukkit.class, config); player = server.addPlayer(); } diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java index 61a361f..9f67017 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java @@ -17,7 +17,6 @@ import java.util.Optional; import static org.junit.jupiter.api.Assertions.assertTrue; public class MapCacheTest { - private static ServerMock server; private static NickoBukkit plugin; private static PlayerMock player; @@ -28,7 +27,7 @@ public class MapCacheTest { DataSourceConfiguration.REDIS_EMPTY, "", false); - server = MockBukkit.mock(); + final ServerMock server = MockBukkit.mock(); plugin = MockBukkit.load(NickoBukkit.class, config); player = server.addPlayer(); } 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 18eb313..beea0b6 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 @@ -18,7 +18,6 @@ import static org.junit.jupiter.api.Assertions.*; @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class RedisCacheTest { - private static ServerMock server; private static NickoBukkit plugin; private static PlayerMock player; @@ -29,7 +28,7 @@ public class RedisCacheTest { new DataSourceConfiguration(true, "127.0.0.1", 6379, "", ""), "", false); - server = MockBukkit.mock(); + final ServerMock server = MockBukkit.mock(); plugin = MockBukkit.load(NickoBukkit.class, config); player = server.addPlayer(); } From 119392320bd238fc13a071b364a86b23f6d36e8e Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 15 Jul 2023 12:39:13 +0200 Subject: [PATCH 082/296] refactor(gui): item placement --- src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java b/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java index ba2475b..7b9d156 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java @@ -18,9 +18,9 @@ public class HomeGUI { public HomeGUI(Player player) { final String[] dynamicStructure = new String[]{ - "# # # # # # # # P", - "# # # N B S # # #", - "E A # # # # # # R"}; + "# # # # # # # # #", + "A # # N B S # # #", + "E P # # # # # # R"}; if (!player.isOp() || !player.hasPermission("nicko.admin")) { dynamicStructure[2] = dynamicStructure[2].replace("A", "#"); From 6fae824fe21f19aa49a8436f458ebab0a638c1f0 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 15 Jul 2023 23:06:47 +0200 Subject: [PATCH 083/296] feat: player management/check --- .../nicko/appearance/AppearanceManager.java | 1 + .../java/xyz/atnrch/nicko/gui/AdminGUI.java | 4 +- .../xyz/atnrch/nicko/gui/PlayerCheckGUI.java | 53 +++++++++++++++++++ .../gui/items/admin/ManagePlayerItem.java | 31 +++++++++++ .../admin/check/PlayerInformationItem.java | 42 +++++++++++++++ 5 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 src/main/java/xyz/atnrch/nicko/gui/PlayerCheckGUI.java create mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/admin/ManagePlayerItem.java create mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/admin/check/PlayerInformationItem.java diff --git a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java index 2b51e6d..f46770d 100644 --- a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java @@ -106,6 +106,7 @@ public class AppearanceManager { if (!actionResult.isError()) { this.profile.setSkin(null); this.profile.setName(null); + dataStore.getCache().cache(uuid, profile); } return actionResult; } diff --git a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java index 015ad69..8c19b38 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java @@ -1,6 +1,7 @@ package xyz.atnrch.nicko.gui; 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.xenondevs.invui.gui.Gui; @@ -16,10 +17,11 @@ public class AdminGUI { this.gui = Gui.normal() .setStructure( "# # # # # # # # #", - "# # # S U U # # #", + "# # # S C U # # #", "B # # # # # # # #" ) .addIngredient('S', new ManageCacheItem()) + .addIngredient('C', new ManagePlayerItem()) .addIngredient('B', new GoBackItem(parent.getGUI(), parent.getTitle())) .build(); this.player = player; diff --git a/src/main/java/xyz/atnrch/nicko/gui/PlayerCheckGUI.java b/src/main/java/xyz/atnrch/nicko/gui/PlayerCheckGUI.java new file mode 100644 index 0000000..a09b80d --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/gui/PlayerCheckGUI.java @@ -0,0 +1,53 @@ +package xyz.atnrch.nicko.gui; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +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.xenondevs.invui.gui.Gui; +import xyz.xenondevs.invui.gui.ScrollGui; +import xyz.xenondevs.invui.gui.structure.Markers; +import xyz.xenondevs.invui.item.Item; +import xyz.xenondevs.invui.window.Window; + +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; + + public PlayerCheckGUI(Player player) { + final List items = Bukkit.getOnlinePlayers().stream() + .map(Entity::getUniqueId) + .map(PlayerInformationItem::new) + .collect(Collectors.toList()); + + final AdminGUI parent = new AdminGUI(player); + gui = ScrollGui.items(guiItemBuilder -> { + guiItemBuilder.setStructure( + "x x x x x x x x U", + "x x x x x x x x #", + "x x x x x x x x #", + "x x x x x x x x #", + "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.setContent(items); + }); + + this.player = player; + } + + public void open() { + Window.single().setGui(gui).setTitle(TITLE).open(player); + } +} 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 new file mode 100644 index 0000000..dcf133f --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManagePlayerItem.java @@ -0,0 +1,31 @@ +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.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); + } + + @Override + public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent + event) { + if (clickType.isLeftClick() || clickType.isRightClick()) { + event.getView().close(); + new PlayerCheckGUI(player).open(); + } + } +} 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 new file mode 100644 index 0000000..6b68fcf --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/check/PlayerInformationItem.java @@ -0,0 +1,42 @@ +package xyz.atnrch.nicko.gui.items.admin.check; + +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.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.builder.SkullBuilder; +import xyz.xenondevs.invui.item.impl.AsyncItem; + +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..."), () -> { + final Player player = Bukkit.getPlayer(uuid); + final SkullBuilder skull = new SkullBuilder(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" + ); + } + + skull.setDisplayName("§6" + player.getName()); + return skull; + }); + } +} From fe78fd0e2b71f6bc3b18adf762b6a22f577eba05 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 15 Jul 2023 23:08:58 +0200 Subject: [PATCH 084/296] feat: folia warning --- src/main/java/xyz/atnrch/nicko/NickoBukkit.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index db07808..bee34ce 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -81,6 +81,12 @@ public class NickoBukkit extends JavaPlugin { } if (!unitTesting) { + try { + Class.forName("io.papermc.paper.threadedregions.RegionizedServerInitEvent"); + getLogger().warning("Nicko has not been tested against Folia and might not work at all!"); + getLogger().warning("Issues regarding Nicko on Folia will not be ignored for now."); + } catch (ClassNotFoundException ignored) { } + localeFileManager = new LocaleFileManager(); if (configuration.isCustomLocale()) { if (localeFileManager.dumpFromLocale(Locale.ENGLISH)) { From 2ef21a796e5129d255634c95a0dbe6b24dcf12b5 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 16 Jul 2023 00:15:59 +0200 Subject: [PATCH 085/296] feat wip(i18n): gui translation --- .../xyz/atnrch/nicko/anvil/AnvilManager.java | 2 +- .../nicko/command/sub/NickoDebugSubCmd.java | 2 +- .../nicko/event/PlayerJoinListener.java | 2 +- src/main/java/xyz/atnrch/nicko/i18n/I18N.java | 35 +++++++++++++++++-- .../atnrch/nicko/i18n/LocaleFileManager.java | 2 +- src/main/resources/fr.yml | 32 ++++++++++++++++- 6 files changed, 68 insertions(+), 7 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java index 2e9f13f..aa65338 100644 --- a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java @@ -107,7 +107,7 @@ public class AnvilManager { if (!actionResult.isError()) { player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.OK)); } else { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.ERROR, i18n.translateWithoutPrefix(actionResult.getErrorKey()))); + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.ERROR, i18n.translatePrefixless(actionResult.getErrorKey()))); } return Collections.singletonList(AnvilGUI.ResponseAction.close()); } diff --git a/src/main/java/xyz/atnrch/nicko/command/sub/NickoDebugSubCmd.java b/src/main/java/xyz/atnrch/nicko/command/sub/NickoDebugSubCmd.java index eee712d..3bfa40d 100644 --- a/src/main/java/xyz/atnrch/nicko/command/sub/NickoDebugSubCmd.java +++ b/src/main/java/xyz/atnrch/nicko/command/sub/NickoDebugSubCmd.java @@ -55,7 +55,7 @@ public class NickoDebugSubCmd { 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.translateWithoutPrefix(result.getErrorKey())); + target.sendMessage(prefix + "§cWhoops. Something happened: " + i18n.translatePrefixless(result.getErrorKey())); } } } diff --git a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java index 02698f5..b4a3a19 100644 --- a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java @@ -29,7 +29,7 @@ public class PlayerJoinListener implements Listener { if (!actionResult.isError()) { player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Restore.OK)); } else { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Restore.ERROR, i18n.translateWithoutPrefix(actionResult.getErrorKey()))); + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Restore.ERROR, i18n.translatePrefixless(actionResult.getErrorKey()))); } } }, 20L); diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java index 18f76bb..0f742fc 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java @@ -7,6 +7,9 @@ import xyz.atnrch.nicko.appearance.AppearanceManager; import java.io.InputStream; import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; public class I18N { private final MessageFormat formatter = new MessageFormat(""); @@ -19,6 +22,21 @@ public class I18N { this.playerLocale = getPlayerLocale(); } + public List translateItem(String key, Object... arguments) { + final ArrayList lines = new ArrayList<>(); + final String itemNameKey = readString(key + ".name"); + final List itemLoreKey = readString(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 String translate(String key, Object... arguments) { final String string = readString(key); @@ -30,7 +48,7 @@ public class I18N { } } - public String translateWithoutPrefix(String key, Object... arguments) { + public String translatePrefixless(String key, Object... arguments) { final String translation = readString(key); try { formatter.applyPattern(translation); @@ -43,7 +61,20 @@ public class I18N { private String readString(String key) { String string; if (playerLocale == Locale.CUSTOM) { - string = instance.getLocaleFileManager().get(key); + string = instance.getLocaleFileManager().getString(key); + } else { + final InputStream resource = instance.getResource(playerLocale.getCode() + ".yml"); + final YamlConfig yamlConfig = YamlConfig.load(resource); + string = yamlConfig.getString(key); + } + + return string; + } + + private List readList(String key) { + String string; + if (playerLocale == Locale.CUSTOM) { + string = instance.getLocaleFileManager().getString(key); } else { final InputStream resource = instance.getResource(playerLocale.getCode() + ".yml"); final YamlConfig yamlConfig = YamlConfig.load(resource); diff --git a/src/main/java/xyz/atnrch/nicko/i18n/LocaleFileManager.java b/src/main/java/xyz/atnrch/nicko/i18n/LocaleFileManager.java index d2ff7e6..b345f88 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/LocaleFileManager.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/LocaleFileManager.java @@ -11,7 +11,7 @@ public class LocaleFileManager { private final File folder = new File(NickoBukkit.getInstance().getDataFolder() + "/lang/"); private final File file = new File(folder, "lang.yml"); - public String get(String key) { + 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); diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 6904949..7aa0f01 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -23,4 +23,34 @@ event: admin: cache: invalidate_cache: "§fCache complet invalidé." - invalidate_entry: "§6{0} §fa été invalidé." \ No newline at end of file + invalidate_entry: "§6{0} §fa été invalidé." + +gui: + exit: "Quitter" + home: + admin: + name: "Panel d'administration" + lore: + - "Configurez et gérez Nicko." + settings: + name: "Paramètres" + lore: + - "Configurez votre expérience." + change_name: + name: "Changer le §6pseudo" + change_skin: + name: "Changer le §6skin" + change_both: + name: "Changer les §6deux" + reset: + name: "Réinitialiser l'apparence" + lore: + - "Supprime complètement votre déguisement." + settings: + language: + name: "Language" + 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 From 77a262301391f729af2c2ce1929b7ffb30d89804 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 16 Jul 2023 00:16:55 +0200 Subject: [PATCH 086/296] fix(folia): they will be. --- src/main/java/xyz/atnrch/nicko/NickoBukkit.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index bee34ce..84dd3f2 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -84,7 +84,7 @@ public class NickoBukkit extends JavaPlugin { try { Class.forName("io.papermc.paper.threadedregions.RegionizedServerInitEvent"); getLogger().warning("Nicko has not been tested against Folia and might not work at all!"); - getLogger().warning("Issues regarding Nicko on Folia will not be ignored for now."); + getLogger().warning("Issues regarding Nicko on Folia will be ignored for now."); } catch (ClassNotFoundException ignored) { } localeFileManager = new LocaleFileManager(); From f15783164183d2b11d9b271687b603563b4b9f9e Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 16 Jul 2023 16:36:50 +0200 Subject: [PATCH 087/296] feat wip: item lore translation --- src/main/java/xyz/atnrch/nicko/i18n/I18N.java | 37 +++++++++------ .../java/xyz/atnrch/nicko/i18n/I18NDict.java | 30 ++++++++---- .../atnrch/nicko/i18n/LocaleFileManager.java | 12 +++++ src/main/resources/fr.yml | 10 ++-- .../atnrch/nicko/test/i18n/I18NLoreTest.java | 46 +++++++++++++++++++ 5 files changed, 110 insertions(+), 25 deletions(-) create mode 100644 src/test/java/xyz/atnrch/nicko/test/i18n/I18NLoreTest.java diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java index 0f742fc..466af0a 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java @@ -22,10 +22,15 @@ public class I18N { this.playerLocale = getPlayerLocale(); } + public I18N(Locale locale) { + this.player = null; + this.playerLocale = locale; + } + public List translateItem(String key, Object... arguments) { final ArrayList lines = new ArrayList<>(); final String itemNameKey = readString(key + ".name"); - final List itemLoreKey = readString(key + ".lore"); + final ArrayList itemLoreKey = readList(key + ".lore"); try { // Item Name formatter.applyPattern(itemNameKey); @@ -59,29 +64,35 @@ public class I18N { } private String readString(String key) { - String string; + YamlConfig yamlFile; if (playerLocale == Locale.CUSTOM) { - string = instance.getLocaleFileManager().getString(key); + yamlFile = instance.getLocaleFileManager().getYamlFile(); } else { final InputStream resource = instance.getResource(playerLocale.getCode() + ".yml"); - final YamlConfig yamlConfig = YamlConfig.load(resource); - string = yamlConfig.getString(key); + yamlFile = YamlConfig.load(resource); } - - return string; + return yamlFile.getString(key); } - private List readList(String key) { - String string; + private ArrayList readList(String key) { + final ArrayList lines = new ArrayList<>(); + YamlConfig yamlFile; if (playerLocale == Locale.CUSTOM) { - string = instance.getLocaleFileManager().getString(key); + yamlFile = instance.getLocaleFileManager().getYamlFile(); } else { final InputStream resource = instance.getResource(playerLocale.getCode() + ".yml"); - final YamlConfig yamlConfig = YamlConfig.load(resource); - string = yamlConfig.getString(key); + yamlFile = YamlConfig.load(resource); } - return string; + // 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; } private Locale getPlayerLocale() { diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index 79489f0..cc4317e 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -1,6 +1,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 class Event { private static final String EVENT_KEY = "event."; @@ -49,14 +60,15 @@ 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 class GUI { + private static final String GUI_KEY = "gui."; + + public static final String EXIT = GUI_KEY + "exit"; + + public static class Home { + private static final String HOME_KEY = GUI_KEY + "home."; + + public static final String ADMIN = HOME_KEY + "admin"; + } } } diff --git a/src/main/java/xyz/atnrch/nicko/i18n/LocaleFileManager.java b/src/main/java/xyz/atnrch/nicko/i18n/LocaleFileManager.java index b345f88..f2ffba8 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/LocaleFileManager.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/LocaleFileManager.java @@ -10,6 +10,7 @@ import java.nio.file.Files; public class LocaleFileManager { private final File folder = new File(NickoBukkit.getInstance().getDataFolder() + "/lang/"); private final File file = new File(folder, "lang.yml"); + private YamlConfig yamlFile; public String getString(String key) { if (!file.exists()) return key; @@ -39,4 +40,15 @@ public class LocaleFileManager { return false; } } + + public YamlConfig getYamlFile() { + if (yamlFile == null) { + try (BufferedInputStream inputStream = new BufferedInputStream(Files.newInputStream(file.toPath()))) { + yamlFile = YamlConfig.load(inputStream); + } catch (IOException ignored) { + return null; + } + } + return yamlFile; + } } diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 7aa0f01..ff0bc85 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -29,13 +29,17 @@ gui: exit: "Quitter" home: admin: - name: "Panel d'administration" + name: "Panel d''administration" lore: - - "Configurez et gérez Nicko." + length: 1 + content: + - "Configurez et gérez Nicko." settings: name: "Paramètres" lore: - - "Configurez votre expérience." + length: 1 + content: + "Configurez votre expérience." change_name: name: "Changer le §6pseudo" change_skin: diff --git a/src/test/java/xyz/atnrch/nicko/test/i18n/I18NLoreTest.java b/src/test/java/xyz/atnrch/nicko/test/i18n/I18NLoreTest.java new file mode 100644 index 0000000..2c17db5 --- /dev/null +++ b/src/test/java/xyz/atnrch/nicko/test/i18n/I18NLoreTest.java @@ -0,0 +1,46 @@ +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; +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.Locale; + +import java.util.List; + +public class I18NLoreTest { + private static NickoBukkit plugin; + private static PlayerMock player; + + @BeforeAll + public static void setup() { + final Configuration config = new Configuration( + DataSourceConfiguration.SQL_EMPTY, + DataSourceConfiguration.REDIS_EMPTY, + "", + false); + final ServerMock server = MockBukkit.mock(); + plugin = MockBukkit.load(NickoBukkit.class, config); + } + + @Test + @DisplayName("Translate Item Lore") + public void translateItemLore() { + final I18N i18n = new I18N(Locale.FRENCH); + List strings = i18n.translateItem(I18NDict.GUI.Home.ADMIN); + System.out.println("strings = " + strings); + } + + @AfterAll + public static void shutdown() { + MockBukkit.unmock(); + } +} From 26daa3a038f8dec2a732b0a561814dd93f9dff51 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 26 Jul 2023 21:10:53 +0200 Subject: [PATCH 088/296] feat(deps): upgrade --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d936797..f644ea5 100644 --- a/pom.xml +++ b/pom.xml @@ -95,7 +95,7 @@ com.github.jsixface yamlconfig - 1.1.2 + 1.2 From 5d3a99f72d136c25ab4d675cec31fe170d8c737e Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 26 Jul 2023 21:42:21 +0200 Subject: [PATCH 089/296] feat: item translator --- .../atnrch/nicko/gui/items/home/ExitItem.java | 8 ++-- src/main/java/xyz/atnrch/nicko/i18n/I18N.java | 32 +++++----------- .../xyz/atnrch/nicko/i18n/ItemTranslator.java | 38 +++++++++++++++++++ src/main/resources/en.yml | 31 ++++++++++++++- 4 files changed, 82 insertions(+), 27 deletions(-) create mode 100644 src/main/java/xyz/atnrch/nicko/i18n/ItemTranslator.java 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..ea6ff09 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,6 +1,5 @@ package xyz.atnrch.nicko.gui.items.home; -import com.comphenix.protocol.utility.MinecraftVersion; import org.bukkit.Material; import org.bukkit.event.inventory.ClickType; import xyz.xenondevs.invui.item.builder.ItemBuilder; @@ -9,13 +8,14 @@ import xyz.xenondevs.invui.item.impl.SimpleItem; public class ExitItem extends SimpleItem { public ExitItem() { super(new ItemBuilder(Material.OAK_DOOR).setDisplayName("Exit"), click -> { - if(MinecraftVersion.BEE_UPDATE.atOrAbove()) { - - } final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { click.getEvent().getView().close(); } }); } + + public ItemBuilder getItemBuilder() { + return null; + } } diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java index 466af0a..891f3e9 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java @@ -13,6 +13,7 @@ import java.util.List; public class I18N { private final MessageFormat formatter = new MessageFormat(""); + private final YamlConfig yamlConfig; private final NickoBukkit instance = NickoBukkit.getInstance(); private final Player player; private final Locale playerLocale; @@ -20,11 +21,13 @@ public class I18N { 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) { @@ -64,35 +67,20 @@ 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; + return yamlConfig.getStringList(key); + } + + private YamlConfig getYamlConfig() { if (playerLocale == Locale.CUSTOM) { - yamlFile = instance.getLocaleFileManager().getYamlFile(); + return instance.getLocaleFileManager().getYamlFile(); } else { final InputStream resource = instance.getResource(playerLocale.getCode() + ".yml"); - yamlFile = YamlConfig.load(resource); + return new YamlConfig(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; } private Locale getPlayerLocale() { diff --git a/src/main/java/xyz/atnrch/nicko/i18n/ItemTranslator.java b/src/main/java/xyz/atnrch/nicko/i18n/ItemTranslator.java new file mode 100644 index 0000000..f5242d5 --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/i18n/ItemTranslator.java @@ -0,0 +1,38 @@ +package xyz.atnrch.nicko.i18n; + +import java.util.ArrayList; +import java.util.Iterator; + +public class ItemTranslator { + private final String name; + private final ArrayList lore; + + public ItemTranslator(String name, ArrayList lore) { + this.name = name; + this.lore = lore; + } + + public Object[] translate(String... args) { + // Add all elements to a list + final ArrayList toTranslate = new ArrayList<>(); + toTranslate.add(name); + toTranslate.addAll(lore); + + // Set starting index to 0 + int index = 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(index); + + // Replace with the corresponding varargs index + toTranslate.set(index, currentLine.replace("{" + index + "}", args[index])); + + // Increment the index + index++; + } + return new Object[]{toTranslate.get(0), toTranslate.subList(1, toTranslate.size())}; + } +} diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 7087dd6..f5471d9 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -25,4 +25,33 @@ 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: + exit: "Exit" + home: + admin: + name: "Administration panel" + lore: + - "Configure and manage Nicko." + settings: + name: "Settings" + lore: + - "Configure your experience." + change_name: + name: "§6Nickname §fchange" + change_skin: + name: "§6Skin §fchange" + change_both: + name: "Change §6both" + reset: + name: "Reset appearance" + lore: + - "Completely remove your disguise." + settings: + language: + name: "Language" + lore: + - "{0}" + - "§7§oGet through the values" + - "§7§oby left or right clicking." \ No newline at end of file From c929e73b0d266e05eea779e9ddf5ba5949b7bc29 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 27 Jul 2023 02:26:11 +0200 Subject: [PATCH 090/296] feat: wip translations --- .../java/xyz/atnrch/nicko/gui/AdminGUI.java | 4 +- .../atnrch/nicko/gui/CacheDetailedGUI.java | 4 +- .../atnrch/nicko/gui/CacheManagementGUI.java | 4 +- .../xyz/atnrch/nicko/gui/PlayerCheckGUI.java | 4 +- .../xyz/atnrch/nicko/gui/SettingsGUI.java | 10 +++-- .../nicko/gui/items/common/GoBackItem.java | 25 +++++++++--- .../atnrch/nicko/gui/items/home/ExitItem.java | 4 -- .../items/settings/BungeeCordCyclingItem.java | 25 +++++++++--- .../items/settings/LanguageCyclingItem.java | 19 +++++++-- src/main/java/xyz/atnrch/nicko/i18n/I18N.java | 39 ++++++++++++------- .../java/xyz/atnrch/nicko/i18n/I18NDict.java | 10 +++++ .../atnrch/nicko/i18n/ItemTranslation.java | 21 ++++++++++ .../xyz/atnrch/nicko/i18n/ItemTranslator.java | 38 ------------------ .../atnrch/nicko/i18n/LocaleFileManager.java | 4 +- src/main/resources/en.yml | 5 +++ src/main/resources/fr.yml | 18 ++++----- .../atnrch/nicko/test/i18n/I18NLoreTest.java | 8 ++-- 17 files changed, 148 insertions(+), 94 deletions(-) create mode 100644 src/main/java/xyz/atnrch/nicko/i18n/ItemTranslation.java delete mode 100644 src/main/java/xyz/atnrch/nicko/i18n/ItemTranslator.java diff --git a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java index 8c19b38..fb95b1d 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java @@ -14,6 +14,8 @@ public class AdminGUI { public AdminGUI(Player player) { final HomeGUI parent = new HomeGUI(player); + final GoBackItem backItem = new GoBackItem(player); + this.gui = Gui.normal() .setStructure( "# # # # # # # # #", @@ -22,7 +24,7 @@ public class AdminGUI { ) .addIngredient('S', new ManageCacheItem()) .addIngredient('C', new ManagePlayerItem()) - .addIngredient('B', new GoBackItem(parent.getGUI(), parent.getTitle())) + .addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle())) .build(); this.player = player; } diff --git a/src/main/java/xyz/atnrch/nicko/gui/CacheDetailedGUI.java b/src/main/java/xyz/atnrch/nicko/gui/CacheDetailedGUI.java index 8d5935a..12694ee 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/CacheDetailedGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/CacheDetailedGUI.java @@ -37,6 +37,8 @@ public class CacheDetailedGUI { .collect(Collectors.toList()); final CacheManagementGUI parent = new CacheManagementGUI(player); + final GoBackItem backItem = new GoBackItem(player); + gui = ScrollGui.items(guiItemBuilder -> { guiItemBuilder.setStructure( "x x x x x x x x U", @@ -48,7 +50,7 @@ public class CacheDetailedGUI { 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('B', backItem.get(parent.getGUI(), parent.getTitle())); guiItemBuilder.setContent(items); }); diff --git a/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java b/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java index c32227d..769349c 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java @@ -15,13 +15,15 @@ public class CacheManagementGUI { public CacheManagementGUI(Player player) { final AdminGUI parent = new AdminGUI(player); + final GoBackItem backItem = new GoBackItem(player); + this.gui = Gui.normal() .setStructure( "# # # # # # # # #", "# # # S A D # # #", "B # # # # # # # #" ) - .addIngredient('B', new GoBackItem(parent.getGUI(), parent.getTitle())) + .addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle())) .addIngredient('S', new CacheStatisticsItem()) .addIngredient('A', new InvalidateCacheItem()) .addIngredient('D', new InvalidateEntryItem()) diff --git a/src/main/java/xyz/atnrch/nicko/gui/PlayerCheckGUI.java b/src/main/java/xyz/atnrch/nicko/gui/PlayerCheckGUI.java index a09b80d..2058cfc 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/PlayerCheckGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/PlayerCheckGUI.java @@ -29,6 +29,8 @@ public class PlayerCheckGUI { .collect(Collectors.toList()); final AdminGUI parent = new AdminGUI(player); + final GoBackItem backItem = new GoBackItem(player); + gui = ScrollGui.items(guiItemBuilder -> { guiItemBuilder.setStructure( "x x x x x x x x U", @@ -40,7 +42,7 @@ public class PlayerCheckGUI { 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('B', backItem.get(parent.getGUI(), parent.getTitle())); guiItemBuilder.setContent(items); }); diff --git a/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java b/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java index 3917d31..54ebf7a 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java @@ -24,11 +24,15 @@ public class SettingsGUI { dynamicStructure[1] = dynamicStructure[1].replace("T", "U"); final HomeGUI parent = new HomeGUI(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('T', bungeeCordItem.get()) .build(); this.player = player; } 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..9a3c643 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,30 @@ 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 Player player; + private final I18N i18n; + + public GoBackItem(Player player) { + this.player = player; + this.i18n = new I18N(player); + } + + public SuppliedItem get(Gui gui, String parentTitle) { + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.GO_BACK); + return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.ARROW); - builder.setDisplayName("Go back"); - builder.addLoreLines("§7Return to the previous window."); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); return builder; }, click -> { click.getEvent().getView().close(); @@ -19,4 +32,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/home/ExitItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/home/ExitItem.java index ea6ff09..b35cf3e 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 @@ -14,8 +14,4 @@ public class ExitItem extends SimpleItem { } }); } - - public ItemBuilder getItemBuilder() { - return null; - } } 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..ed4b0d9 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,6 +1,9 @@ package xyz.atnrch.nicko.gui.items.settings; 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 org.bukkit.Material; import org.bukkit.Sound; @@ -14,12 +17,20 @@ 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) { + public BungeeCordCyclingItem(Player player) { + this.player = player; + this.i18n = new I18N(player); + this.providers = new ItemProvider[]{ + getItemProviderForValue(true), + getItemProviderForValue(false) + }; + } + + public AbstractItem get() { final Optional profile = NickoBukkit.getInstance().getDataStore().getData(player.getUniqueId()); if (profile.isPresent()) { final NickoProfile nickoProfile = profile.get(); @@ -35,7 +46,9 @@ public class BungeeCordCyclingItem { private ItemProvider getItemProviderForValue(boolean enabled) { final ItemBuilder builder = new ItemBuilder(Material.COMPASS); - builder.setDisplayName("BungeeCord transfer"); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Settings.BUNGEECORD); + + builder.setDisplayName(translation.getName()); if (enabled) { builder.addLoreLines("§7> §cDisabled"); builder.addLoreLines("§6§l> §a§lEnabled"); 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..addb9f9 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 @@ -6,6 +6,7 @@ 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.i18n.Locale; import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.PlayerDataStore; @@ -21,9 +22,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()) { @@ -46,7 +55,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()); @@ -61,8 +72,8 @@ public class LanguageCyclingItem { 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 891f3e9..57c3d90 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java @@ -8,8 +8,7 @@ import xyz.atnrch.nicko.appearance.AppearanceManager; import java.io.InputStream; import java.text.MessageFormat; import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.Iterator; public class I18N { private final MessageFormat formatter = new MessageFormat(""); @@ -30,19 +29,31 @@ public class I18N { 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, String... args) { + final String name = readString(key + ".name"); + final ArrayList lore = readList(key + ".lore"); + + // Add all elements to a list + final ArrayList toTranslate = new ArrayList<>(); + toTranslate.add(name); + toTranslate.addAll(lore); + + // Set starting index to 0 + int index = 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(index); + + // Replace with the corresponding varargs index + toTranslate.set(index, currentLine.replace("{" + index + "}", args[index])); + + // Increment the index + index++; } + return new ItemTranslation(toTranslate.get(0), toTranslate.subList(1, toTranslate.size())); } public String translate(String key, Object... arguments) { diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index cc4317e..00a2248 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -64,11 +64,21 @@ 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 class Home { private static final String HOME_KEY = GUI_KEY + "home."; public static final String ADMIN = HOME_KEY + "admin"; } + + 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"; + } + + } } 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..464b629 --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/i18n/ItemTranslation.java @@ -0,0 +1,21 @@ +package xyz.atnrch.nicko.i18n; + +import java.util.List; + +public class ItemTranslation { + private final String name; + private final List lore; + + public ItemTranslation(String name, List lore) { + this.name = name; + this.lore = lore; + } + + public String getName() { + return name; + } + + public List getLore() { + return lore; + } +} diff --git a/src/main/java/xyz/atnrch/nicko/i18n/ItemTranslator.java b/src/main/java/xyz/atnrch/nicko/i18n/ItemTranslator.java deleted file mode 100644 index f5242d5..0000000 --- a/src/main/java/xyz/atnrch/nicko/i18n/ItemTranslator.java +++ /dev/null @@ -1,38 +0,0 @@ -package xyz.atnrch.nicko.i18n; - -import java.util.ArrayList; -import java.util.Iterator; - -public class ItemTranslator { - private final String name; - private final ArrayList lore; - - public ItemTranslator(String name, ArrayList lore) { - this.name = name; - this.lore = lore; - } - - public Object[] translate(String... args) { - // Add all elements to a list - final ArrayList toTranslate = new ArrayList<>(); - toTranslate.add(name); - toTranslate.addAll(lore); - - // Set starting index to 0 - int index = 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(index); - - // Replace with the corresponding varargs index - toTranslate.set(index, currentLine.replace("{" + index + "}", args[index])); - - // Increment the index - index++; - } - return new Object[]{toTranslate.get(0), toTranslate.subList(1, toTranslate.size())}; - } -} 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/resources/en.yml b/src/main/resources/en.yml index f5471d9..310a121 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -53,5 +53,10 @@ gui: name: "Language" lore: - "{0}" + - "§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..1c95045 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -31,15 +31,11 @@ gui: admin: name: "Panel d''administration" lore: - length: 1 - content: - - "Configurez et gérez Nicko." + - "Configurez et gérez Nicko." settings: name: "Paramètres" lore: - length: 1 - content: - "Configurez votre expérience." + - "Configurez votre expérience." change_name: name: "Changer le §6pseudo" change_skin: @@ -52,9 +48,13 @@ gui: - "Supprime complètement votre déguisement." settings: language: - name: "Language" + name: "Langage" 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 + - "§7§oavec un clique gauche/droit." + 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/test/java/xyz/atnrch/nicko/test/i18n/I18NLoreTest.java b/src/test/java/xyz/atnrch/nicko/test/i18n/I18NLoreTest.java index 2c17db5..4d30b13 100644 --- a/src/test/java/xyz/atnrch/nicko/test/i18n/I18NLoreTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/i18n/I18NLoreTest.java @@ -12,10 +12,9 @@ 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 java.util.List; - public class I18NLoreTest { private static NickoBukkit plugin; private static PlayerMock player; @@ -35,8 +34,9 @@ public class I18NLoreTest { @DisplayName("Translate Item Lore") public void translateItemLore() { final I18N i18n = new I18N(Locale.FRENCH); - List strings = i18n.translateItem(I18NDict.GUI.Home.ADMIN); - System.out.println("strings = " + strings); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Home.ADMIN); + System.out.println("name = " + translation.getName()); + System.out.println("lore = " + translation.getLore()); } @AfterAll From b64f56a0bb0d62a5d08f5aba9800ad5754fdab85 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 27 Jul 2023 23:29:57 +0200 Subject: [PATCH 091/296] feat: item translation --- .../nicko/event/PlayerJoinListener.java | 1 + .../nicko/gui/items/common/GoBackItem.java | 5 +- .../items/settings/BungeeCordCyclingItem.java | 25 ++++---- .../items/settings/LanguageCyclingItem.java | 3 +- src/main/java/xyz/atnrch/nicko/i18n/I18N.java | 61 ++++++++++++++----- .../atnrch/nicko/i18n/ItemTranslation.java | 8 +-- src/main/resources/en.yml | 3 + src/main/resources/fr.yml | 11 +++- ...Test.java => I18NItemTranslationTest.java} | 27 +++++--- 9 files changed, 97 insertions(+), 47 deletions(-) rename src/test/java/xyz/atnrch/nicko/test/i18n/{I18NLoreTest.java => I18NItemTranslationTest.java} (60%) diff --git a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java index b4a3a19..7b998c3 100644 --- a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java @@ -33,5 +33,6 @@ public class PlayerJoinListener implements Listener { } } }, 20L); + System.out.println("i18n.getPlayerLocale().getCode() = " + i18n.getPlayerLocale().getCode()); } } 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 9a3c643..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 @@ -11,20 +11,17 @@ import xyz.xenondevs.invui.item.impl.SuppliedItem; import xyz.xenondevs.invui.window.Window; public class GoBackItem { - private final Player player; private final I18N i18n; public GoBackItem(Player player) { - this.player = player; this.i18n = new I18N(player); } public SuppliedItem get(Gui gui, String parentTitle) { - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.GO_BACK); return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.ARROW); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.GO_BACK); builder.setDisplayName(translation.getName()); - translation.getLore().forEach(builder::addLoreLines); return builder; }, click -> { click.getEvent().getView().close(); 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 ed4b0d9..1c3efc0 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,13 +1,13 @@ package xyz.atnrch.nicko.gui.items.settings; +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 org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.entity.Player; import xyz.xenondevs.invui.item.ItemProvider; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.AbstractItem; @@ -49,14 +49,17 @@ public class BungeeCordCyclingItem { final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Settings.BUNGEECORD); builder.setDisplayName(translation.getName()); - 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."); + 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 addb9f9..f3419cc 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 @@ -43,9 +43,10 @@ public class LanguageCyclingItem { observer.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 0.707107f); // 0.707107 ~= C // 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 { + player.sendMessage("Updated language to " + nickoProfile.getLocale().getCode()); } }, localeOrdinal, providers); } diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java index 57c3d90..4859efe 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java @@ -9,11 +9,16 @@ import java.io.InputStream; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Iterator; +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 YamlConfig yamlConfig; + private final Logger logger = Logger.getLogger("I18N"); private final NickoBukkit instance = NickoBukkit.getInstance(); + private final Pattern replacementPattern = Pattern.compile("\\{\\d+}"); + private final YamlConfig yamlConfig; private final Player player; private final Locale playerLocale; @@ -30,37 +35,63 @@ public class I18N { } public ItemTranslation translateItem(String key, String... args) { - final String name = readString(key + ".name"); - final ArrayList lore = readList(key + ".lore"); + 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); - toTranslate.addAll(lore); + if (lore != null && !lore.isEmpty()) { + toTranslate.addAll(lore); + } // Set starting index to 0 - int index = 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) { + while (iterator.hasNext() && iterator.next() != null) { // Get the current line - final String currentLine = toTranslate.get(index); + final String currentLine = toTranslate.get(lineIndex); - // Replace with the corresponding varargs index - toTranslate.set(index, currentLine.replace("{" + index + "}", args[index])); + // If the line doesn't contain {i}, skip it + final Matcher matcher = replacementPattern.matcher(currentLine); + if (!matcher.matches()) { + 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])); + replacementIndex++; + } // Increment the index - index++; + lineIndex++; } - return new ItemTranslation(toTranslate.get(0), toTranslate.subList(1, toTranslate.size())); + + 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; @@ -94,7 +125,7 @@ public class I18N { } } - private Locale getPlayerLocale() { + public Locale getPlayerLocale() { try { final AppearanceManager appearanceManager = AppearanceManager.get(player); return !appearanceManager.hasData() ? Locale.FALLBACK_LOCALE : appearanceManager.getLocale(); diff --git a/src/main/java/xyz/atnrch/nicko/i18n/ItemTranslation.java b/src/main/java/xyz/atnrch/nicko/i18n/ItemTranslation.java index 464b629..035724e 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/ItemTranslation.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/ItemTranslation.java @@ -1,12 +1,12 @@ package xyz.atnrch.nicko.i18n; -import java.util.List; +import java.util.ArrayList; public class ItemTranslation { private final String name; - private final List lore; + private final ArrayList lore; - public ItemTranslation(String name, List lore) { + public ItemTranslation(String name, ArrayList lore) { this.name = name; this.lore = lore; } @@ -15,7 +15,7 @@ public class ItemTranslation { return name; } - public List getLore() { + public ArrayList getLore() { return lore; } } diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 310a121..4144e12 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -29,6 +29,8 @@ event: gui: exit: "Exit" + go_back: + name: "Back" home: admin: name: "Administration panel" @@ -58,5 +60,6 @@ gui: bungeecord: name: "Bungeecord Transfer" lore: + - "{0}" - "§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 1c95045..5954d3a 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -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})" @@ -27,6 +29,8 @@ event: gui: exit: "Quitter" + go_back: + name: "Retour" home: admin: name: "Panel d''administration" @@ -54,7 +58,8 @@ gui: - "§7§oParcourez les valeurs" - "§7§oavec un clique gauche/droit." bungeecord: - name: "Bungeecord Transfer" + name: "Transfert Bungeecord" lore: - - "§7§oGet through the values" - - "§7§oby left or right clicking." \ No newline at end of file + - "{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/I18NLoreTest.java b/src/test/java/xyz/atnrch/nicko/test/i18n/I18NItemTranslationTest.java similarity index 60% rename from src/test/java/xyz/atnrch/nicko/test/i18n/I18NLoreTest.java rename to src/test/java/xyz/atnrch/nicko/test/i18n/I18NItemTranslationTest.java index 4d30b13..31f85a9 100644 --- a/src/test/java/xyz/atnrch/nicko/test/i18n/I18NLoreTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/i18n/I18NItemTranslationTest.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; @@ -15,8 +14,10 @@ import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.i18n.ItemTranslation; import xyz.atnrch.nicko.i18n.Locale; -public class I18NLoreTest { - private static NickoBukkit plugin; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class I18NItemTranslationTest { private static PlayerMock player; @BeforeAll @@ -26,17 +27,25 @@ 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") + @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.Home.ADMIN); - System.out.println("name = " + translation.getName()); - System.out.println("lore = " + translation.getLore()); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Settings.BUNGEECORD, "Test"); + assertEquals("Test", translation.getLore().get(0)); } @AfterAll From e471d86801d10b4601ab753d56c4a073cd4ea180 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 19 Aug 2023 14:59:11 +0200 Subject: [PATCH 092/296] feat: compartmentalization --- .../xyz/atnrch/nicko/anvil/AnvilManager.java | 26 +++-- .../nicko/appearance/AppearanceManager.java | 102 +++++------------- .../atnrch/nicko/command/NickoCommand.java | 21 ++-- ...ckoDebugSubCmd.java => NickoDebugCmd.java} | 48 ++++++--- .../nicko/command/sub/NickoCheckSubCmd.java | 44 -------- .../nicko/event/PlayerJoinListener.java | 27 +++-- .../admin/check/PlayerInformationItem.java | 40 ++++--- .../nicko/gui/items/home/ResetItem.java | 40 ++++--- .../items/settings/BungeeCordCyclingItem.java | 5 +- .../items/settings/LanguageCyclingItem.java | 2 + src/main/java/xyz/atnrch/nicko/i18n/I18N.java | 12 +-- .../java/xyz/atnrch/nicko/i18n/I18NDict.java | 19 ++-- .../nicko/placeholder/NickoExpansion.java | 23 ++-- .../atnrch/nicko/profile/AppearanceData.java | 31 ++++++ .../atnrch/nicko/profile/NickoProfile.java | 71 ++++++++---- .../atnrch/nicko/storage/sql/SQLStorage.java | 13 ++- .../nicko/test/storage/SQLStorageTest.java | 27 +++-- .../test/storage/redis/RedisCacheTest.java | 16 ++- 18 files changed, 300 insertions(+), 267 deletions(-) rename src/main/java/xyz/atnrch/nicko/command/{sub/NickoDebugSubCmd.java => NickoDebugCmd.java} (50%) delete mode 100644 src/main/java/xyz/atnrch/nicko/command/sub/NickoCheckSubCmd.java create mode 100644 src/main/java/xyz/atnrch/nicko/profile/AppearanceData.java 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 From 240d75b1a1229b3a2958c14019b730907cfaef85 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 19 Aug 2023 15:13:10 +0200 Subject: [PATCH 093/296] chore(deps): upgraded to paper --- pom.xml | 14 +++++++------- src/main/java/xyz/atnrch/nicko/NickoBukkit.java | 13 +------------ 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/pom.xml b/pom.xml index f644ea5..b1af5ff 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 @@ -120,12 +120,12 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M7 + 3.0.0-M8 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..dc49b07 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -3,9 +3,7 @@ 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; @@ -22,7 +20,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,15 +41,7 @@ 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); + protected NickoBukkit(Configuration configuration) { unitTesting = true; this.configuration = configuration; getLogger().info("Unit Testing Mode enabled."); From ec587b56c33068703d9166b9e82f67be99239888 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 19 Aug 2023 15:30:28 +0200 Subject: [PATCH 094/296] fix: consistency --- src/main/java/xyz/atnrch/nicko/NickoBukkit.java | 2 +- .../atnrch/nicko/gui/items/settings/LanguageCyclingItem.java | 2 -- src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java | 3 --- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index dc49b07..f2da0ba 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -42,7 +42,7 @@ public class NickoBukkit extends JavaPlugin { * Used by MockBukkit */ protected NickoBukkit(Configuration configuration) { - unitTesting = true; + this.unitTesting = true; this.configuration = configuration; getLogger().info("Unit Testing Mode enabled."); } 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 5081e7d..f3419cc 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,6 +1,5 @@ package xyz.atnrch.nicko.gui.items.settings; -import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; @@ -30,7 +29,6 @@ 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/storage/sql/SQLStorage.java b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java index f12e879..7f7c546 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java @@ -92,9 +92,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(new AppearanceData(name, skin), Locale.fromCode(locale), bungeecord); return Optional.of(profile); From b81eac497a62caa70501c7b5644c3a3382a22324 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 20 Aug 2023 16:21:12 +0200 Subject: [PATCH 095/296] chore(deps): upgrade --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b1af5ff..35552f3 100644 --- a/pom.xml +++ b/pom.xml @@ -120,7 +120,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M8 + 3.0.0-M9 org.apache.maven.plugins From 618af080244ca20fd0d0969cd0c1ab71ec23a8b2 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 21 Aug 2023 17:01:03 +0200 Subject: [PATCH 096/296] feat: streamline profile class --- .../xyz/atnrch/nicko/anvil/AnvilManager.java | 11 ++-- .../nicko/appearance/AppearanceManager.java | 22 +++----- .../atnrch/nicko/command/NickoDebugCmd.java | 9 ++-- .../nicko/event/PlayerJoinListener.java | 8 +-- .../admin/check/PlayerInformationItem.java | 11 ++-- .../nicko/gui/items/home/ResetItem.java | 7 ++- .../nicko/placeholder/NickoExpansion.java | 8 ++- .../atnrch/nicko/profile/NickoProfile.java | 50 ++++++++++++------- .../atnrch/nicko/storage/sql/SQLStorage.java | 13 ++--- .../nicko/test/storage/SQLStorageTest.java | 15 +++--- .../test/storage/redis/RedisCacheTest.java | 7 +-- 11 files changed, 75 insertions(+), 86 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java index 5675560..8747249 100644 --- a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java @@ -11,7 +11,6 @@ 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; @@ -22,7 +21,6 @@ import java.util.Optional; public class AnvilManager { private final Player player; private final AppearanceManager appearanceManager; - private final AppearanceData appearanceData; private final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore(); private final NickoProfile profile; @@ -31,8 +29,7 @@ public class AnvilManager { 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); + this.appearanceManager = new AppearanceManager(player); } public void openNameThenSkinAnvil() { @@ -57,7 +54,7 @@ public class AnvilManager { if (MojangUtils.isUsernameInvalid(snapshot.getText())) { return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); } else { - appearanceData.setName(snapshot.getText()); + profile.setName(snapshot.getText()); dataStore.updateCache(player.getUniqueId(), profile); openSkinAnvil(); return Collections.singletonList(AnvilGUI.ResponseAction.close()); @@ -78,7 +75,7 @@ public class AnvilManager { if (MojangUtils.isUsernameInvalid(snapshot.getText())) { return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); } else { - appearanceData.setName(snapshot.getText()); + profile.setName(snapshot.getText()); dataStore.updateCache(player.getUniqueId(), profile); final ActionResult actionResult = appearanceManager.updatePlayer(false, false); return sendResultAndClose(actionResult); @@ -99,7 +96,7 @@ public class AnvilManager { if (MojangUtils.isUsernameInvalid(snapshot.getText())) { return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); } else { - appearanceData.setSkin(snapshot.getText()); + 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 efab3c3..4b8008a 100644 --- a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java @@ -13,7 +13,6 @@ import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.i18n.I18NDict; 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; @@ -31,7 +30,6 @@ public class AppearanceManager { private final PlayerNameStore nameStore = instance.getNameStore(); private final NickoProfile profile; - private final AppearanceData appearanceData; private final Player player; private final UUID uuid; @@ -40,31 +38,27 @@ public class AppearanceManager { this.player = player; final Optional optionalProfile = dataStore.getData(player.getUniqueId()); + this.profile = optionalProfile.orElse(NickoProfile.EMPTY_PROFILE.clone()); 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); - appearanceData.setName(defaultName); - appearanceData.setSkin(defaultName); + profile.setName(defaultName); + profile.setSkin(defaultName); final ActionResult actionResult = updatePlayer(true, true); if (!actionResult.isError()) { - appearanceData.setSkin(null); - appearanceData.setName(null); + profile.setSkin(null); + profile.setName(null); dataStore.getCache().cache(uuid, profile); } return actionResult; } public ActionResult updatePlayer(boolean skinChange, boolean reset) { - final String displayName = appearanceData.getName() == null ? player.getName() : appearanceData.getName(); + 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); if (!result.isError()) { @@ -91,13 +85,13 @@ public class AppearanceManager { private ActionResult updateGameProfileSkin(WrappedGameProfile gameProfile, boolean skinChange, boolean reset) { - final boolean changeOnlyName = appearanceData.getSkin() != null && !appearanceData.getSkin().equalsIgnoreCase(player.getName()); + final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName()); if (skinChange || changeOnlyName) { Optional skin; try { final MojangAPI mojangAPI = NickoBukkit.getInstance().getMojangAPI(); - final Optional uuid = mojangAPI.getUUID(appearanceData.getSkin()); + final Optional uuid = mojangAPI.getUUID(profile.getSkin()); if (uuid.isPresent()) { skin = reset ? mojangAPI.getSkinWithoutCaching(uuid.get()) : mojangAPI.getSkin(uuid.get()); if (skin.isPresent()) { diff --git a/src/main/java/xyz/atnrch/nicko/command/NickoDebugCmd.java b/src/main/java/xyz/atnrch/nicko/command/NickoDebugCmd.java index 224f360..9cc583a 100644 --- a/src/main/java/xyz/atnrch/nicko/command/NickoDebugCmd.java +++ b/src/main/java/xyz/atnrch/nicko/command/NickoDebugCmd.java @@ -57,10 +57,9 @@ public class NickoDebugCmd { 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); + final AppearanceManager appearanceManager = new AppearanceManager(target); + profile.setName(name); + profile.setSkin(skin); dataStore.updateCache(target.getUniqueId(), profile); final ActionResult result = appearanceManager.updatePlayer(true, false); if (!result.isError()) { @@ -71,7 +70,5 @@ public class NickoDebugCmd { target.sendMessage(prefix + "§cWhoops. Something happened: " + i18n.translatePrefixless(result.getErrorKey())); } } - - } } diff --git a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java index 4433b8e..498030d 100644 --- a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java @@ -30,10 +30,10 @@ public class PlayerJoinListener implements Listener { Bukkit.getScheduler().runTaskLater(instance, () -> { 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()); + 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)); 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 71c2c6f..ac323a9 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,8 +4,6 @@ import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; import xyz.atnrch.nicko.NickoBukkit; -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; @@ -16,8 +14,6 @@ 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..."), () -> { final Player player = Bukkit.getPlayer(uuid); @@ -26,12 +22,11 @@ public class PlayerInformationItem extends AsyncItem { final Optional optionalProfile = dataStore.getData(uuid); optionalProfile.ifPresent(profile -> { - final AppearanceData appearanceData = profile.getAppearanceData(); - if (!appearanceData.isEmpty()) { + if (!profile.hasData()) { skull.addLoreLines( "§cNicked: §a✔", - "§cName: §6" + appearanceData.getName(), - "§cSkin: §6" + appearanceData.getSkin() + "§cName: §6" + profile.getName(), + "§cSkin: §6" + profile.getSkin() ); } else { skull.addLoreLines( 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 5191867..c4f9e40 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 @@ -3,6 +3,7 @@ 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.appearance.AppearanceManager; import xyz.atnrch.nicko.i18n.I18N; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.profile.NickoProfile; @@ -28,13 +29,15 @@ public class ResetItem extends SuppliedItem { final Optional optionalProfile = NickoProfile.get(player); final AtomicBoolean result = new AtomicBoolean(false); optionalProfile.ifPresent(profile -> { - if (profile.getAppearanceData().isEmpty()) { + if (!profile.hasData()) { player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.MISSING)); event.getEvent().getView().close(); result.set(true); + return; } - if (!profile.getAppearanceManager().reset().isError()) { + final AppearanceManager appearanceManager = new AppearanceManager(player); + if (!appearanceManager.reset().isError()) { player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.OK)); result.set(false); } else { diff --git a/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java b/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java index 9fcd597..56e003e 100644 --- a/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java +++ b/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java @@ -5,7 +5,6 @@ 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; @@ -52,10 +51,9 @@ public class NickoExpansion extends PlaceholderExpansion { final Optional optionalProfile = instance.getDataStore().getData(player.getUniqueId()); if (optionalProfile.isPresent()) { final NickoProfile profile = optionalProfile.get(); - final AppearanceData appearanceData = profile.getAppearanceData(); - if (!appearanceData.isEmpty()) { - name = appearanceData.getName(); - skin = appearanceData.getSkin(); + if (!profile.hasData()) { + name = profile.getName(); + skin = profile.getSkin(); } locale = profile.getLocale().getName(); bungeecord = profile.isBungeecordTransfer(); diff --git a/src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java b/src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java index 6685476..05a544b 100644 --- a/src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java +++ b/src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java @@ -3,7 +3,6 @@ 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; @@ -12,29 +11,34 @@ 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(new AppearanceData(null, null), Locale.ENGLISH, true); + public static final NickoProfile EMPTY_PROFILE = new NickoProfile(null, null, Locale.ENGLISH, true); - private final AppearanceData appearanceData; - private final Player player; + private transient final Player player; + + private String name; + private String skin; private Locale locale; private boolean bungeecordTransfer; - public NickoProfile(AppearanceData appearanceData, Locale locale, boolean bungeecordTransfer) { - this.appearanceData = appearanceData; + public NickoProfile(String name, String skin, Locale locale, boolean bungeecordTransfer) { + this.name = name; + this.skin = skin; this.locale = locale; this.bungeecordTransfer = bungeecordTransfer; this.player = null; } - public NickoProfile(Player player, AppearanceData appearanceData, Locale locale, boolean bungeecordTransfer) { + public NickoProfile(Player player, String name, String skin, Locale locale, boolean bungeecordTransfer) { this.player = player; - this.appearanceData = appearanceData; + this.name = name; + this.skin = skin; this.locale = locale; this.bungeecordTransfer = bungeecordTransfer; } - public NickoProfile(UUID uuid, AppearanceData appearanceData, Locale locale, boolean bungeecordTransfer) { - this.appearanceData = appearanceData; + 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); @@ -48,13 +52,24 @@ public class NickoProfile implements Cloneable { return dataStore.getData(uuid); } - public AppearanceManager getAppearanceManager() { - if (player == null) return null; - return new AppearanceManager(player); + public boolean hasData() { + return name != null || skin != null; } - public AppearanceData getAppearanceData() { - return appearanceData; + 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; } public Locale getLocale() { @@ -65,7 +80,6 @@ public class NickoProfile implements Cloneable { this.locale = locale; } - public boolean isBungeecordTransfer() { return bungeecordTransfer; } @@ -77,8 +91,8 @@ public class NickoProfile implements Cloneable { @Override public String toString() { return "NickoProfile{" + - "name='" + appearanceData.getName() + '\'' + - ", skin='" + appearanceData.getSkin() + '\'' + + "name='" + name + '\'' + + ", skin='" + skin + '\'' + ", locale=" + locale + ", bungeecordTransfer=" + bungeecordTransfer + '}'; 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 7f7c546..2c3a159 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java @@ -4,7 +4,6 @@ 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; @@ -93,7 +92,7 @@ public class SQLStorage extends Storage { bungeecord = resultSet.getBoolean("bungeecord"); } - final NickoProfile profile = new NickoProfile(new AppearanceData(name, skin), Locale.fromCode(locale), bungeecord); + final NickoProfile profile = new NickoProfile(name, skin, Locale.fromCode(locale), bungeecord); return Optional.of(profile); } catch (SQLException e) { logger.warning("Couldn't fetch profile: " + e.getMessage()); @@ -121,10 +120,9 @@ 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, appearanceData.getName() == null ? null : appearanceData.getName()); - statement.setString(3, appearanceData.getSkin() == null ? null : appearanceData.getSkin()); + statement.setString(2, profile.getName() == null ? null : profile.getName()); + statement.setString(3, profile.getSkin() == null ? null : profile.getSkin()); statement.setString(4, profile.getLocale().getCode()); statement.setBoolean(5, profile.isBungeecordTransfer()); return statement; @@ -133,9 +131,8 @@ 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); - 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(1, profile.getName() == null ? null : profile.getName()); + statement.setString(2, profile.getSkin() == null ? null : profile.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 720ad9d..c6020bc 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java @@ -7,7 +7,6 @@ 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; @@ -59,14 +58,13 @@ public class SQLStorageTest { assertTrue(optionalProfile.isPresent()); final NickoProfile profile = optionalProfile.get(); - final AppearanceData appearanceData = profile.getAppearanceData(); - assertNull(appearanceData.getName()); - assertNull(appearanceData.getSkin()); + assertNull(profile.getName()); + assertNull(profile.getSkin()); assertEquals(profile.getLocale(), Locale.ENGLISH); assertTrue(profile.isBungeecordTransfer()); - appearanceData.setName("Notch"); - appearanceData.setSkin("Notch"); + profile.setName("Notch"); + profile.setSkin("Notch"); profile.setLocale(Locale.FRENCH); profile.setBungeecordTransfer(false); @@ -82,9 +80,8 @@ public class SQLStorageTest { assertTrue(optionalProfile.isPresent()); final NickoProfile updatedProfile = optionalProfile.get(); - final AppearanceData appearanceData = updatedProfile.getAppearanceData(); - assertEquals(appearanceData.getName(), "Notch"); - assertEquals(appearanceData.getSkin(), "Notch"); + assertEquals(updatedProfile.getName(), "Notch"); + assertEquals(updatedProfile.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 183005e..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 @@ -8,7 +8,6 @@ import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.appearance.ActionResult; 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; @@ -51,15 +50,13 @@ public class RedisCacheTest { final NickoProfile profile = optionalProfile.get(); final PlayerDataStore dataStore = plugin.getDataStore(); - final AppearanceData appearanceData = profile.getAppearanceData(); - appearanceData.setName("Notch"); + profile.setName("Notch"); dataStore.updateCache(player.getUniqueId(), profile); final Optional retrieve = dataStore.getCache().retrieve(player.getUniqueId()); assertTrue(retrieve.isPresent()); final NickoProfile retrieved = retrieve.get(); - final AppearanceData retrievedAppearanceData = retrieved.getAppearanceData(); - assertEquals(retrievedAppearanceData.getName(), "Notch"); + assertEquals(retrieved.getName(), "Notch"); } @Test From 8d87cddbea7916e388e7e6d25c01be88c143a8ce Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 21 Aug 2023 17:52:15 +0200 Subject: [PATCH 097/296] fix: persistence, i18n --- .../xyz/atnrch/nicko/anvil/AnvilManager.java | 4 +-- .../nicko/appearance/AppearanceManager.java | 25 +++++++++---------- .../atnrch/nicko/command/NickoDebugCmd.java | 3 +-- .../java/xyz/atnrch/nicko/gui/HomeGUI.java | 4 ++- .../admin/check/PlayerInformationItem.java | 2 +- .../atnrch/nicko/gui/items/home/ExitItem.java | 25 ++++++++++++++++--- src/main/resources/en.yml | 3 ++- src/main/resources/fr.yml | 3 ++- 8 files changed, 44 insertions(+), 25 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java index 8747249..0e7d16f 100644 --- a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java @@ -44,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)) @@ -65,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)) diff --git a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java index 4b8008a..431751d 100644 --- a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java @@ -21,7 +21,6 @@ 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 { @@ -29,35 +28,29 @@ public class AppearanceManager { private final PlayerDataStore dataStore = instance.getDataStore(); private final PlayerNameStore nameStore = instance.getNameStore(); - private final NickoProfile profile; private final Player player; - private final UUID uuid; public AppearanceManager(Player player) { - this.uuid = player.getUniqueId(); this.player = player; - - final Optional optionalProfile = dataStore.getData(player.getUniqueId()); - this.profile = optionalProfile.orElse(NickoProfile.EMPTY_PROFILE.clone()); - if (!optionalProfile.isPresent()) { - instance.getLogger().warning("Unable to appearance data for: " + player.getUniqueId() + "."); - } } public ActionResult reset() { + final NickoProfile profile = getNickoProfile(); final String defaultName = nameStore.getStoredName(player); profile.setName(defaultName); profile.setSkin(defaultName); + dataStore.getCache().cache(player.getUniqueId(), profile); final ActionResult actionResult = updatePlayer(true, true); if (!actionResult.isError()) { profile.setSkin(null); profile.setName(null); - dataStore.getCache().cache(uuid, profile); + 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); @@ -70,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(); @@ -85,9 +83,10 @@ 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 mojangAPI = NickoBukkit.getInstance().getMojangAPI(); diff --git a/src/main/java/xyz/atnrch/nicko/command/NickoDebugCmd.java b/src/main/java/xyz/atnrch/nicko/command/NickoDebugCmd.java index 9cc583a..4f5b877 100644 --- a/src/main/java/xyz/atnrch/nicko/command/NickoDebugCmd.java +++ b/src/main/java/xyz/atnrch/nicko/command/NickoDebugCmd.java @@ -9,7 +9,6 @@ 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 xyz.atnrch.nicko.profile.AppearanceData; import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.PlayerDataStore; @@ -57,10 +56,10 @@ public class NickoDebugCmd { if (optionalProfile.isPresent()) { final NickoProfile profile = optionalProfile.get(); final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore(); - final AppearanceManager appearanceManager = new AppearanceManager(target); 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!"); diff --git a/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java b/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java index 7b9d156..2f1e3be 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java @@ -26,9 +26,11 @@ public class HomeGUI { dynamicStructure[2] = dynamicStructure[2].replace("A", "#"); } + final ExitItem exitItem = new ExitItem(player); + this.gui = Gui.normal() .setStructure(dynamicStructure) - .addIngredient('E', new ExitItem()) + .addIngredient('E', exitItem.get()) .addIngredient('R', new ResetItem()) .addIngredient('N', new ChangeNameItem()) .addIngredient('B', new ChangeBothItem()) 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 ac323a9..0fd601f 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 @@ -22,7 +22,7 @@ public class PlayerInformationItem extends AsyncItem { final Optional optionalProfile = dataStore.getData(uuid); optionalProfile.ifPresent(profile -> { - if (!profile.hasData()) { + if (profile.hasData()) { skull.addLoreLines( "§cNicked: §a✔", "§cName: §6" + profile.getName(), 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 b35cf3e..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,17 +1,34 @@ 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.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 -> { +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/resources/en.yml b/src/main/resources/en.yml index 4144e12..8583dcc 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -28,7 +28,8 @@ event: invalidate_entry: "§6{0} §fhas been invalidated." gui: - exit: "Exit" + exit: + name: "Exit" go_back: name: "Back" home: diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 5954d3a..16ffac5 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -28,7 +28,8 @@ event: invalidate_entry: "§6{0} §fa été invalidé." gui: - exit: "Quitter" + exit: + name: "Quitter" go_back: name: "Retour" home: From 6a4826f441b658634e0b3dd59cd67f2008d093b6 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 22 Aug 2023 17:51:48 +0200 Subject: [PATCH 098/296] feat: lore --- src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java | 1 - .../atnrch/nicko/gui/items/settings/LanguageCyclingItem.java | 2 +- src/main/resources/en.yml | 1 - src/main/resources/fr.yml | 1 - 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java b/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java index 2f1e3be..be2f02b 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java @@ -27,7 +27,6 @@ public class HomeGUI { } final ExitItem exitItem = new ExitItem(player); - this.gui = Gui.normal() .setStructure(dynamicStructure) .addIngredient('E', exitItem.get()) 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..dc083f0 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 @@ -66,7 +66,7 @@ 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; } diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 8583dcc..2d1983a 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -55,7 +55,6 @@ gui: language: name: "Language" lore: - - "{0}" - "§7§oGet through the values" - "§7§oby left or right clicking." bungeecord: diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 16ffac5..fa6d9fa 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -55,7 +55,6 @@ gui: language: name: "Langage" lore: - - "{0}" - "§7§oParcourez les valeurs" - "§7§oavec un clique gauche/droit." bungeecord: From ccae0084ea85ef577309316775a63ae58bf02b6b Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 29 Aug 2023 20:20:56 +0200 Subject: [PATCH 099/296] feat: delete from cache when leaving, reopen gui on changing language --- .../nicko/gui/items/settings/LanguageCyclingItem.java | 5 +++-- .../java/xyz/atnrch/nicko/storage/PlayerDataStore.java | 10 +++++----- .../xyz/atnrch/nicko/storage/redis/RedisCache.java | 1 + 3 files changed, 9 insertions(+), 7 deletions(-) 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 dc083f0..282ed0a 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,6 +4,7 @@ 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; @@ -44,10 +45,10 @@ public class LanguageCyclingItem { // TODO (Ineanto, 7/14/23): This checks a 2nd time for the profile. if (dataStore.updateCache(player.getUniqueId(), nickoProfile).isError()) { player.sendMessage(i18n.translate(I18NDict.Event.Settings.ERROR)); - player.getOpenInventory().close(); } else { - player.sendMessage("Updated language to " + nickoProfile.getLocale().getCode()); + new SettingsGUI(player).open(); } + player.getOpenInventory().close(); }, localeOrdinal, providers); } 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/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); From 027d585210c798d54143565e03d898d7a1468e66 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 29 Aug 2023 20:24:14 +0200 Subject: [PATCH 100/296] feat: update to paperapi --- src/main/java/xyz/atnrch/nicko/command/NickoCommand.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java b/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java index b6cc62b..13b1df8 100644 --- a/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java +++ b/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java @@ -1,12 +1,12 @@ package xyz.atnrch.nicko.command; -import org.jetbrains.annotations.NotNull; -import xyz.atnrch.nicko.NickoBukkit; -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; @@ -42,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); } } From 8bddd5612440853e4e5d24f5e936bd520ba82c71 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 31 Aug 2023 09:02:00 +0200 Subject: [PATCH 101/296] feat(i18n): updated localization files --- src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java | 8 ++++++++ src/main/resources/en.yml | 12 +++++++++++- src/main/resources/fr.yml | 14 ++++++++++++-- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index b3976fe..dde28f7 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -72,16 +72,24 @@ public class I18NDict { public static class Home { private static final String HOME_KEY = GUI_KEY + "home."; + public static final String TITLE = HOME_KEY + "title"; public static final String ADMIN = HOME_KEY + "admin"; } public static class Settings { private static final String SETTINGS_KEY = GUI_KEY + "settings."; + public static final String TITLE = SETTINGS_KEY + "title"; 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 TITLE = ADMIN_KEY + "title"; + public static final String MANAGE_CACHE = ADMIN_KEY + "manage_cache"; + public static final String MANAGE_PLAYER = ADMIN_KEY + "manage_player"; + } } } diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 2d1983a..7fa8c52 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -33,6 +33,7 @@ gui: go_back: name: "Back" home: + title: "Nicko - Home" admin: name: "Administration panel" lore: @@ -51,6 +52,16 @@ gui: name: "Reset appearance" lore: - "Completely remove your disguise." + admin: + gui_title: "Nicko > Administration" + manage_cache: + name: "Manage §6skin §fcache..." + lore: + - "§7Access the skin cache management panel." + manage_player: + name: "Check a player..." + lore: + - "§7See players' disguise information." settings: language: name: "Language" @@ -60,6 +71,5 @@ gui: bungeecord: name: "Bungeecord Transfer" lore: - - "{0}" - "§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 fa6d9fa..76bb5b7 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -33,6 +33,7 @@ gui: go_back: name: "Retour" home: + title: "Nicko - Accueil" admin: name: "Panel d''administration" lore: @@ -48,9 +49,19 @@ gui: change_both: name: "Changer les §6deux" reset: - name: "Réinitialiser l'apparence" + name: "Réinitialiser l''apparence" lore: - "Supprime complètement votre déguisement." + admin: + title: "Nicko > Administration" + manage_cache: + name: "Gérer le cache d''§6apparences..." + lore: + - "§7Accédez à la gestion du cache d''apparences." + manage_player: + name: "Vérifier un joueur..." + lore: + - "§7Vérifiez les informations de déguisement d'un joueur." settings: language: name: "Langage" @@ -60,6 +71,5 @@ gui: bungeecord: name: "Transfert Bungeecord" lore: - - "{0}" - "§7§oParcourez les valeurs" - "§7§oavec un clique gauche/droit." \ No newline at end of file From dd35f38dc2078cc4fe213e5f7108886fe610a8eb Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 31 Aug 2023 10:44:57 +0200 Subject: [PATCH 102/296] fix: inventory closing --- .../atnrch/nicko/gui/items/settings/LanguageCyclingItem.java | 2 +- .../xyz/atnrch/nicko/test/i18n/I18NItemTranslationTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 282ed0a..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 @@ -42,13 +42,13 @@ 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()) { player.sendMessage(i18n.translate(I18NDict.Event.Settings.ERROR)); } else { new SettingsGUI(player).open(); } - player.getOpenInventory().close(); }, localeOrdinal, providers); } diff --git a/src/test/java/xyz/atnrch/nicko/test/i18n/I18NItemTranslationTest.java b/src/test/java/xyz/atnrch/nicko/test/i18n/I18NItemTranslationTest.java index 31f85a9..e123dae 100644 --- a/src/test/java/xyz/atnrch/nicko/test/i18n/I18NItemTranslationTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/i18n/I18NItemTranslationTest.java @@ -45,7 +45,7 @@ public class I18NItemTranslationTest { public void translateItemLore() { final I18N i18n = new I18N(Locale.FRENCH); final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Settings.BUNGEECORD, "Test"); - assertEquals("Test", translation.getLore().get(0)); + assertEquals("§7§oParcourez les valeurs", translation.getLore().get(0)); } @AfterAll From c57400707eb051a240f3546d5a784545031c011b Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 1 Sep 2023 16:37:01 +0200 Subject: [PATCH 103/296] feat: home gui translated, fly cancel after disguise --- .../nicko/appearance/AppearanceManager.java | 4 ++- .../java/xyz/atnrch/nicko/gui/HomeGUI.java | 26 ++++++++++++++----- .../gui/items/appearance/ChangeBothItem.java | 21 +++++++++++---- .../gui/items/appearance/ChangeNameItem.java | 21 +++++++++++---- .../gui/items/appearance/ChangeSkinItem.java | 20 +++++++++++--- .../nicko/gui/items/home/AdminAccessItem.java | 21 +++++++++++---- .../nicko/gui/items/home/ResetItem.java | 20 +++++++++----- .../gui/items/home/SettingsAccessItem.java | 21 +++++++++++---- .../java/xyz/atnrch/nicko/i18n/I18NDict.java | 5 ++++ src/main/resources/en.yml | 5 ++-- src/main/resources/fr.yml | 9 ++++--- 11 files changed, 128 insertions(+), 45 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java index 431751d..0f8b932 100644 --- a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java @@ -122,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()); @@ -130,8 +131,9 @@ public class AppearanceManager { respawn.setDifficulty(world.getDifficulty()); respawn.setCopyMetadata(true); respawn.sendPacket(player); - player.setFlying(wasFlying); player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); + player.setAllowFlight(wasAllowedToFly); + player.setFlying(wasFlying); player.updateInventory(); // Marked as unstable. } diff --git a/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java b/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java index be2f02b..60a7bc8 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,16 +28,26 @@ public class HomeGUI { dynamicStructure[2] = dynamicStructure[2].replace("A", "#"); } + final I18N i18n = new I18N(player); + this.title = i18n.translatePrefixless(I18NDict.GUI.Home.TITLE); + 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', exitItem.get()) - .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('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/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/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/ResetItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/home/ResetItem.java index c4f9e40..e142dba 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 @@ -6,6 +6,7 @@ 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; @@ -13,17 +14,22 @@ 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(() -> { +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 Optional optionalProfile = NickoProfile.get(player); 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/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index dde28f7..30c1473 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -74,6 +74,11 @@ public class I18NDict { public static final String TITLE = HOME_KEY + "title"; 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 { diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 7fa8c52..1232102 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -41,7 +41,7 @@ gui: settings: name: "Settings" lore: - - "Configure your experience." + - "Fine tune your experience with Nicko." change_name: name: "§6Nickname §fchange" change_skin: @@ -53,7 +53,7 @@ gui: lore: - "Completely remove your disguise." admin: - gui_title: "Nicko > Administration" + title: "Nicko > Administration" manage_cache: name: "Manage §6skin §fcache..." lore: @@ -63,6 +63,7 @@ gui: lore: - "§7See players' disguise information." settings: + title: "Nicko > Settings" language: name: "Language" lore: diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 76bb5b7..7351e15 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -41,7 +41,7 @@ gui: settings: name: "Paramètres" lore: - - "Configurez votre expérience." + - "Gérez votre expérience avec Nicko." change_name: name: "Changer le §6pseudo" change_skin: @@ -49,20 +49,21 @@ gui: change_both: name: "Changer les §6deux" reset: - name: "Réinitialiser l''apparence" + name: "Réinitialiser l'apparence" lore: - "Supprime complètement votre déguisement." admin: title: "Nicko > Administration" manage_cache: - name: "Gérer le cache d''§6apparences..." + name: "Gérer le cache d'§6apparences..." lore: - - "§7Accédez à la gestion du cache d''apparences." + - "§7Accédez à la gestion du cache d'apparences." manage_player: name: "Vérifier un joueur..." lore: - "§7Vérifiez les informations de déguisement d'un joueur." settings: + title: "Nicko > Paramètres" language: name: "Langage" lore: From 1d366855a256990e6439109042a77f11febb8b5b Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 1 Sep 2023 16:40:40 +0200 Subject: [PATCH 104/296] refactor(packet): note --- .../java/xyz/atnrch/nicko/appearance/AppearanceManager.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java index 0f8b932..d655d0e 100644 --- a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java @@ -165,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(), From 94bb9ffc18f827879e3a19c45e52b8eb6e481d14 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 1 Sep 2023 16:49:05 +0200 Subject: [PATCH 105/296] feat: close cache --- src/main/java/xyz/atnrch/nicko/NickoBukkit.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index f2da0ba..9cc3aa6 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -109,11 +109,20 @@ 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."); + } + + if (!dataStore.getCache().getProvider().close()) { + if (!dataStore.getCache().getProvider().close()) { + getLogger().severe("Failed to close cache!"); + } else { + getLogger().info("Cache closed."); + } } } From 6633ac94a83c3f72106156af1148bbf75b62318b Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 1 Sep 2023 22:24:44 +0200 Subject: [PATCH 106/296] fix: revert cache close --- src/main/java/xyz/atnrch/nicko/NickoBukkit.java | 8 -------- src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java | 10 +++++++--- .../xyz/atnrch/nicko/storage/map/MapCacheProvider.java | 1 - .../atnrch/nicko/storage/redis/RedisCacheProvider.java | 7 ++++++- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index 9cc3aa6..a05416d 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -116,14 +116,6 @@ public class NickoBukkit extends JavaPlugin { } else { getLogger().info("Persistence closed."); } - - if (!dataStore.getCache().getProvider().close()) { - if (!dataStore.getCache().getProvider().close()) { - getLogger().severe("Failed to close cache!"); - } else { - getLogger().info("Cache closed."); - } - } } getLogger().info("Nicko (Bukkit) has been disabled."); diff --git a/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java b/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java index 54ebf7a..5765025 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java @@ -4,14 +4,15 @@ import xyz.atnrch.nicko.gui.items.common.GoBackItem; 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,6 +24,9 @@ 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.Settings.TITLE); + final HomeGUI parent = new HomeGUI(player); final LanguageCyclingItem languageItem = new LanguageCyclingItem(player); final BungeeCordCyclingItem bungeeCordItem = new BungeeCordCyclingItem(player); @@ -38,6 +42,6 @@ public class SettingsGUI { } 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/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/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 From 292e9a4a6bda315c44ae08b3523f83028eee9701 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 2 Sep 2023 22:27:25 +0200 Subject: [PATCH 107/296] feat(i18n): translate unavailable item --- .../java/xyz/atnrch/nicko/NickoBukkit.java | 2 -- .../java/xyz/atnrch/nicko/gui/AdminGUI.java | 10 +++++++++- .../xyz/atnrch/nicko/gui/SettingsGUI.java | 3 +++ .../gui/items/common/UnavailableItem.java | 19 ++++++++++++++++--- .../java/xyz/atnrch/nicko/i18n/I18NDict.java | 1 + src/main/resources/en.yml | 4 ++++ src/main/resources/fr.yml | 4 ++++ 7 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index a05416d..ec82768 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -9,7 +9,6 @@ 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; @@ -92,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..."); diff --git a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java index fb95b1d..92f5aeb 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java @@ -4,17 +4,24 @@ 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.Admin.TITLE); + final HomeGUI parent = new HomeGUI(player); final GoBackItem backItem = new GoBackItem(player); + final UnavailableItem unavailableItem = new UnavailableItem(player); this.gui = Gui.normal() .setStructure( @@ -23,6 +30,7 @@ public class AdminGUI { "B # # # # # # # #" ) .addIngredient('S', new ManageCacheItem()) + .addIngredient('U', unavailableItem.get()) .addIngredient('C', new ManagePlayerItem()) .addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle())) .build(); diff --git a/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java b/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java index 5765025..a65de03 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java @@ -1,6 +1,7 @@ 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; @@ -28,6 +29,7 @@ public class SettingsGUI { this.title = i18n.translatePrefixless(I18NDict.GUI.Settings.TITLE); 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); @@ -36,6 +38,7 @@ public class SettingsGUI { .setStructure(dynamicStructure) .addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle())) .addIngredient('L', languageItem.get()) + .addIngredient('U', unavailableItem.get()) .addIngredient('T', bungeeCordItem.get()) .build(); this.player = player; 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..56681d7 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,13 +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); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.UNAVAILABLE); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); builder.setDisplayName("Unavailable"); builder.addLoreLines("§7§oThis button is disabled."); return builder; diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index 30c1473..b345e70 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -67,6 +67,7 @@ public class I18NDict { private static final String GUI_KEY = "gui."; public static final String EXIT = GUI_KEY + "exit"; + public static final String UNAVAILABLE = GUI_KEY + "unavailable"; public static final String GO_BACK = GUI_KEY + "go_back"; public static class Home { diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 1232102..348baf0 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -32,6 +32,10 @@ gui: name: "Exit" go_back: name: "Back" + unavailable: + name: "Unavailable" + lore: + - "§7§oThis button is disabled." home: title: "Nicko - Home" admin: diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 7351e15..c2c8b8e 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -32,6 +32,10 @@ gui: name: "Quitter" go_back: name: "Retour" + unavailable: + name: "Indisponible" + lore: + - "§7§oCe boutton est désactivé." home: title: "Nicko - Accueil" admin: From b24202e8abfa1b7b20bfbbcc167c9d99705ae398 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 7 Sep 2023 22:12:02 +0200 Subject: [PATCH 108/296] feat: updated the localization files, translated coice gui --- .../java/xyz/atnrch/nicko/gui/ChoiceGUI.java | 42 +++++++++++++++++++ .../java/xyz/atnrch/nicko/gui/ConfirmGUI.java | 34 --------------- .../gui/items/admin/cache/CacheEntryItem.java | 6 +-- .../gui/items/common/UnavailableItem.java | 2 - .../gui/items/common/choice/CancelItem.java | 32 ++++++++++++++ .../{confirm => choice}/ChoiceCallback.java | 2 +- .../gui/items/common/choice/ConfirmItem.java | 32 ++++++++++++++ .../gui/items/common/confirm/CancelItem.java | 19 --------- .../gui/items/common/confirm/ConfirmItem.java | 19 --------- .../java/xyz/atnrch/nicko/i18n/I18NDict.java | 8 ++++ src/main/resources/en.yml | 13 ++++-- src/main/resources/fr.yml | 23 ++++++---- 12 files changed, 143 insertions(+), 89 deletions(-) create mode 100644 src/main/java/xyz/atnrch/nicko/gui/ChoiceGUI.java delete mode 100644 src/main/java/xyz/atnrch/nicko/gui/ConfirmGUI.java create mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/common/choice/CancelItem.java rename src/main/java/xyz/atnrch/nicko/gui/items/common/{confirm => choice}/ChoiceCallback.java (61%) create mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/common/choice/ConfirmItem.java delete mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/CancelItem.java delete mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/ConfirmItem.java 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/items/admin/cache/CacheEntryItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntryItem.java index a66f206..06be4d4 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.ChoiceGUI; import xyz.atnrch.nicko.gui.CacheDetailedGUI; -import xyz.atnrch.nicko.gui.items.common.confirm.ChoiceCallback; +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); 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 56681d7..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 @@ -21,8 +21,6 @@ public class UnavailableItem { final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.UNAVAILABLE); builder.setDisplayName(translation.getName()); translation.getLore().forEach(builder::addLoreLines); - builder.setDisplayName("Unavailable"); - builder.addLoreLines("§7§oThis button is disabled."); 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/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index b345e70..6c5110d 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -70,6 +70,14 @@ public class I18NDict { public static final String UNAVAILABLE = GUI_KEY + "unavailable"; public static final String GO_BACK = GUI_KEY + "go_back"; + 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."; diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 348baf0..0b649cd 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -36,16 +36,23 @@ gui: name: "Unavailable" lore: - "§7§oThis button is disabled." + choice: + confirm: + name: "§aConfirm" + choose: + name: "§6§oChoose an option..." + cancel: + name: "§cCancel" home: title: "Nicko - Home" admin: name: "Administration panel" lore: - - "Configure and manage Nicko." + - "§7Configure and manage Nicko." settings: name: "Settings" lore: - - "Fine tune your experience with Nicko." + - "§7Fine tune your experience with Nicko." change_name: name: "§6Nickname §fchange" change_skin: @@ -55,7 +62,7 @@ gui: reset: name: "Reset appearance" lore: - - "Completely remove your disguise." + - "§7Completely remove your disguise." admin: title: "Nicko > Administration" manage_cache: diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index c2c8b8e..504f712 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." @@ -13,14 +13,14 @@ event: error: "§cImpossible de mettre à jour vos paramètres. §7§o({0})" appearance: set: - error: "§cImpossible d''appliquer votre déguisement. §7§o({0})" + error: "§cImpossible d'appliquer votre déguisement. §7§o({0})" ok: "§fDéguisement appliqué." restore: - error: "§cImpossible d''appliquer votre précédent déguisement. §7§o({0})" + error: "§cImpossible d'appliquer votre précédent déguisement. §7§o({0})" ok: "§aVotre précédent déguisement a été appliqué." remove: error: "§cImpossible de retirer votre déguisement. Il sera réinitialisé à votre prochaine reconnexion." - missing: "§cVous n''avez pas de déguisement." + missing: "§cVous n'avez pas de déguisement." ok: "§fDéguisement retiré." admin: cache: @@ -36,16 +36,23 @@ gui: name: "Indisponible" lore: - "§7§oCe boutton est désactivé." + choice: + confirm: + name: "§aConfirmer" + choose: + name: "§6§oChoisissez une option..." + cancel: + name: "§cAnnuler" home: title: "Nicko - Accueil" admin: - name: "Panel d''administration" + name: "Panel d'administration" lore: - - "Configurez et gérez Nicko." + - "§7Configurez et gérez Nicko." settings: name: "Paramètres" lore: - - "Gérez votre expérience avec Nicko." + - "§7Gérez votre expérience avec Nicko." change_name: name: "Changer le §6pseudo" change_skin: @@ -55,7 +62,7 @@ gui: reset: name: "Réinitialiser l'apparence" lore: - - "Supprime complètement votre déguisement." + - "§7Supprime complètement votre déguisement." admin: title: "Nicko > Administration" manage_cache: From 597ed23dbc314549309a07dd23eff14862f16d7c Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 11 Sep 2023 12:18:43 +0200 Subject: [PATCH 109/296] feat(i18n): cache admin --- .../atnrch/nicko/gui/CacheManagementGUI.java | 21 +++++++++---- .../admin/cache/CacheStatisticsItem.java | 30 ++++++++++++++----- .../admin/cache/InvalidateCacheItem.java | 21 ++++++++----- ...EntryItem.java => InvalidateSkinItem.java} | 25 +++++++++++----- src/main/java/xyz/atnrch/nicko/i18n/I18N.java | 5 ++-- .../java/xyz/atnrch/nicko/i18n/I18NDict.java | 9 ++++++ .../nicko/placeholder/NickoExpansion.java | 11 +++++-- src/main/resources/en.yml | 19 ++++++++++++ src/main/resources/fr.yml | 25 ++++++++++++++-- .../test/i18n/I18NItemTranslationTest.java | 4 +-- 10 files changed, 131 insertions(+), 39 deletions(-) rename src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/{InvalidateEntryItem.java => InvalidateSkinItem.java} (54%) diff --git a/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java b/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java index 769349c..9e42ea3 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java @@ -3,30 +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.Admin.Cache.TITLE); + 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', backItem.get(parent.getGUI(), parent.getTitle())) - .addIngredient('S', new CacheStatisticsItem()) - .addIngredient('A', new InvalidateCacheItem()) - .addIngredient('D', new InvalidateEntryItem()) + .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/items/admin/cache/CacheStatisticsItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheStatisticsItem.java index 9398e7a..c759ea5 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,27 @@ 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()) + ); + translation.getLore().forEach(System.out::println); + // 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/InvalidateSkinItem.java similarity index 54% rename from src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateEntryItem.java rename to src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateSkinItem.java index 71627b8..a495263 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateEntryItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateSkinItem.java @@ -1,19 +1,28 @@ package xyz.atnrch.nicko.gui.items.admin.cache; -import xyz.atnrch.nicko.gui.CacheDetailedGUI; import org.bukkit.Material; +import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; +import xyz.atnrch.nicko.gui.CacheDetailedGUI; +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 InvalidateEntryItem extends SuppliedItem { - public InvalidateEntryItem() { - super(() -> { +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); - 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."); + 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(); diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java index 20db750..f0b7385 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java @@ -35,7 +35,7 @@ public class I18N { this.yamlConfig = getYamlConfig(); } - public ItemTranslation translateItem(String key, String... args) { + public ItemTranslation translateItem(String key, Object... args) { final String nameKey = key + ".name"; final String loreKey = key + ".lore"; final String name = readString(nameKey); @@ -74,8 +74,9 @@ public class I18N { // If it does, replace the content with the args at position replacementIndex if (replacementIndex < args.length && args[replacementIndex] != null) { + System.out.println("replacing..."); // Replace with the corresponding varargs index - toTranslate.set(lineIndex, currentLine.replace("{" + replacementIndex + "}", args[replacementIndex])); + toTranslate.set(lineIndex, currentLine.replace("{" + replacementIndex + "}", args[replacementIndex].toString())); replacementIndex++; } diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index 6c5110d..f8df6b8 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -104,6 +104,15 @@ public class I18NDict { public static final String TITLE = ADMIN_KEY + "title"; public static final String MANAGE_CACHE = ADMIN_KEY + "manage_cache"; public static final String MANAGE_PLAYER = ADMIN_KEY + "manage_player"; + + public static class Cache { + private static final String CACHE_KEY = ADMIN_KEY + "cache."; + + public static final String TITLE = CACHE_KEY + "title"; + 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/placeholder/NickoExpansion.java b/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java index 56e003e..1754509 100644 --- a/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java +++ b/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java @@ -51,9 +51,14 @@ public class NickoExpansion extends PlaceholderExpansion { final Optional optionalProfile = instance.getDataStore().getData(player.getUniqueId()); if (optionalProfile.isPresent()) { final NickoProfile profile = optionalProfile.get(); - if (!profile.hasData()) { - 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(); diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 0b649cd..d9658f3 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -73,6 +73,25 @@ gui: name: "Check a player..." lore: - "§7See players' disguise information." + cache: + title: "Nicko > Admin... > 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: title: "Nicko > Settings" language: diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 504f712..9543229 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -66,13 +66,34 @@ gui: admin: title: "Nicko > Administration" manage_cache: - name: "Gérer le cache d'§6apparences..." + name: "Gérer le cache d'§6skin..." lore: - - "§7Accédez à la gestion du cache d'apparences." + - "§7Accédez à la gestion du cache de skin." manage_player: name: "Vérifier un joueur..." lore: - "§7Vérifiez les informations de déguisement d'un joueur." + cache: + title: "Nicko > Admin... > 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: title: "Nicko > Paramètres" language: diff --git a/src/test/java/xyz/atnrch/nicko/test/i18n/I18NItemTranslationTest.java b/src/test/java/xyz/atnrch/nicko/test/i18n/I18NItemTranslationTest.java index e123dae..6e55d99 100644 --- a/src/test/java/xyz/atnrch/nicko/test/i18n/I18NItemTranslationTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/i18n/I18NItemTranslationTest.java @@ -44,8 +44,8 @@ public class I18NItemTranslationTest { @DisplayName("Translate Item") public void translateItemLore() { final I18N i18n = new I18N(Locale.FRENCH); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Settings.BUNGEECORD, "Test"); - assertEquals("§7§oParcourez les valeurs", translation.getLore().get(0)); + final String translation = i18n.translatePrefixless(I18NDict.Event.Settings.ERROR, "Test!"); + assertEquals("§cImpossible de mettre à jour vos paramètres. §7§o(Test!)", translation); } @AfterAll From f436c7db3a90c5872a3d9416feaa6f2c89d59149 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 11 Sep 2023 12:56:56 +0200 Subject: [PATCH 110/296] refactor(wrapper): update accordingly --- .../java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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")); From 8838961f3756e4a39fe7cca3785f6f1897be5a5b Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 15 Sep 2023 22:15:00 +0200 Subject: [PATCH 111/296] feat(i18n): admin gui --- .../java/xyz/atnrch/nicko/gui/AdminGUI.java | 7 +-- .../gui/items/admin/ManageCacheItem.java | 23 +++++----- .../gui/items/admin/ManagePlayerItem.java | 38 ++++++++-------- .../admin/cache/CacheStatisticsItem.java | 1 - .../nicko/gui/items/common/LoadingItem.java | 27 ++++++++++++ .../nicko/gui/items/home/ResetItem.java | 9 ++-- src/main/java/xyz/atnrch/nicko/i18n/I18N.java | 5 +-- .../java/xyz/atnrch/nicko/i18n/I18NDict.java | 3 +- src/main/resources/en.yml | 4 +- src/main/resources/fr.yml | 12 ++--- ...tionTest.java => ItemTranslationTest.java} | 12 ++--- .../nicko/test/i18n/TranslationTest.java | 44 +++++++++++++++++++ 12 files changed, 131 insertions(+), 54 deletions(-) create mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/common/LoadingItem.java rename src/test/java/xyz/atnrch/nicko/test/i18n/{I18NItemTranslationTest.java => ItemTranslationTest.java} (74%) create mode 100644 src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java diff --git a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java index 92f5aeb..3c10319 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java @@ -22,16 +22,17 @@ public class AdminGUI { 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('S', new ManageCacheItem(i18n)) + .addIngredient('C', managePlayerItem.get()) .addIngredient('U', unavailableItem.get()) - .addIngredient('C', new ManagePlayerItem()) .addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle())) .build(); this.player = 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..9e1a2d6 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,25 @@ 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.gui.items.common.LoadingItem; +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.AsyncItem; 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 LoadingItem(i18n).get(), () -> { 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/CacheStatisticsItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheStatisticsItem.java index c759ea5..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 @@ -31,7 +31,6 @@ public class CacheStatisticsItem { stats.requestCount(), Math.round(cache.size()) ); - translation.getLore().forEach(System.out::println); // TODO (Ineanto, 9/11/23): This doesn't work. builder.setDisplayName(translation.getName()); translation.getLore().forEach(builder::addLoreLines); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/LoadingItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/LoadingItem.java new file mode 100644 index 0000000..c305b4a --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/gui/items/common/LoadingItem.java @@ -0,0 +1,27 @@ +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.item.ItemProvider; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.impl.SuppliedItem; + +public class LoadingItem { + private final I18N i18n; + + public LoadingItem(I18N i18n) { + this.i18n = i18n; + } + + public ItemProvider get() { + return 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(); + } +} 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 e142dba..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 @@ -12,7 +12,6 @@ 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 { private final I18N i18n; @@ -33,25 +32,23 @@ public class ResetItem { final ClickType clickType = event.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { final Optional optionalProfile = NickoProfile.get(player); - final AtomicBoolean result = new AtomicBoolean(false); optionalProfile.ifPresent(profile -> { if (!profile.hasData()) { player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.MISSING)); event.getEvent().getView().close(); - result.set(true); return; } final AppearanceManager appearanceManager = new AppearanceManager(player); if (!appearanceManager.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); + profile.setSkin(null); + profile.setName(null); } }); - return result.get(); + return true; } return false; }); diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java index f0b7385..0087468 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java @@ -18,7 +18,7 @@ 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+}"); + private final Pattern replacementPattern = Pattern.compile("\\{\\d+}$", Pattern.DOTALL); private final YamlConfig yamlConfig; private final Player player; private final Locale playerLocale; @@ -67,14 +67,13 @@ public class I18N { // If the line doesn't contain {i}, skip it final Matcher matcher = replacementPattern.matcher(currentLine); - if (!matcher.matches()) { + if (!matcher.find()) { lineIndex++; continue; } // If it does, replace the content with the args at position replacementIndex if (replacementIndex < args.length && args[replacementIndex] != null) { - System.out.println("replacing..."); // Replace with the corresponding varargs index toTranslate.set(lineIndex, currentLine.replace("{" + replacementIndex + "}", args[replacementIndex].toString())); replacementIndex++; diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index f8df6b8..0878f2b 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -67,8 +67,9 @@ public class I18NDict { private static final String GUI_KEY = "gui."; public static final String EXIT = GUI_KEY + "exit"; - public static final String UNAVAILABLE = GUI_KEY + "unavailable"; 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 class Choice { private static final String CHOICE_KEY = GUI_KEY + "choice."; diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index d9658f3..3e904af 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -36,6 +36,8 @@ gui: name: "Unavailable" lore: - "§7§oThis button is disabled." + loading: + name: "§7§oLoading..." choice: confirm: name: "§aConfirm" @@ -68,7 +70,7 @@ gui: manage_cache: name: "Manage §6skin §fcache..." lore: - - "§7Access the skin cache management panel." + - "§7View and manage the skin cache." manage_player: name: "Check a player..." lore: diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 9543229..ebf2428 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -13,14 +13,14 @@ event: error: "§cImpossible de mettre à jour vos paramètres. §7§o({0})" appearance: set: - error: "§cImpossible d'appliquer votre déguisement. §7§o({0})" + error: "§cImpossible d''appliquer votre déguisement. §7§o({0})" ok: "§fDéguisement appliqué." restore: - error: "§cImpossible d'appliquer votre précédent déguisement. §7§o({0})" + error: "§cImpossible d''appliquer votre précédent déguisement. §7§o({0})" ok: "§aVotre précédent déguisement a été appliqué." remove: error: "§cImpossible de retirer votre déguisement. Il sera réinitialisé à votre prochaine reconnexion." - missing: "§cVous n'avez pas de déguisement." + missing: "§cVous n''avez pas de déguisement." ok: "§fDéguisement retiré." admin: cache: @@ -36,6 +36,8 @@ gui: name: "Indisponible" lore: - "§7§oCe boutton est désactivé." + loading: + name: "§7§oChargement..." choice: confirm: name: "§aConfirmer" @@ -66,9 +68,9 @@ gui: admin: title: "Nicko > Administration" manage_cache: - name: "Gérer le cache d'§6skin..." + name: "Gérer le cache de §6skin..." lore: - - "§7Accédez à la gestion du cache de skin." + - "§7Consultez et gérez le cache de skin." manage_player: name: "Vérifier un joueur..." lore: diff --git a/src/test/java/xyz/atnrch/nicko/test/i18n/I18NItemTranslationTest.java b/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java similarity index 74% rename from src/test/java/xyz/atnrch/nicko/test/i18n/I18NItemTranslationTest.java rename to src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java index 6e55d99..a1b6e55 100644 --- a/src/test/java/xyz/atnrch/nicko/test/i18n/I18NItemTranslationTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java @@ -14,10 +14,9 @@ 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.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; -public class I18NItemTranslationTest { +public class ItemTranslationTest { private static PlayerMock player; @BeforeAll @@ -44,8 +43,11 @@ public class I18NItemTranslationTest { @DisplayName("Translate Item") public void translateItemLore() { final I18N i18n = new I18N(Locale.FRENCH); - final String translation = i18n.translatePrefixless(I18NDict.Event.Settings.ERROR, "Test!"); - assertEquals("§cImpossible de mettre à jour vos paramètres. §7§o(Test!)", translation); + 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 diff --git a/src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java b/src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java new file mode 100644 index 0000000..6e16840 --- /dev/null +++ b/src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java @@ -0,0 +1,44 @@ +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.Locale; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class TranslationTest { + 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 Line With Replacement") + public void translateItemTranslationWithoutLore() { + final I18N i18n = new I18N(Locale.FRENCH); + final String translation = i18n.translatePrefixless(I18NDict.Event.Settings.ERROR, "Test"); + assertEquals("§cImpossible de mettre à jour vos paramètres. §7§o(Test)", translation); + } + + @AfterAll + public static void shutdown() { + MockBukkit.unmock(); + } +} From 854039d657ef24b77c3c418fbf504eef2552eef4 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 17 Sep 2023 17:33:21 +0200 Subject: [PATCH 112/296] feat(i18n): gui translation complete --- .../java/xyz/atnrch/nicko/gui/AdminGUI.java | 2 +- .../atnrch/nicko/gui/CacheManagementGUI.java | 2 +- .../java/xyz/atnrch/nicko/gui/HomeGUI.java | 2 +- ...etailedGUI.java => InvalidateSkinGUI.java} | 20 ++++++--- .../xyz/atnrch/nicko/gui/PlayerCheckGUI.java | 18 +++++--- .../xyz/atnrch/nicko/gui/SettingsGUI.java | 2 +- .../gui/items/admin/ManageCacheItem.java | 12 +++++- .../gui/items/admin/cache/CacheEntryItem.java | 4 +- .../items/admin/cache/InvalidateSkinItem.java | 4 +- .../admin/check/PlayerInformationItem.java | 43 +++++++++++-------- .../nicko/gui/items/common/LoadingItem.java | 27 ------------ .../gui/items/common/ScrollDownItem.java | 14 +++--- .../nicko/gui/items/common/ScrollUpItem.java | 16 ++++--- .../java/xyz/atnrch/nicko/i18n/I18NDict.java | 18 ++++++-- src/main/resources/en.yml | 26 +++++++++-- src/main/resources/fr.yml | 26 +++++++++-- 16 files changed, 145 insertions(+), 91 deletions(-) rename src/main/java/xyz/atnrch/nicko/gui/{CacheDetailedGUI.java => InvalidateSkinGUI.java} (76%) delete mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/common/LoadingItem.java diff --git a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java index 3c10319..107e03b 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java @@ -17,7 +17,7 @@ public class AdminGUI { public AdminGUI(Player player) { final I18N i18n = new I18N(player); - this.title = i18n.translatePrefixless(I18NDict.GUI.Admin.TITLE); + this.title = i18n.translatePrefixless(I18NDict.GUI.Titles.ADMIN); final HomeGUI parent = new HomeGUI(player); final GoBackItem backItem = new GoBackItem(player); diff --git a/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java b/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java index 9e42ea3..5c081f9 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java @@ -17,7 +17,7 @@ public class CacheManagementGUI { public CacheManagementGUI(Player player) { final I18N i18n = new I18N(player); - this.title = i18n.translatePrefixless(I18NDict.GUI.Admin.Cache.TITLE); + this.title = i18n.translatePrefixless(I18NDict.GUI.Titles.CACHE); final AdminGUI parent = new AdminGUI(player); final GoBackItem backItem = new GoBackItem(player); diff --git a/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java b/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java index 60a7bc8..9303f45 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java @@ -29,7 +29,7 @@ public class HomeGUI { } final I18N i18n = new I18N(player); - this.title = i18n.translatePrefixless(I18NDict.GUI.Home.TITLE); + this.title = i18n.translatePrefixless(I18NDict.GUI.Titles.HOME); final ExitItem exitItem = new ExitItem(player); final ResetItem resetItem = new ResetItem(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 76% rename from src/main/java/xyz/atnrch/nicko/gui/CacheDetailedGUI.java rename to src/main/java/xyz/atnrch/nicko/gui/InvalidateSkinGUI.java index 12694ee..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,8 @@ 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 -> { @@ -48,8 +54,8 @@ 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('U', scrollUpItem); + guiItemBuilder.addIngredient('D', scrollDownItem); guiItemBuilder.addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle())); guiItemBuilder.setContent(items); }); @@ -58,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 2058cfc..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,19 +19,23 @@ 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( @@ -40,8 +46,8 @@ 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('U', scrollUpItem); + guiItemBuilder.addIngredient('D', scrollDownItem); guiItemBuilder.addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle())); guiItemBuilder.setContent(items); }); @@ -50,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 a65de03..a19be9e 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java @@ -26,7 +26,7 @@ public class SettingsGUI { dynamicStructure[1] = dynamicStructure[1].replace("T", "U"); final I18N i18n = new I18N(player); - this.title = i18n.translatePrefixless(I18NDict.GUI.Settings.TITLE); + this.title = i18n.translatePrefixless(I18NDict.GUI.Titles.SETTINGS); final HomeGUI parent = new HomeGUI(player); final UnavailableItem unavailableItem = new UnavailableItem(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 9e1a2d6..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,20 +1,28 @@ 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.CacheManagementGUI; -import xyz.atnrch.nicko.gui.items.common.LoadingItem; 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(I18N i18n) { - super(new LoadingItem(i18n).get(), + 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"); final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.MANAGE_CACHE); 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 06be4d4..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 @@ -7,7 +7,7 @@ import org.bukkit.event.inventory.InventoryClickEvent; import org.jetbrains.annotations.NotNull; import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.gui.ChoiceGUI; -import xyz.atnrch.nicko.gui.CacheDetailedGUI; +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; @@ -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/InvalidateSkinItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateSkinItem.java index a495263..d7ed378 100644 --- 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 @@ -3,7 +3,7 @@ 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.CacheDetailedGUI; +import xyz.atnrch.nicko.gui.InvalidateSkinGUI; import xyz.atnrch.nicko.i18n.I18N; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.i18n.ItemTranslation; @@ -28,7 +28,7 @@ public class InvalidateSkinItem { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { click.getEvent().getView().close(); - new CacheDetailedGUI(click.getPlayer()).open(); + 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 0fd601f..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,40 +4,47 @@ import org.bukkit.Bukkit; import org.bukkit.Material; 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.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 { - 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); - optionalProfile.ifPresent(profile -> { - if (profile.hasData()) { - skull.addLoreLines( - "§cNicked: §a✔", - "§cName: §6" + profile.getName(), - "§cSkin: §6" + profile.getSkin() - ); - } else { - skull.addLoreLines( - "§cNicked: §c❌", - "§cName: §7N/A", - "§cSkin: §7N/A" - ); - } - skull.setDisplayName("§6" + player.getName()); - }); + 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( + "§cPlease file a bug report", + "§cat https://ineanto.xyz/git/ineanto/nicko!" + ); + } return skull; }); diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/LoadingItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/common/LoadingItem.java deleted file mode 100644 index c305b4a..0000000 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/LoadingItem.java +++ /dev/null @@ -1,27 +0,0 @@ -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.item.ItemProvider; -import xyz.xenondevs.invui.item.builder.ItemBuilder; -import xyz.xenondevs.invui.item.impl.SuppliedItem; - -public class LoadingItem { - private final I18N i18n; - - public LoadingItem(I18N i18n) { - this.i18n = i18n; - } - - public ItemProvider get() { - return 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(); - } -} 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/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index 0878f2b..f60b0ad 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -70,6 +70,19 @@ public class I18NDict { 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."; @@ -82,7 +95,6 @@ public class I18NDict { public static class Home { private static final String HOME_KEY = GUI_KEY + "home."; - public static final String TITLE = HOME_KEY + "title"; 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"; @@ -94,7 +106,6 @@ public class I18NDict { public static class Settings { private static final String SETTINGS_KEY = GUI_KEY + "settings."; - public static final String TITLE = SETTINGS_KEY + "title"; public static final String LANGUAGE = SETTINGS_KEY + "language"; public static final String BUNGEECORD = SETTINGS_KEY + "bungeecord"; } @@ -102,14 +113,13 @@ public class I18NDict { public static class Admin { private static final String ADMIN_KEY = GUI_KEY + "admin."; - public static final String TITLE = ADMIN_KEY + "title"; 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 TITLE = CACHE_KEY + "title"; 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/resources/en.yml b/src/main/resources/en.yml index 3e904af..e896a3b 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -28,6 +28,14 @@ event: 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: @@ -45,8 +53,15 @@ gui: 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: - title: "Nicko - Home" admin: name: "Administration panel" lore: @@ -66,7 +81,6 @@ gui: lore: - "§7Completely remove your disguise." admin: - title: "Nicko > Administration" manage_cache: name: "Manage §6skin §fcache..." lore: @@ -75,8 +89,13 @@ gui: name: "Check a player..." lore: - "§7See players' disguise information." + check: + name: "{0}" + lore: + - "§cNicked: §a{1}" + - "§cName: §6{2}" + - "§cSkin: §6{3}" cache: - title: "Nicko > Admin... > Cache" statistics: name: "Statistics" lore: @@ -95,7 +114,6 @@ gui: - "§7Select a specific skin to invalidate." - "§7Useful if a skin has been recently updated." settings: - title: "Nicko > Settings" language: name: "Language" lore: diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index ebf2428..a5a070c 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -28,6 +28,14 @@ event: invalidate_entry: "§6{0} §fa été invalidé." gui: + 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: @@ -45,8 +53,15 @@ gui: 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: - title: "Nicko - Accueil" admin: name: "Panel d'administration" lore: @@ -66,7 +81,6 @@ gui: lore: - "§7Supprime complètement votre déguisement." admin: - title: "Nicko > Administration" manage_cache: name: "Gérer le cache de §6skin..." lore: @@ -75,8 +89,13 @@ gui: 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: - title: "Nicko > Admin... > Cache" statistics: name: "Statistiques" lore: @@ -97,7 +116,6 @@ gui: - "§7invalider. Utile dans le cas où un skin" - "§7a récemment été mis à jour." settings: - title: "Nicko > Paramètres" language: name: "Langage" lore: From 649e23409af21eb705ab3fe1c3617dac728dd58a Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 17 Sep 2023 17:36:17 +0200 Subject: [PATCH 113/296] Dynamically translate GUI (#3) Reviewed-on: https://ineanto.xyz/git/ineanto/nicko/pulls/3 --- pom.xml | 16 +-- .../java/xyz/atnrch/nicko/NickoBukkit.java | 20 +-- .../xyz/atnrch/nicko/anvil/AnvilManager.java | 27 ++-- .../nicko/appearance/AppearanceManager.java | 108 ++++----------- .../atnrch/nicko/command/NickoCommand.java | 27 ++-- ...ckoDebugSubCmd.java => NickoDebugCmd.java} | 44 +++--- .../nicko/command/sub/NickoCheckSubCmd.java | 44 ------ .../nicko/event/PlayerJoinListener.java | 26 ++-- .../java/xyz/atnrch/nicko/gui/AdminGUI.java | 21 ++- .../atnrch/nicko/gui/CacheManagementGUI.java | 25 +++- .../java/xyz/atnrch/nicko/gui/ChoiceGUI.java | 42 ++++++ .../java/xyz/atnrch/nicko/gui/ConfirmGUI.java | 34 ----- .../java/xyz/atnrch/nicko/gui/HomeGUI.java | 29 ++-- ...etailedGUI.java => InvalidateSkinGUI.java} | 24 ++-- .../xyz/atnrch/nicko/gui/PlayerCheckGUI.java | 22 ++- .../xyz/atnrch/nicko/gui/SettingsGUI.java | 23 +++- .../gui/items/admin/ManageCacheItem.java | 29 ++-- .../gui/items/admin/ManagePlayerItem.java | 38 ++--- .../gui/items/admin/cache/CacheEntryItem.java | 10 +- .../admin/cache/CacheStatisticsItem.java | 29 ++-- .../admin/cache/InvalidateCacheItem.java | 21 +-- .../admin/cache/InvalidateEntryItem.java | 28 ---- .../items/admin/cache/InvalidateSkinItem.java | 37 +++++ .../admin/check/PlayerInformationItem.java | 44 +++--- .../gui/items/appearance/ChangeBothItem.java | 21 ++- .../gui/items/appearance/ChangeNameItem.java | 21 ++- .../gui/items/appearance/ChangeSkinItem.java | 20 ++- .../nicko/gui/items/common/GoBackItem.java | 22 ++- .../gui/items/common/ScrollDownItem.java | 14 +- .../nicko/gui/items/common/ScrollUpItem.java | 16 ++- .../gui/items/common/UnavailableItem.java | 21 ++- .../gui/items/common/choice/CancelItem.java | 32 +++++ .../{confirm => choice}/ChoiceCallback.java | 2 +- .../gui/items/common/choice/ConfirmItem.java | 32 +++++ .../gui/items/common/confirm/CancelItem.java | 19 --- .../gui/items/common/confirm/ConfirmItem.java | 19 --- .../nicko/gui/items/home/AdminAccessItem.java | 21 ++- .../atnrch/nicko/gui/items/home/ExitItem.java | 27 +++- .../nicko/gui/items/home/ResetItem.java | 60 ++++---- .../gui/items/home/SettingsAccessItem.java | 21 ++- .../items/settings/BungeeCordCyclingItem.java | 53 ++++--- .../items/settings/LanguageCyclingItem.java | 27 +++- src/main/java/xyz/atnrch/nicko/i18n/I18N.java | 130 +++++++++++------- .../java/xyz/atnrch/nicko/i18n/I18NDict.java | 71 ++++++++-- .../atnrch/nicko/i18n/ItemTranslation.java | 21 +++ .../atnrch/nicko/i18n/LocaleFileManager.java | 4 +- .../nicko/placeholder/NickoExpansion.java | 26 ++-- .../atnrch/nicko/profile/AppearanceData.java | 31 +++++ .../atnrch/nicko/profile/NickoProfile.java | 57 ++++++-- .../atnrch/nicko/storage/PlayerDataStore.java | 10 +- .../nicko/storage/map/MapCacheProvider.java | 1 - .../nicko/storage/redis/RedisCache.java | 1 + .../storage/redis/RedisCacheProvider.java | 7 +- .../atnrch/nicko/storage/sql/SQLStorage.java | 3 - .../wrapper/WrapperPlayServerRespawn.java | 2 +- src/main/resources/en.yml | 100 +++++++++++++- src/main/resources/fr.yml | 94 +++++++++++-- .../nicko/test/i18n/ItemTranslationTest.java | 57 ++++++++ ...I18NLoreTest.java => TranslationTest.java} | 18 ++- .../nicko/test/storage/SQLStorageTest.java | 12 +- .../test/storage/redis/RedisCacheTest.java | 11 +- 61 files changed, 1243 insertions(+), 629 deletions(-) rename src/main/java/xyz/atnrch/nicko/command/{sub/NickoDebugSubCmd.java => NickoDebugCmd.java} (53%) delete mode 100644 src/main/java/xyz/atnrch/nicko/command/sub/NickoCheckSubCmd.java create mode 100644 src/main/java/xyz/atnrch/nicko/gui/ChoiceGUI.java delete mode 100644 src/main/java/xyz/atnrch/nicko/gui/ConfirmGUI.java rename src/main/java/xyz/atnrch/nicko/gui/{CacheDetailedGUI.java => InvalidateSkinGUI.java} (70%) delete mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateEntryItem.java create mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateSkinItem.java create mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/common/choice/CancelItem.java rename src/main/java/xyz/atnrch/nicko/gui/items/common/{confirm => choice}/ChoiceCallback.java (61%) create mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/common/choice/ConfirmItem.java delete mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/CancelItem.java delete mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/common/confirm/ConfirmItem.java create mode 100644 src/main/java/xyz/atnrch/nicko/i18n/ItemTranslation.java create mode 100644 src/main/java/xyz/atnrch/nicko/profile/AppearanceData.java create mode 100644 src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java rename src/test/java/xyz/atnrch/nicko/test/i18n/{I18NLoreTest.java => TranslationTest.java} (67%) 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(); From 83b7f909765bf11b42a010c05197d1f10cf56390 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 5 Oct 2023 13:43:50 +0200 Subject: [PATCH 114/296] feat-gui-i18n: wrong branch rebase (#5) Reviewed-on: https://ineanto.xyz/git/ineanto/nicko/pulls/5 Co-authored-by: ineanto Co-committed-by: ineanto --- src/main/java/xyz/atnrch/nicko/NickoBukkit.java | 6 ++---- src/main/resources/config.yml | 6 +++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index ec82768..13ab606 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -2,9 +2,7 @@ package xyz.atnrch.nicko; import org.bukkit.Bukkit; import org.bukkit.Material; -import org.bukkit.command.PluginCommand; import org.bukkit.plugin.java.JavaPlugin; -import xyz.atnrch.nicko.command.NickoCommand; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.ConfigurationManager; import xyz.atnrch.nicko.event.PlayerJoinListener; @@ -84,10 +82,10 @@ public class NickoBukkit extends JavaPlugin { } } - final PluginCommand command = getCommand("nicko"); + /*final PluginCommand command = getCommand("nicko"); if (command != null) { command.setExecutor(new NickoCommand()); - } + }*/ Structure.addGlobalIngredient('#', new SimpleItem(new ItemBuilder(Material.AIR))); Structure.addGlobalIngredient('%', new SimpleItem(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setDisplayName(" "))); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 0f162c9..9b854cd 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -21,9 +21,13 @@ customLocale: false # This configuration section manages SQL. sql: # Indicates wherever the data will be stored locally - # inside a .json file or in a SQL database. + # inside a .json file or in an SQL database. # Accepted values: false (Disabled), true (Enabled) enabled: false + # Toggles between the MariaDB and MySQL drivers. + # If you use the MySQL database engine, switch this to off. + # Accepted values: false (Disabled), true (Enabled) + mariadb: true # SQL database's address # Accepted values: valid IP address (e.g. localhost, 127.0.0.1) address: "localhost" From 52c7c00dd1c05e77949d5cedbebef19185c21802 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 5 Oct 2023 13:56:49 +0200 Subject: [PATCH 115/296] feat(storage): add support for mysql --- pom.xml | 6 + .../atnrch/nicko/config/Configuration.java | 8 +- .../nicko/config/DataSourceConfiguration.java | 3 - .../nicko/config/DefaultDataSources.java | 8 + .../config/SQLDataSourceConfiguration.java | 14 ++ .../atnrch/nicko/storage/PlayerDataStore.java | 11 +- .../nicko/storage/mariadb/MariaDBStorage.java | 141 ++++++++++++++++++ .../MariaDBStorageProvider.java} | 10 +- .../MySQLStorage.java} | 12 +- .../storage/mysql/MySQLStorageProvider.java | 88 +++++++++++ .../atnrch/nicko/test/NickoPluginTest.java | 3 +- .../nicko/test/i18n/ItemTranslationTest.java | 6 +- .../nicko/test/i18n/TranslationTest.java | 5 +- .../nicko/test/storage/BrokenSQLTest.java | 3 +- .../nicko/test/storage/SQLStorageTest.java | 3 +- .../nicko/test/storage/map/MapCacheTest.java | 5 +- .../test/storage/redis/RedisCacheTest.java | 3 +- 17 files changed, 296 insertions(+), 33 deletions(-) create mode 100644 src/main/java/xyz/atnrch/nicko/config/DefaultDataSources.java create mode 100644 src/main/java/xyz/atnrch/nicko/config/SQLDataSourceConfiguration.java create mode 100644 src/main/java/xyz/atnrch/nicko/storage/mariadb/MariaDBStorage.java rename src/main/java/xyz/atnrch/nicko/storage/{sql/SQLStorageProvider.java => mariadb/MariaDBStorageProvider.java} (90%) rename src/main/java/xyz/atnrch/nicko/storage/{sql/SQLStorage.java => mysql/MySQLStorage.java} (94%) create mode 100644 src/main/java/xyz/atnrch/nicko/storage/mysql/MySQLStorageProvider.java diff --git a/pom.xml b/pom.xml index 35552f3..a258e34 100644 --- a/pom.xml +++ b/pom.xml @@ -91,6 +91,12 @@ mariadb-java-client 3.1.2 + + com.mysql + mysql-connector-j + 8.1.0 + + com.github.jsixface diff --git a/src/main/java/xyz/atnrch/nicko/config/Configuration.java b/src/main/java/xyz/atnrch/nicko/config/Configuration.java index e5ff073..9fdef97 100644 --- a/src/main/java/xyz/atnrch/nicko/config/Configuration.java +++ b/src/main/java/xyz/atnrch/nicko/config/Configuration.java @@ -4,13 +4,13 @@ import com.fasterxml.jackson.annotation.JsonProperty; public class Configuration { @JsonProperty("sql") - private final DataSourceConfiguration sqlConfiguration; + private final SQLDataSourceConfiguration sqlConfiguration; @JsonProperty("redis") private final DataSourceConfiguration redisConfiguration; private final String prefix; private final Boolean customLocale; - public Configuration(DataSourceConfiguration sqlConfiguration, DataSourceConfiguration redisConfiguration, String prefix, Boolean customLocale) { + public Configuration(SQLDataSourceConfiguration sqlConfiguration, DataSourceConfiguration redisConfiguration, String prefix, Boolean customLocale) { this.sqlConfiguration = sqlConfiguration; this.redisConfiguration = redisConfiguration; this.prefix = prefix; @@ -19,14 +19,14 @@ public class Configuration { public Configuration() { this( - new DataSourceConfiguration(false, "", 3306, "", ""), + new SQLDataSourceConfiguration(false, "", 3306, "", "", true), new DataSourceConfiguration(false, "", 6379, "", ""), "", false ); } - public DataSourceConfiguration getSqlConfiguration() { + public SQLDataSourceConfiguration getSqlConfiguration() { return sqlConfiguration; } diff --git a/src/main/java/xyz/atnrch/nicko/config/DataSourceConfiguration.java b/src/main/java/xyz/atnrch/nicko/config/DataSourceConfiguration.java index 291d242..20509df 100644 --- a/src/main/java/xyz/atnrch/nicko/config/DataSourceConfiguration.java +++ b/src/main/java/xyz/atnrch/nicko/config/DataSourceConfiguration.java @@ -1,9 +1,6 @@ package xyz.atnrch.nicko.config; public class DataSourceConfiguration { - public static final DataSourceConfiguration SQL_EMPTY = new DataSourceConfiguration(false, "127.0.0.1", 3306, "root", ""); - public static final DataSourceConfiguration REDIS_EMPTY = new DataSourceConfiguration(false, "127.0.0.1", 6379, "", ""); - private final boolean enabled; private final String address; private final Integer port; diff --git a/src/main/java/xyz/atnrch/nicko/config/DefaultDataSources.java b/src/main/java/xyz/atnrch/nicko/config/DefaultDataSources.java new file mode 100644 index 0000000..076ff54 --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/config/DefaultDataSources.java @@ -0,0 +1,8 @@ +package xyz.atnrch.nicko.config; + +public class DefaultDataSources { + public static final DataSourceConfiguration REDIS_EMPTY = new DataSourceConfiguration(false, "127.0.0.1", 6379, "", ""); + public static final SQLDataSourceConfiguration MARIADB_EMPTY = new SQLDataSourceConfiguration(false, "127.0.0.1", 3306, "root", "", true); + public static final SQLDataSourceConfiguration SQL_EMPTY = new SQLDataSourceConfiguration(false, "127.0.0.1", 3306, "root", "", false); + +} diff --git a/src/main/java/xyz/atnrch/nicko/config/SQLDataSourceConfiguration.java b/src/main/java/xyz/atnrch/nicko/config/SQLDataSourceConfiguration.java new file mode 100644 index 0000000..0bb9852 --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/config/SQLDataSourceConfiguration.java @@ -0,0 +1,14 @@ +package xyz.atnrch.nicko.config; + +public class SQLDataSourceConfiguration extends DataSourceConfiguration { + private final boolean mariadb; + + public SQLDataSourceConfiguration(boolean enabled, String address, Integer port, String username, String password, boolean mariadb) { + super(enabled, address, port, username, password); + this.mariadb = mariadb; + } + + public boolean isMariadb() { + return mariadb; + } +} diff --git a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java index 0412913..bf7c719 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java +++ b/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java @@ -1,16 +1,17 @@ package xyz.atnrch.nicko.storage; import org.bukkit.entity.Player; -import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.profile.NickoProfile; +import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.mojang.MojangAPI; import xyz.atnrch.nicko.mojang.MojangUtils; +import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.json.JSONStorage; import xyz.atnrch.nicko.storage.map.MapCache; +import xyz.atnrch.nicko.storage.mariadb.MariaDBStorage; +import xyz.atnrch.nicko.storage.mysql.MySQLStorage; import xyz.atnrch.nicko.storage.redis.RedisCache; -import xyz.atnrch.nicko.storage.sql.SQLStorage; import java.io.IOException; import java.util.Optional; @@ -24,7 +25,9 @@ public class PlayerDataStore { public PlayerDataStore(MojangAPI mojangAPI, Configuration configuration) { this.mojangAPI = mojangAPI; - this.storage = configuration.getSqlConfiguration().isEnabled() ? new SQLStorage(configuration) : new JSONStorage(); + this.storage = configuration.getSqlConfiguration().isEnabled() ? + configuration.getSqlConfiguration().isMariadb() ? new MariaDBStorage(configuration) : new MySQLStorage(configuration) + : new JSONStorage(); this.cache = configuration.getRedisConfiguration().isEnabled() ? new RedisCache(configuration) : new MapCache(); } diff --git a/src/main/java/xyz/atnrch/nicko/storage/mariadb/MariaDBStorage.java b/src/main/java/xyz/atnrch/nicko/storage/mariadb/MariaDBStorage.java new file mode 100644 index 0000000..6908612 --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/storage/mariadb/MariaDBStorage.java @@ -0,0 +1,141 @@ +package xyz.atnrch.nicko.storage.mariadb; + +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.NickoProfile; +import xyz.atnrch.nicko.storage.Storage; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Optional; +import java.util.UUID; +import java.util.logging.Logger; + +public class MariaDBStorage extends Storage { + private final Logger logger = Logger.getLogger("SQLStorage"); + private final Configuration configuration; + + private MariaDBStorageProvider provider; + + public MariaDBStorage(Configuration configuration) { + this.configuration = configuration; + } + + @Override + public MariaDBStorageProvider getProvider() { + if (provider == null) { + provider = new MariaDBStorageProvider(configuration); + } + return provider; + } + + @Override + public ActionResult store(UUID uuid, NickoProfile profile) { + final Connection connection = getProvider().getConnection(); + if (connection == null) return ActionResult.error(I18NDict.Error.SQL_ERROR); + + try { + final PreparedStatement statement = isStored(uuid) ? + getUpdateStatement(connection, uuid, profile) : getInsertStatement(connection, uuid, profile); + statement.executeUpdate(); + return ActionResult.ok(); + } catch (SQLException e) { + logger.warning("Couldn't send SQL Request: " + e.getMessage()); + return ActionResult.error(I18NDict.Error.SQL_ERROR); + } + } + + @Override + public boolean isStored(UUID uuid) { + final Connection connection = getProvider().getConnection(); + if (connection == null) return false; + + try { + final String sql = "SELECT uuid FROM nicko.DATA WHERE uuid = ?"; + + final PreparedStatement statement = connection.prepareStatement(sql); + statement.setString(1, uuid.toString()); + + final ResultSet resultSet = statement.executeQuery(); + return resultSet.next(); + } catch (SQLException e) { + logger.warning("Couldn't check if data is present: " + e.getMessage()); + return false; + } + } + + @Override + public Optional retrieve(UUID uuid) { + final Connection connection = getProvider().getConnection(); + if (connection == null) return Optional.empty(); + if (!isStored(uuid)) return Optional.empty(); + + try { + final String sql = "SELECT * FROM nicko.DATA WHERE uuid = ?"; + + final PreparedStatement statement = connection.prepareStatement(sql); + statement.setString(1, uuid.toString()); + + final ResultSet resultSet = statement.executeQuery(); + String name = ""; + String skin = ""; + String locale = ""; + boolean bungeecord = false; + while (resultSet.next()) { + name = resultSet.getString("name"); + skin = resultSet.getString("skin"); + locale = resultSet.getString("locale"); + bungeecord = resultSet.getBoolean("bungeecord"); + } + + final NickoProfile profile = new NickoProfile(name, skin, Locale.fromCode(locale), bungeecord); + return Optional.of(profile); + } catch (SQLException e) { + logger.warning("Couldn't fetch profile: " + e.getMessage()); + return Optional.empty(); + } + } + + @Override + public ActionResult delete(UUID uuid) { + final Connection connection = getProvider().getConnection(); + if (connection == null) return ActionResult.error(I18NDict.Error.SQL_ERROR); + + try { + final String sql = "DELETE FROM nicko.DATA WHERE uuid = ?"; + final PreparedStatement statement = connection.prepareStatement(sql); + statement.setString(1, uuid.toString()); + int rows = statement.executeUpdate(); + return (rows == 1 ? ActionResult.ok() : ActionResult.error(I18NDict.Error.SQL_ERROR)); + } catch (SQLException e) { + logger.warning("Couldn't delete profile: " + e.getMessage()); + return ActionResult.error(I18NDict.Error.SQL_ERROR); + } + } + + 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); + 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(4, profile.getLocale().getCode()); + statement.setBoolean(5, profile.isBungeecordTransfer()); + return statement; + } + + 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()); + statement.setString(3, profile.getLocale().getCode()); + statement.setBoolean(4, profile.isBungeecordTransfer()); + statement.setString(5, uuid.toString()); + return statement; + } +} diff --git a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java b/src/main/java/xyz/atnrch/nicko/storage/mariadb/MariaDBStorageProvider.java similarity index 90% rename from src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java rename to src/main/java/xyz/atnrch/nicko/storage/mariadb/MariaDBStorageProvider.java index 473fd77..0c44ec5 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorageProvider.java +++ b/src/main/java/xyz/atnrch/nicko/storage/mariadb/MariaDBStorageProvider.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.storage.sql; +package xyz.atnrch.nicko.storage.mariadb; import org.mariadb.jdbc.MariaDbDataSource; import xyz.atnrch.nicko.config.Configuration; @@ -10,15 +10,15 @@ import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.logging.Logger; -public class SQLStorageProvider implements StorageProvider { - private final Logger logger = Logger.getLogger("SQLStorageProvider"); +public class MariaDBStorageProvider implements StorageProvider { + private final Logger logger = Logger.getLogger("MariaDBStorageProvider"); private final Configuration configuration; private Connection connection; private final String schemaName = "nicko"; - public SQLStorageProvider(Configuration configuration) { + public MariaDBStorageProvider(Configuration configuration) { this.configuration = configuration; } @@ -40,7 +40,7 @@ public class SQLStorageProvider implements StorageProvider { createTable(); return true; } catch (SQLException e) { - logger.severe("Couldn't establish a connection to the MySQL database: " + e.getMessage()); + logger.severe("Couldn't establish a connection to the MariaDB database: " + e.getMessage()); return false; } } diff --git a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java b/src/main/java/xyz/atnrch/nicko/storage/mysql/MySQLStorage.java similarity index 94% rename from src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java rename to src/main/java/xyz/atnrch/nicko/storage/mysql/MySQLStorage.java index 2c3a159..fb58b04 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/mysql/MySQLStorage.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.storage.sql; +package xyz.atnrch.nicko.storage.mysql; import xyz.atnrch.nicko.appearance.ActionResult; import xyz.atnrch.nicko.config.Configuration; @@ -15,20 +15,20 @@ import java.util.Optional; import java.util.UUID; import java.util.logging.Logger; -public class SQLStorage extends Storage { +public class MySQLStorage extends Storage { private final Logger logger = Logger.getLogger("SQLStorage"); private final Configuration configuration; - private SQLStorageProvider provider; + private MySQLStorageProvider provider; - public SQLStorage(Configuration configuration) { + public MySQLStorage(Configuration configuration) { this.configuration = configuration; } @Override - public SQLStorageProvider getProvider() { + public MySQLStorageProvider getProvider() { if (provider == null) { - provider = new SQLStorageProvider(configuration); + provider = new MySQLStorageProvider(configuration); } return provider; } diff --git a/src/main/java/xyz/atnrch/nicko/storage/mysql/MySQLStorageProvider.java b/src/main/java/xyz/atnrch/nicko/storage/mysql/MySQLStorageProvider.java new file mode 100644 index 0000000..0df0978 --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/storage/mysql/MySQLStorageProvider.java @@ -0,0 +1,88 @@ +package xyz.atnrch.nicko.storage.mysql; + +import com.mysql.cj.jdbc.MysqlDataSource; +import xyz.atnrch.nicko.config.Configuration; +import xyz.atnrch.nicko.config.DataSourceConfiguration; +import xyz.atnrch.nicko.storage.StorageProvider; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.logging.Logger; + +public class MySQLStorageProvider implements StorageProvider { + private final Logger logger = Logger.getLogger("MySQLStorageProvider"); + private final Configuration configuration; + + private Connection connection; + + private final String schemaName = "nicko"; + + public MySQLStorageProvider(Configuration configuration) { + this.configuration = configuration; + } + + @Override + public boolean init() { + try { + final MysqlDataSource dataSource = new MysqlDataSource(); + final DataSourceConfiguration sqlConfiguration = configuration.getSqlConfiguration(); + dataSource.setUrl("jdbc:mysql://" + sqlConfiguration.getAddress() + ":" + sqlConfiguration.getPort()); + dataSource.setUser(sqlConfiguration.getUsername()); + dataSource.setPassword(sqlConfiguration.getPassword()); + connection = dataSource.getConnection(); + connection.setAutoCommit(true); + final boolean initialized = connection != null && !connection.isClosed(); + + if (!initialized) return false; + + createDatabase(); + createTable(); + return true; + } catch (SQLException e) { + logger.severe("Couldn't establish a connection to the MySQL database: " + e.getMessage()); + return false; + } + } + + @Override + public boolean close() { + if (connection == null) { return true; } + try { + connection.close(); + return connection.isClosed(); + } catch (SQLException e) { + return false; + } + } + + private void createTable() throws SQLException { + final Connection connection = getConnection(); + + String query = "CREATE TABLE IF NOT EXISTS %s.DATA " + + "(uuid varchar(36) NOT NULL," + + "name varchar(16)," + + "skin varchar(16)," + + "locale char(2) NOT NULL," + + "bungeecord boolean NOT NULL," + + "PRIMARY KEY (uuid))"; + query = query.replace("%s", schemaName); + + final PreparedStatement statement = connection.prepareStatement(query); + statement.executeUpdate(); + } + + private void createDatabase() throws SQLException { + final Connection connection = getConnection(); + + String query = "CREATE DATABASE IF NOT EXISTS %s"; + query = query.replace("%s", schemaName); + + final PreparedStatement statement = connection.prepareStatement(query); + statement.executeUpdate(); + } + + public Connection getConnection() { + return connection; + } +} diff --git a/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java b/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java index a046898..72b2a7f 100644 --- a/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java @@ -5,6 +5,7 @@ import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.DataSourceConfiguration; import org.junit.jupiter.api.*; +import xyz.atnrch.nicko.config.DefaultDataSources; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -15,7 +16,7 @@ public class NickoPluginTest { public static void setup() { final Configuration config = new Configuration( new DataSourceConfiguration(true, "127.0.0.1", 3306, "root", "12345"), - DataSourceConfiguration.REDIS_EMPTY, + DefaultDataSources.REDIS_EMPTY, "", false); MockBukkit.mock(); diff --git a/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java b/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java index a1b6e55..d68dc50 100644 --- a/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java @@ -8,7 +8,7 @@ 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.config.DefaultDataSources; import xyz.atnrch.nicko.i18n.I18N; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.i18n.ItemTranslation; @@ -22,8 +22,8 @@ public class ItemTranslationTest { @BeforeAll public static void setup() { final Configuration config = new Configuration( - DataSourceConfiguration.SQL_EMPTY, - DataSourceConfiguration.REDIS_EMPTY, + DefaultDataSources.SQL_EMPTY, + DefaultDataSources.REDIS_EMPTY, "", false); MockBukkit.mock(); diff --git a/src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java b/src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java index 6e16840..b8abd0b 100644 --- a/src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java @@ -9,6 +9,7 @@ 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.config.DefaultDataSources; import xyz.atnrch.nicko.i18n.I18N; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.i18n.Locale; @@ -21,8 +22,8 @@ public class TranslationTest { @BeforeAll public static void setup() { final Configuration config = new Configuration( - DataSourceConfiguration.SQL_EMPTY, - DataSourceConfiguration.REDIS_EMPTY, + DefaultDataSources.SQL_EMPTY, + DefaultDataSources.REDIS_EMPTY, "", false); MockBukkit.mock(); diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java index 120e5fc..133067c 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java @@ -7,6 +7,7 @@ import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.DataSourceConfiguration; import xyz.atnrch.nicko.appearance.ActionResult; +import xyz.atnrch.nicko.config.DefaultDataSources; import xyz.atnrch.nicko.profile.NickoProfile; import org.junit.jupiter.api.*; @@ -23,7 +24,7 @@ public class BrokenSQLTest { public static void setup() { final Configuration config = new Configuration( new DataSourceConfiguration(true, "127.0.0.1", 3306, "root", ""), - DataSourceConfiguration.REDIS_EMPTY, + DefaultDataSources.REDIS_EMPTY, "", false); final ServerMock server = MockBukkit.mock(); 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 c6020bc..abccf52 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java @@ -6,6 +6,7 @@ import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.appearance.ActionResult; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.DataSourceConfiguration; +import xyz.atnrch.nicko.config.DefaultDataSources; import xyz.atnrch.nicko.i18n.Locale; import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.PlayerDataStore; @@ -24,7 +25,7 @@ public class SQLStorageTest { public static void setup() { final Configuration config = new Configuration( new DataSourceConfiguration(true, "127.0.0.1", 3306, "root", "12345"), - DataSourceConfiguration.REDIS_EMPTY, + DefaultDataSources.REDIS_EMPTY, "", false); diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java index 9f67017..a46bd0a 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java @@ -6,6 +6,7 @@ import be.seeseemelk.mockbukkit.entity.PlayerMock; import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.DataSourceConfiguration; +import xyz.atnrch.nicko.config.DefaultDataSources; import xyz.atnrch.nicko.profile.NickoProfile; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -23,8 +24,8 @@ public class MapCacheTest { @BeforeAll public static void setup() { final Configuration config = new Configuration( - DataSourceConfiguration.SQL_EMPTY, - DataSourceConfiguration.REDIS_EMPTY, + DefaultDataSources.SQL_EMPTY, + DefaultDataSources.REDIS_EMPTY, "", false); final ServerMock server = MockBukkit.mock(); 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 e3bb4de..19006de 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 @@ -8,6 +8,7 @@ import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.appearance.ActionResult; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.DataSourceConfiguration; +import xyz.atnrch.nicko.config.DefaultDataSources; import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.PlayerDataStore; @@ -23,7 +24,7 @@ public class RedisCacheTest { @BeforeAll public static void setup() { final Configuration config = new Configuration( - DataSourceConfiguration.SQL_EMPTY, + DefaultDataSources.SQL_EMPTY, new DataSourceConfiguration(true, "127.0.0.1", 6379, "", ""), "", false); From 4977e59d24e4d43aefdde8dd8ff30694f04b760c Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 10 Oct 2023 13:15:06 +0200 Subject: [PATCH 116/296] fix(test): gson constructor missing --- pom.xml | 11 +++++++++++ .../nicko/config/SQLDataSourceConfiguration.java | 2 ++ .../java/xyz/atnrch/nicko/test/NickoPluginTest.java | 8 +++++--- .../xyz/atnrch/nicko/test/storage/BrokenSQLTest.java | 11 +++++++---- .../xyz/atnrch/nicko/test/storage/SQLStorageTest.java | 4 ++-- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index a258e34..8765da4 100644 --- a/pom.xml +++ b/pom.xml @@ -47,6 +47,12 @@ paper-api 1.20.1-R0.1-SNAPSHOT provided + + + com.google.code.gson + gson + + com.comphenix.protocol @@ -149,6 +155,7 @@ org.mariadb.jdbc:* redis.clients:* org.apache.commons:commons-pool2 + com.google.code.gson:gson @@ -184,6 +191,10 @@ org.apache.commons.pool2 net.artelnatif.libs.pool2 + + com.google.code.gson + net.artelnatif.libs.gson + false diff --git a/src/main/java/xyz/atnrch/nicko/config/SQLDataSourceConfiguration.java b/src/main/java/xyz/atnrch/nicko/config/SQLDataSourceConfiguration.java index 0bb9852..7e62a1f 100644 --- a/src/main/java/xyz/atnrch/nicko/config/SQLDataSourceConfiguration.java +++ b/src/main/java/xyz/atnrch/nicko/config/SQLDataSourceConfiguration.java @@ -3,6 +3,8 @@ package xyz.atnrch.nicko.config; public class SQLDataSourceConfiguration extends DataSourceConfiguration { private final boolean mariadb; + public SQLDataSourceConfiguration() { this(false, "", 0, "", "", true); } + public SQLDataSourceConfiguration(boolean enabled, String address, Integer port, String username, String password, boolean mariadb) { super(enabled, address, port, username, password); this.mariadb = mariadb; diff --git a/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java b/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java index 72b2a7f..a0562e1 100644 --- a/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java @@ -1,10 +1,12 @@ package xyz.atnrch.nicko.test; import be.seeseemelk.mockbukkit.MockBukkit; +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 org.junit.jupiter.api.*; import xyz.atnrch.nicko.config.DefaultDataSources; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -15,7 +17,7 @@ public class NickoPluginTest { @BeforeAll public static void setup() { final Configuration config = new Configuration( - new DataSourceConfiguration(true, "127.0.0.1", 3306, "root", "12345"), + DefaultDataSources.MARIADB_EMPTY, DefaultDataSources.REDIS_EMPTY, "", false); diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java index 133067c..13d2195 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java @@ -3,13 +3,16 @@ package xyz.atnrch.nicko.test.storage; 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; +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.appearance.ActionResult; +import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.DefaultDataSources; +import xyz.atnrch.nicko.config.SQLDataSourceConfiguration; import xyz.atnrch.nicko.profile.NickoProfile; -import org.junit.jupiter.api.*; import java.util.Optional; @@ -23,7 +26,7 @@ public class BrokenSQLTest { @BeforeAll public static void setup() { final Configuration config = new Configuration( - new DataSourceConfiguration(true, "127.0.0.1", 3306, "root", ""), + new SQLDataSourceConfiguration(true, "127.0.0.1", 3306, "root", "", true), DefaultDataSources.REDIS_EMPTY, "", false); 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 abccf52..9defabb 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java @@ -5,8 +5,8 @@ import org.junit.jupiter.api.*; import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.appearance.ActionResult; import xyz.atnrch.nicko.config.Configuration; -import xyz.atnrch.nicko.config.DataSourceConfiguration; import xyz.atnrch.nicko.config.DefaultDataSources; +import xyz.atnrch.nicko.config.SQLDataSourceConfiguration; import xyz.atnrch.nicko.i18n.Locale; import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.PlayerDataStore; @@ -24,7 +24,7 @@ public class SQLStorageTest { @BeforeAll public static void setup() { final Configuration config = new Configuration( - new DataSourceConfiguration(true, "127.0.0.1", 3306, "root", "12345"), + new SQLDataSourceConfiguration(true, "127.0.0.1", 3306, "root", "12345", true), DefaultDataSources.REDIS_EMPTY, "", false); From 074c07f628003b0afc7e38650f3b9335f71700fa Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 10 Oct 2023 14:27:50 +0200 Subject: [PATCH 117/296] chore: update deps to mc 1.20.2 --- pom.xml | 8 +- .../atnrch/nicko/command/NickoDebugCmd.java | 73 ------------------- 2 files changed, 4 insertions(+), 77 deletions(-) delete mode 100644 src/main/java/xyz/atnrch/nicko/command/NickoDebugCmd.java diff --git a/pom.xml b/pom.xml index 8765da4..e877050 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.comphenix.protocol ProtocolLib - 5.0.0-SNAPSHOT + 5.0.1-SNAPSHOT provided @@ -69,18 +69,18 @@ xyz.xenondevs.invui invui - 1.14 + 1.20 pom net.wesjd anvilgui - 1.7.0-SNAPSHOT + 1.9.0-SNAPSHOT com.github.seeseemelk MockBukkit-v1.20 - 3.9.0 + 3.31.0 test diff --git a/src/main/java/xyz/atnrch/nicko/command/NickoDebugCmd.java b/src/main/java/xyz/atnrch/nicko/command/NickoDebugCmd.java deleted file mode 100644 index 4f5b877..0000000 --- a/src/main/java/xyz/atnrch/nicko/command/NickoDebugCmd.java +++ /dev/null @@ -1,73 +0,0 @@ -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 xyz.atnrch.nicko.profile.NickoProfile; -import xyz.atnrch.nicko.storage.PlayerDataStore; - -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]; - skin = args[2]; - } else { - if (args.length < 3) { - sender.sendMessage(prefix + "§cMissing argument."); - return; - } - - playerName = args[1]; - name = args[2]; - skin = args[3]; - - target = Bukkit.getPlayer(playerName); - if (target == null) { - sender.sendMessage(prefix + "§cSpecified player is offline."); - return; - } - } - - if (MojangUtils.isUsernameInvalid(name)) { - sender.sendMessage(prefix + "§cSpecified username is invalid."); - return; - } - - if (MojangUtils.isUsernameInvalid(skin)) { - sender.sendMessage(prefix + "§cSpecified skin is invalid."); - return; - } - - 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())); - } - } - } -} From 36589747afcbd265cce26128183739f30d0f3882 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 10 Oct 2023 14:28:06 +0200 Subject: [PATCH 118/296] feat(command): remove debug command --- .../java/xyz/atnrch/nicko/NickoBukkit.java | 6 ++++-- .../atnrch/nicko/command/NickoCommand.java | 19 ------------------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index 13ab606..ec82768 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -2,7 +2,9 @@ package xyz.atnrch.nicko; import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.command.PluginCommand; import org.bukkit.plugin.java.JavaPlugin; +import xyz.atnrch.nicko.command.NickoCommand; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.ConfigurationManager; import xyz.atnrch.nicko.event.PlayerJoinListener; @@ -82,10 +84,10 @@ public class NickoBukkit extends JavaPlugin { } } - /*final PluginCommand command = getCommand("nicko"); + final PluginCommand command = getCommand("nicko"); if (command != null) { command.setExecutor(new NickoCommand()); - }*/ + } Structure.addGlobalIngredient('#', new SimpleItem(new ItemBuilder(Material.AIR))); Structure.addGlobalIngredient('%', new SimpleItem(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setDisplayName(" "))); diff --git a/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java b/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java index 13b1df8..9d07c9b 100644 --- a/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java +++ b/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java @@ -5,29 +5,15 @@ 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; public class NickoCommand implements CommandExecutor { - private String helpMessage = "§cNicko §8§o[{version}] §f- §2Help:\n" + - "§6/nicko §f- §7Open the GUI.\n" + - "§6/nicko help §f- §7Print this help message.\n"; - @Override 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) { - 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.*")) { new HomeGUI(player).open(); } else { @@ -40,9 +26,4 @@ public class NickoCommand implements CommandExecutor { sender.sendMessage("This plugin can only be used in-game. Sorry!"); return false; } - - public void sendHelpMessage(CommandSender sender) { - helpMessage = helpMessage.replace("{version}", NickoBukkit.getInstance().getPluginMeta().getVersion()); - sender.sendMessage(helpMessage); - } } From 2a326232ca9c9cbbe92e7358ce286d9d6b1a1214 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 24 Oct 2023 07:37:34 +0200 Subject: [PATCH 119/296] feat: preliminary 1.20.2 support --- pom.xml | 10 +-- .../nicko/appearance/AppearanceManager.java | 2 +- .../wrapper/WrapperPlayServerRespawn.java | 77 ++++++++++--------- ...java => WrapperPlayServerSpawnEntity.java} | 6 +- 4 files changed, 50 insertions(+), 45 deletions(-) rename src/main/java/xyz/atnrch/nicko/wrapper/{WrapperPlayServerNamedEntitySpawn.java => WrapperPlayServerSpawnEntity.java} (96%) diff --git a/pom.xml b/pom.xml index e877050..67072a0 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,10 @@ + + dmulloy2-repo + https://repo.dmulloy2.net/repository/public/ + xenondevs https://repo.xenondevs.xyz/releases @@ -32,10 +36,6 @@ placeholderapi https://repo.extendedclip.com/content/repositories/placeholderapi/ - - dmulloy2-repo - https://repo.dmulloy2.net/repository/public/ - @@ -57,7 +57,7 @@ com.comphenix.protocol ProtocolLib - 5.0.1-SNAPSHOT + 5.1.1-SNAPSHOT provided diff --git a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java index d655d0e..8977e14 100644 --- a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java @@ -70,7 +70,7 @@ public class AppearanceManager { public void updateOthers() { final WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy(); - final WrapperPlayServerNamedEntitySpawn spawn = new WrapperPlayServerNamedEntitySpawn(); + final WrapperPlayServerSpawnEntity spawn = new WrapperPlayServerSpawnEntity(); destroy.setEntityIds(IntList.of(player.getEntityId())); spawn.setEntityId(player.getEntityId()); spawn.setLocation(player.getLocation()); diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java index 2106bd0..8d395cc 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java @@ -18,28 +18,45 @@ import org.bukkit.World; * for the PacketPlayServerRespawn. * * @author ineanto, based on work from dmulloy2 and Kristian S. Strangeland + *

+ *

+ * Packet changes history (not accurate) + *

+ * In 1.20.2, all the fields were replaced with a + * single "CommonPlayerSpawnInfo" record object. + *

+ * The dimension field was changed numerous times: + * - 1.8 through 1.17 (?) required an integer, + * - 1.18 need an instance of a Holder of a ResourceKey, + * - 1.19 and after dropped this requirement. + * N.b.: this field is a nightmare please mojang stop refactoring + * your code to change things that were working perfectly fine before + *

+ * The Seed field was added in 1.15. + * The Difficulty field was removed in 1.14. */ public class WrapperPlayServerRespawn extends AbstractPacket { public static final PacketType TYPE = PacketType.Play.Server.RESPAWN; + private InternalStructure commonPlayerSpawnInfoStructure; + public WrapperPlayServerRespawn() { super(new PacketContainer(TYPE), TYPE); handle.getModifier().writeDefaults(); + if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { + commonPlayerSpawnInfoStructure = handle.getStructures().read(0); + } } - //............. - // Dimension/World Field - // The dimension field has changed numerous times: - // - 1.8 through 1.17 (?) need an integer, - // - 1.18 need a Holder of a World ResourceKey, - // - 1.19 and beyond don't require a Holder. - // - // n.b.: this field is a nightmare please mojang stop refactoring - // your code to change things that were working perfectly fine before - //............. - public void setDimension(World value) { - if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { + if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { + // 1.20.2 + final InternalStructure dimensionType = commonPlayerSpawnInfoStructure.getStructures().read(0); + dimensionType.getMinecraftKeys().write(0, new MinecraftKey("minecraft", "dimension_type")); + dimensionType.getMinecraftKeys().write(1, new MinecraftKey("minecraft", "overworld")); + commonPlayerSpawnInfoStructure.getStructures().write(0, dimensionType); + commonPlayerSpawnInfoStructure.getWorldKeys().write(0, value); + } else if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { // 1.19 to 1.20.1 // Thank you lukalt! final InternalStructure dimensionType = handle.getStructures().read(0); @@ -59,50 +76,38 @@ public class WrapperPlayServerRespawn extends AbstractPacket { } } - //............. - // GameMode Field - //............. - public void setGameMode(GameMode value) { + if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { + commonPlayerSpawnInfoStructure.getGameModes().write(0, EnumWrappers.NativeGameMode.fromBukkit(value)); + return; + } + handle.getGameModes().write(0, EnumWrappers.NativeGameMode.fromBukkit(value)); } - //............. - // Previous GameMode Field - //............. - public void setPreviousGameMode(GameMode value) { + if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { + commonPlayerSpawnInfoStructure.getGameModes().write(1, EnumWrappers.NativeGameMode.fromBukkit(value)); + return; + } handle.getGameModes().write(1, EnumWrappers.NativeGameMode.fromBukkit(value)); } - //............. - // Copy Metadata Field - //............. - public void setCopyMetadata(boolean value) { - if(MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) { + if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) return; + if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) { handle.getBytes().write(0, ((byte) (value ? 0x01 : 0x00))); } else { handle.getBooleans().write(0, value); } } - //............. - // Seed Field - // Added in 1.15. - //............. - public void setSeed(long value) { - if (MinecraftVersion.BEE_UPDATE.atOrAbove()) { + if (MinecraftVersion.BEE_UPDATE.atOrAbove() && !MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { handle.getLongs().write(0, Hashing.sha256().hashLong(value).asLong()); } } - //............. - // Difficulty Field - // Removed in 1.14. - //............. - public void setDifficulty(Difficulty difficulty) { if (difficulty != null && !MinecraftVersion.VILLAGE_UPDATE.atOrAbove()) { handle.getDifficulties().write(0, EnumWrappers.Difficulty.valueOf(difficulty.name())); diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerNamedEntitySpawn.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerSpawnEntity.java similarity index 96% rename from src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerNamedEntitySpawn.java rename to src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerSpawnEntity.java index fb82152..8a37c41 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerNamedEntitySpawn.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerSpawnEntity.java @@ -12,16 +12,16 @@ import java.util.UUID; /** * This packet is sent by the server when a player comes into visible range, not when a player joins. */ -public class WrapperPlayServerNamedEntitySpawn extends AbstractPacket { +public class WrapperPlayServerSpawnEntity extends AbstractPacket { /** * The packet type that is wrapped by this wrapper. */ - public static final PacketType TYPE = PacketType.Play.Server.NAMED_ENTITY_SPAWN; + public static final PacketType TYPE = PacketType.Play.Server.SPAWN_ENTITY; /** * Constructors a new wrapper for the specified packet */ - public WrapperPlayServerNamedEntitySpawn() { + public WrapperPlayServerSpawnEntity() { super(new PacketContainer(TYPE), TYPE); handle.getModifier().writeDefaults(); } From 2aa37a10a688aa5bd969bea3ebc81856ebf30710 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 23 Nov 2023 23:12:08 +0100 Subject: [PATCH 120/296] deps(chore): bump deps and update accordingly --- pom.xml | 8 ++-- .../nicko/appearance/AppearanceManager.java | 3 +- .../atnrch/nicko/gui/InvalidateSkinGUI.java | 2 +- .../gui/items/admin/ManageCacheItem.java | 23 +++++++--- .../gui/items/admin/cache/CacheEntryItem.java | 22 +++++++--- .../admin/check/PlayerInformationItem.java | 43 ++++++++++++------- .../gui/items/appearance/ChangeSkinItem.java | 25 ++++++++--- .../java/xyz/atnrch/nicko/i18n/I18NDict.java | 1 + .../atnrch/nicko/profile/AppearanceData.java | 31 ------------- src/main/resources/en.yml | 4 ++ 10 files changed, 93 insertions(+), 69 deletions(-) delete mode 100644 src/main/java/xyz/atnrch/nicko/profile/AppearanceData.java diff --git a/pom.xml b/pom.xml index 67072a0..468a730 100644 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,7 @@ io.papermc.paper paper-api - 1.20.1-R0.1-SNAPSHOT + 1.20.2-R0.1-SNAPSHOT provided @@ -63,13 +63,13 @@ me.clip placeholderapi - 2.11.2 + 2.11.4 provided xyz.xenondevs.invui invui - 1.20 + 1.23 pom @@ -80,7 +80,7 @@ com.github.seeseemelk MockBukkit-v1.20 - 3.31.0 + 3.47.0 test diff --git a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java index 8977e14..91172b3 100644 --- a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java @@ -84,9 +84,8 @@ public class AppearanceManager { private ActionResult updateGameProfileSkin(WrappedGameProfile gameProfile, boolean skinChange, boolean reset) { final NickoProfile profile = getNickoProfile(); - final boolean changeOnlyName = profile.getSkin() != null && profile.getSkin().equals(player.getName()); - if (skinChange || !changeOnlyName) { + if (skinChange) { Optional skin; try { final MojangAPI mojangAPI = NickoBukkit.getInstance().getMojangAPI(); diff --git a/src/main/java/xyz/atnrch/nicko/gui/InvalidateSkinGUI.java b/src/main/java/xyz/atnrch/nicko/gui/InvalidateSkinGUI.java index 768ffc5..f79842a 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/InvalidateSkinGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/InvalidateSkinGUI.java @@ -37,7 +37,7 @@ public class InvalidateSkinGUI { .collect(Collectors.toList()); final List items = loadedSkins.stream() - .map(CacheEntryItem::new) + .map(uuid -> new CacheEntryItem(i18n, uuid)) .collect(Collectors.toList()); final CacheManagementGUI parent = new CacheManagementGUI(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 a63a7f0..a2cbf4a 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 @@ -5,6 +5,7 @@ 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.NickoBukkit; import xyz.atnrch.nicko.gui.CacheManagementGUI; import xyz.atnrch.nicko.i18n.I18N; import xyz.atnrch.nicko.i18n.I18NDict; @@ -13,6 +14,9 @@ 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 xyz.xenondevs.invui.util.MojangApiUtils; + +import java.io.IOException; public class ManageCacheItem extends AsyncItem { public ManageCacheItem(I18N i18n) { @@ -24,11 +28,20 @@ public class ManageCacheItem extends AsyncItem { return builder; }, (click -> true)).getItemProvider(), () -> { - final SkullBuilder builder = new SkullBuilder("Notch"); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.MANAGE_CACHE); - builder.setDisplayName(translation.getName()); - translation.getLore().forEach(builder::addLoreLines); - return builder; + try { + final SkullBuilder builder = new SkullBuilder("Notch"); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.MANAGE_CACHE); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); + return builder; + } catch (MojangApiUtils.MojangApiException | IOException e) { + final ItemBuilder builder = new ItemBuilder(Material.TNT); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.ERROR); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); + NickoBukkit.getInstance().getLogger().warning("Unable to get Head texture for Notch! (GUI/ManageCache)"); + return builder; + } }); } 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 37f8bc3..000a218 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 @@ -11,11 +11,14 @@ 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.i18n.ItemTranslation; import xyz.atnrch.nicko.mojang.MojangAPI; 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.util.MojangApiUtils; +import java.io.IOException; import java.util.UUID; public class CacheEntryItem extends AsyncItem { @@ -23,14 +26,23 @@ public class CacheEntryItem extends AsyncItem { private final String uuid; private final MojangAPI mojangAPI = NickoBukkit.getInstance().getMojangAPI(); - public CacheEntryItem(String uuid) { + public CacheEntryItem(I18N i18n, String uuid) { super(new ItemBuilder(Material.PAINTING).setDisplayName("§7§oLoading..."), () -> { final String dashedUuid = uuid.replaceAll("(.{8})(.{4})(.{4})(.{4})(.+)", "$1-$2-$3-$4-$5"); final UUID uuidObject = UUID.fromString(dashedUuid); - final SkullBuilder skull = new SkullBuilder(uuidObject); - skull.setDisplayName("§6" + NickoBukkit.getInstance().getMojangAPI().getUUIDName(uuid)); - skull.addLoreLines("§7Click to invalidate skin"); - return skull; + try { + final SkullBuilder skull = new SkullBuilder(uuidObject); + skull.setDisplayName("§6" + NickoBukkit.getInstance().getMojangAPI().getUUIDName(uuid)); + skull.addLoreLines("§7Click to invalidate skin"); + return skull; + } catch (MojangApiUtils.MojangApiException | IOException e) { + final ItemBuilder builder = new ItemBuilder(Material.TNT); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.ERROR); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); + NickoBukkit.getInstance().getLogger().warning("Unable to get Head texture for Notch! (GUI/ManageCache)"); + return builder; + } }); this.uuid = uuid; this.name = mojangAPI.getUUIDName(uuid); 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 76578e4..5506edd 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 @@ -13,7 +13,9 @@ 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 xyz.xenondevs.invui.util.MojangApiUtils; +import java.io.IOException; import java.util.Optional; import java.util.UUID; @@ -27,26 +29,35 @@ public class PlayerInformationItem extends AsyncItem { 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); + try { + final SkullBuilder skull = new SkullBuilder(uuid); + final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore(); + final Optional optionalProfile = dataStore.getData(uuid); + 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( + "§cPlease file a bug report", + "§cat https://ineanto.xyz/git/ineanto/nicko!" + ); + } - 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( - "§cPlease file a bug report", - "§cat https://ineanto.xyz/git/ineanto/nicko!" - ); + return skull; + } catch (MojangApiUtils.MojangApiException | IOException e) { + NickoBukkit.getInstance().getLogger().severe("Unable to get head for specified UUID ( " + uuid + ")! (GUI/PlayerCheck)"); } - return skull; + final ItemBuilder builder = new ItemBuilder(Material.TNT); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.ERROR); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); + return builder; }); } } 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 2903cdf..51e414b 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 @@ -1,13 +1,19 @@ package xyz.atnrch.nicko.gui.items.appearance; +import org.bukkit.Material; +import xyz.atnrch.nicko.NickoBukkit; 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.ItemBuilder; import xyz.xenondevs.invui.item.builder.SkullBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; +import xyz.xenondevs.invui.util.MojangApiUtils; + +import java.io.IOException; public class ChangeSkinItem { private final I18N i18n; @@ -20,11 +26,20 @@ public class ChangeSkinItem { public SuppliedItem get() { return new SuppliedItem(() -> { - final SkullBuilder builder = new SkullBuilder(player.getName()); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Home.CHANGE_SKIN); - builder.setDisplayName(translation.getName()); - translation.getLore().forEach(builder::addLoreLines); - return builder; + try { + final SkullBuilder builder = new SkullBuilder(player.getName()); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Home.CHANGE_SKIN); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); + return builder; + } catch (MojangApiUtils.MojangApiException | IOException e) { + final ItemBuilder builder = new ItemBuilder(Material.TNT); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.ERROR); + builder.setDisplayName(translation.getName()); + translation.getLore().forEach(builder::addLoreLines); + NickoBukkit.getInstance().getLogger().warning("Unable to get Head texture for specified player (" + player.getName() + ")! (GUI/Home)"); + return builder; + } }, click -> { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index f60b0ad..cc2b2d9 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -70,6 +70,7 @@ public class I18NDict { 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 ERROR = GUI_KEY + "error"; public static final String SCROLL_UP = GUI_KEY + "scroll_up"; public static final String SCROLL_DOWN = GUI_KEY + "scroll_down"; diff --git a/src/main/java/xyz/atnrch/nicko/profile/AppearanceData.java b/src/main/java/xyz/atnrch/nicko/profile/AppearanceData.java deleted file mode 100644 index 362e576..0000000 --- a/src/main/java/xyz/atnrch/nicko/profile/AppearanceData.java +++ /dev/null @@ -1,31 +0,0 @@ -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/resources/en.yml b/src/main/resources/en.yml index e896a3b..a1536e7 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -44,6 +44,10 @@ gui: name: "Unavailable" lore: - "§7§oThis button is disabled." + error: + name: "Error!" + lore: + - "§7§oAn error occurred." loading: name: "§7§oLoading..." choice: From b1632c049e909e9fcf0aea0944ba56fa3ae29b76 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 23 Nov 2023 23:12:44 +0100 Subject: [PATCH 121/296] fix(i18n): scroll down --- .../java/xyz/atnrch/nicko/gui/items/common/ScrollDownItem.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 6a8515b..3c7935c 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 @@ -20,7 +20,7 @@ public class ScrollDownItem extends ScrollItem { @Override public ItemProvider getItemProvider(ScrollGui gui) { ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.SCROLL_UP); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.SCROLL_DOWN); builder.setDisplayName(translation.getName()); if (!gui.canScroll(1)) translation.getLore().forEach(builder::addLoreLines); return builder; From 95cb60a6b3f185caea786ed903e33e19c3459a0b Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 23 Nov 2023 23:21:15 +0100 Subject: [PATCH 122/296] fix(chat validation): it works! Chat Sessions are not invalidated anymore after disguised. --- .../atnrch/nicko/appearance/AppearanceManager.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java index 91172b3..f9bab11 100644 --- a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java @@ -158,22 +158,14 @@ public class AppearanceManager { remove.broadcastPacket(); } - // Yes, I skip providing chat session data. - // Yes, this will cause players to get kicked - // as soon as they send a message on versions above 1.19.2. - // 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(), true, EnumWrappers.NativeGameMode.fromBukkit(player.getGameMode()), gameProfile, - WrappedChatComponent.fromText(displayName) + WrappedChatComponent.fromText(displayName), + WrappedRemoteChatSessionData.fromPlayer(player) ))); add.broadcastPacket(); } From 2cf7f4c8d421f1d8dd90707c2c483e3ae479ba60 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 23 Nov 2023 23:38:18 +0100 Subject: [PATCH 123/296] fix(gui): check empty name/skin --- README.md | 14 +++++++++----- .../items/admin/check/PlayerInformationItem.java | 6 +++++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index cd38263..cc81fce 100644 --- a/README.md +++ b/README.md @@ -14,13 +14,17 @@ Coming soon! ⏳ Q: Players are getting kicked when they send a message on versions above 1.19.2! -A: Install [NoEncryption](https://www.spigotmc.org/resources/noencryption.102902/). +A: +This should not happen. +Try installing [NoEncryption](https://www.spigotmc.org/resources/noencryption.102902/). --- #### Version compatibility table -| Version | Plugin | -|----------|----------------------------------------------------------------------------| -| < 1.12.2 | Use [NickReloaded](https://www.spigotmc.org/resources/nickreloaded.46335/) | -| > 1.12.2 | Use Nicko | +| Version | Plugin | +|---------------|-----------------------------------------------------------------------------| +| 1.7 and lower | Unsupported | +| 1.8 - 1.12.2 | Use [NickReloaded](https://www.spigotmc.org/resources/nickreloaded.46335/) | +| 1.13 | Unsupported (The library I use for the GUIs doesn't support 1.13 and lower) | +| 1.14 and up | Use Nicko | 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 5506edd..5ef2f7d 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 @@ -36,7 +36,11 @@ public class PlayerInformationItem extends AsyncItem { 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()); + final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.CHECK, + player.getName(), + (profile.hasData() ? "§a✔" : "§c❌"), + (profile.getName() == null ? "§cN/A" : profile.getName()), + (profile.getSkin() == null ? "§cN/A" : profile.getSkin())); skull.setDisplayName("§6" + translation.getName()); translation.getLore().forEach(skull::addLoreLines); } else { From f74b6d2f81025898d11c8e5d954706aee5de0bdb Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 23 Nov 2023 23:43:01 +0100 Subject: [PATCH 124/296] feat(readme): update to new logo --- README.md | 2 +- img/LOGO.png | Bin 14880 -> 8524 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cc81fce..3b9f30c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# _Nicko_ +# *Nicko* ## The feature packed, next generation disguise plugin for Minecraft. diff --git a/img/LOGO.png b/img/LOGO.png index 47193761c9945697c35b9cac13dc80293b053214..747222945b1fa5dde3bebadb04535a33b0d1db01 100644 GIT binary patch literal 8524 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 From 00e820735d993b70977176e2a585dd0cc7b7527d Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 24 Nov 2023 22:10:52 +0100 Subject: [PATCH 125/296] refactor(i18n): optimize code --- .../java/xyz/atnrch/nicko/gui/AdminGUI.java | 8 ++--- .../java/xyz/atnrch/nicko/gui/ChoiceGUI.java | 8 ++--- .../xyz/atnrch/nicko/gui/SettingsGUI.java | 8 ++--- .../atnrch/nicko/gui/items/ItemDefaults.java | 22 +++++++++++++ .../gui/items/admin/ManageCacheItem.java | 18 +++-------- .../gui/items/admin/ManagePlayerItem.java | 6 +--- .../gui/items/admin/cache/CacheEntryItem.java | 14 +++----- .../admin/cache/CacheStatisticsItem.java | 9 ++---- .../admin/cache/InvalidateCacheItem.java | 12 +++---- .../items/admin/cache/InvalidateSkinItem.java | 6 +--- .../admin/check/PlayerInformationItem.java | 32 +++++-------------- .../gui/items/appearance/ChangeBothItem.java | 10 ++---- .../gui/items/appearance/ChangeNameItem.java | 10 ++---- .../gui/items/appearance/ChangeSkinItem.java | 19 +++-------- .../nicko/gui/items/common/GoBackItem.java | 5 +-- .../gui/items/common/ScrollDownItem.java | 4 +-- .../nicko/gui/items/common/ScrollUpItem.java | 2 +- .../gui/items/common/UnavailableItem.java | 27 ---------------- .../gui/items/common/choice/CancelItem.java | 5 +-- .../gui/items/common/choice/ConfirmItem.java | 5 +-- .../nicko/gui/items/home/AdminAccessItem.java | 6 +--- .../atnrch/nicko/gui/items/home/ExitItem.java | 4 +-- .../nicko/gui/items/home/ResetItem.java | 6 +--- .../gui/items/home/SettingsAccessItem.java | 10 ++---- .../items/settings/BungeeCordCyclingItem.java | 4 +-- .../items/settings/LanguageCyclingItem.java | 2 +- src/main/java/xyz/atnrch/nicko/i18n/I18N.java | 10 +++++- .../java/xyz/atnrch/nicko/i18n/I18NDict.java | 2 ++ src/main/resources/en.yml | 10 ++++-- src/main/resources/fr.yml | 7 +++- .../nicko/test/i18n/ItemTranslationTest.java | 4 +-- 31 files changed, 111 insertions(+), 184 deletions(-) create mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/ItemDefaults.java delete mode 100644 src/main/java/xyz/atnrch/nicko/gui/items/common/UnavailableItem.java diff --git a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java index 107e03b..4d605ee 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java @@ -1,13 +1,14 @@ package xyz.atnrch.nicko.gui; +import org.bukkit.entity.Player; +import xyz.atnrch.nicko.gui.items.ItemDefaults; 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.item.impl.SimpleItem; import xyz.xenondevs.invui.window.Window; public class AdminGUI { @@ -21,7 +22,6 @@ public class AdminGUI { 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() @@ -32,7 +32,7 @@ public class AdminGUI { ) .addIngredient('S', new ManageCacheItem(i18n)) .addIngredient('C', managePlayerItem.get()) - .addIngredient('U', unavailableItem.get()) + .addIngredient('U', new SimpleItem(ItemDefaults.getUnavailableItem(i18n))) .addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle())) .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 index 5b7b7e6..90e31dd 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/ChoiceGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/ChoiceGUI.java @@ -7,7 +7,6 @@ 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; @@ -16,13 +15,14 @@ import xyz.xenondevs.invui.window.Window; public class ChoiceGUI { private final Player player; private final Gui gui; + private final String title; 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.title = i18n.translatePrefixless(I18NDict.GUI.Titles.CONFIRM); this.gui = Gui.normal() .setStructure( "@ @ @ @ % & & & &", @@ -31,12 +31,12 @@ public class ChoiceGUI { ) .addIngredient('@', confirmItem.get()) .addIngredient('&', cancelItem.get()) - .addIngredient('I', new SimpleItem(new ItemBuilder(Material.PAPER).setDisplayName(chooseItemTranslation.getName()).get())) + .addIngredient('I', new SimpleItem(i18n.translateItem(new ItemBuilder(Material.PAPER), I18NDict.GUI.Choice.CHOOSE))) .build(); this.player = player; } public void open() { - Window.single().setGui(gui).setTitle("... > Invalidate > Confirm").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 a19be9e..e44bbea 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java +++ b/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java @@ -1,13 +1,14 @@ package xyz.atnrch.nicko.gui; +import org.bukkit.entity.Player; +import xyz.atnrch.nicko.gui.items.ItemDefaults; 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.item.impl.SimpleItem; import xyz.xenondevs.invui.window.Window; public class SettingsGUI { @@ -29,7 +30,6 @@ public class SettingsGUI { 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); @@ -38,7 +38,7 @@ public class SettingsGUI { .setStructure(dynamicStructure) .addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle())) .addIngredient('L', languageItem.get()) - .addIngredient('U', unavailableItem.get()) + .addIngredient('U', new SimpleItem(ItemDefaults.getUnavailableItem(i18n))) .addIngredient('T', bungeeCordItem.get()) .build(); this.player = player; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/ItemDefaults.java b/src/main/java/xyz/atnrch/nicko/gui/items/ItemDefaults.java new file mode 100644 index 0000000..0f0864e --- /dev/null +++ b/src/main/java/xyz/atnrch/nicko/gui/items/ItemDefaults.java @@ -0,0 +1,22 @@ +package xyz.atnrch.nicko.gui.items; + +import org.bukkit.Material; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.xenondevs.invui.item.builder.AbstractItemBuilder; +import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.builder.SkullBuilder; + +public class ItemDefaults { + public static AbstractItemBuilder getErrorSkullItem(I18N i18n, String key, Object... args) { + // "Missing Value" (Valve's signature missing texture) Texture Value + final SkullBuilder.HeadTexture headTexture = new SkullBuilder.HeadTexture("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNjNmZTU5YjJhMWQyYmYzMjcwNDA2OGVmYzg2MGM3NWY5MjEyYzIzMTBiNDNkMDdjNGJiYTRiNGViMjM0ZTY4NCJ9fX0="); + final SkullBuilder builder = new SkullBuilder(headTexture); + return i18n.translateItem(builder, key, args); + } + + public static AbstractItemBuilder getUnavailableItem(I18N i18n) { + final ItemBuilder builder = new ItemBuilder(Material.RED_TERRACOTTA); + return i18n.translateItem(builder, I18NDict.GUI.UNAVAILABLE); + } +} 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 a2cbf4a..a233745 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 @@ -7,9 +7,9 @@ import org.bukkit.event.inventory.InventoryClickEvent; import org.jetbrains.annotations.NotNull; import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.gui.CacheManagementGUI; +import xyz.atnrch.nicko.gui.items.ItemDefaults; 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; @@ -22,25 +22,15 @@ public class ManageCacheItem extends AsyncItem { 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; + return i18n.translateItem(builder, I18NDict.GUI.LOADING); }, (click -> true)).getItemProvider(), () -> { try { final SkullBuilder builder = new SkullBuilder("Notch"); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.MANAGE_CACHE); - builder.setDisplayName(translation.getName()); - translation.getLore().forEach(builder::addLoreLines); - return builder; + return i18n.translateItem(builder, I18NDict.GUI.Admin.MANAGE_CACHE); } catch (MojangApiUtils.MojangApiException | IOException e) { - final ItemBuilder builder = new ItemBuilder(Material.TNT); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.ERROR); - builder.setDisplayName(translation.getName()); - translation.getLore().forEach(builder::addLoreLines); NickoBukkit.getInstance().getLogger().warning("Unable to get Head texture for Notch! (GUI/ManageCache)"); - return builder; + return ItemDefaults.getErrorSkullItem(i18n, I18NDict.GUI.Admin.MANAGE_CACHE); } }); } 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 0736036..947577f 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 @@ -5,7 +5,6 @@ import org.bukkit.entity.Player; 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; @@ -21,10 +20,7 @@ public class ManagePlayerItem { 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; + return i18n.translateItem(builder, I18NDict.GUI.Admin.MANAGE_PLAYER); }, 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 000a218..2d6d194 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 @@ -8,10 +8,10 @@ import org.jetbrains.annotations.NotNull; import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.gui.ChoiceGUI; import xyz.atnrch.nicko.gui.InvalidateSkinGUI; +import xyz.atnrch.nicko.gui.items.ItemDefaults; 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.i18n.ItemTranslation; import xyz.atnrch.nicko.mojang.MojangAPI; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.builder.SkullBuilder; @@ -32,16 +32,10 @@ public class CacheEntryItem extends AsyncItem { final UUID uuidObject = UUID.fromString(dashedUuid); try { final SkullBuilder skull = new SkullBuilder(uuidObject); - skull.setDisplayName("§6" + NickoBukkit.getInstance().getMojangAPI().getUUIDName(uuid)); - skull.addLoreLines("§7Click to invalidate skin"); - return skull; + return i18n.translateItem(skull, I18NDict.GUI.Admin.Cache.ENTRY, NickoBukkit.getInstance().getMojangAPI().getUUIDName(uuid)); } catch (MojangApiUtils.MojangApiException | IOException e) { - final ItemBuilder builder = new ItemBuilder(Material.TNT); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.ERROR); - builder.setDisplayName(translation.getName()); - translation.getLore().forEach(builder::addLoreLines); - NickoBukkit.getInstance().getLogger().warning("Unable to get Head texture for Notch! (GUI/ManageCache)"); - return builder; + NickoBukkit.getInstance().getLogger().warning("Unable to get Head texture for specified UUID (" + uuid + ")! (GUI/Cache/Entry)"); + return ItemDefaults.getErrorSkullItem(i18n, I18NDict.GUI.Admin.Cache.ENTRY, NickoBukkit.getInstance().getMojangAPI().getUUIDName(uuid)); } }); this.uuid = uuid; 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 027100e..8df1db6 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,13 +2,12 @@ package xyz.atnrch.nicko.gui.items.admin.cache; import com.google.common.cache.CacheStats; import com.google.common.cache.LoadingCache; +import org.bukkit.Material; 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; import xyz.xenondevs.invui.item.impl.SuppliedItem; @@ -27,14 +26,10 @@ public class CacheStatisticsItem { final LoadingCache> cache = NickoBukkit.getInstance().getMojangAPI().getSkinCache(); final CacheStats stats = cache.stats(); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.Cache.STATISTICS, + return i18n.translateItem(builder, 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); } } \ No newline at end of file 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 3d0aca5..40c7b89 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 @@ -1,12 +1,11 @@ package xyz.atnrch.nicko.gui.items.admin.cache; -import xyz.atnrch.nicko.NickoBukkit; -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.ItemTranslation; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.i18n.I18N; +import xyz.atnrch.nicko.i18n.I18NDict; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; @@ -20,10 +19,7 @@ public class InvalidateCacheItem { public SuppliedItem get() { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.TNT); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.Cache.INVALIDATE_CACHE); - builder.setDisplayName(translation.getName()); - translation.getLore().forEach(builder::addLoreLines); - return builder; + return i18n.translateItem(builder, I18NDict.GUI.Admin.Cache.INVALIDATE_CACHE); }, (click) -> { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { 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 index d7ed378..8f2d7d7 100644 --- 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 @@ -6,7 +6,6 @@ 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; @@ -20,10 +19,7 @@ public class InvalidateSkinItem { 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; + return i18n.translateItem(builder, I18NDict.GUI.Admin.Cache.INVALIDATE_SKIN); }, (click) -> { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { 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 5ef2f7d..0f2b6a6 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,9 +4,9 @@ import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.gui.items.ItemDefaults; 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; @@ -23,10 +23,7 @@ public class PlayerInformationItem extends AsyncItem { 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; + return i18n.translateItem(builder, I18NDict.GUI.LOADING); }, (click -> true)).getItemProvider(), () -> { final Player player = Bukkit.getPlayer(uuid); try { @@ -36,32 +33,19 @@ public class PlayerInformationItem extends AsyncItem { if (optionalProfile.isPresent()) { final NickoProfile profile = optionalProfile.get(); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.CHECK, + return i18n.translateItem(skull, I18NDict.GUI.Admin.CHECK, player.getName(), (profile.hasData() ? "§a✔" : "§c❌"), - (profile.getName() == null ? "§cN/A" : profile.getName()), - (profile.getSkin() == null ? "§cN/A" : 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( - "§cPlease file a bug report", - "§cat https://ineanto.xyz/git/ineanto/nicko!" - ); + (profile.getName() == null ? "§7N/A" : profile.getName()), + (profile.getSkin() == null ? "§7N/A" : profile.getSkin())); } - - return skull; } catch (MojangApiUtils.MojangApiException | IOException e) { NickoBukkit.getInstance().getLogger().severe("Unable to get head for specified UUID ( " + uuid + ")! (GUI/PlayerCheck)"); } - final ItemBuilder builder = new ItemBuilder(Material.TNT); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.ERROR); - builder.setDisplayName(translation.getName()); - translation.getLore().forEach(builder::addLoreLines); - return builder; + return ItemDefaults.getErrorSkullItem(i18n, I18NDict.GUI.Admin.CHECK, + "§4???", "§cN/A", "§cN/A", "§cN/A" + ); }); } } 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 91259b3..3863585 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,12 +1,11 @@ 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.entity.Player; import org.bukkit.event.inventory.ClickType; +import xyz.atnrch.nicko.anvil.AnvilManager; 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; @@ -20,10 +19,7 @@ public class ChangeBothItem { public SuppliedItem get() { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.TOTEM_OF_UNDYING); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Home.CHANGE_BOTH); - builder.setDisplayName(translation.getName()); - translation.getLore().forEach(builder::addLoreLines); - return builder; + return i18n.translateItem(builder, I18NDict.GUI.Home.CHANGE_BOTH); }, click -> { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { 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 243f91c..c553ec6 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,12 +1,11 @@ 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.entity.Player; import org.bukkit.event.inventory.ClickType; +import xyz.atnrch.nicko.anvil.AnvilManager; 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; @@ -20,10 +19,7 @@ public class ChangeNameItem { public SuppliedItem get() { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.NAME_TAG); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Home.CHANGE_NAME); - builder.setDisplayName(translation.getName()); - translation.getLore().forEach(builder::addLoreLines); - return builder; + return i18n.translateItem(builder, I18NDict.GUI.Home.CHANGE_NAME); }, click -> { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { 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 51e414b..91c9404 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 @@ -1,14 +1,12 @@ package xyz.atnrch.nicko.gui.items.appearance; -import org.bukkit.Material; -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.anvil.AnvilManager; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; +import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.anvil.AnvilManager; +import xyz.atnrch.nicko.gui.items.ItemDefaults; 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.SuppliedItem; import xyz.xenondevs.invui.util.MojangApiUtils; @@ -28,17 +26,10 @@ public class ChangeSkinItem { return new SuppliedItem(() -> { try { final SkullBuilder builder = new SkullBuilder(player.getName()); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Home.CHANGE_SKIN); - builder.setDisplayName(translation.getName()); - translation.getLore().forEach(builder::addLoreLines); - return builder; + return i18n.translateItem(builder, I18NDict.GUI.Home.CHANGE_SKIN); } catch (MojangApiUtils.MojangApiException | IOException e) { - final ItemBuilder builder = new ItemBuilder(Material.TNT); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.ERROR); - builder.setDisplayName(translation.getName()); - translation.getLore().forEach(builder::addLoreLines); NickoBukkit.getInstance().getLogger().warning("Unable to get Head texture for specified player (" + player.getName() + ")! (GUI/Home)"); - return builder; + return ItemDefaults.getErrorSkullItem(i18n, I18NDict.GUI.Home.CHANGE_SKIN); } }, 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 db9ea70..16df2d5 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 @@ -4,7 +4,6 @@ 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; @@ -20,9 +19,7 @@ public class GoBackItem { public SuppliedItem get(Gui gui, String parentTitle) { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.ARROW); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.GO_BACK); - builder.setDisplayName(translation.getName()); - return builder; + return i18n.translateItem(builder, I18NDict.GUI.GO_BACK); }, click -> { click.getEvent().getView().close(); Window.single().setGui(gui).setTitle(parentTitle).open(click.getPlayer()); 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 3c7935c..9e6f636 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 @@ -19,8 +19,8 @@ public class ScrollDownItem extends ScrollItem { @Override public ItemProvider getItemProvider(ScrollGui gui) { - ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.SCROLL_DOWN); + final ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); + final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.SCROLL_DOWN); 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 6b2a714..06e457d 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 @@ -20,7 +20,7 @@ public class ScrollUpItem extends ScrollItem { @Override public ItemProvider getItemProvider(ScrollGui gui) { final ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.SCROLL_UP); + final ItemTranslation translation = i18n.fetchTranslation(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 deleted file mode 100644 index 8532511..0000000 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/UnavailableItem.java +++ /dev/null @@ -1,27 +0,0 @@ -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 { - 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); - 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 index 3be6245..ee9965a 100644 --- 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 @@ -4,7 +4,6 @@ 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; @@ -20,9 +19,7 @@ public class CancelItem { 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; + return i18n.translateItem(builder, I18NDict.GUI.Choice.CANCEL); }, click -> { click.getEvent().getView().close(); callback.onCancel(); 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 index fe5dc97..3116706 100644 --- 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 @@ -4,7 +4,6 @@ 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; @@ -20,9 +19,7 @@ public class ConfirmItem { 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; + return i18n.translateItem(builder, I18NDict.GUI.Choice.CONFIRM); }, click -> { click.getEvent().getView().close(); callback.onConfirm(); 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 9afff1d..590075a 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 @@ -6,7 +6,6 @@ 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; @@ -20,10 +19,7 @@ public class AdminAccessItem { public SuppliedItem get() { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.COMMAND_BLOCK_MINECART); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Home.ADMIN); - builder.setDisplayName(translation.getName()); - translation.getLore().forEach(builder::addLoreLines); - return builder; + return i18n.translateItem(builder, I18NDict.GUI.Home.ADMIN); }, click -> { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { 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 0bcb23e..8e11b3d 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 @@ -19,9 +19,7 @@ public class ExitItem { 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; + return i18n.translateItem(builder, I18NDict.GUI.EXIT); }, click -> { click.getEvent().getView().close(); final ClickType clickType = click.getClickType(); 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 ff9df25..a717914 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 @@ -6,7 +6,6 @@ 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; @@ -23,10 +22,7 @@ public class ResetItem { public SuppliedItem get() { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.TNT); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Home.RESET); - builder.setDisplayName(translation.getName()); - translation.getLore().forEach(builder::addLoreLines); - return builder; + return i18n.translateItem(builder, I18NDict.GUI.Home.RESET); }, (event) -> { final Player player = event.getPlayer(); final ClickType clickType = event.getClickType(); 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 d566161..aa4630e 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,12 +1,11 @@ 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.entity.Player; import org.bukkit.event.inventory.ClickType; +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.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; @@ -20,10 +19,7 @@ public class SettingsAccessItem { public SuppliedItem get() { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.COMPARATOR); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Home.SETTINGS); - builder.setDisplayName(translation.getName()); - translation.getLore().forEach(builder::addLoreLines); - return builder; + return i18n.translateItem(builder, I18NDict.GUI.Home.SETTINGS); }, click -> { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { 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 24a0e3b..c644d3b 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 @@ -47,9 +47,9 @@ public class BungeeCordCyclingItem { return new SimpleItem(ItemProvider.EMPTY); } - private ItemProvider getItemProviderForValue(boolean enabled) { + private ItemProvider getItemProviderForValue(boolean ignored) { final ItemBuilder builder = new ItemBuilder(Material.COMPASS); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Settings.BUNGEECORD); + final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.Settings.BUNGEECORD); builder.setDisplayName(translation.getName()); translation.getLore().forEach(builder::addLoreLines); 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 67f64d2..8024244 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 @@ -57,7 +57,7 @@ public class LanguageCyclingItem { private ItemProvider generateItem(Locale locale, List locales) { final ItemBuilder builder = new ItemBuilder(Material.OAK_SIGN); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Settings.LANGUAGE); + final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.Settings.LANGUAGE); builder.setDisplayName(translation.getName()); for (Locale value : locales) { diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java index 0087468..ed4bd53 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18N.java @@ -4,6 +4,7 @@ import com.github.jsixface.YamlConfig; import org.bukkit.entity.Player; import xyz.atnrch.nicko.NickoBukkit; import xyz.atnrch.nicko.profile.NickoProfile; +import xyz.xenondevs.invui.item.builder.AbstractItemBuilder; import java.io.InputStream; import java.text.MessageFormat; @@ -35,7 +36,14 @@ public class I18N { this.yamlConfig = getYamlConfig(); } - public ItemTranslation translateItem(String key, Object... args) { + public AbstractItemBuilder translateItem(AbstractItemBuilder item, String key, Object... args) { + final ItemTranslation translation = fetchTranslation(key, args); + item.setDisplayName(translation.getName()); + translation.getLore().forEach(item::addLoreLines); + return item; + } + + public ItemTranslation fetchTranslation(String key, Object... args) { final String nameKey = key + ".name"; final String loreKey = key + ".lore"; final String name = readString(nameKey); diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java index cc2b2d9..54b2d8c 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java @@ -81,6 +81,7 @@ public class I18NDict { 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 CONFIRM = TITLE_KEY + "confirm"; public static final String CACHE = TITLE_KEY + "cache"; public static final String INVALIDATE_SKIN = TITLE_KEY + "invalidate_skin"; } @@ -124,6 +125,7 @@ public class I18NDict { 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"; + public static final String ENTRY = CACHE_KEY + "entry"; } } } diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index a1536e7..1951936 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -33,6 +33,7 @@ gui: settings: "Nicko > Settings" admin: "Nicko > Administration" check: "Nicko > Admin... > Check" + confirm: "... > Invalidate > Confirm" cache: "Nicko > Admin... > Cache" invalidate_skin: "... > Cache > Invalidate" @@ -47,7 +48,8 @@ gui: error: name: "Error!" lore: - - "§7§oAn error occurred." + - "§7" + - "§7The item texture failed to load, but it might still work." loading: name: "§7§oLoading..." choice: @@ -94,7 +96,7 @@ gui: lore: - "§7See players' disguise information." check: - name: "{0}" + name: "§6{0}" lore: - "§cNicked: §a{1}" - "§cName: §6{2}" @@ -117,6 +119,10 @@ gui: lore: - "§7Select a specific skin to invalidate." - "§7Useful if a skin has been recently updated." + entry: + name: "§6{0}" + lore: + - "§7Click to invalidate..." settings: language: name: "Language" diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index a5a070c..f154e54 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -33,6 +33,7 @@ gui: settings: "Nicko > Paramètres" admin: "Nicko > Administration" check: "Nicko > Admin... > Vérification" + confirm: "... > Invalider > Confirmer" cache: "Nicko > Admin... > Cache" invalidate_skin: "... > Cache > Invalider" @@ -90,7 +91,7 @@ gui: lore: - "§7Vérifiez les informations de déguisement d'un joueur." check: - name: "{0}" + name: "§6{0}" lore: - "§cDéguisé: §a{1}" - "§cNom: §6{2}" @@ -115,6 +116,10 @@ gui: - "§7Sélectionnez une apparence spécifique à" - "§7invalider. Utile dans le cas où un skin" - "§7a récemment été mis à jour." + entry: + name: "§6{0}" + lore: + - "§7Cliquez pour invalider..." settings: language: name: "Langage" diff --git a/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java b/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java index d68dc50..fc3a1b8 100644 --- a/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java @@ -34,7 +34,7 @@ public class ItemTranslationTest { @DisplayName("Translate Item Without Lore") public void translateItemTranslationWithoutLore() { final I18N i18n = new I18N(Locale.FRENCH); - final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.GO_BACK); + final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.GO_BACK); assertTrue(translation.getLore().isEmpty()); assertEquals(translation.getName(), "Retour"); } @@ -43,7 +43,7 @@ public class ItemTranslationTest { @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"); + final ItemTranslation translation = i18n.fetchTranslation(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)); From 3ee51ef6a7584719debb28b8b30f3bb5b5d4f2a0 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 24 Nov 2023 22:48:08 +0100 Subject: [PATCH 126/296] style(wrapper): update note --- .../java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java index 8d395cc..e6efa8e 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java @@ -57,7 +57,7 @@ public class WrapperPlayServerRespawn extends AbstractPacket { commonPlayerSpawnInfoStructure.getStructures().write(0, dimensionType); commonPlayerSpawnInfoStructure.getWorldKeys().write(0, value); } else if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { - // 1.19 to 1.20.1 + // 1.19 to 1.20.2 // Thank you lukalt! final InternalStructure dimensionType = handle.getStructures().read(0); dimensionType.getMinecraftKeys().write(0, new MinecraftKey("minecraft", "dimension_type")); From 46ce1036eaf9dd72a7844cb1035a0031415a5761 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 24 Nov 2023 23:09:49 +0100 Subject: [PATCH 127/296] feat(docs): known bugs --- README.md | 9 +++++++++ src/main/java/xyz/atnrch/nicko/NickoBukkit.java | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/README.md b/README.md index 3b9f30c..ad3c862 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,15 @@ Coming soon! ⏳ --- +## Known bugs: + +- Players who have operator (OP) status lose access to the Operator Items tab in creative mode + after disguising **(1.20 and up)**. +- When disguising and only changing their display name, players will have the new default + skins **(1.20 and up)**. + +--- + ## Q/A Q: Players are getting kicked when they send a message on versions above 1.19.2! diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index ec82768..59a3715 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -1,5 +1,6 @@ package xyz.atnrch.nicko; +import com.comphenix.protocol.utility.MinecraftVersion; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.command.PluginCommand; @@ -49,6 +50,11 @@ public class NickoBukkit extends JavaPlugin { @Override public void onEnable() { plugin = this; + + if (!MinecraftVersion.VILLAGE_UPDATE.atOrAbove()) { + getLogger().severe("This version (" + MinecraftVersion.getCurrentVersion().getVersion() + ") is not supported by Nicko!"); + } + configurationManager = new ConfigurationManager(getDataFolder()); configurationManager.saveDefaultConfig(); From b673a6409f0004bf4f81cdc26123f795e9e34cc0 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 24 Nov 2023 23:10:45 +0100 Subject: [PATCH 128/296] refactor(readme): unnecessary explanation --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ad3c862..1047a18 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,9 @@ Try installing [NoEncryption](https://www.spigotmc.org/resources/noencryption.10 #### Version compatibility table -| Version | Plugin | -|---------------|-----------------------------------------------------------------------------| -| 1.7 and lower | Unsupported | -| 1.8 - 1.12.2 | Use [NickReloaded](https://www.spigotmc.org/resources/nickreloaded.46335/) | -| 1.13 | Unsupported (The library I use for the GUIs doesn't support 1.13 and lower) | -| 1.14 and up | Use Nicko | +| Version | Plugin | +|---------------|----------------------------------------------------------------------------| +| 1.7 and lower | Unsupported | +| 1.8 - 1.12.2 | Use [NickReloaded](https://www.spigotmc.org/resources/nickreloaded.46335/) | +| 1.13 | Unsupported | +| 1.14 and up | Use Nicko | From 25e3893771617159ba45b51f39798b9e25f6085c Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 24 Nov 2023 23:22:14 +0100 Subject: [PATCH 129/296] refactor(note): i'm dumb --- .../java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java index e6efa8e..8d395cc 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java @@ -57,7 +57,7 @@ public class WrapperPlayServerRespawn extends AbstractPacket { commonPlayerSpawnInfoStructure.getStructures().write(0, dimensionType); commonPlayerSpawnInfoStructure.getWorldKeys().write(0, value); } else if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { - // 1.19 to 1.20.2 + // 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")); From 9bcbb510a0779cf61ec0cc50703a5b14ef05d162 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 24 Nov 2023 23:42:06 +0100 Subject: [PATCH 130/296] refactor: remove todo --- src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java | 1 - src/main/resources/plugin.yml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java index 498030d..cfd9523 100644 --- a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java @@ -25,7 +25,6 @@ public class PlayerJoinListener implements Listener { 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 Optional optionalProfile = dataStore.getData(player.getUniqueId()); diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index d43e165..1819aa0 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -2,7 +2,7 @@ name: Nicko main: xyz.atnrch.nicko.NickoBukkit version: 1.0-SNAPSHOT author: Ineanto -description: "In-game appearance manager." +description: "The feature packed, next generation disguise plugin for Minecraft." api-version: 1.13 softdepend: [ PlaceholderAPI ] depend: From d673d34a51f30e4693ceefec641f3dd7fc4b727a Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 24 Nov 2023 23:42:51 +0100 Subject: [PATCH 131/296] style(comment): date format --- src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 d6ad5e4..96bc57a 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java @@ -50,8 +50,8 @@ 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 + // 08/29/23: what the fuck was I talking about? + // TODO (Ineanto, 05/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); return Optional.of(profile); From d75aad65968d9cefee538168cc2e0ab2724f8f00 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 3 Dec 2023 22:46:59 +0100 Subject: [PATCH 132/296] feat(disguise): update others when joining --- .../xyz/atnrch/nicko/appearance/AppearanceManager.java | 7 +++++-- .../java/xyz/atnrch/nicko/event/PlayerJoinListener.java | 8 +++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java index f9bab11..185beae 100644 --- a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java @@ -58,7 +58,7 @@ public class AppearanceManager { updateMetadata(); updateTabList(gameProfile, displayName); respawnPlayer(); - updateOthers(); + updateForOthers(); } return result; } @@ -68,7 +68,10 @@ public class AppearanceManager { return optionalProfile.orElse(NickoProfile.EMPTY_PROFILE.clone()); } - public void updateOthers() { + public void updateForOthers() { + final NickoProfile nickoProfile = getNickoProfile(); + if (!nickoProfile.hasData()) return; + final WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy(); final WrapperPlayServerSpawnEntity spawn = new WrapperPlayServerSpawnEntity(); destroy.setEntityIds(IntList.of(player.getEntityId())); diff --git a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java index cfd9523..4038733 100644 --- a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java @@ -3,6 +3,7 @@ package xyz.atnrch.nicko.event; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import xyz.atnrch.nicko.NickoBukkit; @@ -17,7 +18,7 @@ import xyz.atnrch.nicko.storage.name.PlayerNameStore; import java.util.Optional; public class PlayerJoinListener implements Listener { - @EventHandler + @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onPlayerJoin(PlayerJoinEvent event) { final Player player = event.getPlayer(); final NickoBukkit instance = NickoBukkit.getInstance(); @@ -41,6 +42,11 @@ public class PlayerJoinListener implements Listener { } } }); + + for (Player online : Bukkit.getOnlinePlayers()) { + final AppearanceManager appearanceManager = new AppearanceManager(online); + appearanceManager.updateForOthers(); + } }, 20L); } } From fcc45903969e8fadc09afa20691d60272b8554e6 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 3 Dec 2023 23:25:42 +0100 Subject: [PATCH 133/296] fix: players appearing as allays --- .../java/xyz/atnrch/nicko/NickoBukkit.java | 10 ++- .../WrapperPlayServerEntityDestroy.java | 2 +- .../wrapper/WrapperPlayServerRespawn.java | 36 ++++---- .../wrapper/WrapperPlayServerSpawnEntity.java | 87 ++----------------- .../WrapperPlayerServerPlayerInfo.java | 6 +- .../WrapperPlayerServerPlayerInfoRemove.java | 2 +- 6 files changed, 37 insertions(+), 106 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index 59a3715..bace7b2 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -51,10 +51,6 @@ public class NickoBukkit extends JavaPlugin { public void onEnable() { plugin = this; - if (!MinecraftVersion.VILLAGE_UPDATE.atOrAbove()) { - getLogger().severe("This version (" + MinecraftVersion.getCurrentVersion().getVersion() + ") is not supported by Nicko!"); - } - configurationManager = new ConfigurationManager(getDataFolder()); configurationManager.saveDefaultConfig(); @@ -62,6 +58,12 @@ public class NickoBukkit extends JavaPlugin { dataStore = new PlayerDataStore(mojangAPI, getNickoConfig()); nameStore = new PlayerNameStore(); + if (!MinecraftVersion.VILLAGE_UPDATE.atOrAbove()) { + getLogger().severe("This version (" + MinecraftVersion.getCurrentVersion().getVersion() + ") is not supported by Nicko!"); + dataStore.getStorage().setError(true); + Bukkit.getPluginManager().disablePlugin(this); + } + getLogger().info("Loading persistence..."); if (!dataStore.getStorage().getProvider().init()) { dataStore.getStorage().setError(true); diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerEntityDestroy.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerEntityDestroy.java index 38f9067..2699619 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerEntityDestroy.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerEntityDestroy.java @@ -35,7 +35,7 @@ public class WrapperPlayServerEntityDestroy extends AbstractPacket { * @param value New value for field 'entityIds' */ public void setEntityIds(IntList value) { - this.handle.getModifier().withType(IntList.class, Converters.passthrough(IntList.class)).write(0, value); + this.handle.getModifier().withType(IntList.class, Converters.passthrough(IntList.class)).writeSafely(0, value); } } \ No newline at end of file diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java index 8d395cc..3d0ed53 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java @@ -52,65 +52,65 @@ public class WrapperPlayServerRespawn extends AbstractPacket { if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { // 1.20.2 final InternalStructure dimensionType = commonPlayerSpawnInfoStructure.getStructures().read(0); - dimensionType.getMinecraftKeys().write(0, new MinecraftKey("minecraft", "dimension_type")); - dimensionType.getMinecraftKeys().write(1, new MinecraftKey("minecraft", "overworld")); - commonPlayerSpawnInfoStructure.getStructures().write(0, dimensionType); - commonPlayerSpawnInfoStructure.getWorldKeys().write(0, value); + dimensionType.getMinecraftKeys().writeSafely(0, new MinecraftKey("minecraft", "dimension_type")); + dimensionType.getMinecraftKeys().writeSafely(1, new MinecraftKey("minecraft", "overworld")); + commonPlayerSpawnInfoStructure.getStructures().writeSafely(0, dimensionType); + commonPlayerSpawnInfoStructure.getWorldKeys().writeSafely(0, value); } else if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { // 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")); - dimensionType.getMinecraftKeys().write(1, new MinecraftKey("minecraft", "overworld")); - handle.getStructures().write(0, dimensionType); - handle.getWorldKeys().write(0, value); + dimensionType.getMinecraftKeys().writeSafely(0, new MinecraftKey("minecraft", "dimension_type")); + dimensionType.getMinecraftKeys().writeSafely(1, new MinecraftKey("minecraft", "overworld")); + handle.getStructures().writeSafely(0, dimensionType); + handle.getWorldKeys().writeSafely(0, value); } else if (MinecraftVersion.CAVES_CLIFFS_2.atOrAbove()) { // 1.18 handle.getHolders( MinecraftReflection.getDimensionManager(), BukkitConverters.getDimensionConverter() - ).write(0, value); + ).writeSafely(0, value); } else { // 1.17 and below (untested) - handle.getDimensions().write(0, value.getEnvironment().ordinal()); + handle.getDimensions().writeSafely(0, value.getEnvironment().ordinal()); } } public void setGameMode(GameMode value) { if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { - commonPlayerSpawnInfoStructure.getGameModes().write(0, EnumWrappers.NativeGameMode.fromBukkit(value)); + commonPlayerSpawnInfoStructure.getGameModes().writeSafely(0, EnumWrappers.NativeGameMode.fromBukkit(value)); return; } - handle.getGameModes().write(0, EnumWrappers.NativeGameMode.fromBukkit(value)); + handle.getGameModes().writeSafely(0, EnumWrappers.NativeGameMode.fromBukkit(value)); } public void setPreviousGameMode(GameMode value) { if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { - commonPlayerSpawnInfoStructure.getGameModes().write(1, EnumWrappers.NativeGameMode.fromBukkit(value)); + commonPlayerSpawnInfoStructure.getGameModes().writeSafely(1, EnumWrappers.NativeGameMode.fromBukkit(value)); return; } - handle.getGameModes().write(1, EnumWrappers.NativeGameMode.fromBukkit(value)); + handle.getGameModes().writeSafely(1, EnumWrappers.NativeGameMode.fromBukkit(value)); } public void setCopyMetadata(boolean value) { if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) return; if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) { - handle.getBytes().write(0, ((byte) (value ? 0x01 : 0x00))); + handle.getBytes().writeSafely(0, ((byte) (value ? 0x01 : 0x00))); } else { - handle.getBooleans().write(0, value); + handle.getBooleans().writeSafely(0, value); } } public void setSeed(long value) { if (MinecraftVersion.BEE_UPDATE.atOrAbove() && !MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { - handle.getLongs().write(0, Hashing.sha256().hashLong(value).asLong()); + handle.getLongs().writeSafely(0, Hashing.sha256().hashLong(value).asLong()); } } public void setDifficulty(Difficulty difficulty) { if (difficulty != null && !MinecraftVersion.VILLAGE_UPDATE.atOrAbove()) { - handle.getDifficulties().write(0, EnumWrappers.Difficulty.valueOf(difficulty.name())); + handle.getDifficulties().writeSafely(0, EnumWrappers.Difficulty.valueOf(difficulty.name())); } } } diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerSpawnEntity.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerSpawnEntity.java index 8a37c41..9e1b8fd 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerSpawnEntity.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerSpawnEntity.java @@ -3,10 +3,9 @@ package xyz.atnrch.nicko.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.PacketContainer; import org.bukkit.Location; -import org.bukkit.World; +import org.bukkit.entity.EntityType; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.util.UUID; /** @@ -26,31 +25,14 @@ public class WrapperPlayServerSpawnEntity extends AbstractPacket { handle.getModifier().writeDefaults(); } - /** - * Retrieves entity id of the player - * - * @return 'entityId' - */ - public int getEntityId() { - return this.handle.getIntegers().read(0); - } - /** * Sets the entity id of the player * * @param value New value for field 'entityId' */ public void setEntityId(int value) { - this.handle.getIntegers().write(0, value); - } - - /** - * Retrieves the unique id of the player - * - * @return 'playerId' - */ - public UUID getPlayerId() { - return this.handle.getUUIDs().read(0); + this.handle.getIntegers().writeSafely(0, value); + this.handle.getEntityTypeModifier().writeSafely(0, EntityType.PLAYER); } /** @@ -59,16 +41,7 @@ public class WrapperPlayServerSpawnEntity extends AbstractPacket { * @param value New value for field 'playerId' */ public void setPlayerId(UUID value) { - this.handle.getUUIDs().write(0, value); - } - - /** - * Retrieves the value of field 'x' - * - * @return 'x' - */ - public double getX() { - return this.handle.getDoubles().read(0); + this.handle.getUUIDs().writeSafely(0, value); } /** @@ -77,16 +50,7 @@ public class WrapperPlayServerSpawnEntity extends AbstractPacket { * @param value New value for field 'x' */ public void setX(double value) { - this.handle.getDoubles().write(0, value); - } - - /** - * Retrieves the value of field 'y' - * - * @return 'y' - */ - public double getY() { - return this.handle.getDoubles().read(1); + this.handle.getDoubles().writeSafely(0, value); } /** @@ -95,16 +59,7 @@ public class WrapperPlayServerSpawnEntity extends AbstractPacket { * @param value New value for field 'y' */ public void setY(double value) { - this.handle.getDoubles().write(1, value); - } - - /** - * Retrieves the value of field 'z' - * - * @return 'z' - */ - public double getZ() { - return this.handle.getDoubles().read(2); + this.handle.getDoubles().writeSafely(1, value); } /** @@ -116,31 +71,13 @@ public class WrapperPlayServerSpawnEntity extends AbstractPacket { this.handle.getDoubles().write(2, value); } - /** - * Retrieves the discrete rotation around the y-axis (yaw) - * - * @return 'yRot' - */ - public byte getYRotRaw() { - return this.handle.getBytes().read(0); - } - /** * Sets the discrete rotation around the y-axis (yaw) * * @param value New value for field 'yRot' */ public void setYRotRaw(byte value) { - this.handle.getBytes().write(0, value); - } - - /** - * Retrieves the value of field 'xRot' - * - * @return 'xRot' - */ - public byte getXRotRaw() { - return this.handle.getBytes().read(1); + this.handle.getBytes().writeSafely(0, value); } /** @@ -149,11 +86,7 @@ public class WrapperPlayServerSpawnEntity extends AbstractPacket { * @param value New value for field 'xRot' */ public void setXRotRaw(byte value) { - this.handle.getBytes().write(1, value); - } - - public Location getLocation(@Nullable World world) { - return new Location(world, getX(), getY(), getZ(), angleToDegrees(getYRotRaw()), angleToDegrees(getXRotRaw())); + this.handle.getBytes().writeSafely(1, value); } public void setLocation(@Nonnull Location location) { @@ -164,10 +97,6 @@ public class WrapperPlayServerSpawnEntity extends AbstractPacket { setXRotRaw(degreesToAngle(location.getPitch())); } - private float angleToDegrees(byte rawAngle) { - return rawAngle / 256.0F * 360.0F; - } - private byte degreesToAngle(float degree) { return (byte)((int)(degree * 256.0F / 360.0F)); } diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java index 432019c..ccf7584 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java @@ -25,13 +25,13 @@ public class WrapperPlayerServerPlayerInfo extends AbstractPacket { public void setActions(Set value) { if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) { - handle.getPlayerInfoActions().write(0, value); + handle.getPlayerInfoActions().writeSafely(0, value); } else { - handle.getPlayerInfoAction().write(0, value.stream().iterator().next()); // Get the first Value. + handle.getPlayerInfoAction().writeSafely(0, value.stream().iterator().next()); // Get the first Value. } } public void setData(List value) { - handle.getPlayerInfoDataLists().write(1, value); + handle.getPlayerInfoDataLists().writeSafely(1, value); } } diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java index 5c48f9d..0f3f355 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java +++ b/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java @@ -22,6 +22,6 @@ public class WrapperPlayerServerPlayerInfoRemove extends AbstractPacket { } public void setUUIDs(List value) { - handle.getUUIDLists().write(0, value); + handle.getUUIDLists().writeSafely(0, value); } } From ddb4b6d39ca21a2b0c7a5c81e7880e21f5f50dd5 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 6 Dec 2023 19:26:19 +0100 Subject: [PATCH 134/296] feat: add warning using offline mode --- src/main/java/xyz/atnrch/nicko/NickoBukkit.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java index bace7b2..c6ff4c1 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/atnrch/nicko/NickoBukkit.java @@ -58,6 +58,12 @@ public class NickoBukkit extends JavaPlugin { dataStore = new PlayerDataStore(mojangAPI, getNickoConfig()); nameStore = new PlayerNameStore(); + if (!Bukkit.getOnlineMode()) { + getLogger().warning("Nicko has not been tested using offline mode!"); + getLogger().warning("Issues regarding Nicko being used in offline mode will be ignored for now."); + } + + if (!MinecraftVersion.VILLAGE_UPDATE.atOrAbove()) { getLogger().severe("This version (" + MinecraftVersion.getCurrentVersion().getVersion() + ") is not supported by Nicko!"); dataStore.getStorage().setError(true); From 17345a6b5f09b03457299986e37419bf75718df0 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 6 Dec 2023 19:27:41 +0100 Subject: [PATCH 135/296] feat(ver): bump api version --- src/main/resources/plugin.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 1819aa0..15e88d5 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -3,7 +3,7 @@ main: xyz.atnrch.nicko.NickoBukkit version: 1.0-SNAPSHOT author: Ineanto description: "The feature packed, next generation disguise plugin for Minecraft." -api-version: 1.13 +api-version: 1.14 softdepend: [ PlaceholderAPI ] depend: - ProtocolLib From 37e6f031a6100c59d364522828fa9b1ab3326daa Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 6 Dec 2023 19:35:34 +0100 Subject: [PATCH 136/296] refactor: cleanup for rc1 --- pom.xml | 4 +-- .../nicko/NickoBukkit.java | 26 ++++++++--------- .../nicko/anvil/AnvilManager.java | 18 ++++++------ .../nicko/appearance/ActionResult.java | 2 +- .../nicko/appearance/AppearanceManager.java | 18 ++++++------ .../nicko/command/NickoCommand.java | 8 +++--- .../nicko/config/Configuration.java | 2 +- .../nicko/config/ConfigurationManager.java | 2 +- .../nicko/config/DataSourceConfiguration.java | 2 +- .../nicko/config/DefaultDataSources.java | 2 +- .../config/SQLDataSourceConfiguration.java | 2 +- .../nicko/event/PlayerJoinListener.java | 18 ++++++------ .../nicko/event/PlayerQuitListener.java | 6 ++-- .../nicko/gui/AdminGUI.java | 14 +++++----- .../nicko/gui/CacheManagementGUI.java | 14 +++++----- .../nicko/gui/ChoiceGUI.java | 12 ++++---- .../nicko/gui/HomeGUI.java | 20 ++++++------- .../nicko/gui/InvalidateSkinGUI.java | 18 ++++++------ .../nicko/gui/PlayerCheckGUI.java | 14 +++++----- .../nicko/gui/SettingsGUI.java | 14 +++++----- .../nicko/gui/items/ItemDefaults.java | 6 ++-- .../gui/items/admin/ManageCacheItem.java | 12 ++++---- .../gui/items/admin/ManagePlayerItem.java | 8 +++--- .../gui/items/admin/cache/CacheEntryItem.java | 18 ++++++------ .../admin/cache/CacheStatisticsItem.java | 10 +++---- .../admin/cache/InvalidateCacheItem.java | 8 +++--- .../items/admin/cache/InvalidateSkinItem.java | 8 +++--- .../admin/check/PlayerInformationItem.java | 14 +++++----- .../gui/items/appearance/ChangeBothItem.java | 8 +++--- .../gui/items/appearance/ChangeNameItem.java | 8 +++--- .../gui/items/appearance/ChangeSkinItem.java | 12 ++++---- .../nicko/gui/items/common/GoBackItem.java | 6 ++-- .../gui/items/common/ScrollDownItem.java | 8 +++--- .../nicko/gui/items/common/ScrollUpItem.java | 8 +++--- .../gui/items/common/choice/CancelItem.java | 6 ++-- .../items/common/choice/ChoiceCallback.java | 2 +- .../gui/items/common/choice/ConfirmItem.java | 6 ++-- .../nicko/gui/items/home/AdminAccessItem.java | 8 +++--- .../nicko/gui/items/home/ExitItem.java | 7 ++--- .../nicko/gui/items/home/ResetItem.java | 10 +++---- .../gui/items/home/SettingsAccessItem.java | 8 +++--- .../items/settings/BungeeCordCyclingItem.java | 14 +++++----- .../items/settings/LanguageCyclingItem.java | 18 ++++++------ .../{atnrch => ineanto}/nicko/i18n/I18N.java | 6 ++-- .../nicko/i18n/I18NDict.java | 2 +- .../nicko/i18n/ItemTranslation.java | 2 +- .../nicko/i18n/Locale.java | 2 +- .../nicko/i18n/LocaleFileManager.java | 4 +-- .../nicko/mojang/MojangAPI.java | 2 +- .../nicko/mojang/MojangSkin.java | 2 +- .../nicko/mojang/MojangUtils.java | 2 +- .../nicko/placeholder/NickoExpansion.java | 6 ++-- .../nicko/profile/NickoProfile.java | 28 +++---------------- .../nicko/storage/Cache.java | 6 ++-- .../nicko/storage/CacheProvider.java | 2 +- .../nicko/storage/PlayerDataStore.java | 24 ++++++++-------- .../nicko/storage/Storage.java | 6 ++-- .../nicko/storage/StorageProvider.java | 2 +- .../nicko/storage/json/JSONStorage.java | 14 +++++----- .../storage/json/JSONStorageProvider.java | 4 +-- .../nicko/storage/map/MapCache.java | 10 +++---- .../nicko/storage/map/MapCacheProvider.java | 6 ++-- .../nicko/storage/mariadb/MariaDBStorage.java | 14 +++++----- .../mariadb/MariaDBStorageProvider.java | 8 +++--- .../nicko/storage/mysql/MySQLStorage.java | 14 +++++----- .../storage/mysql/MySQLStorageProvider.java | 8 +++--- .../nicko/storage/name/PlayerNameStore.java | 2 +- .../nicko/storage/redis/RedisCache.java | 12 ++++---- .../storage/redis/RedisCacheProvider.java | 8 +++--- .../nicko/wrapper/AbstractPacket.java | 2 +- .../WrapperPlayServerEntityDestroy.java | 2 +- .../wrapper/WrapperPlayServerRespawn.java | 2 +- .../wrapper/WrapperPlayServerSpawnEntity.java | 2 +- .../WrapperPlayerServerPlayerInfo.java | 2 +- .../WrapperPlayerServerPlayerInfoRemove.java | 2 +- src/main/resources/plugin.yml | 4 +-- .../atnrch/nicko/test/NickoPluginTest.java | 6 ++-- .../nicko/test/config/ConfigurationTest.java | 4 +-- .../nicko/test/i18n/ItemTranslationTest.java | 14 +++++----- .../nicko/test/i18n/TranslationTest.java | 13 ++++----- .../nicko/test/storage/BrokenSQLTest.java | 12 ++++---- .../nicko/test/storage/SQLStorageTest.java | 16 +++++------ .../nicko/test/storage/map/MapCacheTest.java | 9 +++--- .../test/storage/redis/RedisCacheTest.java | 14 +++++----- 84 files changed, 353 insertions(+), 376 deletions(-) rename src/main/java/xyz/{atnrch => ineanto}/nicko/NickoBukkit.java (90%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/anvil/AnvilManager.java (92%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/appearance/ActionResult.java (94%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/appearance/AppearanceManager.java (95%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/command/NickoCommand.java (86%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/config/Configuration.java (97%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/config/ConfigurationManager.java (98%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/config/DataSourceConfiguration.java (97%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/config/DefaultDataSources.java (92%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/config/SQLDataSourceConfiguration.java (93%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/event/PlayerJoinListener.java (83%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/event/PlayerQuitListener.java (82%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/AdminGUI.java (81%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/CacheManagementGUI.java (81%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/ChoiceGUI.java (81%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/HomeGUI.java (79%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/InvalidateSkinGUI.java (84%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/PlayerCheckGUI.java (85%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/SettingsGUI.java (82%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/ItemDefaults.java (90%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/admin/ManageCacheItem.java (87%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/admin/ManagePlayerItem.java (81%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/admin/cache/CacheEntryItem.java (85%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/admin/cache/CacheStatisticsItem.java (82%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/admin/cache/InvalidateCacheItem.java (88%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/admin/cache/InvalidateSkinItem.java (84%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/admin/check/PlayerInformationItem.java (86%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/appearance/ChangeBothItem.java (85%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/appearance/ChangeNameItem.java (85%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/appearance/ChangeSkinItem.java (84%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/common/GoBackItem.java (87%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/common/ScrollDownItem.java (83%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/common/ScrollUpItem.java (82%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/common/choice/CancelItem.java (86%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/common/choice/ChoiceCallback.java (61%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/common/choice/ConfirmItem.java (86%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/home/AdminAccessItem.java (85%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/home/ExitItem.java (84%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/home/ResetItem.java (89%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/home/SettingsAccessItem.java (85%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/settings/BungeeCordCyclingItem.java (88%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/gui/items/settings/LanguageCyclingItem.java (89%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/i18n/I18N.java (97%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/i18n/I18NDict.java (99%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/i18n/ItemTranslation.java (92%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/i18n/Locale.java (95%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/i18n/LocaleFileManager.java (96%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/mojang/MojangAPI.java (99%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/mojang/MojangSkin.java (95%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/mojang/MojangUtils.java (96%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/placeholder/NickoExpansion.java (94%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/profile/NickoProfile.java (72%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/storage/Cache.java (80%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/storage/CacheProvider.java (69%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/storage/PlayerDataStore.java (84%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/storage/Storage.java (80%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/storage/StorageProvider.java (69%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/storage/json/JSONStorage.java (90%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/storage/json/JSONStorageProvider.java (80%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/storage/map/MapCache.java (84%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/storage/map/MapCacheProvider.java (77%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/storage/mariadb/MariaDBStorage.java (94%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/storage/mariadb/MariaDBStorageProvider.java (93%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/storage/mysql/MySQLStorage.java (94%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/storage/mysql/MySQLStorageProvider.java (93%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/storage/name/PlayerNameStore.java (94%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/storage/redis/RedisCache.java (87%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/storage/redis/RedisCacheProvider.java (83%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/wrapper/AbstractPacket.java (98%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/wrapper/WrapperPlayServerEntityDestroy.java (97%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/wrapper/WrapperPlayServerRespawn.java (99%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/wrapper/WrapperPlayServerSpawnEntity.java (98%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/wrapper/WrapperPlayerServerPlayerInfo.java (97%) rename src/main/java/xyz/{atnrch => ineanto}/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java (95%) diff --git a/pom.xml b/pom.xml index 468a730..ca6669d 100644 --- a/pom.xml +++ b/pom.xml @@ -4,9 +4,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - xyz.atnrch + xyz.ineanto nicko - 1.0-SNAPSHOT + 1.0-RC1 Nicko diff --git a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java similarity index 90% rename from src/main/java/xyz/atnrch/nicko/NickoBukkit.java rename to src/main/java/xyz/ineanto/nicko/NickoBukkit.java index c6ff4c1..a2dd590 100644 --- a/src/main/java/xyz/atnrch/nicko/NickoBukkit.java +++ b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java @@ -1,21 +1,21 @@ -package xyz.atnrch.nicko; +package xyz.ineanto.nicko; import com.comphenix.protocol.utility.MinecraftVersion; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.command.PluginCommand; import org.bukkit.plugin.java.JavaPlugin; -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.i18n.Locale; -import xyz.atnrch.nicko.i18n.LocaleFileManager; -import xyz.atnrch.nicko.mojang.MojangAPI; -import xyz.atnrch.nicko.placeholder.NickoExpansion; -import xyz.atnrch.nicko.storage.PlayerDataStore; -import xyz.atnrch.nicko.storage.name.PlayerNameStore; +import xyz.ineanto.nicko.command.NickoCommand; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.config.ConfigurationManager; +import xyz.ineanto.nicko.event.PlayerJoinListener; +import xyz.ineanto.nicko.event.PlayerQuitListener; +import xyz.ineanto.nicko.i18n.Locale; +import xyz.ineanto.nicko.i18n.LocaleFileManager; +import xyz.ineanto.nicko.mojang.MojangAPI; +import xyz.ineanto.nicko.placeholder.NickoExpansion; +import xyz.ineanto.nicko.storage.PlayerDataStore; +import xyz.ineanto.nicko.storage.name.PlayerNameStore; import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SimpleItem; @@ -115,7 +115,7 @@ public class NickoBukkit extends JavaPlugin { getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this); } - getLogger().info("Nicko (Bukkit) has been enabled."); + getLogger().info("Nicko has been enabled."); } @Override diff --git a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java similarity index 92% rename from src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java rename to src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java index 0e7d16f..15dcabf 100644 --- a/src/main/java/xyz/atnrch/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java @@ -1,18 +1,18 @@ -package xyz.atnrch.nicko.anvil; +package xyz.ineanto.nicko.anvil; import net.wesjd.anvilgui.AnvilGUI; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -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.i18n.I18NDict; -import xyz.atnrch.nicko.mojang.MojangUtils; -import xyz.atnrch.nicko.profile.NickoProfile; -import xyz.atnrch.nicko.storage.PlayerDataStore; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.appearance.ActionResult; +import xyz.ineanto.nicko.appearance.AppearanceManager; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.mojang.MojangUtils; +import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.storage.PlayerDataStore; import java.util.Collections; import java.util.List; diff --git a/src/main/java/xyz/atnrch/nicko/appearance/ActionResult.java b/src/main/java/xyz/ineanto/nicko/appearance/ActionResult.java similarity index 94% rename from src/main/java/xyz/atnrch/nicko/appearance/ActionResult.java rename to src/main/java/xyz/ineanto/nicko/appearance/ActionResult.java index c527832..18984c1 100644 --- a/src/main/java/xyz/atnrch/nicko/appearance/ActionResult.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/ActionResult.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.appearance; +package xyz.ineanto.nicko.appearance; public class ActionResult { private final String errorKey; diff --git a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java similarity index 95% rename from src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java rename to src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index 185beae..f18f8e9 100644 --- a/src/main/java/xyz/atnrch/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.appearance; +package xyz.ineanto.nicko.appearance; import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.wrappers.*; @@ -9,14 +9,14 @@ import org.bukkit.Bukkit; import org.bukkit.World; 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.mojang.MojangAPI; -import xyz.atnrch.nicko.mojang.MojangSkin; -import xyz.atnrch.nicko.profile.NickoProfile; -import xyz.atnrch.nicko.storage.PlayerDataStore; -import xyz.atnrch.nicko.storage.name.PlayerNameStore; -import xyz.atnrch.nicko.wrapper.*; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.mojang.MojangAPI; +import xyz.ineanto.nicko.mojang.MojangSkin; +import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.storage.PlayerDataStore; +import xyz.ineanto.nicko.storage.name.PlayerNameStore; +import xyz.ineanto.nicko.wrapper.*; import java.io.IOException; import java.util.EnumSet; diff --git a/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java b/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java similarity index 86% rename from src/main/java/xyz/atnrch/nicko/command/NickoCommand.java rename to src/main/java/xyz/ineanto/nicko/command/NickoCommand.java index 9d07c9b..bb23afd 100644 --- a/src/main/java/xyz/atnrch/nicko/command/NickoCommand.java +++ b/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java @@ -1,13 +1,13 @@ -package xyz.atnrch.nicko.command; +package xyz.ineanto.nicko.command; 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.gui.HomeGUI; -import xyz.atnrch.nicko.i18n.I18N; -import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.gui.HomeGUI; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; public class NickoCommand implements CommandExecutor { @Override diff --git a/src/main/java/xyz/atnrch/nicko/config/Configuration.java b/src/main/java/xyz/ineanto/nicko/config/Configuration.java similarity index 97% rename from src/main/java/xyz/atnrch/nicko/config/Configuration.java rename to src/main/java/xyz/ineanto/nicko/config/Configuration.java index 9fdef97..048c6d2 100644 --- a/src/main/java/xyz/atnrch/nicko/config/Configuration.java +++ b/src/main/java/xyz/ineanto/nicko/config/Configuration.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.config; +package xyz.ineanto.nicko.config; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/xyz/atnrch/nicko/config/ConfigurationManager.java b/src/main/java/xyz/ineanto/nicko/config/ConfigurationManager.java similarity index 98% rename from src/main/java/xyz/atnrch/nicko/config/ConfigurationManager.java rename to src/main/java/xyz/ineanto/nicko/config/ConfigurationManager.java index f322668..0824ee5 100644 --- a/src/main/java/xyz/atnrch/nicko/config/ConfigurationManager.java +++ b/src/main/java/xyz/ineanto/nicko/config/ConfigurationManager.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.config; +package xyz.ineanto.nicko.config; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/src/main/java/xyz/atnrch/nicko/config/DataSourceConfiguration.java b/src/main/java/xyz/ineanto/nicko/config/DataSourceConfiguration.java similarity index 97% rename from src/main/java/xyz/atnrch/nicko/config/DataSourceConfiguration.java rename to src/main/java/xyz/ineanto/nicko/config/DataSourceConfiguration.java index 20509df..6d00ceb 100644 --- a/src/main/java/xyz/atnrch/nicko/config/DataSourceConfiguration.java +++ b/src/main/java/xyz/ineanto/nicko/config/DataSourceConfiguration.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.config; +package xyz.ineanto.nicko.config; public class DataSourceConfiguration { private final boolean enabled; diff --git a/src/main/java/xyz/atnrch/nicko/config/DefaultDataSources.java b/src/main/java/xyz/ineanto/nicko/config/DefaultDataSources.java similarity index 92% rename from src/main/java/xyz/atnrch/nicko/config/DefaultDataSources.java rename to src/main/java/xyz/ineanto/nicko/config/DefaultDataSources.java index 076ff54..715bda2 100644 --- a/src/main/java/xyz/atnrch/nicko/config/DefaultDataSources.java +++ b/src/main/java/xyz/ineanto/nicko/config/DefaultDataSources.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.config; +package xyz.ineanto.nicko.config; public class DefaultDataSources { public static final DataSourceConfiguration REDIS_EMPTY = new DataSourceConfiguration(false, "127.0.0.1", 6379, "", ""); diff --git a/src/main/java/xyz/atnrch/nicko/config/SQLDataSourceConfiguration.java b/src/main/java/xyz/ineanto/nicko/config/SQLDataSourceConfiguration.java similarity index 93% rename from src/main/java/xyz/atnrch/nicko/config/SQLDataSourceConfiguration.java rename to src/main/java/xyz/ineanto/nicko/config/SQLDataSourceConfiguration.java index 7e62a1f..583981d 100644 --- a/src/main/java/xyz/atnrch/nicko/config/SQLDataSourceConfiguration.java +++ b/src/main/java/xyz/ineanto/nicko/config/SQLDataSourceConfiguration.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.config; +package xyz.ineanto.nicko.config; public class SQLDataSourceConfiguration extends DataSourceConfiguration { private final boolean mariadb; diff --git a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java similarity index 83% rename from src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java rename to src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java index 4038733..c3b6925 100644 --- a/src/main/java/xyz/atnrch/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.event; +package xyz.ineanto.nicko.event; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -6,14 +6,14 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; -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.i18n.I18NDict; -import xyz.atnrch.nicko.profile.NickoProfile; -import xyz.atnrch.nicko.storage.PlayerDataStore; -import xyz.atnrch.nicko.storage.name.PlayerNameStore; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.appearance.ActionResult; +import xyz.ineanto.nicko.appearance.AppearanceManager; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.storage.PlayerDataStore; +import xyz.ineanto.nicko.storage.name.PlayerNameStore; import java.util.Optional; diff --git a/src/main/java/xyz/atnrch/nicko/event/PlayerQuitListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java similarity index 82% rename from src/main/java/xyz/atnrch/nicko/event/PlayerQuitListener.java rename to src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java index 6da9607..8c5647d 100644 --- a/src/main/java/xyz/atnrch/nicko/event/PlayerQuitListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java @@ -1,7 +1,7 @@ -package xyz.atnrch.nicko.event; +package xyz.ineanto.nicko.event; -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.appearance.ActionResult; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.appearance.ActionResult; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; diff --git a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java b/src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java similarity index 81% rename from src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java rename to src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java index 4d605ee..1828ec4 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/AdminGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java @@ -1,12 +1,12 @@ -package xyz.atnrch.nicko.gui; +package xyz.ineanto.nicko.gui; import org.bukkit.entity.Player; -import xyz.atnrch.nicko.gui.items.ItemDefaults; -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 xyz.atnrch.nicko.i18n.I18N; -import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.gui.items.ItemDefaults; +import xyz.ineanto.nicko.gui.items.admin.ManageCacheItem; +import xyz.ineanto.nicko.gui.items.admin.ManagePlayerItem; +import xyz.ineanto.nicko.gui.items.common.GoBackItem; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.item.impl.SimpleItem; import xyz.xenondevs.invui.window.Window; diff --git a/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java b/src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java similarity index 81% rename from src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java rename to src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java index 5c081f9..14d2812 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/CacheManagementGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java @@ -1,12 +1,12 @@ -package xyz.atnrch.nicko.gui; +package xyz.ineanto.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.InvalidateSkinItem; -import xyz.atnrch.nicko.gui.items.common.GoBackItem; -import xyz.atnrch.nicko.i18n.I18N; -import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.gui.items.admin.cache.CacheStatisticsItem; +import xyz.ineanto.nicko.gui.items.admin.cache.InvalidateCacheItem; +import xyz.ineanto.nicko.gui.items.admin.cache.InvalidateSkinItem; +import xyz.ineanto.nicko.gui.items.common.GoBackItem; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; diff --git a/src/main/java/xyz/atnrch/nicko/gui/ChoiceGUI.java b/src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java similarity index 81% rename from src/main/java/xyz/atnrch/nicko/gui/ChoiceGUI.java rename to src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java index 90e31dd..3a2e045 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/ChoiceGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java @@ -1,12 +1,12 @@ -package xyz.atnrch.nicko.gui; +package xyz.ineanto.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.ineanto.nicko.gui.items.common.choice.CancelItem; +import xyz.ineanto.nicko.gui.items.common.choice.ChoiceCallback; +import xyz.ineanto.nicko.gui.items.common.choice.ConfirmItem; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SimpleItem; diff --git a/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java b/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java similarity index 79% rename from src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java rename to src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java index 9303f45..b0c8612 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/HomeGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java @@ -1,15 +1,15 @@ -package xyz.atnrch.nicko.gui; +package xyz.ineanto.nicko.gui; import org.bukkit.entity.Player; -import xyz.atnrch.nicko.gui.items.appearance.ChangeBothItem; -import xyz.atnrch.nicko.gui.items.appearance.ChangeNameItem; -import xyz.atnrch.nicko.gui.items.appearance.ChangeSkinItem; -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.ineanto.nicko.gui.items.appearance.ChangeBothItem; +import xyz.ineanto.nicko.gui.items.appearance.ChangeNameItem; +import xyz.ineanto.nicko.gui.items.appearance.ChangeSkinItem; +import xyz.ineanto.nicko.gui.items.home.AdminAccessItem; +import xyz.ineanto.nicko.gui.items.home.ExitItem; +import xyz.ineanto.nicko.gui.items.home.ResetItem; +import xyz.ineanto.nicko.gui.items.home.SettingsAccessItem; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; diff --git a/src/main/java/xyz/atnrch/nicko/gui/InvalidateSkinGUI.java b/src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java similarity index 84% rename from src/main/java/xyz/atnrch/nicko/gui/InvalidateSkinGUI.java rename to src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java index f79842a..da49bc7 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/InvalidateSkinGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java @@ -1,17 +1,17 @@ -package xyz.atnrch.nicko.gui; +package xyz.ineanto.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.ineanto.nicko.gui.items.common.GoBackItem; +import xyz.ineanto.nicko.gui.items.common.ScrollUpItem; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.mojang.MojangSkin; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.gui.structure.Markers; import xyz.xenondevs.invui.item.Item; -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.gui.items.admin.cache.CacheEntryItem; -import xyz.atnrch.nicko.gui.items.common.ScrollDownItem; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.gui.items.admin.cache.CacheEntryItem; +import xyz.ineanto.nicko.gui.items.common.ScrollDownItem; import org.bukkit.entity.Player; import xyz.xenondevs.invui.window.Window; diff --git a/src/main/java/xyz/atnrch/nicko/gui/PlayerCheckGUI.java b/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java similarity index 85% rename from src/main/java/xyz/atnrch/nicko/gui/PlayerCheckGUI.java rename to src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java index 5326d6d..4775213 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/PlayerCheckGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java @@ -1,14 +1,14 @@ -package xyz.atnrch.nicko.gui; +package xyz.ineanto.nicko.gui; import org.bukkit.Bukkit; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; -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.ineanto.nicko.gui.items.admin.check.PlayerInformationItem; +import xyz.ineanto.nicko.gui.items.common.GoBackItem; +import xyz.ineanto.nicko.gui.items.common.ScrollDownItem; +import xyz.ineanto.nicko.gui.items.common.ScrollUpItem; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.gui.structure.Markers; diff --git a/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java b/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java similarity index 82% rename from src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java rename to src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java index e44bbea..6086cad 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/SettingsGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java @@ -1,12 +1,12 @@ -package xyz.atnrch.nicko.gui; +package xyz.ineanto.nicko.gui; import org.bukkit.entity.Player; -import xyz.atnrch.nicko.gui.items.ItemDefaults; -import xyz.atnrch.nicko.gui.items.common.GoBackItem; -import xyz.atnrch.nicko.gui.items.settings.BungeeCordCyclingItem; -import xyz.atnrch.nicko.gui.items.settings.LanguageCyclingItem; -import xyz.atnrch.nicko.i18n.I18N; -import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.gui.items.ItemDefaults; +import xyz.ineanto.nicko.gui.items.common.GoBackItem; +import xyz.ineanto.nicko.gui.items.settings.BungeeCordCyclingItem; +import xyz.ineanto.nicko.gui.items.settings.LanguageCyclingItem; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.item.impl.SimpleItem; import xyz.xenondevs.invui.window.Window; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/ItemDefaults.java b/src/main/java/xyz/ineanto/nicko/gui/items/ItemDefaults.java similarity index 90% rename from src/main/java/xyz/atnrch/nicko/gui/items/ItemDefaults.java rename to src/main/java/xyz/ineanto/nicko/gui/items/ItemDefaults.java index 0f0864e..88ed8f5 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/ItemDefaults.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/ItemDefaults.java @@ -1,8 +1,8 @@ -package xyz.atnrch.nicko.gui.items; +package xyz.ineanto.nicko.gui.items; import org.bukkit.Material; -import xyz.atnrch.nicko.i18n.I18N; -import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.item.builder.AbstractItemBuilder; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.builder.SkullBuilder; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCacheItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java similarity index 87% rename from src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCacheItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java index a233745..81a48cb 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManageCacheItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java @@ -1,15 +1,15 @@ -package xyz.atnrch.nicko.gui.items.admin; +package xyz.ineanto.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.NickoBukkit; -import xyz.atnrch.nicko.gui.CacheManagementGUI; -import xyz.atnrch.nicko.gui.items.ItemDefaults; -import xyz.atnrch.nicko.i18n.I18N; -import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.gui.CacheManagementGUI; +import xyz.ineanto.nicko.gui.items.ItemDefaults; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.builder.SkullBuilder; import xyz.xenondevs.invui.item.impl.AsyncItem; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManagePlayerItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManagePlayerItem.java similarity index 81% rename from src/main/java/xyz/atnrch/nicko/gui/items/admin/ManagePlayerItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/admin/ManagePlayerItem.java index 947577f..ffe3732 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/ManagePlayerItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManagePlayerItem.java @@ -1,10 +1,10 @@ -package xyz.atnrch.nicko.gui.items.admin; +package xyz.ineanto.nicko.gui.items.admin; import org.bukkit.Material; import org.bukkit.entity.Player; -import xyz.atnrch.nicko.gui.PlayerCheckGUI; -import xyz.atnrch.nicko.i18n.I18N; -import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.gui.PlayerCheckGUI; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntryItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java similarity index 85% rename from src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntryItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java index 2d6d194..28b9cf9 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheEntryItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java @@ -1,18 +1,18 @@ -package xyz.atnrch.nicko.gui.items.admin.cache; +package xyz.ineanto.nicko.gui.items.admin.cache; 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.NickoBukkit; -import xyz.atnrch.nicko.gui.ChoiceGUI; -import xyz.atnrch.nicko.gui.InvalidateSkinGUI; -import xyz.atnrch.nicko.gui.items.ItemDefaults; -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; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.gui.ChoiceGUI; +import xyz.ineanto.nicko.gui.InvalidateSkinGUI; +import xyz.ineanto.nicko.gui.items.ItemDefaults; +import xyz.ineanto.nicko.gui.items.common.choice.ChoiceCallback; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.mojang.MojangAPI; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.builder.SkullBuilder; import xyz.xenondevs.invui.item.impl.AsyncItem; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheStatisticsItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheStatisticsItem.java similarity index 82% rename from src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheStatisticsItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheStatisticsItem.java index 8df1db6..71feec5 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/CacheStatisticsItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheStatisticsItem.java @@ -1,13 +1,13 @@ -package xyz.atnrch.nicko.gui.items.admin.cache; +package xyz.ineanto.nicko.gui.items.admin.cache; import com.google.common.cache.CacheStats; import com.google.common.cache.LoadingCache; import org.bukkit.Material; 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.mojang.MojangSkin; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.mojang.MojangSkin; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCacheItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java similarity index 88% rename from src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCacheItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java index 40c7b89..b2196af 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateCacheItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java @@ -1,11 +1,11 @@ -package xyz.atnrch.nicko.gui.items.admin.cache; +package xyz.ineanto.nicko.gui.items.admin.cache; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.i18n.I18N; -import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateSkinItem.java similarity index 84% rename from src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateSkinItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateSkinItem.java index 8f2d7d7..cbf690c 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/cache/InvalidateSkinItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateSkinItem.java @@ -1,11 +1,11 @@ -package xyz.atnrch.nicko.gui.items.admin.cache; +package xyz.ineanto.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.ineanto.nicko.gui.InvalidateSkinGUI; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/admin/check/PlayerInformationItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java similarity index 86% rename from src/main/java/xyz/atnrch/nicko/gui/items/admin/check/PlayerInformationItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java index 0f2b6a6..429fa1b 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/admin/check/PlayerInformationItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java @@ -1,14 +1,14 @@ -package xyz.atnrch.nicko.gui.items.admin.check; +package xyz.ineanto.nicko.gui.items.admin.check; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.gui.items.ItemDefaults; -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.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.gui.items.ItemDefaults; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.storage.PlayerDataStore; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.builder.SkullBuilder; import xyz.xenondevs.invui.item.impl.AsyncItem; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeBothItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java similarity index 85% rename from src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeBothItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java index 3863585..0308eef 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeBothItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java @@ -1,11 +1,11 @@ -package xyz.atnrch.nicko.gui.items.appearance; +package xyz.ineanto.nicko.gui.items.appearance; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; -import xyz.atnrch.nicko.anvil.AnvilManager; -import xyz.atnrch.nicko.i18n.I18N; -import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.anvil.AnvilManager; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeNameItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java similarity index 85% rename from src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeNameItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java index c553ec6..0f83859 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeNameItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java @@ -1,11 +1,11 @@ -package xyz.atnrch.nicko.gui.items.appearance; +package xyz.ineanto.nicko.gui.items.appearance; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; -import xyz.atnrch.nicko.anvil.AnvilManager; -import xyz.atnrch.nicko.i18n.I18N; -import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.anvil.AnvilManager; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java similarity index 84% rename from src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeSkinItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java index 91c9404..7e6e865 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/appearance/ChangeSkinItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java @@ -1,12 +1,12 @@ -package xyz.atnrch.nicko.gui.items.appearance; +package xyz.ineanto.nicko.gui.items.appearance; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.anvil.AnvilManager; -import xyz.atnrch.nicko.gui.items.ItemDefaults; -import xyz.atnrch.nicko.i18n.I18N; -import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.anvil.AnvilManager; +import xyz.ineanto.nicko.gui.items.ItemDefaults; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.item.builder.SkullBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; import xyz.xenondevs.invui.util.MojangApiUtils; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/GoBackItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/GoBackItem.java similarity index 87% rename from src/main/java/xyz/atnrch/nicko/gui/items/common/GoBackItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/common/GoBackItem.java index 16df2d5..afd1e3d 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/GoBackItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/GoBackItem.java @@ -1,9 +1,9 @@ -package xyz.atnrch.nicko.gui.items.common; +package xyz.ineanto.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.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollDownItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java similarity index 83% rename from src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollDownItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java index 9e6f636..b9c382c 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollDownItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java @@ -1,9 +1,9 @@ -package xyz.atnrch.nicko.gui.items.common; +package xyz.ineanto.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.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.i18n.ItemTranslation; import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.item.ItemProvider; import xyz.xenondevs.invui.item.builder.ItemBuilder; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollUpItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java similarity index 82% rename from src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollUpItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java index 06e457d..9aedd45 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/ScrollUpItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java @@ -1,9 +1,9 @@ -package xyz.atnrch.nicko.gui.items.common; +package xyz.ineanto.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.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.i18n.ItemTranslation; import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.item.ItemProvider; import xyz.xenondevs.invui.item.builder.ItemBuilder; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/choice/CancelItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/CancelItem.java similarity index 86% rename from src/main/java/xyz/atnrch/nicko/gui/items/common/choice/CancelItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/common/choice/CancelItem.java index ee9965a..257b2ae 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/choice/CancelItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/CancelItem.java @@ -1,9 +1,9 @@ -package xyz.atnrch.nicko.gui.items.common.choice; +package xyz.ineanto.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.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/common/choice/ChoiceCallback.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/ChoiceCallback.java similarity index 61% rename from src/main/java/xyz/atnrch/nicko/gui/items/common/choice/ChoiceCallback.java rename to src/main/java/xyz/ineanto/nicko/gui/items/common/choice/ChoiceCallback.java index e1e3f84..ebe70fa 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/choice/ChoiceCallback.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/ChoiceCallback.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.gui.items.common.choice; +package xyz.ineanto.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/ineanto/nicko/gui/items/common/choice/ConfirmItem.java similarity index 86% rename from src/main/java/xyz/atnrch/nicko/gui/items/common/choice/ConfirmItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/common/choice/ConfirmItem.java index 3116706..397b839 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/common/choice/ConfirmItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/ConfirmItem.java @@ -1,9 +1,9 @@ -package xyz.atnrch.nicko.gui.items.common.choice; +package xyz.ineanto.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.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/home/AdminAccessItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java similarity index 85% rename from src/main/java/xyz/atnrch/nicko/gui/items/home/AdminAccessItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java index 590075a..a0b0873 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/home/AdminAccessItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java @@ -1,11 +1,11 @@ -package xyz.atnrch.nicko.gui.items.home; +package xyz.ineanto.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.ineanto.nicko.gui.AdminGUI; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/home/ExitItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/ExitItem.java similarity index 84% rename from src/main/java/xyz/atnrch/nicko/gui/items/home/ExitItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/home/ExitItem.java index 8e11b3d..c78a230 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/home/ExitItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/ExitItem.java @@ -1,11 +1,10 @@ -package xyz.atnrch.nicko.gui.items.home; +package xyz.ineanto.nicko.gui.items.home; 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.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/home/ResetItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java similarity index 89% rename from src/main/java/xyz/atnrch/nicko/gui/items/home/ResetItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java index a717914..c1c4523 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/home/ResetItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java @@ -1,12 +1,12 @@ -package xyz.atnrch.nicko.gui.items.home; +package xyz.ineanto.nicko.gui.items.home; 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.profile.NickoProfile; +import xyz.ineanto.nicko.appearance.AppearanceManager; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.profile.NickoProfile; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/home/SettingsAccessItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/SettingsAccessItem.java similarity index 85% rename from src/main/java/xyz/atnrch/nicko/gui/items/home/SettingsAccessItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/home/SettingsAccessItem.java index aa4630e..06aa368 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/home/SettingsAccessItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/SettingsAccessItem.java @@ -1,11 +1,11 @@ -package xyz.atnrch.nicko.gui.items.home; +package xyz.ineanto.nicko.gui.items.home; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; -import xyz.atnrch.nicko.gui.SettingsGUI; -import xyz.atnrch.nicko.i18n.I18N; -import xyz.atnrch.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.gui.SettingsGUI; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/settings/BungeeCordCyclingItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/settings/BungeeCordCyclingItem.java similarity index 88% rename from src/main/java/xyz/atnrch/nicko/gui/items/settings/BungeeCordCyclingItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/settings/BungeeCordCyclingItem.java index c644d3b..e62a7d0 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/settings/BungeeCordCyclingItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/settings/BungeeCordCyclingItem.java @@ -1,14 +1,14 @@ -package xyz.atnrch.nicko.gui.items.settings; +package xyz.ineanto.nicko.gui.items.settings; 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.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.i18n.ItemTranslation; +import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.storage.PlayerDataStore; import xyz.xenondevs.invui.item.ItemProvider; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.AbstractItem; diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCyclingItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java similarity index 89% rename from src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCyclingItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java index 8024244..3d6fc7a 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCyclingItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java @@ -1,16 +1,16 @@ -package xyz.atnrch.nicko.gui.items.settings; +package xyz.ineanto.nicko.gui.items.settings; 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; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.gui.SettingsGUI; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.i18n.ItemTranslation; +import xyz.ineanto.nicko.i18n.Locale; +import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.storage.PlayerDataStore; import xyz.xenondevs.invui.item.ItemProvider; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.AbstractItem; diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java b/src/main/java/xyz/ineanto/nicko/i18n/I18N.java similarity index 97% rename from src/main/java/xyz/atnrch/nicko/i18n/I18N.java rename to src/main/java/xyz/ineanto/nicko/i18n/I18N.java index ed4bd53..28cc27a 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18N.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/I18N.java @@ -1,9 +1,9 @@ -package xyz.atnrch.nicko.i18n; +package xyz.ineanto.nicko.i18n; import com.github.jsixface.YamlConfig; import org.bukkit.entity.Player; -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.profile.NickoProfile; import xyz.xenondevs.invui.item.builder.AbstractItemBuilder; import java.io.InputStream; diff --git a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java b/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java similarity index 99% rename from src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java rename to src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java index 54b2d8c..d80c9ff 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.i18n; +package xyz.ineanto.nicko.i18n; public class I18NDict { public static class Error { diff --git a/src/main/java/xyz/atnrch/nicko/i18n/ItemTranslation.java b/src/main/java/xyz/ineanto/nicko/i18n/ItemTranslation.java similarity index 92% rename from src/main/java/xyz/atnrch/nicko/i18n/ItemTranslation.java rename to src/main/java/xyz/ineanto/nicko/i18n/ItemTranslation.java index 035724e..3d07aad 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/ItemTranslation.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/ItemTranslation.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.i18n; +package xyz.ineanto.nicko.i18n; import java.util.ArrayList; diff --git a/src/main/java/xyz/atnrch/nicko/i18n/Locale.java b/src/main/java/xyz/ineanto/nicko/i18n/Locale.java similarity index 95% rename from src/main/java/xyz/atnrch/nicko/i18n/Locale.java rename to src/main/java/xyz/ineanto/nicko/i18n/Locale.java index 607b54c..8821142 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/Locale.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/Locale.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.i18n; +package xyz.ineanto.nicko.i18n; import java.io.Serializable; diff --git a/src/main/java/xyz/atnrch/nicko/i18n/LocaleFileManager.java b/src/main/java/xyz/ineanto/nicko/i18n/LocaleFileManager.java similarity index 96% rename from src/main/java/xyz/atnrch/nicko/i18n/LocaleFileManager.java rename to src/main/java/xyz/ineanto/nicko/i18n/LocaleFileManager.java index 4ffb155..31518e5 100644 --- a/src/main/java/xyz/atnrch/nicko/i18n/LocaleFileManager.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/LocaleFileManager.java @@ -1,7 +1,7 @@ -package xyz.atnrch.nicko.i18n; +package xyz.ineanto.nicko.i18n; import com.github.jsixface.YamlConfig; -import xyz.atnrch.nicko.NickoBukkit; +import xyz.ineanto.nicko.NickoBukkit; import xyz.xenondevs.invui.util.IOUtils; import java.io.*; diff --git a/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java b/src/main/java/xyz/ineanto/nicko/mojang/MojangAPI.java similarity index 99% rename from src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java rename to src/main/java/xyz/ineanto/nicko/mojang/MojangAPI.java index 5630015..55144fa 100644 --- a/src/main/java/xyz/atnrch/nicko/mojang/MojangAPI.java +++ b/src/main/java/xyz/ineanto/nicko/mojang/MojangAPI.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.mojang; +package xyz.ineanto.nicko.mojang; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; diff --git a/src/main/java/xyz/atnrch/nicko/mojang/MojangSkin.java b/src/main/java/xyz/ineanto/nicko/mojang/MojangSkin.java similarity index 95% rename from src/main/java/xyz/atnrch/nicko/mojang/MojangSkin.java rename to src/main/java/xyz/ineanto/nicko/mojang/MojangSkin.java index 2033147..bf8f342 100644 --- a/src/main/java/xyz/atnrch/nicko/mojang/MojangSkin.java +++ b/src/main/java/xyz/ineanto/nicko/mojang/MojangSkin.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.mojang; +package xyz.ineanto.nicko.mojang; import com.google.gson.JsonObject; diff --git a/src/main/java/xyz/atnrch/nicko/mojang/MojangUtils.java b/src/main/java/xyz/ineanto/nicko/mojang/MojangUtils.java similarity index 96% rename from src/main/java/xyz/atnrch/nicko/mojang/MojangUtils.java rename to src/main/java/xyz/ineanto/nicko/mojang/MojangUtils.java index 6845392..6ed3606 100644 --- a/src/main/java/xyz/atnrch/nicko/mojang/MojangUtils.java +++ b/src/main/java/xyz/ineanto/nicko/mojang/MojangUtils.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.mojang; +package xyz.ineanto.nicko.mojang; import java.util.UUID; import java.util.regex.Pattern; diff --git a/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java b/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java similarity index 94% rename from src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java rename to src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java index 1754509..03c6839 100644 --- a/src/main/java/xyz/atnrch/nicko/placeholder/NickoExpansion.java +++ b/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java @@ -1,11 +1,11 @@ -package xyz.atnrch.nicko.placeholder; +package xyz.ineanto.nicko.placeholder; import me.clip.placeholderapi.expansion.PlaceholderExpansion; 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.NickoProfile; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.profile.NickoProfile; import java.util.Optional; diff --git a/src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java b/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java similarity index 72% rename from src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java rename to src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java index 05a544b..0dd8b6c 100644 --- a/src/main/java/xyz/atnrch/nicko/profile/NickoProfile.java +++ b/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java @@ -1,10 +1,9 @@ -package xyz.atnrch.nicko.profile; +package xyz.ineanto.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 xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.i18n.Locale; +import xyz.ineanto.nicko.storage.PlayerDataStore; import java.util.Optional; import java.util.UUID; @@ -13,8 +12,6 @@ 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; @@ -25,23 +22,6 @@ public class NickoProfile implements Cloneable { this.skin = skin; this.locale = locale; this.bungeecordTransfer = bungeecordTransfer; - this.player = 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) { diff --git a/src/main/java/xyz/atnrch/nicko/storage/Cache.java b/src/main/java/xyz/ineanto/nicko/storage/Cache.java similarity index 80% rename from src/main/java/xyz/atnrch/nicko/storage/Cache.java rename to src/main/java/xyz/ineanto/nicko/storage/Cache.java index e771324..1b2616d 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/Cache.java +++ b/src/main/java/xyz/ineanto/nicko/storage/Cache.java @@ -1,7 +1,7 @@ -package xyz.atnrch.nicko.storage; +package xyz.ineanto.nicko.storage; -import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.appearance.ActionResult; +import xyz.ineanto.nicko.profile.NickoProfile; import java.util.Optional; import java.util.UUID; diff --git a/src/main/java/xyz/atnrch/nicko/storage/CacheProvider.java b/src/main/java/xyz/ineanto/nicko/storage/CacheProvider.java similarity index 69% rename from src/main/java/xyz/atnrch/nicko/storage/CacheProvider.java rename to src/main/java/xyz/ineanto/nicko/storage/CacheProvider.java index e0f19cd..3597ac5 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/CacheProvider.java +++ b/src/main/java/xyz/ineanto/nicko/storage/CacheProvider.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.storage; +package xyz.ineanto.nicko.storage; public interface CacheProvider { boolean init(); diff --git a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java b/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java similarity index 84% rename from src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java rename to src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java index bf7c719..56e151c 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/PlayerDataStore.java +++ b/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java @@ -1,17 +1,17 @@ -package xyz.atnrch.nicko.storage; +package xyz.ineanto.nicko.storage; import org.bukkit.entity.Player; -import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.config.Configuration; -import xyz.atnrch.nicko.i18n.I18NDict; -import xyz.atnrch.nicko.mojang.MojangAPI; -import xyz.atnrch.nicko.mojang.MojangUtils; -import xyz.atnrch.nicko.profile.NickoProfile; -import xyz.atnrch.nicko.storage.json.JSONStorage; -import xyz.atnrch.nicko.storage.map.MapCache; -import xyz.atnrch.nicko.storage.mariadb.MariaDBStorage; -import xyz.atnrch.nicko.storage.mysql.MySQLStorage; -import xyz.atnrch.nicko.storage.redis.RedisCache; +import xyz.ineanto.nicko.appearance.ActionResult; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.mojang.MojangAPI; +import xyz.ineanto.nicko.mojang.MojangUtils; +import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.storage.json.JSONStorage; +import xyz.ineanto.nicko.storage.map.MapCache; +import xyz.ineanto.nicko.storage.mariadb.MariaDBStorage; +import xyz.ineanto.nicko.storage.mysql.MySQLStorage; +import xyz.ineanto.nicko.storage.redis.RedisCache; import java.io.IOException; import java.util.Optional; diff --git a/src/main/java/xyz/atnrch/nicko/storage/Storage.java b/src/main/java/xyz/ineanto/nicko/storage/Storage.java similarity index 80% rename from src/main/java/xyz/atnrch/nicko/storage/Storage.java rename to src/main/java/xyz/ineanto/nicko/storage/Storage.java index d9c6743..9cac04a 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/Storage.java +++ b/src/main/java/xyz/ineanto/nicko/storage/Storage.java @@ -1,7 +1,7 @@ -package xyz.atnrch.nicko.storage; +package xyz.ineanto.nicko.storage; -import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.appearance.ActionResult; +import xyz.ineanto.nicko.profile.NickoProfile; import java.util.Optional; import java.util.UUID; diff --git a/src/main/java/xyz/atnrch/nicko/storage/StorageProvider.java b/src/main/java/xyz/ineanto/nicko/storage/StorageProvider.java similarity index 69% rename from src/main/java/xyz/atnrch/nicko/storage/StorageProvider.java rename to src/main/java/xyz/ineanto/nicko/storage/StorageProvider.java index c12b930..3981771 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/StorageProvider.java +++ b/src/main/java/xyz/ineanto/nicko/storage/StorageProvider.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.storage; +package xyz.ineanto.nicko.storage; public interface StorageProvider { boolean init(); diff --git a/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java b/src/main/java/xyz/ineanto/nicko/storage/json/JSONStorage.java similarity index 90% rename from src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java rename to src/main/java/xyz/ineanto/nicko/storage/json/JSONStorage.java index 747a739..1bf1837 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java +++ b/src/main/java/xyz/ineanto/nicko/storage/json/JSONStorage.java @@ -1,13 +1,13 @@ -package xyz.atnrch.nicko.storage.json; +package xyz.ineanto.nicko.storage.json; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.profile.NickoProfile; -import xyz.atnrch.nicko.i18n.I18NDict; -import xyz.atnrch.nicko.storage.Storage; -import xyz.atnrch.nicko.storage.StorageProvider; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.appearance.ActionResult; +import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.storage.Storage; +import xyz.ineanto.nicko.storage.StorageProvider; import java.io.*; import java.util.Optional; diff --git a/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorageProvider.java b/src/main/java/xyz/ineanto/nicko/storage/json/JSONStorageProvider.java similarity index 80% rename from src/main/java/xyz/atnrch/nicko/storage/json/JSONStorageProvider.java rename to src/main/java/xyz/ineanto/nicko/storage/json/JSONStorageProvider.java index 2d58096..c2976f3 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorageProvider.java +++ b/src/main/java/xyz/ineanto/nicko/storage/json/JSONStorageProvider.java @@ -1,6 +1,6 @@ -package xyz.atnrch.nicko.storage.json; +package xyz.ineanto.nicko.storage.json; -import xyz.atnrch.nicko.storage.StorageProvider; +import xyz.ineanto.nicko.storage.StorageProvider; import java.io.File; diff --git a/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java b/src/main/java/xyz/ineanto/nicko/storage/map/MapCache.java similarity index 84% rename from src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java rename to src/main/java/xyz/ineanto/nicko/storage/map/MapCache.java index c573457..ebc3a88 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java +++ b/src/main/java/xyz/ineanto/nicko/storage/map/MapCache.java @@ -1,9 +1,9 @@ -package xyz.atnrch.nicko.storage.map; +package xyz.ineanto.nicko.storage.map; -import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.profile.NickoProfile; -import xyz.atnrch.nicko.storage.Cache; -import xyz.atnrch.nicko.storage.CacheProvider; +import xyz.ineanto.nicko.appearance.ActionResult; +import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.storage.Cache; +import xyz.ineanto.nicko.storage.CacheProvider; import java.util.HashMap; import java.util.Optional; diff --git a/src/main/java/xyz/atnrch/nicko/storage/map/MapCacheProvider.java b/src/main/java/xyz/ineanto/nicko/storage/map/MapCacheProvider.java similarity index 77% rename from src/main/java/xyz/atnrch/nicko/storage/map/MapCacheProvider.java rename to src/main/java/xyz/ineanto/nicko/storage/map/MapCacheProvider.java index 3a83100..bfb85bd 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/map/MapCacheProvider.java +++ b/src/main/java/xyz/ineanto/nicko/storage/map/MapCacheProvider.java @@ -1,7 +1,7 @@ -package xyz.atnrch.nicko.storage.map; +package xyz.ineanto.nicko.storage.map; -import xyz.atnrch.nicko.profile.NickoProfile; -import xyz.atnrch.nicko.storage.CacheProvider; +import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.storage.CacheProvider; import java.util.HashMap; import java.util.UUID; diff --git a/src/main/java/xyz/atnrch/nicko/storage/mariadb/MariaDBStorage.java b/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java similarity index 94% rename from src/main/java/xyz/atnrch/nicko/storage/mariadb/MariaDBStorage.java rename to src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java index 6908612..57374d7 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/mariadb/MariaDBStorage.java +++ b/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java @@ -1,11 +1,11 @@ -package xyz.atnrch.nicko.storage.mariadb; +package xyz.ineanto.nicko.storage.mariadb; -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.NickoProfile; -import xyz.atnrch.nicko.storage.Storage; +import xyz.ineanto.nicko.appearance.ActionResult; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.i18n.Locale; +import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.storage.Storage; import java.sql.Connection; import java.sql.PreparedStatement; diff --git a/src/main/java/xyz/atnrch/nicko/storage/mariadb/MariaDBStorageProvider.java b/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorageProvider.java similarity index 93% rename from src/main/java/xyz/atnrch/nicko/storage/mariadb/MariaDBStorageProvider.java rename to src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorageProvider.java index 0c44ec5..ba3e37a 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/mariadb/MariaDBStorageProvider.java +++ b/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorageProvider.java @@ -1,9 +1,9 @@ -package xyz.atnrch.nicko.storage.mariadb; +package xyz.ineanto.nicko.storage.mariadb; import org.mariadb.jdbc.MariaDbDataSource; -import xyz.atnrch.nicko.config.Configuration; -import xyz.atnrch.nicko.config.DataSourceConfiguration; -import xyz.atnrch.nicko.storage.StorageProvider; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.config.DataSourceConfiguration; +import xyz.ineanto.nicko.storage.StorageProvider; import java.sql.Connection; import java.sql.PreparedStatement; diff --git a/src/main/java/xyz/atnrch/nicko/storage/mysql/MySQLStorage.java b/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java similarity index 94% rename from src/main/java/xyz/atnrch/nicko/storage/mysql/MySQLStorage.java rename to src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java index fb58b04..7b43630 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/mysql/MySQLStorage.java +++ b/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java @@ -1,11 +1,11 @@ -package xyz.atnrch.nicko.storage.mysql; +package xyz.ineanto.nicko.storage.mysql; -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.NickoProfile; -import xyz.atnrch.nicko.storage.Storage; +import xyz.ineanto.nicko.appearance.ActionResult; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.i18n.Locale; +import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.storage.Storage; import java.sql.Connection; import java.sql.PreparedStatement; diff --git a/src/main/java/xyz/atnrch/nicko/storage/mysql/MySQLStorageProvider.java b/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorageProvider.java similarity index 93% rename from src/main/java/xyz/atnrch/nicko/storage/mysql/MySQLStorageProvider.java rename to src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorageProvider.java index 0df0978..2211189 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/mysql/MySQLStorageProvider.java +++ b/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorageProvider.java @@ -1,9 +1,9 @@ -package xyz.atnrch.nicko.storage.mysql; +package xyz.ineanto.nicko.storage.mysql; import com.mysql.cj.jdbc.MysqlDataSource; -import xyz.atnrch.nicko.config.Configuration; -import xyz.atnrch.nicko.config.DataSourceConfiguration; -import xyz.atnrch.nicko.storage.StorageProvider; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.config.DataSourceConfiguration; +import xyz.ineanto.nicko.storage.StorageProvider; import java.sql.Connection; import java.sql.PreparedStatement; diff --git a/src/main/java/xyz/atnrch/nicko/storage/name/PlayerNameStore.java b/src/main/java/xyz/ineanto/nicko/storage/name/PlayerNameStore.java similarity index 94% rename from src/main/java/xyz/atnrch/nicko/storage/name/PlayerNameStore.java rename to src/main/java/xyz/ineanto/nicko/storage/name/PlayerNameStore.java index 6dccd32..1e90b11 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/name/PlayerNameStore.java +++ b/src/main/java/xyz/ineanto/nicko/storage/name/PlayerNameStore.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.storage.name; +package xyz.ineanto.nicko.storage.name; import org.bukkit.entity.Player; diff --git a/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java b/src/main/java/xyz/ineanto/nicko/storage/redis/RedisCache.java similarity index 87% rename from src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java rename to src/main/java/xyz/ineanto/nicko/storage/redis/RedisCache.java index 96bc57a..c768538 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java +++ b/src/main/java/xyz/ineanto/nicko/storage/redis/RedisCache.java @@ -1,13 +1,13 @@ -package xyz.atnrch.nicko.storage.redis; +package xyz.ineanto.nicko.storage.redis; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import redis.clients.jedis.Jedis; -import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.config.Configuration; -import xyz.atnrch.nicko.profile.NickoProfile; -import xyz.atnrch.nicko.storage.Cache; -import xyz.atnrch.nicko.storage.CacheProvider; +import xyz.ineanto.nicko.appearance.ActionResult; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.storage.Cache; +import xyz.ineanto.nicko.storage.CacheProvider; import java.util.Optional; import java.util.UUID; diff --git a/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCacheProvider.java b/src/main/java/xyz/ineanto/nicko/storage/redis/RedisCacheProvider.java similarity index 83% rename from src/main/java/xyz/atnrch/nicko/storage/redis/RedisCacheProvider.java rename to src/main/java/xyz/ineanto/nicko/storage/redis/RedisCacheProvider.java index f4d5afe..7408326 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCacheProvider.java +++ b/src/main/java/xyz/ineanto/nicko/storage/redis/RedisCacheProvider.java @@ -1,9 +1,9 @@ -package xyz.atnrch.nicko.storage.redis; +package xyz.ineanto.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; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.config.DataSourceConfiguration; +import xyz.ineanto.nicko.storage.CacheProvider; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/AbstractPacket.java b/src/main/java/xyz/ineanto/nicko/wrapper/AbstractPacket.java similarity index 98% rename from src/main/java/xyz/atnrch/nicko/wrapper/AbstractPacket.java rename to src/main/java/xyz/ineanto/nicko/wrapper/AbstractPacket.java index c1ff601..57b8598 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/AbstractPacket.java +++ b/src/main/java/xyz/ineanto/nicko/wrapper/AbstractPacket.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package xyz.atnrch.nicko.wrapper; +package xyz.ineanto.nicko.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerEntityDestroy.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerEntityDestroy.java similarity index 97% rename from src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerEntityDestroy.java rename to src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerEntityDestroy.java index 2699619..1af54f7 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerEntityDestroy.java +++ b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerEntityDestroy.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.wrapper; +package xyz.ineanto.nicko.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.PacketContainer; diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java similarity index 99% rename from src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java rename to src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java index 3d0ed53..9082ad1 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.wrapper; +package xyz.ineanto.nicko.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.InternalStructure; diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerSpawnEntity.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerSpawnEntity.java similarity index 98% rename from src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerSpawnEntity.java rename to src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerSpawnEntity.java index 9e1b8fd..7f09a16 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayServerSpawnEntity.java +++ b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerSpawnEntity.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.wrapper; +package xyz.ineanto.nicko.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.PacketContainer; diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfo.java similarity index 97% rename from src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java rename to src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfo.java index ccf7584..3347f98 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfo.java +++ b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfo.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.wrapper; +package xyz.ineanto.nicko.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.PacketContainer; diff --git a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java similarity index 95% rename from src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java rename to src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java index 0f3f355..a619249 100644 --- a/src/main/java/xyz/atnrch/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java +++ b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.wrapper; +package xyz.ineanto.nicko.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.PacketContainer; diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 15e88d5..6fc9aa8 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Nicko -main: xyz.atnrch.nicko.NickoBukkit -version: 1.0-SNAPSHOT +main: xyz.ineanto.nicko.NickoBukkit +version: 1.0-RC1 author: Ineanto description: "The feature packed, next generation disguise plugin for Minecraft." api-version: 1.14 diff --git a/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java b/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java index a0562e1..94e508f 100644 --- a/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java @@ -5,9 +5,9 @@ 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.DefaultDataSources; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.config.DefaultDataSources; import static org.junit.jupiter.api.Assertions.assertNotNull; diff --git a/src/test/java/xyz/atnrch/nicko/test/config/ConfigurationTest.java b/src/test/java/xyz/atnrch/nicko/test/config/ConfigurationTest.java index 647740a..b334534 100644 --- a/src/test/java/xyz/atnrch/nicko/test/config/ConfigurationTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/config/ConfigurationTest.java @@ -5,8 +5,8 @@ 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.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.config.Configuration; import static org.junit.jupiter.api.Assertions.assertFalse; diff --git a/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java b/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java index fc3a1b8..acc5c1c 100644 --- a/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java @@ -6,13 +6,13 @@ 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.DefaultDataSources; -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.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.config.DefaultDataSources; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.i18n.ItemTranslation; +import xyz.ineanto.nicko.i18n.Locale; import static org.junit.jupiter.api.Assertions.*; diff --git a/src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java b/src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java index b8abd0b..dc4d7f4 100644 --- a/src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java @@ -6,13 +6,12 @@ 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.config.DefaultDataSources; -import xyz.atnrch.nicko.i18n.I18N; -import xyz.atnrch.nicko.i18n.I18NDict; -import xyz.atnrch.nicko.i18n.Locale; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.config.DefaultDataSources; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.i18n.Locale; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java index 13d2195..da8b09a 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java @@ -7,12 +7,12 @@ 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.appearance.ActionResult; -import xyz.atnrch.nicko.config.Configuration; -import xyz.atnrch.nicko.config.DefaultDataSources; -import xyz.atnrch.nicko.config.SQLDataSourceConfiguration; -import xyz.atnrch.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.appearance.ActionResult; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.config.DefaultDataSources; +import xyz.ineanto.nicko.config.SQLDataSourceConfiguration; +import xyz.ineanto.nicko.profile.NickoProfile; import java.util.Optional; 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 9defabb..7539591 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java @@ -2,14 +2,14 @@ package xyz.atnrch.nicko.test.storage; import be.seeseemelk.mockbukkit.MockBukkit; import org.junit.jupiter.api.*; -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.config.Configuration; -import xyz.atnrch.nicko.config.DefaultDataSources; -import xyz.atnrch.nicko.config.SQLDataSourceConfiguration; -import xyz.atnrch.nicko.i18n.Locale; -import xyz.atnrch.nicko.profile.NickoProfile; -import xyz.atnrch.nicko.storage.PlayerDataStore; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.appearance.ActionResult; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.config.DefaultDataSources; +import xyz.ineanto.nicko.config.SQLDataSourceConfiguration; +import xyz.ineanto.nicko.i18n.Locale; +import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.storage.PlayerDataStore; import java.util.Optional; import java.util.UUID; diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java index a46bd0a..3f972bb 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java @@ -3,11 +3,10 @@ package xyz.atnrch.nicko.test.storage.map; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; import be.seeseemelk.mockbukkit.entity.PlayerMock; -import xyz.atnrch.nicko.NickoBukkit; -import xyz.atnrch.nicko.config.Configuration; -import xyz.atnrch.nicko.config.DataSourceConfiguration; -import xyz.atnrch.nicko.config.DefaultDataSources; -import xyz.atnrch.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.config.DefaultDataSources; +import xyz.ineanto.nicko.profile.NickoProfile; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; 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 19006de..fe49c52 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 @@ -4,13 +4,13 @@ import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; 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.config.Configuration; -import xyz.atnrch.nicko.config.DataSourceConfiguration; -import xyz.atnrch.nicko.config.DefaultDataSources; -import xyz.atnrch.nicko.profile.NickoProfile; -import xyz.atnrch.nicko.storage.PlayerDataStore; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.appearance.ActionResult; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.config.DataSourceConfiguration; +import xyz.ineanto.nicko.config.DefaultDataSources; +import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.storage.PlayerDataStore; import java.util.Optional; From 14b118eadf21748a54ee3328130672cb7db33859 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 6 Dec 2023 22:09:35 +0100 Subject: [PATCH 137/296] fix(build): include mysql drivers --- pom.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ca6669d..1cdaba5 100644 --- a/pom.xml +++ b/pom.xml @@ -132,7 +132,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M9 + 3.1.2 org.apache.maven.plugins @@ -153,6 +153,7 @@ com.fasterxml.jackson.dataformat:* com.fasterxml.jackson.core:* org.mariadb.jdbc:* + com.mysql:* redis.clients:* org.apache.commons:commons-pool2 com.google.code.gson:gson @@ -195,6 +196,10 @@ com.google.code.gson net.artelnatif.libs.gson + + com.mysql + net.artelnatif.libs.mysql + false From 4f8c3c9eec2704315d52d57194ba03d99b1aad65 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 6 Dec 2023 22:10:57 +0100 Subject: [PATCH 138/296] =?UTF-8?q?feat:=20Nicko=20is=20out!=20?= =?UTF-8?q?=F0=9F=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1047a18..1779d78 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ## Download: -Coming soon! ⏳ +https://www.spigotmc.org/resources/nicko.113868/ --- From 99e7dd439ad2040dadf2b072584bf36acf792388 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 6 Dec 2023 22:35:31 +0100 Subject: [PATCH 139/296] fix: make players disguise on join --- .../nicko/appearance/AppearanceManager.java | 17 +++++++++++++++-- .../ineanto/nicko/event/PlayerJoinListener.java | 13 ++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index f18f8e9..9ff1183 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -58,7 +58,20 @@ public class AppearanceManager { updateMetadata(); updateTabList(gameProfile, displayName); respawnPlayer(); - updateForOthers(); + respawnEntityForOthers(); + } + return result; + } + + public ActionResult updateForOthers(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); + if (!result.isError()) { + updateMetadata(); + updateTabList(gameProfile, displayName); + respawnEntityForOthers(); } return result; } @@ -68,7 +81,7 @@ public class AppearanceManager { return optionalProfile.orElse(NickoProfile.EMPTY_PROFILE.clone()); } - public void updateForOthers() { + public void respawnEntityForOthers() { final NickoProfile nickoProfile = getNickoProfile(); if (!nickoProfile.hasData()) return; diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java index c3b6925..a1175e9 100644 --- a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java @@ -16,6 +16,7 @@ import xyz.ineanto.nicko.storage.PlayerDataStore; import xyz.ineanto.nicko.storage.name.PlayerNameStore; import java.util.Optional; +import java.util.stream.Collectors; public class PlayerJoinListener implements Listener { @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) @@ -43,9 +44,15 @@ public class PlayerJoinListener implements Listener { } }); - for (Player online : Bukkit.getOnlinePlayers()) { - final AppearanceManager appearanceManager = new AppearanceManager(online); - appearanceManager.updateForOthers(); + // TODO (Ineanto, 12/6/23): Make this cleaner. + for (Player online : Bukkit.getOnlinePlayers().stream().filter(op -> op.getUniqueId() != player.getUniqueId()).collect(Collectors.toList())) { + final Optional optionalOnlinePlayerProfile = dataStore.getData(online.getUniqueId()); + + optionalOnlinePlayerProfile.ifPresent(profile -> { + final AppearanceManager appearanceManager = new AppearanceManager(online); + final boolean needsASkinChange = profile.getSkin() != null && !profile.getSkin().equals(online.getName()); + appearanceManager.updateForOthers(needsASkinChange, false); + }); } }, 20L); } From 8d1c80a5fba466f422a220ec595d67939b5f6956 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 6 Dec 2023 22:41:49 +0100 Subject: [PATCH 140/296] feat: bump version and version filtering --- pom.xml | 2 +- src/main/resources/plugin.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 1cdaba5..4ed58d2 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ xyz.ineanto nicko - 1.0-RC1 + 1.0.1-RC1 Nicko diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 6fc9aa8..e7c1639 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Nicko main: xyz.ineanto.nicko.NickoBukkit -version: 1.0-RC1 +version: ${project.version} author: Ineanto description: "The feature packed, next generation disguise plugin for Minecraft." api-version: 1.14 From fc2be7c7a4cd9bdb9a08310f3cf7af5a30925970 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 6 Dec 2023 22:53:51 +0100 Subject: [PATCH 141/296] refactor: relocate packages --- README.md | 1 + pom.xml | 24 +++++++++---------- .../nicko/appearance/AppearanceManager.java | 2 +- .../nicko/event/PlayerJoinListener.java | 8 ++++++- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 1779d78..1b12e6f 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ https://www.spigotmc.org/resources/nicko.113868/ ## Known bugs: +- Disguising will heal and feed players to full health. - Players who have operator (OP) status lose access to the Operator Items tab in creative mode after disguising **(1.20 and up)**. - When disguising and only changing their display name, players will have the new default diff --git a/pom.xml b/pom.xml index 4ed58d2..4203596 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ xyz.ineanto nicko - 1.0.1-RC1 + 1.0.2-RC1 Nicko @@ -162,43 +162,43 @@ net.wesjd.anvilgui - net.artelnatif.libs.anvilgui + xyz.ineanto.nicko.libs.anvilgui - xyz.xenondevs.invui - net.artelnatif.libs.invui + xyz.xenondevs + xyz.ineanto.nicko.libs.invui com.github.jsixface - net.artelnatif.libs.yaml + xyz.ineanto.nicko.libs.yaml com.fasterxml.jackson.dataformat - net.artelnatif.libs.jackson.yaml + xyz.ineanto.nicko.libs.jackson.yaml com.fasterxml.jackson.core - net.artelnatif.libs.jackson.core + xyz.ineanto.nicko.libs.jackson.core org.mariadb.jdbc - net.artelnatif.libs.mariadb + xyz.ineanto.nicko.libs.mariadb redis.clients - net.artelnatif.libs.redis + xyz.ineanto.nicko.libs.redis org.apache.commons.pool2 - net.artelnatif.libs.pool2 + xyz.ineanto.nicko.libs.pool2 com.google.code.gson - net.artelnatif.libs.gson + xyz.ineanto.nicko.libs.gson com.mysql - net.artelnatif.libs.mysql + xyz.ineanto.nicko.libs.mysql diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index 9ff1183..33c5c0a 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -149,7 +149,7 @@ public class AppearanceManager { player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); player.setAllowFlight(wasAllowedToFly); player.setFlying(wasFlying); - player.updateInventory(); // Marked as unstable. + player.updateInventory(); } @SuppressWarnings("deprecation") diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java index a1175e9..d905a9b 100644 --- a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java @@ -16,9 +16,12 @@ import xyz.ineanto.nicko.storage.PlayerDataStore; import xyz.ineanto.nicko.storage.name.PlayerNameStore; import java.util.Optional; +import java.util.logging.Logger; import java.util.stream.Collectors; public class PlayerJoinListener implements Listener { + private final Logger logger = Logger.getLogger("PlayerJoinListener"); + @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onPlayerJoin(PlayerJoinEvent event) { final Player player = event.getPlayer(); @@ -51,7 +54,10 @@ public class PlayerJoinListener implements Listener { optionalOnlinePlayerProfile.ifPresent(profile -> { final AppearanceManager appearanceManager = new AppearanceManager(online); final boolean needsASkinChange = profile.getSkin() != null && !profile.getSkin().equals(online.getName()); - appearanceManager.updateForOthers(needsASkinChange, false); + final ActionResult actionResult = appearanceManager.updateForOthers(needsASkinChange, false); + if (actionResult.isError()) { + logger.warning("Something wrong happened while updating players to joining player (" + actionResult.getErrorKey() + ")"); + } }); } }, 20L); From a8483b4a15b75bd97c78ddca853d590136f8b7ca Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 6 Dec 2023 22:54:07 +0100 Subject: [PATCH 142/296] fix: typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1b12e6f..2b36e0e 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ https://www.spigotmc.org/resources/nicko.113868/ ## Known bugs: -- Disguising will heal and feed players to full health. +- Disguising will heal and feed players fully. - Players who have operator (OP) status lose access to the Operator Items tab in creative mode after disguising **(1.20 and up)**. - When disguising and only changing their display name, players will have the new default From b7fff273cf67c747a459114e231e18638b14a172 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 6 Dec 2023 22:54:33 +0100 Subject: [PATCH 143/296] fix: rephrase --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2b36e0e..1fe8508 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ https://www.spigotmc.org/resources/nicko.113868/ ## Known bugs: -- Disguising will heal and feed players fully. +- Disguising will fully heal and feed players. - Players who have operator (OP) status lose access to the Operator Items tab in creative mode after disguising **(1.20 and up)**. - When disguising and only changing their display name, players will have the new default From 98c0a446c6db08a54479ef06481b8f95758682b6 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 7 Dec 2023 12:34:27 +0100 Subject: [PATCH 144/296] fix: visually update health and food levels --- .../java/xyz/ineanto/nicko/appearance/AppearanceManager.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index 33c5c0a..bc40bcb 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -138,6 +138,7 @@ public class AppearanceManager { final World world = player.getWorld(); final boolean wasFlying = player.isFlying(); final boolean wasAllowedToFly = player.getAllowFlight(); + final int foodLevel = player.getFoodLevel(); final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(); respawn.setDimension(world); respawn.setSeed(world.getSeed()); @@ -150,6 +151,8 @@ public class AppearanceManager { player.setAllowFlight(wasAllowedToFly); player.setFlying(wasFlying); player.updateInventory(); + player.sendHealthUpdate(); + player.setFoodLevel(foodLevel); } @SuppressWarnings("deprecation") From 8611ef2604d4c8000bc76a6f88bc326b6a3a8ec5 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 7 Dec 2023 13:28:36 +0100 Subject: [PATCH 145/296] feat(version): bump --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4203596..51f50e4 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ xyz.ineanto nicko - 1.0.2-RC1 + 1.0.3-RC1 Nicko From 4eecbf416e2a95969d35919007ac0ece1bbf6758 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 7 Dec 2023 16:03:43 +0100 Subject: [PATCH 146/296] feat: reset skin via admin panel --- pom.xml | 2 +- .../nicko/event/PlayerQuitListener.java | 4 +- .../xyz/ineanto/nicko/gui/PlayerCheckGUI.java | 2 +- .../admin/check/PlayerInformationItem.java | 53 +++++++++++++++---- .../java/xyz/ineanto/nicko/i18n/I18NDict.java | 6 +++ src/main/resources/en.yml | 6 ++- src/main/resources/fr.yml | 6 ++- 7 files changed, 62 insertions(+), 17 deletions(-) diff --git a/pom.xml b/pom.xml index 51f50e4..3ad828b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ xyz.ineanto nicko - 1.0.3-RC1 + 1.0.4-RC1 Nicko diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java index 8c5647d..c0c232f 100644 --- a/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java @@ -1,11 +1,11 @@ package xyz.ineanto.nicko.event; -import xyz.ineanto.nicko.NickoBukkit; -import xyz.ineanto.nicko.appearance.ActionResult; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.appearance.ActionResult; public class PlayerQuitListener implements Listener { @EventHandler diff --git a/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java b/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java index 4775213..f59616d 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java @@ -29,7 +29,7 @@ public class PlayerCheckGUI { final List items = Bukkit.getOnlinePlayers().stream() .map(Entity::getUniqueId) - .map(uuid -> new PlayerInformationItem(i18n, uuid)) + .map(uuid -> new PlayerInformationItem(i18n, Bukkit.getPlayer(uuid))) .collect(Collectors.toList()); final AdminGUI parent = new AdminGUI(player); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java index 429fa1b..a3abfa6 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java @@ -1,14 +1,19 @@ package xyz.ineanto.nicko.gui.items.admin.check; -import org.bukkit.Bukkit; 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.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.appearance.AppearanceManager; +import xyz.ineanto.nicko.gui.ChoiceGUI; +import xyz.ineanto.nicko.gui.PlayerCheckGUI; import xyz.ineanto.nicko.gui.items.ItemDefaults; +import xyz.ineanto.nicko.gui.items.common.choice.ChoiceCallback; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; import xyz.ineanto.nicko.profile.NickoProfile; -import xyz.ineanto.nicko.storage.PlayerDataStore; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.builder.SkullBuilder; import xyz.xenondevs.invui.item.impl.AsyncItem; @@ -17,35 +22,61 @@ import xyz.xenondevs.invui.util.MojangApiUtils; import java.io.IOException; import java.util.Optional; -import java.util.UUID; public class PlayerInformationItem extends AsyncItem { - public PlayerInformationItem(I18N i18n, UUID uuid) { + private final Player target; + private final NickoProfile profile; + + public PlayerInformationItem(I18N i18n, Player target) { super(new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.PAINTING); return i18n.translateItem(builder, I18NDict.GUI.LOADING); }, (click -> true)).getItemProvider(), () -> { - final Player player = Bukkit.getPlayer(uuid); try { - final SkullBuilder skull = new SkullBuilder(uuid); - final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore(); - final Optional optionalProfile = dataStore.getData(uuid); + final SkullBuilder skull = new SkullBuilder(target.getUniqueId()); + final Optional optionalProfile = NickoBukkit.getInstance().getDataStore().getData(target.getUniqueId()); if (optionalProfile.isPresent()) { final NickoProfile profile = optionalProfile.get(); return i18n.translateItem(skull, I18NDict.GUI.Admin.CHECK, - player.getName(), + target.getName(), (profile.hasData() ? "§a✔" : "§c❌"), (profile.getName() == null ? "§7N/A" : profile.getName()), (profile.getSkin() == null ? "§7N/A" : profile.getSkin())); } } catch (MojangApiUtils.MojangApiException | IOException e) { - NickoBukkit.getInstance().getLogger().severe("Unable to get head for specified UUID ( " + uuid + ")! (GUI/PlayerCheck)"); + NickoBukkit.getInstance().getLogger().severe("Unable to get head for specified UUID ( " + target.getUniqueId() + ")! (GUI/PlayerCheck)"); } return ItemDefaults.getErrorSkullItem(i18n, I18NDict.GUI.Admin.CHECK, - "§4???", "§cN/A", "§cN/A", "§cN/A" + "§c§l?!?", "§cN/A", "§cN/A", "§cN/A" ); }); + this.target = target; + this.profile = NickoBukkit.getInstance().getDataStore().getData(target.getUniqueId()).orElse(NickoProfile.EMPTY_PROFILE); } + + @Override + public void handleClick(@NotNull ClickType click, @NotNull Player player, @NotNull InventoryClickEvent event) { + if (click.isLeftClick() || click.isRightClick()) { + if (profile.hasData()) { + event.getView().close(); + new ChoiceGUI(player, new ChoiceCallback() { + @Override + public void onConfirm() { + final AppearanceManager appearanceManager = new AppearanceManager(target); + appearanceManager.reset(); + final I18N i18n = new I18N(player); + player.sendMessage(i18n.translate(I18NDict.Event.Admin.Check.REMOVE_SKIN, target.getName())); + } + + @Override + public void onCancel() { + new PlayerCheckGUI(player).open(); + } + }).open(); + } + } + } + } diff --git a/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java b/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java index d80c9ff..2bf7676 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java @@ -28,6 +28,12 @@ public class I18NDict { public static final String INVALIDATE_ENTRY = CACHE_KEY + "invalidate_entry"; } + + public static class Check { + private static final String CHECK_KEY = ADMIN_KEY + "check."; + + public static final String REMOVE_SKIN = CHECK_KEY + "remove_skin"; + } } public static class Settings { diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 1951936..84e6d82 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -26,6 +26,8 @@ event: cache: invalidate_cache: "§fComplete cache invalidated." invalidate_entry: "§6{0} §fhas been invalidated." + check: + remove_skin: "§fSkin removed from player." gui: title: @@ -33,7 +35,7 @@ gui: settings: "Nicko > Settings" admin: "Nicko > Administration" check: "Nicko > Admin... > Check" - confirm: "... > Invalidate > Confirm" + confirm: "... > Confirm action" cache: "Nicko > Admin... > Cache" invalidate_skin: "... > Cache > Invalidate" @@ -101,6 +103,8 @@ gui: - "§cNicked: §a{1}" - "§cName: §6{2}" - "§cSkin: §6{3}" + - " " + - "§7§oClick to remove skin!" cache: statistics: name: "Statistics" diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index f154e54..02783c6 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -26,6 +26,8 @@ event: cache: invalidate_cache: "§fCache complet invalidé." invalidate_entry: "§6{0} §fa été invalidé." + check: + remove_skin: "§fSkin retiré du joueur." gui: title: @@ -33,7 +35,7 @@ gui: settings: "Nicko > Paramètres" admin: "Nicko > Administration" check: "Nicko > Admin... > Vérification" - confirm: "... > Invalider > Confirmer" + confirm: "... > Confirmer l'action" cache: "Nicko > Admin... > Cache" invalidate_skin: "... > Cache > Invalider" @@ -96,6 +98,8 @@ gui: - "§cDéguisé: §a{1}" - "§cNom: §6{2}" - "§cSkin: §6{3}" + - " " + - "§7§oCliquez pour retirer le skin!" cache: statistics: name: "Statistiques" From d0488bae84d307ea4526da03df59ed03fcc94637 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 7 Dec 2023 19:08:13 +0100 Subject: [PATCH 147/296] fix(i18n): colors --- .../nicko/gui/items/admin/check/PlayerInformationItem.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java index a3abfa6..b0bcba0 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java @@ -49,7 +49,7 @@ public class PlayerInformationItem extends AsyncItem { } return ItemDefaults.getErrorSkullItem(i18n, I18NDict.GUI.Admin.CHECK, - "§c§l?!?", "§cN/A", "§cN/A", "§cN/A" + "§c§l?!?", "§7N/A", "§7N/A", "§7N/A" ); }); this.target = target; From 8a53b2f188ca80e512f9af5e8eee4a37bf814d6e Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 9 Dec 2023 14:49:17 +0100 Subject: [PATCH 148/296] feat(check gui): dynamic gui --- .../nicko/event/PlayerJoinListener.java | 17 +++++++++++++ .../nicko/event/PlayerQuitListener.java | 25 +++++++++++++++++++ .../xyz/ineanto/nicko/gui/PlayerCheckGUI.java | 15 ++++++++--- .../ineanto/nicko/gui/PlayerCheckGUIData.java | 8 ++++++ .../gui/items/admin/ManagePlayerItem.java | 3 ++- .../admin/check/PlayerInformationItem.java | 3 ++- 6 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUIData.java diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java index d905a9b..a0baed4 100644 --- a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java @@ -9,13 +9,19 @@ import org.bukkit.event.player.PlayerJoinEvent; import xyz.ineanto.nicko.NickoBukkit; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.appearance.AppearanceManager; +import xyz.ineanto.nicko.gui.PlayerCheckGUI; +import xyz.ineanto.nicko.gui.PlayerCheckGUIData; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.PlayerDataStore; import xyz.ineanto.nicko.storage.name.PlayerNameStore; +import xyz.xenondevs.invui.window.Window; +import xyz.xenondevs.invui.window.WindowManager; +import java.util.ArrayList; import java.util.Optional; +import java.util.UUID; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -61,5 +67,16 @@ public class PlayerJoinListener implements Listener { }); } }, 20L); + + @SuppressWarnings("unchecked") final ArrayList viewers = (ArrayList) PlayerCheckGUIData.VIEWERS.clone(); + viewers.forEach(uuid -> { + final Player windowWatcher = Bukkit.getPlayer(uuid); + final Window openWindow = WindowManager.getInstance().getOpenWindow(windowWatcher); + if (openWindow != null) { + final PlayerCheckGUI gui = new PlayerCheckGUI(windowWatcher, Bukkit.getOnlinePlayers()); + openWindow.close(); + gui.open(); + } + }); } } diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java index c0c232f..25ccb49 100644 --- a/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java @@ -1,11 +1,21 @@ package xyz.ineanto.nicko.event; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; import xyz.ineanto.nicko.NickoBukkit; import xyz.ineanto.nicko.appearance.ActionResult; +import xyz.ineanto.nicko.gui.PlayerCheckGUI; +import xyz.ineanto.nicko.gui.PlayerCheckGUIData; +import xyz.xenondevs.invui.window.Window; +import xyz.xenondevs.invui.window.WindowManager; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; public class PlayerQuitListener implements Listener { @EventHandler @@ -15,5 +25,20 @@ public class PlayerQuitListener implements Listener { if (result.isError()) { NickoBukkit.getInstance().getLogger().warning("Failed to save data for " + player.getName()); } + + // This is a dirty way to do it but could be worse tbh + @SuppressWarnings("unchecked") final ArrayList viewers = (ArrayList) PlayerCheckGUIData.VIEWERS.clone(); + viewers.forEach(uuid -> { + final Player windowWatcher = Bukkit.getPlayer(uuid); + final Window openWindow = WindowManager.getInstance().getOpenWindow(windowWatcher); + if (openWindow != null) { + final List playersWithoutOffline = Bukkit.getOnlinePlayers() + .stream() + .filter(online -> online.getUniqueId() != player.getUniqueId()).collect(Collectors.toList()); + final PlayerCheckGUI gui = new PlayerCheckGUI(windowWatcher, playersWithoutOffline); + openWindow.close(); + gui.open(); + } + }); } } diff --git a/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java b/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java index f59616d..c6dbe1d 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java @@ -15,7 +15,9 @@ import xyz.xenondevs.invui.gui.structure.Markers; import xyz.xenondevs.invui.item.Item; import xyz.xenondevs.invui.window.Window; +import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; public class PlayerCheckGUI { @@ -23,13 +25,15 @@ public class PlayerCheckGUI { private final Gui gui; private final String title; - public PlayerCheckGUI(Player player) { + public PlayerCheckGUI(Player player, Collection players) { final I18N i18n = new I18N(player); this.title = i18n.translatePrefixless(I18NDict.GUI.Titles.CHECK); - final List items = Bukkit.getOnlinePlayers().stream() + final List items = players.stream() .map(Entity::getUniqueId) - .map(uuid -> new PlayerInformationItem(i18n, Bukkit.getPlayer(uuid))) + .map(Bukkit::getPlayer) + .filter(Objects::nonNull) + .map(mappedPlayer -> new PlayerInformationItem(i18n, mappedPlayer)) .collect(Collectors.toList()); final AdminGUI parent = new AdminGUI(player); @@ -56,6 +60,9 @@ public class PlayerCheckGUI { } public void open() { - Window.single().setGui(gui).setTitle(title).open(player); + final Window.Builder.Normal.Single window = Window.single().setGui(gui).setTitle(title); + window.addOpenHandler(() -> PlayerCheckGUIData.VIEWERS.add(player.getUniqueId())); + window.addCloseHandler(() -> PlayerCheckGUIData.VIEWERS.remove(player.getUniqueId())); + window.open(player); } } diff --git a/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUIData.java b/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUIData.java new file mode 100644 index 0000000..e238a93 --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUIData.java @@ -0,0 +1,8 @@ +package xyz.ineanto.nicko.gui; + +import java.util.ArrayList; +import java.util.UUID; + +public class PlayerCheckGUIData { + public static final ArrayList VIEWERS = new ArrayList<>(); +} diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManagePlayerItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManagePlayerItem.java index ffe3732..adde45b 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManagePlayerItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManagePlayerItem.java @@ -1,5 +1,6 @@ package xyz.ineanto.nicko.gui.items.admin; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; import xyz.ineanto.nicko.gui.PlayerCheckGUI; @@ -22,7 +23,7 @@ public class ManagePlayerItem { final ItemBuilder builder = new ItemBuilder(Material.WRITABLE_BOOK); return i18n.translateItem(builder, I18NDict.GUI.Admin.MANAGE_PLAYER); }, click -> { - new PlayerCheckGUI(player).open(); + new PlayerCheckGUI(player, Bukkit.getOnlinePlayers()).open(); return true; }); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java index b0bcba0..8055016 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java @@ -1,5 +1,6 @@ package xyz.ineanto.nicko.gui.items.admin.check; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; @@ -72,7 +73,7 @@ public class PlayerInformationItem extends AsyncItem { @Override public void onCancel() { - new PlayerCheckGUI(player).open(); + new PlayerCheckGUI(player, Bukkit.getOnlinePlayers()).open(); } }).open(); } From 264d0745ba886dbcaba06b3e0fb60273934598ad Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 11 Dec 2023 12:00:33 +0100 Subject: [PATCH 149/296] feat(build): move to gradle for performances reasons --- .gitignore | 60 ++--- .idea/.gitignore | 8 + .idea/gradle.xml | 17 ++ .idea/inspectionProfiles/Project_Default.xml | 7 + .idea/misc.xml | 11 + .idea/uiDesigner.xml | 124 ++++++++++ build.gradle.kts | 117 +++++++++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 60756 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 234 ++++++++++++++++++ gradlew.bat | 89 +++++++ pom.xml | 218 ---------------- settings.gradle.kts | 2 + src/main/resources/plugin.yml | 2 +- .../nicko/test/NickoPluginTest.java | 2 +- .../nicko/test/config/ConfigurationTest.java | 2 +- .../nicko/test/i18n/ItemTranslationTest.java | 2 +- .../nicko/test/i18n/TranslationTest.java | 2 +- .../nicko/test/storage/BrokenSQLTest.java | 2 +- .../nicko/test/storage/SQLStorageTest.java | 2 +- .../nicko/test/storage/map/MapCacheTest.java | 2 +- .../test/storage/redis/RedisCacheTest.java | 2 +- 22 files changed, 647 insertions(+), 264 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/gradle.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/uiDesigner.xml create mode 100644 build.gradle.kts create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat delete mode 100644 pom.xml create mode 100644 settings.gradle.kts rename src/test/java/xyz/{atnrch => ineanto}/nicko/test/NickoPluginTest.java (96%) rename src/test/java/xyz/{atnrch => ineanto}/nicko/test/config/ConfigurationTest.java (96%) rename src/test/java/xyz/{atnrch => ineanto}/nicko/test/i18n/ItemTranslationTest.java (98%) rename src/test/java/xyz/{atnrch => ineanto}/nicko/test/i18n/TranslationTest.java (97%) rename src/test/java/xyz/{atnrch => ineanto}/nicko/test/storage/BrokenSQLTest.java (98%) rename src/test/java/xyz/{atnrch => ineanto}/nicko/test/storage/SQLStorageTest.java (98%) rename src/test/java/xyz/{atnrch => ineanto}/nicko/test/storage/map/MapCacheTest.java (97%) rename src/test/java/xyz/{atnrch => ineanto}/nicko/test/storage/redis/RedisCacheTest.java (98%) diff --git a/.gitignore b/.gitignore index 2b2c724..a43a0f4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,40 +1,26 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ -# Compiled class file -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* -replay_pid* - -# Idea files +### IntelliJ IDEA ### +.idea/ +*.iws *.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ -# Idea Folder -.idea - -# Build folder -target - -# Maven Dependency Reduced Pom -dependency-reduced-pom.xml - -# Logs -logs/ \ No newline at end of file +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..d28243b --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..1632839 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..aff9edf --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..cdfc2df --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,117 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + +plugins { + id("io.github.goooler.shadow") version "8.1.2" + id("java") +} + +group = "xyz.ineanto" +version = "1.0.5-RC1" + +val shadowImplementation: Configuration by configurations.creating +configurations["implementation"].extendsFrom(shadowImplementation) +configurations["testImplementation"].extendsFrom(shadowImplementation) + +repositories { + mavenCentral() + mavenLocal() + maven { + name = "dmulloy2" + url = uri("https://repo.dmulloy2.net/repository/public/") + } + maven { + name = "xenondevs" + url = uri("https://repo.xenondevs.xyz/releases") + } + maven { + name = "papermc" + url = uri("https://repo.papermc.io/repository/maven-public/") + } + maven { + name = "codemc" + url = uri("https://repo.codemc.io/repository/maven-snapshots/") + } + maven { + name = "placeholderapi" + url = uri("https://repo.extendedclip.com/content/repositories/placeholderapi/") + } +} + +dependencies { + implementation("io.papermc.paper:paper-api:1.20.2-R0.1-SNAPSHOT") + implementation("me.clip:placeholderapi:2.11.4") + implementation("com.comphenix.protocol:ProtocolLib:5.1.1-SNAPSHOT") + + shadowImplementation("xyz.xenondevs.invui:invui:1.23") + shadowImplementation("net.wesjd:anvilgui:1.9.0-SNAPSHOT") + shadowImplementation("com.github.jsixface:yamlconfig:1.2") + shadowImplementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.2") + shadowImplementation("com.fasterxml.jackson.core:jackson-core:2.15.2") + shadowImplementation("com.mysql:mysql-connector-j:8.1.0") + shadowImplementation("org.mariadb.jdbc:mariadb-java-client:3.1.2") + shadowImplementation("redis.clients:jedis:4.4.3") + shadowImplementation("com.google.code.gson:gson:2.10.1") + + testImplementation("com.github.seeseemelk:MockBukkit-v1.20:3.58.0") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.1") + testImplementation("org.junit.jupiter:junit-jupiter-engine:5.10.1") + testImplementation("org.junit.jupiter:junit-jupiter:5.10.1") +} + +tasks.processResources { + from("src/main/resources") + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + filesMatching("plugin.yml") { + expand("version" to version) + } +} + +tasks { + named("shadowJar") { + mustRunAfter(test) + archiveBaseName.set("nicko") + archiveVersion.set(version.toString()) + archiveAppendix.set("") + archiveClassifier.set("") + + configurations = listOf(shadowImplementation) + + // EXCLUSIONS + dependencies { + exclude("io.papermc.paper:paper-api:.*") + exclude("me.clip:placeholderapi:.*") + exclude("com.comphenix.protocol:ProtocolLib:.*") + } + + // RELOCATIONS + relocate("xyz.xenondevs", "xyz.ineanto.nicko.libs.invui") + relocate("net.wesjd", "xyz.ineanto.nicko.libs.anvilgui") + relocate("com.github.jsixface", "xyz.ineanto.nicko.libs.yaml") + relocate("com.fasterxml.jackson.dataformat", "xyz.ineanto.nicko.libs.jackson.yaml") + relocate("com.fasterxml.jackson.core", "xyz.ineanto.nicko.libs.jackson.core") + relocate("com.mysql", "xyz.ineanto.nicko.libs.mysql") + relocate("org.mariadb.jdbc", "xyz.ineanto.nicko.libs.mariadb") + relocate("redis.clients", "xyz.ineanto.nicko.libs.redis") + relocate("org.apache.commons.pool2", "xyz.ineanto.nicko.libs.pool2") + relocate("com.google.code.gson", "xyz.ineanto.nicko.libs.gson") + + // MINIMIZING + minimize { + exclude(dependency("net.wesjd:.*")) + exclude(dependency("xyz.xenondevs.invui:.*")) + exclude("colors.bin") + exclude("org/**") + exclude("waffle/**") + exclude("google/**") + exclude("com/sun/**") + } + } +} + +tasks.named("jar").configure { + enabled = false +} + +tasks.test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..249e5832f090a2944b7473328c07c9755baa3196 GIT binary patch literal 60756 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 '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..ac1b06f --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 3ad828b..0000000 --- a/pom.xml +++ /dev/null @@ -1,218 +0,0 @@ - - - 4.0.0 - - xyz.ineanto - nicko - 1.0.4-RC1 - Nicko - - - 8 - 8 - UTF-8 - - - - - dmulloy2-repo - https://repo.dmulloy2.net/repository/public/ - - - xenondevs - https://repo.xenondevs.xyz/releases - - - papermc - https://repo.papermc.io/repository/maven-public/ - - - codemc-snapshots - https://repo.codemc.io/repository/maven-snapshots/ - - - placeholderapi - https://repo.extendedclip.com/content/repositories/placeholderapi/ - - - - - - - io.papermc.paper - paper-api - 1.20.2-R0.1-SNAPSHOT - provided - - - com.google.code.gson - gson - - - - - com.comphenix.protocol - ProtocolLib - 5.1.1-SNAPSHOT - provided - - - me.clip - placeholderapi - 2.11.4 - provided - - - xyz.xenondevs.invui - invui - 1.23 - pom - - - net.wesjd - anvilgui - 1.9.0-SNAPSHOT - - - com.github.seeseemelk - MockBukkit-v1.20 - 3.47.0 - test - - - - - com.google.code.gson - gson - 2.10.1 - - - org.mariadb.jdbc - mariadb-java-client - 3.1.2 - - - com.mysql - mysql-connector-j - 8.1.0 - - - - - com.github.jsixface - yamlconfig - 1.2 - - - - com.fasterxml.jackson.core - jackson-core - 2.15.2 - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - 2.15.2 - - - redis.clients - jedis - 4.4.3 - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.1.2 - - - org.apache.maven.plugins - maven-shade-plugin - 3.5.0 - - - package - - shade - - - - - net.wesjd:anvilgui - xyz.xenondevs.invui:* - com.github.jsixface:* - com.fasterxml.jackson.dataformat:* - com.fasterxml.jackson.core:* - org.mariadb.jdbc:* - com.mysql:* - redis.clients:* - org.apache.commons:commons-pool2 - com.google.code.gson:gson - - - - - net.wesjd.anvilgui - xyz.ineanto.nicko.libs.anvilgui - - - xyz.xenondevs - xyz.ineanto.nicko.libs.invui - - - com.github.jsixface - xyz.ineanto.nicko.libs.yaml - - - com.fasterxml.jackson.dataformat - xyz.ineanto.nicko.libs.jackson.yaml - - - com.fasterxml.jackson.core - xyz.ineanto.nicko.libs.jackson.core - - - org.mariadb.jdbc - xyz.ineanto.nicko.libs.mariadb - - - redis.clients - xyz.ineanto.nicko.libs.redis - - - org.apache.commons.pool2 - xyz.ineanto.nicko.libs.pool2 - - - com.google.code.gson - xyz.ineanto.nicko.libs.gson - - - com.mysql - xyz.ineanto.nicko.libs.mysql - - - - false - - - - - - - - true - ${basedir}/src/main/resources/ - - - - \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..4549581 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,2 @@ +rootProject.name = "nicko" + diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index e7c1639..27a3947 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: Nicko main: xyz.ineanto.nicko.NickoBukkit -version: ${project.version} +version: ${version} author: Ineanto description: "The feature packed, next generation disguise plugin for Minecraft." api-version: 1.14 diff --git a/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java b/src/test/java/xyz/ineanto/nicko/test/NickoPluginTest.java similarity index 96% rename from src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java rename to src/test/java/xyz/ineanto/nicko/test/NickoPluginTest.java index 94e508f..e500995 100644 --- a/src/test/java/xyz/atnrch/nicko/test/NickoPluginTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/NickoPluginTest.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.test; +package xyz.ineanto.nicko.test; import be.seeseemelk.mockbukkit.MockBukkit; import org.junit.jupiter.api.AfterAll; diff --git a/src/test/java/xyz/atnrch/nicko/test/config/ConfigurationTest.java b/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java similarity index 96% rename from src/test/java/xyz/atnrch/nicko/test/config/ConfigurationTest.java rename to src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java index b334534..3853c9f 100644 --- a/src/test/java/xyz/atnrch/nicko/test/config/ConfigurationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.test.config; +package xyz.ineanto.nicko.test.config; import be.seeseemelk.mockbukkit.MockBukkit; import org.junit.jupiter.api.AfterAll; diff --git a/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java b/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java similarity index 98% rename from src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java rename to src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java index acc5c1c..5f77ade 100644 --- a/src/test/java/xyz/atnrch/nicko/test/i18n/ItemTranslationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.test.i18n; +package xyz.ineanto.nicko.test.i18n; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.entity.PlayerMock; diff --git a/src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java b/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java similarity index 97% rename from src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java rename to src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java index dc4d7f4..59a8705 100644 --- a/src/test/java/xyz/atnrch/nicko/test/i18n/TranslationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.test.i18n; +package xyz.ineanto.nicko.test.i18n; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.entity.PlayerMock; diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/BrokenSQLTest.java similarity index 98% rename from src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java rename to src/test/java/xyz/ineanto/nicko/test/storage/BrokenSQLTest.java index da8b09a..7c23d27 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/BrokenSQLTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/storage/BrokenSQLTest.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.test.storage; +package xyz.ineanto.nicko.test.storage; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java similarity index 98% rename from src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java rename to src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java index 7539591..555e6d0 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.test.storage; +package xyz.ineanto.nicko.test.storage; import be.seeseemelk.mockbukkit.MockBukkit; import org.junit.jupiter.api.*; diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/map/MapCacheTest.java similarity index 97% rename from src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java rename to src/test/java/xyz/ineanto/nicko/test/storage/map/MapCacheTest.java index 3f972bb..9698f26 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/map/MapCacheTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/storage/map/MapCacheTest.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.test.storage.map; +package xyz.ineanto.nicko.test.storage.map; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/redis/RedisCacheTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/redis/RedisCacheTest.java similarity index 98% rename from src/test/java/xyz/atnrch/nicko/test/storage/redis/RedisCacheTest.java rename to src/test/java/xyz/ineanto/nicko/test/storage/redis/RedisCacheTest.java index fe49c52..c12eae0 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/redis/RedisCacheTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/storage/redis/RedisCacheTest.java @@ -1,4 +1,4 @@ -package xyz.atnrch.nicko.test.storage.redis; +package xyz.ineanto.nicko.test.storage.redis; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; From f306c3abaaea4b8fc0827922c771bb6acba0842e Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 11 Dec 2023 12:01:29 +0100 Subject: [PATCH 150/296] fix(readme): bug fixed --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 1fe8508..1779d78 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,6 @@ https://www.spigotmc.org/resources/nicko.113868/ ## Known bugs: -- Disguising will fully heal and feed players. - Players who have operator (OP) status lose access to the Operator Items tab in creative mode after disguising **(1.20 and up)**. - When disguising and only changing their display name, players will have the new default From e5ce8bde1abefb07381779232741436c593ee803 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 11 Dec 2023 12:31:16 +0100 Subject: [PATCH 151/296] fix(build): includes/excludes fix (1.0.5-RC1) --- build.gradle.kts | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index cdfc2df..b157f0f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -39,16 +39,16 @@ repositories { dependencies { implementation("io.papermc.paper:paper-api:1.20.2-R0.1-SNAPSHOT") - implementation("me.clip:placeholderapi:2.11.4") implementation("com.comphenix.protocol:ProtocolLib:5.1.1-SNAPSHOT") + shadowImplementation("me.clip:placeholderapi:2.11.4") shadowImplementation("xyz.xenondevs.invui:invui:1.23") shadowImplementation("net.wesjd:anvilgui:1.9.0-SNAPSHOT") shadowImplementation("com.github.jsixface:yamlconfig:1.2") shadowImplementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.2") shadowImplementation("com.fasterxml.jackson.core:jackson-core:2.15.2") shadowImplementation("com.mysql:mysql-connector-j:8.1.0") - shadowImplementation("org.mariadb.jdbc:mariadb-java-client:3.1.2") + shadowImplementation("org.mariadb.jdbc:mariadb-java-client:3.3.1") shadowImplementation("redis.clients:jedis:4.4.3") shadowImplementation("com.google.code.gson:gson:2.10.1") @@ -76,15 +76,9 @@ tasks { configurations = listOf(shadowImplementation) - // EXCLUSIONS - dependencies { - exclude("io.papermc.paper:paper-api:.*") - exclude("me.clip:placeholderapi:.*") - exclude("com.comphenix.protocol:ProtocolLib:.*") - } - // RELOCATIONS relocate("xyz.xenondevs", "xyz.ineanto.nicko.libs.invui") + relocate("me.clip", "xyz.ineanto.nicko.libs.placeholderapi") relocate("net.wesjd", "xyz.ineanto.nicko.libs.anvilgui") relocate("com.github.jsixface", "xyz.ineanto.nicko.libs.yaml") relocate("com.fasterxml.jackson.dataformat", "xyz.ineanto.nicko.libs.jackson.yaml") @@ -92,19 +86,24 @@ tasks { relocate("com.mysql", "xyz.ineanto.nicko.libs.mysql") relocate("org.mariadb.jdbc", "xyz.ineanto.nicko.libs.mariadb") relocate("redis.clients", "xyz.ineanto.nicko.libs.redis") + relocate("com.google.gson", "xyz.ineanto.nicko.libs.gson") relocate("org.apache.commons.pool2", "xyz.ineanto.nicko.libs.pool2") - relocate("com.google.code.gson", "xyz.ineanto.nicko.libs.gson") - // MINIMIZING - minimize { - exclude(dependency("net.wesjd:.*")) - exclude(dependency("xyz.xenondevs.invui:.*")) - exclude("colors.bin") - exclude("org/**") - exclude("waffle/**") - exclude("google/**") - exclude("com/sun/**") - } + exclude("colors.bin") + exclude("waffle/**") + exclude("com/sun/**") + exclude("com/google/protobuf/**") + exclude("com/google/errorprone/**") + exclude("org/apache/commons/logging/**") + exclude("org/bstats/**") + exclude("org/jetbrains/**") + exclude("org/intellij/**") + exclude("org/checkerframework/**") + exclude("org/json/**") + exclude("org/slf4j/**") + exclude("org/yaml/**") + exclude("google/protobuf/**") + exclude("net/kyori/**") } } From a3227dfb94234d271c15653ebd76cfafb1276365 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 11 Dec 2023 12:31:44 +0100 Subject: [PATCH 152/296] feat(build): minimize jar --- build.gradle.kts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index b157f0f..92a3043 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -69,13 +69,14 @@ tasks.processResources { tasks { named("shadowJar") { mustRunAfter(test) + configurations = listOf(shadowImplementation) + + // NAMING archiveBaseName.set("nicko") archiveVersion.set(version.toString()) archiveAppendix.set("") archiveClassifier.set("") - configurations = listOf(shadowImplementation) - // RELOCATIONS relocate("xyz.xenondevs", "xyz.ineanto.nicko.libs.invui") relocate("me.clip", "xyz.ineanto.nicko.libs.placeholderapi") @@ -89,6 +90,7 @@ tasks { relocate("com.google.gson", "xyz.ineanto.nicko.libs.gson") relocate("org.apache.commons.pool2", "xyz.ineanto.nicko.libs.pool2") + // EXCLUSIONS exclude("colors.bin") exclude("waffle/**") exclude("com/sun/**") @@ -104,6 +106,12 @@ tasks { exclude("org/yaml/**") exclude("google/protobuf/**") exclude("net/kyori/**") + + // MINIFY + minimize { + exclude(dependency("xyz.xenondevs.invui:.*")) + exclude(dependency("net.wesjd:.*")) + } } } From 9fc902aa757c23319fefd19cca3d966b55d020da Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 11 Dec 2023 13:02:32 +0100 Subject: [PATCH 153/296] feat(telemetry): add metrics --- build.gradle.kts | 3 ++- src/main/java/xyz/ineanto/nicko/NickoBukkit.java | 2 ++ .../xyz/ineanto/nicko/test/config/ConfigurationTest.java | 9 ++++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 92a3043..10df944 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -51,6 +51,7 @@ dependencies { shadowImplementation("org.mariadb.jdbc:mariadb-java-client:3.3.1") shadowImplementation("redis.clients:jedis:4.4.3") shadowImplementation("com.google.code.gson:gson:2.10.1") + shadowImplementation("org.bstats:bstats-bukkit:3.0.2") testImplementation("com.github.seeseemelk:MockBukkit-v1.20:3.58.0") testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.1") @@ -89,6 +90,7 @@ tasks { relocate("redis.clients", "xyz.ineanto.nicko.libs.redis") relocate("com.google.gson", "xyz.ineanto.nicko.libs.gson") relocate("org.apache.commons.pool2", "xyz.ineanto.nicko.libs.pool2") + relocate("org.bstats", "xyz.ineanto.nicko.libs.bstats") // EXCLUSIONS exclude("colors.bin") @@ -97,7 +99,6 @@ tasks { exclude("com/google/protobuf/**") exclude("com/google/errorprone/**") exclude("org/apache/commons/logging/**") - exclude("org/bstats/**") exclude("org/jetbrains/**") exclude("org/intellij/**") exclude("org/checkerframework/**") diff --git a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java index a2dd590..c8ed78e 100644 --- a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java +++ b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java @@ -1,6 +1,7 @@ package xyz.ineanto.nicko; import com.comphenix.protocol.utility.MinecraftVersion; +import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.command.PluginCommand; @@ -113,6 +114,7 @@ public class NickoBukkit extends JavaPlugin { getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this); getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this); + new Metrics(this, 20483); } getLogger().info("Nicko has been enabled."); diff --git a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java b/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java index 3853c9f..1b29a52 100644 --- a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java @@ -7,6 +7,8 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import xyz.ineanto.nicko.NickoBukkit; import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.config.DefaultDataSources; +import xyz.ineanto.nicko.config.SQLDataSourceConfiguration; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -16,7 +18,12 @@ public class ConfigurationTest { @BeforeAll public static void setup() { MockBukkit.mock(); - plugin = MockBukkit.load(NickoBukkit.class); + final Configuration config = new Configuration( + DefaultDataSources.SQL_EMPTY, + DefaultDataSources.REDIS_EMPTY, + "", + false); + plugin = MockBukkit.load(NickoBukkit.class, config); } @Test From e360d5c8a70b24c6cc5a3cc5d7b18913f741e729 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 11 Dec 2023 13:02:48 +0100 Subject: [PATCH 154/296] feat: bump version (1.0.6-RC1) --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 10df944..e64c35b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "xyz.ineanto" -version = "1.0.5-RC1" +version = "1.0.6-RC1" val shadowImplementation: Configuration by configurations.creating configurations["implementation"].extendsFrom(shadowImplementation) From 2447c086362f546c67df7c604aabd36d9efaa1ed Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 11 Dec 2023 13:09:17 +0100 Subject: [PATCH 155/296] refactor(i18n): remove array type declaration --- src/main/java/xyz/ineanto/nicko/i18n/I18N.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/xyz/ineanto/nicko/i18n/I18N.java b/src/main/java/xyz/ineanto/nicko/i18n/I18N.java index 28cc27a..166d04d 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/I18N.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/I18N.java @@ -51,7 +51,7 @@ public class I18N { if (name == null) { logger.warning(nameKey + " doesn't exists! Please translate this entry."); - return new ItemTranslation(nameKey, new ArrayList() {{ + return new ItemTranslation(nameKey, new ArrayList<>() {{ add(loreKey); }}); } From dd5aff034dafd25d33c2921993cb7c7714ad340b Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 11 Dec 2023 13:09:36 +0100 Subject: [PATCH 156/296] fix(i18n): remove deprecated entry --- src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java b/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java index 2bf7676..1090c62 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java @@ -9,8 +9,6 @@ public class I18NDict { 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"; } From 3949113dee415b52bf56a0bc093d02685154b39f Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 11 Dec 2023 13:21:30 +0100 Subject: [PATCH 157/296] fix(project): various optimizations --- .idea/misc.xml | 2 +- CHANGELOG.log | 4 ++++ build.gradle.kts | 6 ++++++ .../java/xyz/ineanto/nicko/anvil/AnvilManager.java | 3 ++- src/main/java/xyz/ineanto/nicko/i18n/I18N.java | 2 +- .../xyz/ineanto/nicko/i18n/LocaleFileManager.java | 14 +++----------- .../nicko/test/config/ConfigurationTest.java | 1 - 7 files changed, 17 insertions(+), 15 deletions(-) create mode 100644 CHANGELOG.log diff --git a/.idea/misc.xml b/.idea/misc.xml index aff9edf..3434f4e 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -5,7 +5,7 @@ +

- *

- * Packet changes history (not accurate) - *

* In 1.20.2, all the fields were replaced with a * single "CommonPlayerSpawnInfo" record object. - *

- * The dimension field was changed numerous times: - * - 1.8 through 1.17 (?) required an integer, - * - 1.18 need an instance of a Holder of a ResourceKey, - * - 1.19 and after dropped this requirement. - * N.b.: this field is a nightmare please mojang stop refactoring - * your code to change things that were working perfectly fine before - *

- * The Seed field was added in 1.15. - * The Difficulty field was removed in 1.14. */ public class WrapperPlayServerRespawn extends AbstractPacket { public static final PacketType TYPE = PacketType.Play.Server.RESPAWN; @@ -51,28 +35,10 @@ public class WrapperPlayServerRespawn extends AbstractPacket { public void setDimension(World value) { if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { // 1.20.2 - final InternalStructure dimensionType = commonPlayerSpawnInfoStructure.getStructures().read(0); - dimensionType.getMinecraftKeys().writeSafely(0, new MinecraftKey("minecraft", "dimension_type")); - dimensionType.getMinecraftKeys().writeSafely(1, new MinecraftKey("minecraft", "overworld")); - commonPlayerSpawnInfoStructure.getStructures().writeSafely(0, dimensionType); - commonPlayerSpawnInfoStructure.getWorldKeys().writeSafely(0, value); + writeDimensionToStructure(value, commonPlayerSpawnInfoStructure.getStructures(), commonPlayerSpawnInfoStructure.getWorldKeys()); } else if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { - // 1.19 to 1.20.1 - // Thank you lukalt! - final InternalStructure dimensionType = handle.getStructures().read(0); - dimensionType.getMinecraftKeys().writeSafely(0, new MinecraftKey("minecraft", "dimension_type")); - dimensionType.getMinecraftKeys().writeSafely(1, new MinecraftKey("minecraft", "overworld")); - handle.getStructures().writeSafely(0, dimensionType); - handle.getWorldKeys().writeSafely(0, value); - } else if (MinecraftVersion.CAVES_CLIFFS_2.atOrAbove()) { - // 1.18 - handle.getHolders( - MinecraftReflection.getDimensionManager(), - BukkitConverters.getDimensionConverter() - ).writeSafely(0, value); - } else { - // 1.17 and below (untested) - handle.getDimensions().writeSafely(0, value.getEnvironment().ordinal()); + // 1.19 to 1.20.1, props to lukalt for helping me figure this out. + writeDimensionToStructure(value, handle.getStructures(), handle.getWorldKeys()); } } @@ -81,7 +47,6 @@ public class WrapperPlayServerRespawn extends AbstractPacket { commonPlayerSpawnInfoStructure.getGameModes().writeSafely(0, EnumWrappers.NativeGameMode.fromBukkit(value)); return; } - handle.getGameModes().writeSafely(0, EnumWrappers.NativeGameMode.fromBukkit(value)); } @@ -103,14 +68,16 @@ public class WrapperPlayServerRespawn extends AbstractPacket { } public void setSeed(long value) { - if (MinecraftVersion.BEE_UPDATE.atOrAbove() && !MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { + if (MinecraftVersion.WILD_UPDATE.atOrAbove() && !MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { handle.getLongs().writeSafely(0, Hashing.sha256().hashLong(value).asLong()); } } - public void setDifficulty(Difficulty difficulty) { - if (difficulty != null && !MinecraftVersion.VILLAGE_UPDATE.atOrAbove()) { - handle.getDifficulties().writeSafely(0, EnumWrappers.Difficulty.valueOf(difficulty.name())); - } + private void writeDimensionToStructure(World value, StructureModifier structures, StructureModifier worldKeys) { + final InternalStructure dimensionType = structures.read(0); + dimensionType.getMinecraftKeys().writeSafely(0, new MinecraftKey("minecraft", "dimension_type")); + dimensionType.getMinecraftKeys().writeSafely(1, new MinecraftKey("minecraft", "overworld")); + structures.writeSafely(0, dimensionType); + worldKeys.writeSafely(0, value); } } diff --git a/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java b/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java index 5f77ade..6ee6905 100644 --- a/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java @@ -35,8 +35,8 @@ public class ItemTranslationTest { public void translateItemTranslationWithoutLore() { final I18N i18n = new I18N(Locale.FRENCH); final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.GO_BACK); - assertTrue(translation.getLore().isEmpty()); - assertEquals(translation.getName(), "Retour"); + assertTrue(translation.lore().isEmpty()); + assertEquals(translation.name(), "Retour"); } @Test @@ -44,10 +44,10 @@ public class ItemTranslationTest { public void translateItemLore() { final I18N i18n = new I18N(Locale.FRENCH); final ItemTranslation translation = i18n.fetchTranslation(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)); + assertFalse(translation.lore().isEmpty()); + assertEquals("§fNombre de requêtes: §b1", translation.lore().get(0)); + assertEquals("§fNb. de skin dans le cache: §b1", translation.lore().get(1)); + assertEquals("§8§oLe cache est vidé toutes les 24 heures.", translation.lore().get(2)); } @AfterAll diff --git a/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java b/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java index 59a8705..4f0c937 100644 --- a/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java @@ -1,7 +1,6 @@ package xyz.ineanto.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; @@ -16,8 +15,6 @@ import xyz.ineanto.nicko.i18n.Locale; import static org.junit.jupiter.api.Assertions.assertEquals; public class TranslationTest { - private static PlayerMock player; - @BeforeAll public static void setup() { final Configuration config = new Configuration( From b2b67b376374f5323a7f7ef7e69908c554ca8892 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 13 Dec 2023 16:12:36 +0100 Subject: [PATCH 159/296] fix(changelog): date --- CHANGELOG.log | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.log b/CHANGELOG.log index 5d39c7f..8896a27 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,4 +1,4 @@ -1.0.7-RC1: Update n°4 (11/12/23) +1.0.7-RC1: Update n°4 (13/12/23) [OTHER] • In line with my thinking that Minecraft servers should always be in one of the latest versions to give developers more freedom and less maintenance hassle, From 424f0df002740ec274f350a8af1f67ac0e1db458 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 13 Dec 2023 16:48:16 +0100 Subject: [PATCH 160/296] style(changelog): update changelog --- CHANGELOG.log | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.log b/CHANGELOG.log index 8896a27..25d6590 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,8 +1,5 @@ 1.0.7-RC1: Update n°4 (13/12/23) [OTHER] - • In line with my thinking that Minecraft servers should always be in one of the latest versions to give developers more freedom and less maintenance hassle, - Nicko will now only be supporting the previous major version and current major version. - This results in this version of Nicko now needing at minimum of JRE 17 and a server running 1.19. - If you can't upgrade, consider skipping the plugin altogether. I'm sorry. - • Various optimizations and improvements. \ No newline at end of file + • In line with my thinking that Minecraft servers should always be in one of the latest versions to give developers more freedom and less maintenance hassle, Nicko will now only be supporting the current major version and the one before it. This results in this version of Nicko now needing at minimum Java version 17 and a server running 1.19. If you can't upgrade, consider myself sorry. + • Various optimizations and improvements following the upgrade to Java 17. \ No newline at end of file From 4238e7b091d18771bcf4333616c9d84d2176d922 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 14 Dec 2023 00:45:48 +0100 Subject: [PATCH 161/296] fix(readme): update compatibility chart --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1779d78..6ff3cc5 100644 --- a/README.md +++ b/README.md @@ -35,5 +35,5 @@ Try installing [NoEncryption](https://www.spigotmc.org/resources/noencryption.10 |---------------|----------------------------------------------------------------------------| | 1.7 and lower | Unsupported | | 1.8 - 1.12.2 | Use [NickReloaded](https://www.spigotmc.org/resources/nickreloaded.46335/) | -| 1.13 | Unsupported | -| 1.14 and up | Use Nicko | +| 1.13 to 1.18 | Unsupported | +| 1.19 - 1.20 | Use Nicko | From c305f03df5d3ffe46b9e99ed62879eba8863c1e8 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 14 Dec 2023 00:52:38 +0100 Subject: [PATCH 162/296] fix(storage): redundant cache call --- src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java index 9ec0ed1..0ce0449 100644 --- a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java @@ -56,7 +56,6 @@ public class AnvilManager { return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); } else { profile.setName(snapshot.getText()); - dataStore.updateCache(player.getUniqueId(), profile); openSkinAnvil(); return Collections.singletonList(AnvilGUI.ResponseAction.close()); } From cb98fd2671022c859a762ce97300cf6505563996 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 14 Dec 2023 00:57:06 +0100 Subject: [PATCH 163/296] feat: up-to-date changelog (1.0.7-RC1) --- CHANGELOG.log | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.log b/CHANGELOG.log index 25d6590..c502cb2 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,5 +1,35 @@ -1.0.7-RC1: Update n°4 (13/12/23) +1.0.8-RC1: Update n°5 (XX/XX/XX) + [OTHER] + - Various optimizations and improvements. + +1.0.7-RC1: Update n°4 (13/12/23) + [OTHER] + - In line with my thinking that Minecraft servers should always be in one of the latest versions to give developers more freedom and less maintenance hassle, Nicko will now only be supporting the current major version and the one before it. This results in this version of Nicko now needing at minimum Java version 17 and a server running 1.19. If you can't upgrade, consider myself sorry. + - Various optimizations and improvements following the upgrade to Java 17. + +1.0.6-RC1: Update n°3 (11/12/23) + [OTHER] + - Added telemetry via bStats to gather useful informations about Nicko. This feature is optional and can be disabled inside the "bStats" folder found in plugins folder. Informations gathered are public record and can be found at: https://bstats.org/plugin/bukkit/Nicko/20483. + +1.0.5-RC1: Update n°2 (11/12/23) + [OTHER] + - Moved plugin to the Gradle build chain, resulting in faster builds and smaller Jar. This has no consequences for players. + +1.0.4-RC1: + [FEATURES] + - The players check GUI is now updated upon player's joining and leaving + - Administrators are now able to remove a player's disguise through the player check GUI + +1.0.3-RC1: Hotfix n°3 (07/12/23) + [FIXES] + - Fixed a visual bug where players in survival mode were seeing themselves as having full health and hunger after disguising. + +1.0.2-RC1: Hotfix n°2 (06/12/23) + [FIXES] + - Internal refactoring + +1.0.1-RC1: Hotfix n°1 (06/12/23) + [FIXES] + - Fixed an issue when joining and players being disguised were not for the player joining. + -[OTHER] - • In line with my thinking that Minecraft servers should always be in one of the latest versions to give developers more freedom and less maintenance hassle, Nicko will now only be supporting the current major version and the one before it. This results in this version of Nicko now needing at minimum Java version 17 and a server running 1.19. If you can't upgrade, consider myself sorry. - • Various optimizations and improvements following the upgrade to Java 17. \ No newline at end of file From 48ca85028b640a53536358df5bfd1d8ce67dac77 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 14 Dec 2023 01:35:18 +0100 Subject: [PATCH 164/296] feat(storage): fallback on local storage --- build.gradle.kts | 2 +- src/main/java/xyz/ineanto/nicko/NickoBukkit.java | 14 ++++++++++---- .../ineanto/nicko/storage/PlayerDataStore.java | 15 ++++++++++++--- .../ineanto/nicko/test/storage/BrokenSQLTest.java | 6 ++---- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 0ea5c9c..28f462b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "xyz.ineanto" -version = "1.0.7-RC1" +version = "1.0.8-RC1" val shadowImplementation: Configuration by configurations.creating configurations["implementation"].extendsFrom(shadowImplementation) diff --git a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java index 8c12497..8fc665f 100644 --- a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java +++ b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java @@ -16,6 +16,8 @@ import xyz.ineanto.nicko.i18n.LocaleFileManager; import xyz.ineanto.nicko.mojang.MojangAPI; import xyz.ineanto.nicko.placeholder.NickoExpansion; import xyz.ineanto.nicko.storage.PlayerDataStore; +import xyz.ineanto.nicko.storage.json.JSONStorage; +import xyz.ineanto.nicko.storage.map.MapCache; import xyz.ineanto.nicko.storage.name.PlayerNameStore; import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.item.builder.ItemBuilder; @@ -73,14 +75,18 @@ public class NickoBukkit extends JavaPlugin { getLogger().info("Loading persistence..."); if (!dataStore.getStorage().getProvider().init()) { - dataStore.getStorage().setError(true); - getLogger().severe("Failed to open persistence, data will NOT be saved!"); + getLogger().severe("Couldn't connect to distant persistence, falling back on local persistence."); + final JSONStorage storage = new JSONStorage(); + storage.getProvider().init(); + dataStore.setStorage(storage); } getLogger().info("Loading cache..."); if (!dataStore.getCache().getProvider().init()) { - dataStore.getCache().setError(true); - getLogger().severe("Failed to open cache, data will NOT be saved!"); + getLogger().severe("Couldn't connect to distant cache, falling back on local cache."); + final MapCache cache = new MapCache(); + cache.getProvider().init(); + dataStore.setCache(cache); } if (!unitTesting) { diff --git a/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java b/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java index 441f9a5..e3b444b 100644 --- a/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java +++ b/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java @@ -19,10 +19,11 @@ import java.util.UUID; import java.util.concurrent.ExecutionException; public class PlayerDataStore { - private final Storage storage; - private final Cache cache; private final MojangAPI mojangAPI; + private Storage storage; + private Cache cache; + public PlayerDataStore(MojangAPI mojangAPI, Configuration configuration) { this.mojangAPI = mojangAPI; this.storage = configuration.getSqlConfiguration().isEnabled() ? @@ -81,7 +82,7 @@ public class PlayerDataStore { if (!cache.isCached(player.getUniqueId())) return ActionResult.error(I18NDict.Error.CACHE); final Optional cachedProfile = cache.retrieve(player.getUniqueId()); - if (!cachedProfile.isPresent()) return ActionResult.error(I18NDict.Error.CACHE); + if (cachedProfile.isEmpty()) return ActionResult.error(I18NDict.Error.CACHE); cache.delete(player.getUniqueId()); return storage.store(player.getUniqueId(), cachedProfile.get()); @@ -91,7 +92,15 @@ public class PlayerDataStore { return storage; } + public void setStorage(Storage storage) { + this.storage = storage; + } + public Cache getCache() { return cache; } + + public void setCache(Cache cache) { + this.cache = cache; + } } diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/BrokenSQLTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/BrokenSQLTest.java index 7c23d27..986f419 100644 --- a/src/test/java/xyz/ineanto/nicko/test/storage/BrokenSQLTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/storage/BrokenSQLTest.java @@ -3,10 +3,7 @@ package xyz.ineanto.nicko.test.storage; 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; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.*; import xyz.ineanto.nicko.NickoBukkit; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.config.Configuration; @@ -19,6 +16,7 @@ import java.util.Optional; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +@Disabled public class BrokenSQLTest { private static NickoBukkit plugin; private static PlayerMock player; From 60fa1d46f9a5379ec3d94f23006889436dca80d1 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 14 Dec 2023 01:36:00 +0100 Subject: [PATCH 165/296] feat(changelog): update --- CHANGELOG.log | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.log b/CHANGELOG.log index c502cb2..e3d46ff 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,4 +1,7 @@ 1.0.8-RC1: Update n°5 (XX/XX/XX) + [FEATURES] + - Persistence and cache will now fallback to local alternatives when unreachable. + [OTHER] - Various optimizations and improvements. From a08744dee386868a1b93b2e36c34065006cbe742 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 18 Dec 2023 20:39:15 +0100 Subject: [PATCH 166/296] refactor(test): folders --- .../nicko/test/storage/BrokenSQLTest.java | 62 ------------------- .../test/storage/{map => }/MapCacheTest.java | 2 +- .../storage/{redis => }/RedisCacheTest.java | 2 +- 3 files changed, 2 insertions(+), 64 deletions(-) delete mode 100644 src/test/java/xyz/ineanto/nicko/test/storage/BrokenSQLTest.java rename src/test/java/xyz/ineanto/nicko/test/storage/{map => }/MapCacheTest.java (97%) rename src/test/java/xyz/ineanto/nicko/test/storage/{redis => }/RedisCacheTest.java (98%) diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/BrokenSQLTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/BrokenSQLTest.java deleted file mode 100644 index 986f419..0000000 --- a/src/test/java/xyz/ineanto/nicko/test/storage/BrokenSQLTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package xyz.ineanto.nicko.test.storage; - -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.entity.PlayerMock; -import org.junit.jupiter.api.*; -import xyz.ineanto.nicko.NickoBukkit; -import xyz.ineanto.nicko.appearance.ActionResult; -import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.config.DefaultDataSources; -import xyz.ineanto.nicko.config.SQLDataSourceConfiguration; -import xyz.ineanto.nicko.profile.NickoProfile; - -import java.util.Optional; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -@Disabled -public class BrokenSQLTest { - private static NickoBukkit plugin; - private static PlayerMock player; - - @BeforeAll - public static void setup() { - final Configuration config = new Configuration( - new SQLDataSourceConfiguration(true, "127.0.0.1", 3306, "root", "", true), - DefaultDataSources.REDIS_EMPTY, - "", - false); - final ServerMock server = MockBukkit.mock(); - plugin = MockBukkit.load(NickoBukkit.class, config); - player = server.addPlayer(); - } - - @Test - @DisplayName("Fail to create Tables") - public void createSQLTables() { - assertTrue(plugin.getDataStore().getStorage().isError()); - } - - @Test - @DisplayName("Fail to Store Player Via SQL") - public void storePlayer() { - final Optional optionalProfile = plugin.getDataStore().getData(player.getUniqueId()); - assertFalse(optionalProfile.isPresent()); - ActionResult result = plugin.getDataStore().saveData(player); - assertTrue(result.isError()); - } - - @Test - @DisplayName("Fail to Retrieve Player Via SQL") - public void retrievePlayer() { - final Optional storeAction = plugin.getDataStore().getData(player.getUniqueId()); - assertFalse(storeAction.isPresent()); - } - - @AfterAll - public static void shutdown() { - MockBukkit.unmock(); - } -} \ No newline at end of file diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/map/MapCacheTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/MapCacheTest.java similarity index 97% rename from src/test/java/xyz/ineanto/nicko/test/storage/map/MapCacheTest.java rename to src/test/java/xyz/ineanto/nicko/test/storage/MapCacheTest.java index 9698f26..f940ad9 100644 --- a/src/test/java/xyz/ineanto/nicko/test/storage/map/MapCacheTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/storage/MapCacheTest.java @@ -1,4 +1,4 @@ -package xyz.ineanto.nicko.test.storage.map; +package xyz.ineanto.nicko.test.storage; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/redis/RedisCacheTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java similarity index 98% rename from src/test/java/xyz/ineanto/nicko/test/storage/redis/RedisCacheTest.java rename to src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java index c12eae0..d2f79e3 100644 --- a/src/test/java/xyz/ineanto/nicko/test/storage/redis/RedisCacheTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java @@ -1,4 +1,4 @@ -package xyz.ineanto.nicko.test.storage.redis; +package xyz.ineanto.nicko.test.storage; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; From 2b71bd18eb9d52e360b186146cf8c4b2e9c13bed Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 18 Dec 2023 21:11:16 +0100 Subject: [PATCH 167/296] refactor(i18n): simplify --- CHANGELOG.log | 3 ++- src/main/java/xyz/ineanto/nicko/i18n/I18N.java | 2 +- src/main/java/xyz/ineanto/nicko/i18n/Locale.java | 2 -- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.log b/CHANGELOG.log index e3d46ff..a192561 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -4,6 +4,7 @@ [OTHER] - Various optimizations and improvements. + - Internal refactoring 1.0.7-RC1: Update n°4 (13/12/23) [OTHER] @@ -28,7 +29,7 @@ - Fixed a visual bug where players in survival mode were seeing themselves as having full health and hunger after disguising. 1.0.2-RC1: Hotfix n°2 (06/12/23) - [FIXES] + [OTHER] - Internal refactoring 1.0.1-RC1: Hotfix n°1 (06/12/23) diff --git a/src/main/java/xyz/ineanto/nicko/i18n/I18N.java b/src/main/java/xyz/ineanto/nicko/i18n/I18N.java index 18b0b46..bce6c32 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/I18N.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/I18N.java @@ -139,7 +139,7 @@ public class I18N { if (optionalProfile.isPresent()) { return optionalProfile.get().getLocale(); } else { - return Locale.FALLBACK_LOCALE; + return Locale.ENGLISH; } } } diff --git a/src/main/java/xyz/ineanto/nicko/i18n/Locale.java b/src/main/java/xyz/ineanto/nicko/i18n/Locale.java index 8821142..3d8bd58 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/Locale.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/Locale.java @@ -7,8 +7,6 @@ public enum Locale implements Serializable { FRENCH("fr", "Français"), CUSTOM("cm", "Server Custom"); - public static final Locale FALLBACK_LOCALE = ENGLISH; - private final String code; private transient final String name; From e9d6f339308a9aabcdc2303dde4db005d174d7d7 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 19 Dec 2023 14:31:15 +0100 Subject: [PATCH 168/296] feat(i18n): version checking --- .gitignore | 5 +- CHANGELOG.log | 1 + build.gradle.kts | 34 +++++++++----- .../java/xyz/ineanto/nicko/NickoBukkit.java | 4 +- .../xyz/ineanto/nicko/anvil/AnvilManager.java | 17 ++++--- .../nicko/event/PlayerJoinListener.java | 3 +- .../event/custom/PlayerDisguiseEvent.java | 47 +++++++++++++++++++ .../java/xyz/ineanto/nicko/i18n/I18N.java | 2 +- .../nicko/storage/redis/RedisCache.java | 10 ++++ .../xyz/ineanto/nicko/version/Version.java | 16 +++++++ src/main/resources/config.yml | 6 ++- src/main/resources/en.yml | 2 + src/main/resources/fr.yml | 2 + 13 files changed, 125 insertions(+), 24 deletions(-) create mode 100644 src/main/java/xyz/ineanto/nicko/event/custom/PlayerDisguiseEvent.java create mode 100644 src/main/java/xyz/ineanto/nicko/version/Version.java diff --git a/.gitignore b/.gitignore index a43a0f4..8a238de 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,7 @@ out/ .sts4-cache bin/ !**/src/main/**/bin/ -!**/src/test/**/bin/ \ No newline at end of file +!**/src/test/**/bin/ + +### Server ### +run/ \ No newline at end of file diff --git a/CHANGELOG.log b/CHANGELOG.log index a192561..9a1c2a5 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,6 +1,7 @@ 1.0.8-RC1: Update n°5 (XX/XX/XX) [FEATURES] - Persistence and cache will now fallback to local alternatives when unreachable. + - Developers can now listen to the PlayerDisguiseEvent and cancel the disguise process. [OTHER] - Various optimizations and improvements. diff --git a/build.gradle.kts b/build.gradle.kts index 28f462b..2fda361 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,8 +1,7 @@ -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar - plugins { - id("io.github.goooler.shadow") version "8.1.2" id("java") + id("io.github.goooler.shadow") version "8.1.2" + id("xyz.jpenilla.run-paper") version "2.2.2" } group = "xyz.ineanto" @@ -67,16 +66,16 @@ dependencies { testImplementation("org.junit.jupiter:junit-jupiter:5.10.1") } -tasks.processResources { - from("src/main/resources") - duplicatesStrategy = DuplicatesStrategy.EXCLUDE - filesMatching("plugin.yml") { - expand("version" to version) - } -} - tasks { - named("shadowJar") { + processResources { + from("src/main/resources") + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + filesMatching("plugin.yml") { + expand("version" to version) + } + } + + shadowJar { mustRunAfter(test) configurations = listOf(shadowImplementation) @@ -122,6 +121,17 @@ tasks { exclude(dependency("net.wesjd:.*")) } } + + runServer { + downloadPlugins { + url("https://download.luckperms.net/1526/bukkit/loader/LuckPerms-Bukkit-5.4.113.jar") + url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar") + } + // Configure the Minecraft version for our task. + // This is the only required configuration besides applying the plugin. + // Your plugin's jar (or shadowJar if present) will be used automatically. + minecraftVersion("1.20.2") + } } tasks.named("jar").configure { diff --git a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java index 8fc665f..94507d5 100644 --- a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java +++ b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java @@ -36,6 +36,7 @@ public class NickoBukkit extends JavaPlugin { private Configuration configuration; private LocaleFileManager localeFileManager; private PlayerNameStore nameStore; + private Metrics metrics; public NickoBukkit() { this.unitTesting = false; @@ -120,7 +121,7 @@ public class NickoBukkit extends JavaPlugin { getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this); getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this); - new Metrics(this, 20483); + metrics = new Metrics(this, 20483); } getLogger().info("Nicko has been enabled."); @@ -138,6 +139,7 @@ public class NickoBukkit extends JavaPlugin { } } + if(!unitTesting) metrics.shutdown(); getLogger().info("Nicko (Bukkit) has been disabled."); } diff --git a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java index 0ce0449..4dd47ce 100644 --- a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java @@ -2,6 +2,7 @@ package xyz.ineanto.nicko.anvil; import net.kyori.adventure.text.Component; import net.wesjd.anvilgui.AnvilGUI; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -9,6 +10,7 @@ import org.bukkit.inventory.meta.ItemMeta; import xyz.ineanto.nicko.NickoBukkit; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.appearance.AppearanceManager; +import xyz.ineanto.nicko.event.custom.PlayerDisguiseEvent; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; import xyz.ineanto.nicko.mojang.MojangUtils; @@ -77,8 +79,7 @@ public class AnvilManager { } else { profile.setName(snapshot.getText()); dataStore.updateCache(player.getUniqueId(), profile); - final ActionResult actionResult = appearanceManager.updatePlayer(false, false); - return sendResultAndClose(actionResult); + return sendResultAndClose(false); } } return Collections.emptyList(); @@ -98,8 +99,7 @@ public class AnvilManager { } else { profile.setSkin(snapshot.getText()); dataStore.updateCache(player.getUniqueId(), profile); - final ActionResult actionResult = appearanceManager.updatePlayer(true, false); - return sendResultAndClose(actionResult); + return sendResultAndClose(true); } } return Collections.emptyList(); @@ -107,8 +107,13 @@ public class AnvilManager { .text("New skin..."); } - private List sendResultAndClose(ActionResult actionResult) { + private List sendResultAndClose(boolean skinChange) { + final PlayerDisguiseEvent event = new PlayerDisguiseEvent(player, profile.getSkin(), player.getName()); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) { return Collections.singletonList(AnvilGUI.ResponseAction.close()); } + final I18N i18n = new I18N(player); + final ActionResult actionResult = appearanceManager.updatePlayer(skinChange, false); if (!actionResult.isError()) { player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.OK)); } else { @@ -120,7 +125,7 @@ public class AnvilManager { private ItemStack getLeftItem(boolean skin) { final ItemStack item = new ItemStack(Material.PAPER); final ItemMeta meta = item.getItemMeta(); - if (meta != null) meta.displayName(Component.text("§0New " + (skin ? "skin" : "name") + "...")); + if (meta != null) meta.displayName(Component.text("New " + (skin ? "skin" : "name") + "...")); item.setItemMeta(meta); return item; } diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java index 133ee1b..31a7d6b 100644 --- a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java @@ -23,7 +23,6 @@ import java.util.ArrayList; import java.util.Optional; import java.util.UUID; import java.util.logging.Logger; -import java.util.stream.Collectors; public class PlayerJoinListener implements Listener { private final Logger logger = Logger.getLogger("PlayerJoinListener"); @@ -53,7 +52,7 @@ public class PlayerJoinListener implements Listener { } }); - for (Player online : Bukkit.getOnlinePlayers().stream().filter(op -> op.getUniqueId() != player.getUniqueId()).collect(Collectors.toList())) { + for (Player online : Bukkit.getOnlinePlayers().stream().filter(op -> op.getUniqueId() != player.getUniqueId()).toList()) { final Optional optionalOnlinePlayerProfile = dataStore.getData(online.getUniqueId()); optionalOnlinePlayerProfile.ifPresent(profile -> { diff --git a/src/main/java/xyz/ineanto/nicko/event/custom/PlayerDisguiseEvent.java b/src/main/java/xyz/ineanto/nicko/event/custom/PlayerDisguiseEvent.java new file mode 100644 index 0000000..e7c3776 --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/event/custom/PlayerDisguiseEvent.java @@ -0,0 +1,47 @@ +package xyz.ineanto.nicko.event.custom; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +public class PlayerDisguiseEvent extends Event implements Cancellable { + private static final HandlerList HANDLERS_LIST = new HandlerList(); + private boolean isCancelled; + private final Player player; + private final String skin, name; + + public PlayerDisguiseEvent(Player player, String skin, String name) { + this.player = player; + this.skin = skin; + this.name = name; + } + + @Override + public boolean isCancelled() { + return isCancelled; + } + + @Override + public void setCancelled(boolean isCancelled) { + this.isCancelled = isCancelled; + } + + @Override + public @NotNull HandlerList getHandlers() { + return HANDLERS_LIST; + } + + public Player getPlayer() { + return player; + } + + public String getSkin() { + return skin; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/xyz/ineanto/nicko/i18n/I18N.java b/src/main/java/xyz/ineanto/nicko/i18n/I18N.java index bce6c32..9f512a4 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/I18N.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/I18N.java @@ -50,7 +50,7 @@ public class I18N { final ArrayList lore = readList(loreKey); if (name == null) { - logger.warning(nameKey + " doesn't exists! Please translate this entry."); + logger.warning(nameKey + " doesn't exists! Is your language file outdated?"); return new ItemTranslation(nameKey, new ArrayList<>() {{ add(loreKey); }}); diff --git a/src/main/java/xyz/ineanto/nicko/storage/redis/RedisCache.java b/src/main/java/xyz/ineanto/nicko/storage/redis/RedisCache.java index 77fe270..a3c0525 100644 --- a/src/main/java/xyz/ineanto/nicko/storage/redis/RedisCache.java +++ b/src/main/java/xyz/ineanto/nicko/storage/redis/RedisCache.java @@ -3,8 +3,10 @@ package xyz.ineanto.nicko.storage.redis; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import redis.clients.jedis.Jedis; +import redis.clients.jedis.exceptions.JedisException; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.i18n.I18NDict; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.Cache; import xyz.ineanto.nicko.storage.CacheProvider; @@ -37,6 +39,8 @@ public class RedisCache extends Cache { try (Jedis jedis = provider.getJedis()) { jedis.set("nicko:" + uuid.toString(), gson.toJson(profile)); return ActionResult.ok(); + } catch (JedisException exception) { + return ActionResult.error(I18NDict.Error.CACHE); } } @@ -44,6 +48,8 @@ public class RedisCache extends Cache { public boolean isCached(UUID uuid) { try (Jedis jedis = provider.getJedis()) { return jedis.exists("nicko:" + uuid.toString()); + } catch (JedisException exception) { + return false; } } @@ -55,6 +61,8 @@ public class RedisCache extends Cache { final String data = jedis.get("nicko:" + uuid.toString()); final NickoProfile profile = gson.fromJson(data, NickoProfile.class); return Optional.of(profile); + } catch (JedisException exception) { + return Optional.empty(); } } @@ -63,6 +71,8 @@ public class RedisCache extends Cache { try (Jedis jedis = provider.getJedis()) { jedis.del("nicko:" + uuid.toString()); return ActionResult.ok(); + } catch (JedisException exception) { + return ActionResult.error(I18NDict.Error.CACHE); } } } diff --git a/src/main/java/xyz/ineanto/nicko/version/Version.java b/src/main/java/xyz/ineanto/nicko/version/Version.java new file mode 100644 index 0000000..fe660cf --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/version/Version.java @@ -0,0 +1,16 @@ +package xyz.ineanto.nicko.version; + +import org.jetbrains.annotations.NotNull; + +import java.util.Comparator; + +public record Version(int major, int minor, int patch) implements Comparable { + @Override + public int compareTo(@NotNull Version otherVersion) { + final Comparator comparator = Comparator + .comparingInt(Version::major) + .thenComparingInt(Version::minor) + .thenComparingInt(Version::patch); + return comparator.compare(this, otherVersion); + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 9b854cd..ce98b0f 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,5 +1,9 @@ # Nicko ${project.version} - Config: +# Don't modify this. +# No, like... really. +version: "1.0.8" + ############ # LANGUAGE # ############ @@ -49,7 +53,7 @@ redis: # Accepted values: false (Disabled), true (Enabled) enabled: false # Redis server's address - # Accepted values: valid IP address (e.g. localhost, 127.0.0.1) + # Accepted values: valid IP address (e.g.: localhost, 127.0.0.1) address: "localhost" # Redis server's port # Accepted values: valid integer (e.g. 3306, 25565) diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 84e6d82..6216055 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -1,3 +1,5 @@ +version: "1.0.8" + error: generic: "An unknown error occurred." permission: "§cYou do not have the required permission." diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 02783c6..79e70a2 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -1,3 +1,5 @@ +version: "1.0.8" + error: generic: "Une erreur inconnue c'est produite." permission: "§cVous ne possédez pas la permission." From 29e50966fd1c9802293d1d3a1b941d6e9ff62149 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 19 Dec 2023 14:45:18 +0100 Subject: [PATCH 169/296] refactor: delete version --- .../java/xyz/ineanto/nicko/version/Version.java | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 src/main/java/xyz/ineanto/nicko/version/Version.java diff --git a/src/main/java/xyz/ineanto/nicko/version/Version.java b/src/main/java/xyz/ineanto/nicko/version/Version.java deleted file mode 100644 index fe660cf..0000000 --- a/src/main/java/xyz/ineanto/nicko/version/Version.java +++ /dev/null @@ -1,16 +0,0 @@ -package xyz.ineanto.nicko.version; - -import org.jetbrains.annotations.NotNull; - -import java.util.Comparator; - -public record Version(int major, int minor, int patch) implements Comparable { - @Override - public int compareTo(@NotNull Version otherVersion) { - final Comparator comparator = Comparator - .comparingInt(Version::major) - .thenComparingInt(Version::minor) - .thenComparingInt(Version::patch); - return comparator.compare(this, otherVersion); - } -} From a06435249237ae04439d0adf98b2cd8a0de00425 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 19 Dec 2023 19:57:08 +0100 Subject: [PATCH 170/296] feat: config version and improvements --- build.gradle.kts | 3 + .../java/xyz/ineanto/nicko/NickoBukkit.java | 24 ++++++- .../ineanto/nicko/config/Configuration.java | 35 ++++++--- .../nicko/config/ConfigurationManager.java | 17 +++++ .../admin/check/PlayerInformationItem.java | 14 +++- .../xyz/ineanto/nicko/version/Version.java | 33 +++++++++ src/main/resources/config.yml | 6 +- src/main/resources/en.yml | 2 - src/main/resources/fr.yml | 2 - .../ineanto/nicko/test/NickoPluginTest.java | 7 +- .../nicko/test/config/ConfigurationTest.java | 7 +- .../test/config/ConfigurationVersionTest.java | 72 +++++++++++++++++++ .../nicko/test/i18n/ItemTranslationTest.java | 7 +- .../nicko/test/i18n/TranslationTest.java | 7 +- .../nicko/test/storage/MapCacheTest.java | 13 ++-- .../nicko/test/storage/RedisCacheTest.java | 1 + .../nicko/test/storage/SQLStorageTest.java | 1 + 17 files changed, 198 insertions(+), 53 deletions(-) create mode 100644 src/main/java/xyz/ineanto/nicko/version/Version.java create mode 100644 src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java diff --git a/build.gradle.kts b/build.gradle.kts index 2fda361..97d8151 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -70,6 +70,9 @@ tasks { processResources { from("src/main/resources") duplicatesStrategy = DuplicatesStrategy.EXCLUDE + filesMatching("config.yml") { + expand("version" to version) + } filesMatching("plugin.yml") { expand("version" to version) } diff --git a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java index 94507d5..f73941c 100644 --- a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java +++ b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java @@ -24,6 +24,8 @@ import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SimpleItem; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; public class NickoBukkit extends JavaPlugin { private static NickoBukkit plugin; @@ -67,7 +69,6 @@ public class NickoBukkit extends JavaPlugin { getLogger().warning("Issues regarding Nicko being used in offline mode will be ignored for now."); } - if (!MinecraftVersion.WILD_UPDATE.atOrAbove()) { getLogger().severe("This version (" + MinecraftVersion.getCurrentVersion().getVersion() + ") is not supported by Nicko!"); dataStore.getStorage().setError(true); @@ -91,6 +92,20 @@ public class NickoBukkit extends JavaPlugin { } if (!unitTesting) { + // Migrate configuration (1.0.8-RC1) + if (configuration.getVersion() == null + || configuration.getVersion().isEmpty() + || configuration.getVersionObject().compareTo(Configuration.VERSION) != 0) { + getLogger().info("Migrating configuration file from older version..."); + try { + Files.copy(configurationManager.getFile().toPath(), configurationManager.getBackupFile().toPath(), StandardCopyOption.REPLACE_EXISTING); + Files.delete(configurationManager.getFile().toPath()); + configurationManager.saveDefaultConfig(); + } catch (IOException e) { + getLogger().severe("Failed to migrate your configuration!"); + } + } + try { Class.forName("io.papermc.paper.threadedregions.RegionizedServerInitEvent"); getLogger().warning("Nicko has not been tested against Folia and might not work at all!"); @@ -139,7 +154,7 @@ public class NickoBukkit extends JavaPlugin { } } - if(!unitTesting) metrics.shutdown(); + if (!unitTesting) metrics.shutdown(); getLogger().info("Nicko (Bukkit) has been disabled."); } @@ -149,7 +164,10 @@ public class NickoBukkit extends JavaPlugin { public Configuration getNickoConfig() { try { - if (configuration == null) { return configuration = configurationManager.load(); } + if (configuration == null) { + configuration = configurationManager.load(); + getLogger().info("Configuration file loaded."); + } return configuration; } catch (IOException e) { getLogger().severe("Failed to load the configuration file!"); diff --git a/src/main/java/xyz/ineanto/nicko/config/Configuration.java b/src/main/java/xyz/ineanto/nicko/config/Configuration.java index 048c6d2..a4958ad 100644 --- a/src/main/java/xyz/ineanto/nicko/config/Configuration.java +++ b/src/main/java/xyz/ineanto/nicko/config/Configuration.java @@ -1,29 +1,48 @@ package xyz.ineanto.nicko.config; import com.fasterxml.jackson.annotation.JsonProperty; +import xyz.ineanto.nicko.version.Version; public class Configuration { + public static final Version VERSION = new Version(1, 0, 8); + public static final Configuration DEFAULT = new Configuration(VERSION.toString(), + DefaultDataSources.SQL_EMPTY, + DefaultDataSources.REDIS_EMPTY, + "§6Nicko §8§l| §r", + false); + + private final transient Version versionObject; + + @JsonProperty("version") + private final String version; @JsonProperty("sql") private final SQLDataSourceConfiguration sqlConfiguration; @JsonProperty("redis") private final DataSourceConfiguration redisConfiguration; + @JsonProperty("prefix") private final String prefix; + @JsonProperty("customLocale") private final Boolean customLocale; - public Configuration(SQLDataSourceConfiguration sqlConfiguration, DataSourceConfiguration redisConfiguration, String prefix, Boolean customLocale) { + public Configuration(@JsonProperty("version") String version, + @JsonProperty("sql") SQLDataSourceConfiguration sqlConfiguration, + @JsonProperty("redis") DataSourceConfiguration redisConfiguration, + @JsonProperty("prefix") String prefix, + @JsonProperty("customLocale") Boolean customLocale) { + this.version = version; + this.versionObject = Version.fromString(version); this.sqlConfiguration = sqlConfiguration; this.redisConfiguration = redisConfiguration; this.prefix = prefix; this.customLocale = customLocale; } - public Configuration() { - this( - new SQLDataSourceConfiguration(false, "", 3306, "", "", true), - new DataSourceConfiguration(false, "", 6379, "", ""), - "", - false - ); + public String getVersion() { + return version; + } + + public Version getVersionObject() { + return versionObject; } public SQLDataSourceConfiguration getSqlConfiguration() { diff --git a/src/main/java/xyz/ineanto/nicko/config/ConfigurationManager.java b/src/main/java/xyz/ineanto/nicko/config/ConfigurationManager.java index 0824ee5..566d55e 100644 --- a/src/main/java/xyz/ineanto/nicko/config/ConfigurationManager.java +++ b/src/main/java/xyz/ineanto/nicko/config/ConfigurationManager.java @@ -7,16 +7,25 @@ import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import java.io.*; import java.nio.file.Files; import java.nio.file.StandardCopyOption; +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.logging.Logger; public class ConfigurationManager { private final Logger logger = Logger.getLogger("ConfigurationManager"); private final ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); private final File file; + private final File backupFile; public ConfigurationManager(File directory) { + final String date = Instant.now() + .atZone(ZoneId.systemDefault()) + .format(DateTimeFormatter.ofPattern("dd-MM-yyyy")); this.file = new File(directory, "config.yml"); + this.backupFile = new File(directory, "config.old-" + date + ".yml"); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true); } public void save(Configuration configuration) throws IOException { @@ -47,4 +56,12 @@ public class ConfigurationManager { return mapper.readValue(reader, Configuration.class); } } + + public File getFile() { + return file; + } + + public File getBackupFile() { + return backupFile; + } } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java index 8055016..1ba5b43 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java @@ -15,6 +15,7 @@ import xyz.ineanto.nicko.gui.items.common.choice.ChoiceCallback; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.xenondevs.invui.item.builder.AbstractItemBuilder; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.builder.SkullBuilder; import xyz.xenondevs.invui.item.impl.AsyncItem; @@ -27,6 +28,7 @@ import java.util.Optional; public class PlayerInformationItem extends AsyncItem { private final Player target; private final NickoProfile profile; + private final I18N i18n; public PlayerInformationItem(I18N i18n, Player target) { super(new SuppliedItem(() -> { @@ -39,11 +41,19 @@ public class PlayerInformationItem extends AsyncItem { if (optionalProfile.isPresent()) { final NickoProfile profile = optionalProfile.get(); - return i18n.translateItem(skull, I18NDict.GUI.Admin.CHECK, + final AbstractItemBuilder headItem = i18n.translateItem(skull, I18NDict.GUI.Admin.CHECK, target.getName(), (profile.hasData() ? "§a✔" : "§c❌"), (profile.getName() == null ? "§7N/A" : profile.getName()), (profile.getSkin() == null ? "§7N/A" : profile.getSkin())); + + if (!profile.hasData()) { + // Remove the last 2 lines of the lore. + headItem.removeLoreLine(headItem.getLore().size() - 1); + headItem.removeLoreLine(headItem.getLore().size() - 1); + } + + return headItem; } } catch (MojangApiUtils.MojangApiException | IOException e) { NickoBukkit.getInstance().getLogger().severe("Unable to get head for specified UUID ( " + target.getUniqueId() + ")! (GUI/PlayerCheck)"); @@ -53,6 +63,7 @@ public class PlayerInformationItem extends AsyncItem { "§c§l?!?", "§7N/A", "§7N/A", "§7N/A" ); }); + this.i18n = i18n; this.target = target; this.profile = NickoBukkit.getInstance().getDataStore().getData(target.getUniqueId()).orElse(NickoProfile.EMPTY_PROFILE); } @@ -67,7 +78,6 @@ public class PlayerInformationItem extends AsyncItem { public void onConfirm() { final AppearanceManager appearanceManager = new AppearanceManager(target); appearanceManager.reset(); - final I18N i18n = new I18N(player); player.sendMessage(i18n.translate(I18NDict.Event.Admin.Check.REMOVE_SKIN, target.getName())); } diff --git a/src/main/java/xyz/ineanto/nicko/version/Version.java b/src/main/java/xyz/ineanto/nicko/version/Version.java new file mode 100644 index 0000000..b3a7f1a --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/version/Version.java @@ -0,0 +1,33 @@ +package xyz.ineanto.nicko.version; + +import org.jetbrains.annotations.NotNull; + +import java.util.Comparator; + +public record Version(int major, int minor, int patch) implements Comparable { + @Override + public int compareTo(@NotNull Version otherVersion) { + final Comparator comparator = Comparator + .comparingInt(Version::major) + .thenComparingInt(Version::minor) + .thenComparingInt(Version::patch); + return comparator.compare(this, otherVersion); + } + + @Override + public String toString() { + return major + "." + minor + "." + patch; + } + + public static Version fromString(String versionString) { + if (versionString == null || versionString.isEmpty()) { return new Version(0, 0, 0); } + final String[] split = versionString.split("\\."); + try { + return new Version(Integer.parseInt(split[0]), + Integer.parseInt(split[1]), + Integer.parseInt(split[2])); + } catch (NumberFormatException exception) { + return new Version(0, 0, 0); + } + } +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index ce98b0f..27cca69 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,7 +1,7 @@ -# Nicko ${project.version} - Config: +# Nicko ${version} - Config: -# Don't modify this. -# No, like... really. +# Specifies the configuration version. +# Do NOT modify this field. version: "1.0.8" ############ diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 6216055..84e6d82 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -1,5 +1,3 @@ -version: "1.0.8" - error: generic: "An unknown error occurred." permission: "§cYou do not have the required permission." diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 79e70a2..02783c6 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -1,5 +1,3 @@ -version: "1.0.8" - error: generic: "Une erreur inconnue c'est produite." permission: "§cVous ne possédez pas la permission." diff --git a/src/test/java/xyz/ineanto/nicko/test/NickoPluginTest.java b/src/test/java/xyz/ineanto/nicko/test/NickoPluginTest.java index e500995..8b848dd 100644 --- a/src/test/java/xyz/ineanto/nicko/test/NickoPluginTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/NickoPluginTest.java @@ -7,7 +7,6 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import xyz.ineanto.nicko.NickoBukkit; import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.config.DefaultDataSources; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -16,11 +15,7 @@ public class NickoPluginTest { @BeforeAll public static void setup() { - final Configuration config = new Configuration( - DefaultDataSources.MARIADB_EMPTY, - DefaultDataSources.REDIS_EMPTY, - "", - false); + final Configuration config = Configuration.DEFAULT; MockBukkit.mock(); plugin = MockBukkit.load(NickoBukkit.class, config); } diff --git a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java b/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java index 76c798f..cd78d77 100644 --- a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java @@ -7,7 +7,6 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import xyz.ineanto.nicko.NickoBukkit; import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.config.DefaultDataSources; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -17,11 +16,7 @@ public class ConfigurationTest { @BeforeAll public static void setup() { MockBukkit.mock(); - final Configuration config = new Configuration( - DefaultDataSources.SQL_EMPTY, - DefaultDataSources.REDIS_EMPTY, - "", - false); + final Configuration config = Configuration.DEFAULT; plugin = MockBukkit.load(NickoBukkit.class, config); } diff --git a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java b/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java new file mode 100644 index 0000000..a1b55ba --- /dev/null +++ b/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java @@ -0,0 +1,72 @@ +package xyz.ineanto.nicko.test.config; + +import be.seeseemelk.mockbukkit.MockBukkit; +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.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.config.DefaultDataSources; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ConfigurationVersionTest { + private static NickoBukkit plugin; + + @BeforeAll + public static void setup() { + MockBukkit.mock(); + final Configuration configuration = Configuration.DEFAULT; + plugin = MockBukkit.load(NickoBukkit.class, configuration); + } + + @Test + @DisplayName("Compare configuration version") + public void compareConfigurationVersion() { + final Configuration configuration = new Configuration(Configuration.VERSION.toString(), + DefaultDataSources.SQL_EMPTY, + DefaultDataSources.REDIS_EMPTY, + "", + false); + assertEquals(configuration.getVersionObject().compareTo(Configuration.VERSION), 0); + } + + @Test + @DisplayName("Compare newer configuration version") + public void compareNewerConfigurationVersion() { + final Configuration configuration = new Configuration("24.1.0", + DefaultDataSources.SQL_EMPTY, + DefaultDataSources.REDIS_EMPTY, + "", + false); + assertEquals(configuration.getVersionObject().compareTo(Configuration.VERSION), 1); + } + + @Test + @DisplayName("Compare older configuration version") + public void compareOlderConfigurationVersion() { + final Configuration configuration = new Configuration("0.23.3", + DefaultDataSources.SQL_EMPTY, + DefaultDataSources.REDIS_EMPTY, + "", + false); + assertEquals(configuration.getVersionObject().compareTo(Configuration.VERSION), -1); + } + + @Test + @DisplayName("Compare unknown configuration version") + public void compareUnknownConfigurationVersion() { + final Configuration configuration = new Configuration(null, + DefaultDataSources.SQL_EMPTY, + DefaultDataSources.REDIS_EMPTY, + "", + false); + assertEquals(configuration.getVersionObject().compareTo(Configuration.VERSION), -1); + } + + @AfterAll + public static void shutdown() { + MockBukkit.unmock(); + } +} diff --git a/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java b/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java index 6ee6905..50905c3 100644 --- a/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java @@ -8,7 +8,6 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import xyz.ineanto.nicko.NickoBukkit; import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.config.DefaultDataSources; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; import xyz.ineanto.nicko.i18n.ItemTranslation; @@ -21,11 +20,7 @@ public class ItemTranslationTest { @BeforeAll public static void setup() { - final Configuration config = new Configuration( - DefaultDataSources.SQL_EMPTY, - DefaultDataSources.REDIS_EMPTY, - "", - false); + final Configuration config = Configuration.DEFAULT; MockBukkit.mock(); MockBukkit.load(NickoBukkit.class, config); } diff --git a/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java b/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java index 4f0c937..759c4bd 100644 --- a/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java @@ -7,7 +7,6 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import xyz.ineanto.nicko.NickoBukkit; import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.config.DefaultDataSources; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; import xyz.ineanto.nicko.i18n.Locale; @@ -17,11 +16,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; public class TranslationTest { @BeforeAll public static void setup() { - final Configuration config = new Configuration( - DefaultDataSources.SQL_EMPTY, - DefaultDataSources.REDIS_EMPTY, - "", - false); + final Configuration config = Configuration.DEFAULT; MockBukkit.mock(); MockBukkit.load(NickoBukkit.class, config); } diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/MapCacheTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/MapCacheTest.java index f940ad9..d1dc888 100644 --- a/src/test/java/xyz/ineanto/nicko/test/storage/MapCacheTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/storage/MapCacheTest.java @@ -3,14 +3,13 @@ package xyz.ineanto.nicko.test.storage; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; import be.seeseemelk.mockbukkit.entity.PlayerMock; -import xyz.ineanto.nicko.NickoBukkit; -import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.config.DefaultDataSources; -import xyz.ineanto.nicko.profile.NickoProfile; 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.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.profile.NickoProfile; import java.util.Optional; @@ -22,11 +21,7 @@ public class MapCacheTest { @BeforeAll public static void setup() { - final Configuration config = new Configuration( - DefaultDataSources.SQL_EMPTY, - DefaultDataSources.REDIS_EMPTY, - "", - false); + final Configuration config = Configuration.DEFAULT; final ServerMock server = MockBukkit.mock(); plugin = MockBukkit.load(NickoBukkit.class, config); player = server.addPlayer(); diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java index d2f79e3..e9b2859 100644 --- a/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java @@ -24,6 +24,7 @@ public class RedisCacheTest { @BeforeAll public static void setup() { final Configuration config = new Configuration( + "", DefaultDataSources.SQL_EMPTY, new DataSourceConfiguration(true, "127.0.0.1", 6379, "", ""), "", diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java index 555e6d0..774059e 100644 --- a/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java @@ -24,6 +24,7 @@ public class SQLStorageTest { @BeforeAll public static void setup() { final Configuration config = new Configuration( + "", new SQLDataSourceConfiguration(true, "127.0.0.1", 3306, "root", "12345", true), DefaultDataSources.REDIS_EMPTY, "", From 04690bf72c007f697f79654d7c393051fe3d7c43 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 19 Dec 2023 19:57:31 +0100 Subject: [PATCH 171/296] feat: bump api-version --- src/main/resources/plugin.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 27a3947..6ccf67a 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -3,7 +3,7 @@ main: xyz.ineanto.nicko.NickoBukkit version: ${version} author: Ineanto description: "The feature packed, next generation disguise plugin for Minecraft." -api-version: 1.14 +api-version: 1.19 softdepend: [ PlaceholderAPI ] depend: - ProtocolLib From 5d92cc6d3283a7e6014946daa99a15f53e111ffe Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 19 Dec 2023 19:59:11 +0100 Subject: [PATCH 172/296] feat: update changelog --- CHANGELOG.log | 1 + src/main/java/xyz/ineanto/nicko/i18n/ItemTranslation.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.log b/CHANGELOG.log index 9a1c2a5..42ef889 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,6 +1,7 @@ 1.0.8-RC1: Update n°5 (XX/XX/XX) [FEATURES] - Persistence and cache will now fallback to local alternatives when unreachable. + - Player check GUI has been updated to better reflect the current state of player's disguises. - Developers can now listen to the PlayerDisguiseEvent and cancel the disguise process. [OTHER] diff --git a/src/main/java/xyz/ineanto/nicko/i18n/ItemTranslation.java b/src/main/java/xyz/ineanto/nicko/i18n/ItemTranslation.java index 03c4084..e27d22e 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/ItemTranslation.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/ItemTranslation.java @@ -2,4 +2,4 @@ package xyz.ineanto.nicko.i18n; import java.util.ArrayList; -public record ItemTranslation(String name, ArrayList lore) {} +public record ItemTranslation(String name, ArrayList lore) {} \ No newline at end of file From d44a92372b7c950224beeb6622ad2ce368119240 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 19 Dec 2023 20:00:55 +0100 Subject: [PATCH 173/296] refactor(i18n): late init --- src/main/java/xyz/ineanto/nicko/NickoBukkit.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java index f73941c..414a781 100644 --- a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java +++ b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java @@ -112,8 +112,8 @@ public class NickoBukkit extends JavaPlugin { getLogger().warning("Issues regarding Nicko on Folia will be ignored for now."); } catch (ClassNotFoundException ignored) { } - localeFileManager = new LocaleFileManager(); if (configuration.isCustomLocale()) { + localeFileManager = new LocaleFileManager(); if (localeFileManager.dumpFromLocale(Locale.ENGLISH)) { getLogger().info("Successfully loaded custom language file."); } else { From 95cb064e2915cc11e87517f4b03a54d13c161409 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 19 Dec 2023 20:07:03 +0100 Subject: [PATCH 174/296] feat(changelog): update (1.0.8-RC1) --- CHANGELOG.log | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.log b/CHANGELOG.log index 42ef889..72187b8 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,5 +1,6 @@ -1.0.8-RC1: Update n°5 (XX/XX/XX) +1.0.8-RC1: Update n°5 (19/12/23) [FEATURES] + - Introduced a version string inside Nicko's configuration to plan future updated to the file. Your previous configuration file will automatically be migrated to this current version (with the backup of your old one included!) - Persistence and cache will now fallback to local alternatives when unreachable. - Player check GUI has been updated to better reflect the current state of player's disguises. - Developers can now listen to the PlayerDisguiseEvent and cancel the disguise process. From 8a544d1ba59481eb2ae534002334319c6a21dcaa Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 21 Dec 2023 00:16:19 +0100 Subject: [PATCH 175/296] fix: don't minimize bstats --- CHANGELOG.log | 7 +++++++ build.gradle.kts | 1 + 2 files changed, 8 insertions(+) diff --git a/CHANGELOG.log b/CHANGELOG.log index 72187b8..fd7fe3c 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,3 +1,10 @@ +1.0.9-RC1: Update n°6 (20/12/23) + [FEATURES] + - + + [FIXES] + - bStats metrics should be properly sent now(?) + 1.0.8-RC1: Update n°5 (19/12/23) [FEATURES] - Introduced a version string inside Nicko's configuration to plan future updated to the file. Your previous configuration file will automatically be migrated to this current version (with the backup of your old one included!) diff --git a/build.gradle.kts b/build.gradle.kts index 97d8151..f1838b6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -122,6 +122,7 @@ tasks { minimize { exclude(dependency("xyz.xenondevs.invui:.*")) exclude(dependency("net.wesjd:.*")) + exclude(dependency("org.bstats:.*")) } } From fdada8f44fcd2fba345eb473e00d3d4588d3beac Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 21 Dec 2023 17:40:57 +0100 Subject: [PATCH 176/296] feat: start working on random skin --- build.gradle.kts | 25 +- .../appearance/random/RandomNameFetcher.java | 36 ++ .../xyz/ineanto/nicko/gui/SettingsGUI.java | 13 +- .../items/settings/LanguageCyclingItem.java | 2 +- ...ngItem.java => RandomSkinCyclingItem.java} | 42 +- .../java/xyz/ineanto/nicko/i18n/I18NDict.java | 2 +- .../nicko/placeholder/NickoExpansion.java | 8 +- .../ineanto/nicko/profile/NickoProfile.java | 16 +- .../nicko/storage/mariadb/MariaDBStorage.java | 4 +- .../nicko/storage/mysql/MySQLStorage.java | 4 +- src/main/resources/en.yml | 6 +- src/main/resources/fr.yml | 6 +- src/main/resources/names.csv | 490 ++++++++++++++++++ .../nicko/test/appearance/RandomNameTest.java | 35 ++ .../nicko/test/storage/SQLStorageTest.java | 6 +- 15 files changed, 636 insertions(+), 59 deletions(-) create mode 100644 src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java rename src/main/java/xyz/ineanto/nicko/gui/items/settings/{BungeeCordCyclingItem.java => RandomSkinCyclingItem.java} (59%) create mode 100644 src/main/resources/names.csv create mode 100644 src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java diff --git a/build.gradle.kts b/build.gradle.kts index f1838b6..6dbf254 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,10 +2,11 @@ plugins { id("java") id("io.github.goooler.shadow") version "8.1.2" id("xyz.jpenilla.run-paper") version "2.2.2" + id("jvm-test-suite") } group = "xyz.ineanto" -version = "1.0.8-RC1" +version = "1.1.0-RC1" val shadowImplementation: Configuration by configurations.creating configurations["implementation"].extendsFrom(shadowImplementation) @@ -144,4 +145,24 @@ tasks.named("jar").configure { tasks.test { useJUnitPlatform() -} \ No newline at end of file +} + +// For when Gradle 9.0 releases. +/** +testing { + suites { + val test by getting(JvmTestSuite::class) { + targets { + useJUnitJupiter() + } + + dependencies { + implementation(project()) + implementation("com.github.seeseemelk:MockBukkit-v1.20:3.58.0") + implementation("org.junit.jupiter:junit-jupiter-api:5.10.1") + implementation("org.junit.jupiter:junit-jupiter-engine:5.10.1") + implementation("org.junit.jupiter:junit-jupiter:5.10.1") + } + } + } +} */ \ No newline at end of file diff --git a/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java b/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java new file mode 100644 index 0000000..0557047 --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java @@ -0,0 +1,36 @@ +package xyz.ineanto.nicko.appearance.random; + +import xyz.ineanto.nicko.NickoBukkit; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +public class RandomNameFetcher { + private final NickoBukkit instance; + + public RandomNameFetcher(NickoBukkit instance) { + this.instance = instance; + } + + public String getRandomUsername() { + final InputStream resource = instance.getResource("names.csv"); + final List> records = new ArrayList<>(); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource))) { + String line; + while ((line = reader.readLine()) != null) { + String[] values = line.split("\n"); + records.add(Arrays.asList(values)); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + + return records.get(new Random().nextInt(records.size() -1)).get(0); + } +} diff --git a/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java b/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java index f887c6d..76079b7 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java @@ -1,14 +1,12 @@ package xyz.ineanto.nicko.gui; import org.bukkit.entity.Player; -import xyz.ineanto.nicko.gui.items.ItemDefaults; import xyz.ineanto.nicko.gui.items.common.GoBackItem; -import xyz.ineanto.nicko.gui.items.settings.BungeeCordCyclingItem; import xyz.ineanto.nicko.gui.items.settings.LanguageCyclingItem; +import xyz.ineanto.nicko.gui.items.settings.RandomSkinCyclingItem; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.gui.Gui; -import xyz.xenondevs.invui.item.impl.SimpleItem; import xyz.xenondevs.invui.window.Window; public class SettingsGUI { @@ -19,26 +17,23 @@ public class SettingsGUI { public SettingsGUI(Player player) { final String[] dynamicStructure = new String[]{ "# # # # # # # # #", - "# # # L T U # # #", + "# # # L # R # # #", "B # # # # # # # #" }; - 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 LanguageCyclingItem languageItem = new LanguageCyclingItem(player); - final BungeeCordCyclingItem bungeeCordItem = new BungeeCordCyclingItem(player); + final RandomSkinCyclingItem skinItem = new RandomSkinCyclingItem(player); final GoBackItem backItem = new GoBackItem(player); this.gui = Gui.normal() .setStructure(dynamicStructure) .addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle())) .addIngredient('L', languageItem.get()) - .addIngredient('U', new SimpleItem(ItemDefaults.getUnavailableItem(i18n))) - .addIngredient('T', bungeeCordItem.get()) + .addIngredient('R', skinItem.get()) .build(); this.player = player; } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java index 906f118..de5a31e 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java @@ -40,8 +40,8 @@ public class LanguageCyclingItem { final NickoProfile nickoProfile = profile.get(); int localeOrdinal = nickoProfile.getLocale().ordinal(); return CycleItem.withStateChangeHandler((observer, integer) -> { - nickoProfile.setLocale(Locale.values()[integer]); observer.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 0.707107f); // 0.707107 ~= C + nickoProfile.setLocale(Locale.values()[integer]); player.getOpenInventory().close(); if (dataStore.updateCache(player.getUniqueId(), nickoProfile).isError()) { player.sendMessage(i18n.translate(I18NDict.Event.Settings.ERROR)); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/settings/BungeeCordCyclingItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java similarity index 59% rename from src/main/java/xyz/ineanto/nicko/gui/items/settings/BungeeCordCyclingItem.java rename to src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java index 520ebd6..2261a8e 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/settings/BungeeCordCyclingItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java @@ -1,6 +1,5 @@ package xyz.ineanto.nicko.gui.items.settings; -import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; import xyz.ineanto.nicko.NickoBukkit; @@ -10,19 +9,19 @@ import xyz.ineanto.nicko.i18n.ItemTranslation; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.PlayerDataStore; import xyz.xenondevs.invui.item.ItemProvider; -import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.builder.SkullBuilder; import xyz.xenondevs.invui.item.impl.AbstractItem; import xyz.xenondevs.invui.item.impl.CycleItem; import xyz.xenondevs.invui.item.impl.SimpleItem; import java.util.Optional; -public class BungeeCordCyclingItem { +public class RandomSkinCyclingItem { private final Player player; - private final I18N i18n; private final ItemProvider[] providers; + private final I18N i18n; - public BungeeCordCyclingItem(Player player) { + public RandomSkinCyclingItem(Player player) { this.player = player; this.i18n = new I18N(player); this.providers = new ItemProvider[]{ @@ -36,33 +35,30 @@ public class BungeeCordCyclingItem { final Optional profile = dataStore.getData(player.getUniqueId()); if (profile.isPresent()) { final NickoProfile nickoProfile = profile.get(); - int startingState = nickoProfile.isBungeecordTransfer() ? 0 : 1; + int localeOrdinal = nickoProfile.isRandomSkin() ? 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); + nickoProfile.setRandomSkin(integer != 1); + if (dataStore.updateCache(player.getUniqueId(), nickoProfile).isError()) { + player.sendMessage(i18n.translate(I18NDict.Event.Settings.ERROR)); + player.getOpenInventory().close(); + } + }, localeOrdinal, providers); } return new SimpleItem(ItemProvider.EMPTY); } - private ItemProvider getItemProviderForValue(boolean ignored) { - final ItemBuilder builder = new ItemBuilder(Material.COMPASS); - final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.Settings.BUNGEECORD); + private ItemProvider getItemProviderForValue(boolean enabled) { + final SkullBuilder.HeadTexture texture = new SkullBuilder.HeadTexture("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzgzMTEzOGMyMDYxMWQzMDJjNDIzZmEzMjM3MWE3NDNkMTc0MzdhMTg5NzNjMzUxOTczNDQ3MGE3YWJiNCJ9fX0="); + final SkullBuilder builder = new SkullBuilder(texture); + final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.Settings.RANDOM_SKIN, + (enabled ? "§7> §cDisabled" : "§6§l> §c§lDisabled"), + (enabled ? "§6§l> §a§lEnabled" : "§7> §aEnabled") + ); builder.setDisplayName(translation.name()); translation.lore().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; } -} +} \ No newline at end of file diff --git a/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java b/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java index 020154f..4ce1f45 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java @@ -112,7 +112,7 @@ public class I18NDict { 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 final String RANDOM_SKIN = SETTINGS_KEY + "random_skin"; } public static class Admin { diff --git a/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java b/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java index 1f3f9fe..1200110 100644 --- a/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java +++ b/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java @@ -42,11 +42,11 @@ public class NickoExpansion extends PlaceholderExpansion { if (player == null) return null; String name, skin, locale; - boolean bungeecord; + boolean randomSkin; name = skin = player.getName(); locale = "N/A"; - bungeecord = true; + randomSkin = false; final Optional optionalProfile = instance.getDataStore().getData(player.getUniqueId()); if (optionalProfile.isPresent()) { @@ -61,14 +61,14 @@ public class NickoExpansion extends PlaceholderExpansion { } } locale = profile.getLocale().getName(); - bungeecord = profile.isBungeecordTransfer(); + randomSkin = profile.isRandomSkin(); } return switch (params) { case "name" -> name; case "skin" -> skin; case "locale" -> locale; - case "bungeecord" -> String.valueOf(bungeecord); + case "bungeecord" -> String.valueOf(randomSkin); default -> null; }; } diff --git a/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java b/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java index 0dd8b6c..d70f7ff 100644 --- a/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java +++ b/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java @@ -15,13 +15,13 @@ public class NickoProfile implements Cloneable { private String name; private String skin; private Locale locale; - private boolean bungeecordTransfer; + private boolean randomSkin; - public NickoProfile(String name, String skin, Locale locale, boolean bungeecordTransfer) { + public NickoProfile(String name, String skin, Locale locale, boolean randomSkin) { this.name = name; this.skin = skin; this.locale = locale; - this.bungeecordTransfer = bungeecordTransfer; + this.randomSkin = randomSkin; } public static Optional get(Player player) { @@ -60,12 +60,12 @@ public class NickoProfile implements Cloneable { this.locale = locale; } - public boolean isBungeecordTransfer() { - return bungeecordTransfer; + public boolean isRandomSkin() { + return randomSkin; } - public void setBungeecordTransfer(boolean bungeecordTransfer) { - this.bungeecordTransfer = bungeecordTransfer; + public void setRandomSkin(boolean randomSkin) { + this.randomSkin = randomSkin; } @Override @@ -74,7 +74,7 @@ public class NickoProfile implements Cloneable { "name='" + name + '\'' + ", skin='" + skin + '\'' + ", locale=" + locale + - ", bungeecordTransfer=" + bungeecordTransfer + + ", randomSkin=" + randomSkin + '}'; } diff --git a/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java b/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java index c4fc100..f761f56 100644 --- a/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java +++ b/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java @@ -124,7 +124,7 @@ public class MariaDBStorage extends Storage { statement.setString(2, profile.getName() == null ? null : profile.getName()); statement.setString(3, profile.getSkin() == null ? null : profile.getSkin()); statement.setString(4, profile.getLocale().getCode()); - statement.setBoolean(5, profile.isBungeecordTransfer()); + statement.setBoolean(5, profile.isRandomSkin()); return statement; } @@ -134,7 +134,7 @@ public class MariaDBStorage extends Storage { statement.setString(1, profile.getName() == null ? null : profile.getName()); statement.setString(2, profile.getSkin() == null ? null : profile.getSkin()); statement.setString(3, profile.getLocale().getCode()); - statement.setBoolean(4, profile.isBungeecordTransfer()); + statement.setBoolean(4, profile.isRandomSkin()); statement.setString(5, uuid.toString()); return statement; } diff --git a/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java b/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java index 85c8d9e..490c8e1 100644 --- a/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java +++ b/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java @@ -124,7 +124,7 @@ public class MySQLStorage extends Storage { statement.setString(2, profile.getName() == null ? null : profile.getName()); statement.setString(3, profile.getSkin() == null ? null : profile.getSkin()); statement.setString(4, profile.getLocale().getCode()); - statement.setBoolean(5, profile.isBungeecordTransfer()); + statement.setBoolean(5, profile.isRandomSkin()); return statement; } @@ -134,7 +134,7 @@ public class MySQLStorage extends Storage { statement.setString(1, profile.getName() == null ? null : profile.getName()); statement.setString(2, profile.getSkin() == null ? null : profile.getSkin()); statement.setString(3, profile.getLocale().getCode()); - statement.setBoolean(4, profile.isBungeecordTransfer()); + statement.setBoolean(4, profile.isRandomSkin()); statement.setString(5, uuid.toString()); return statement; } diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 84e6d82..7297af5 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -133,8 +133,10 @@ gui: lore: - "§7§oGet through the values" - "§7§oby left or right clicking." - bungeecord: - name: "Bungeecord Transfer" + random_skin: + name: "Random skin on join" lore: + - "{0}" + - "{1}" - "§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 02783c6..38a568a 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -130,8 +130,10 @@ gui: lore: - "§7§oParcourez les valeurs" - "§7§oavec un clique gauche/droit." - bungeecord: - name: "Transfert Bungeecord" + random_skin: + name: "Apparence aléatoire à la connexion" lore: + - "{0}" + - "{1}" - "§7§oParcourez les valeurs" - "§7§oavec un clique gauche/droit." \ No newline at end of file diff --git a/src/main/resources/names.csv b/src/main/resources/names.csv new file mode 100644 index 0000000..4eae88f --- /dev/null +++ b/src/main/resources/names.csv @@ -0,0 +1,490 @@ +w4nderlost +TooParanoids +Der_OG_31er +9xxDaRkShAdOwxx9 +giiiaan_ +Jqstinnn +Tillysboy92 +AlwaysCello +SyndrexG0D +Peypeycake +ThePerjurer +Tioe +Elternbaum +BarkersRover_16 +pebsso +cyrus6950 +Bigest_guy +RV0REU +R379 +Shetell +_HEAPASS_ +Iamaloner21 +TheFardoxGamerHD +Flyboi43 +Cha0smusik +kat00 +Infreat +Crummymoofin +MijnVriend +momsrightkidney +dmacrado +Elephantman321 +ii_hamoudi_YT +FaurePavane +ambiezzz +XD_Bandit695_XD +Nabingo +Cyl0re +ku5 +SrAragon +StarlightDream9 +CJ5370 +rainbees +KeroTheWolf +Andrews9722 +cursed_Assyrian +yamateni +ProgramEXE +exprso +harrypanda +LookerMD +migykins +Wintrous +ZzGaBi +Flayber +Grenixal +maeve_wells +Creeper10fr +10Chairs +2525lock +Shqipe +XenitsuZen +Berno17_ +wolle1313 +HalfDogHalfCat1 +NachoGarcia +popsicoal +NemesiSevil2006 +AnywayOj +Tanko12345 +Samdweck +LYRECODE123 +Resulten +SirBastii +Maku056 +ItzArnizzz +Brsh3620 +Masonita +kapplanium +shoezo +Mansur203 +Waterboy15217 +redragonne +ghko325 +HopePVP_tw7 +xtka +NimwenxZ +Hiro0408 +PanderaWz +Shesu +_Aniste_NY_ +Besceste +3ee3 +ArcticGalaxy123 +snooze_mingo +LizzyLomnh +FaZeChulupa +LineZeeK +liabilaty +BlackSheep1610 +Simif69 +Aficionado +riekin +XLuggas +MathExams +6fq +Marveel +lolme51 +TaioSayUwU +Fonklift +blvw +Po1204 +Pierre_Rabbit +mifimasters +MrRidge1 +arnqen +Nick_cage102 +Geo_9918 +SSShudder +Nicolas_Mom +WolfMatrix101 +frictionless_ +Gughik +gold_dragon_4 +nealxero +ClonedPickle +SourWatermelonxX +devilunion +Daryifuny +joaomarcos11 +Dekeef +PadfootTheDog +DarkScopez80 +flowers220 +Gaiiya +The_Yeet_ +juuuuwu +MrMafioz +Surpasses +TypicalOwen +0lober +Zerfixy +Sunny3803b +neostanley +Creeper_Kart +minestin +Goldenfredster +Vju +MrArchI_YT +Casper1709 +Backiii_ +DrCreate +Nova_Lux1 +Jayvin_Blanco +ShadowMan1770 +0KOPO40K +Silk_Altermann69 +Alu____ +Honey_MilkExe112 +T0XEI +CB_13 +Paragorn +HaGiang +Shivendra8i +Mayflower47 +Not_Someguy +raxx111bg +IceyGlaceon +grasseffect +PoopTNTpvp +codecyber +Shrumpkin13 +Shqdown +Cmartin82 +KTCXD_5p0tty +rockesalt +goldjeong +TheRealAKD +NamiSwaaan +yaaratol +Dikiy_Flexer +PoLecker24 +_SakuraTree +PikkOgP0rno +HawksFang +BlueWinterWolf +hskmerk +gurmaw +Lunggor +clashfield +Zelaste +ACommonMouse +TJ_Mystery +Dizzy3312 +Raindropsss +minecraftxiaoju +sachilovebbh +Celina_LaZyCxt +firered6 +55000000 +Illunarnati +Jedidiah2003 +setomz1 +basically_e +TommyGreif02 +Bongrip42069 +Coco_Keopi +Lt_Colt +Kuurotta +GqmeKnight +WinCo_Foods +FKDLZ +IanPumpkin +tastywtf +natedawg0 +ZQLFenyx +GamerMaster110 +papajobi9 +Yucaroon +Xion_69 +AirJaw +funfun321234 +khalleesii +Pozisch +thorso15 +kyumisoup +Leonqrd +BmwDreamer +TehRos +pitplayer69 +_ve0 +Miss_Yuka +I_am_a_Bucket +nicolas_bean +xHorizonGC +RTX3060_ +Borec188 +c8to +megan3groCENG +ventriloquize +galczin +Scorch3dEarth3d +nightstarLP +VittyGam3r +GLaDOS__ +hydrelo +JustACarter +MikeDropperPlay +NorthernWest +_Skelesam_ +ZX_Style +Tamas_Boi +taylub +VyacheslavO_O +trippyaubs +udtpic +Lunarglow +Stoolman +legendary_meow +Loganii +CaptainStain56 +FoofieGeto +Judgeavapl +OneBigDigger +Sorem13 +Raisonneur +IlkoalI +Naxa +craigbabyonebay +NicholasG04 +UtopianCrisi +CalamarPasGenti +ryluh_ +Aceslimz +Howardygh99927 +brandon257 +MarcoswildHD +x_XSkylerX_x +Bronco09 +That_Kookie_ +Danigtz +Ricky_lol +999keyt +Thilow15 +Difesito +ostehovl +isacano_12 +big_esra +secretbaguette +MrCommunism +Jekube +GrandeMaster +DrGrip +TheArnek +JacsMars +Lliam14 +MrGameandWatch84 +Rinzap +XrazzeD +ukknown +ZohanPrent +Naspo +Rajem +VepiGHG +matoureal +BrianChen87 +Jrocky +stivo999 +Des_cole +ReqGames +Kingja1912 +issssyy +Apache424 +Nick_Zockt_ +Mr_Haider_10 +ValentineBun +fedorPro228 +xTilz +blockbuster02k +4ck +FrostedTree +VegasTortoise +ZBellaV12121 +paypales +qDread +itsRiven +i8oreo +_kimcream_ +Phisuss +Oscargray +Elsiff +callofdutydog00 +BruhTheMoment +Pazmaa +MythicalOak +komuchi33 +awf4 +Jacobsaurus21 +itsjohannaa +Jello12 +Adrien183 +jajazzywazzy +Jorjie22 +SuperBrawlr5788 +KaraageV +_Hanime_tv +Padilhao +Tikkas +ordinaryducky +Mothytix95 +renopotouwu +1000voices +niclas05 +Felipstein +DoutorBauer +FireballPlaysMC +vapelordsheep +Aboain +ImGrexy +Aivokolo +SuperAmazing101 +va75a77a +_DawYans_ +AceT1223 +Livvyboo7 +Saaaaaaaaaaaaans +okaychill +AwesomeBro1122 +absolutesnek +jogie5000 +curtainSenpai +gabbyisaloser +gamergurl6969 +ZeusDk +FranaRibas +Discoboss +SYZ_1 +Nakoe +FIU_Captive +xSiFan_ +ilyDeathxz +da_fipsi +Lochy +The_Lavie37 +Tonion +vnvrchy +xX0meg4Xx +haohxtheone +VtTronic +xDaniGum +tikkelill +DatYoshi +eyehamstewpit +nicholas460_ +Memsly445 +nugunugu +AndreSlayz +jashik1 +Qweenoftheocean +Coltable +treblaclef +Kisaxx +69Dxddy69 +RaulCuh +3Wheat +_OscarTheGrouch +oIsqk +Blockbusterweng +AntoineDegauss +ValeIsTheBest +SwaggyCrabby +DieOfSanity +SirenMC +Jade_Jewel +Tropic44 +666splendor +TallnessTallness +breadgang9827 +Muffin_Worlds +DedicatedVeggie +Gonzalox_7 +datrandomasian +Chasemon01 +Nyavix +Lonely_Summers +_RoveN +ok_kyro +LN_hunter +saharsabz +Roselilianna +Gadx +xtytan +RoRo_levosgien88 +Bowsesqe_21 +Bennett528 +TheShipSailsWest +KaiserGaming +Layna_Shinozaki +OP_greatly +D3rpTaco +Loufink +Jorlmungus +Snichol1801 +Ludixeo +Imoeto +MarshallNebunu +crazycrystals +Parapatus +HahaDani +MrQuaring +DonTurnt +SailorRoberts101 +FluffieBear +TripleThick +KingSparta +MummysHome +Cooga3 +Technosista +Youmerstudios +SkyyRaine +criss102 +mrfailt +CraftingBasic +qnxkdifh +Igorex2k20 +LaLisette +ReBoredGamer +warlordwest +ExoTemporal +KingLonmc +666Horus +IslandCity2 +TheBigSavage1 +Trishke2003 +skyrowin +Krissy3D +AntonWTobias +SaddyWasTaken +Ahoy_Peko_Hao_Yo +T4nTr1Ss +aleciolike +ninja_shenley +Lordmord1337 +eatmypoopfather +Ktanner +The42OWeedGOD +CooperBee +_MikuMiku_ +althume +Tr3bba93 diff --git a/src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java b/src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java new file mode 100644 index 0000000..c5486b6 --- /dev/null +++ b/src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java @@ -0,0 +1,35 @@ +package xyz.ineanto.nicko.test.appearance; + +import be.seeseemelk.mockbukkit.MockBukkit; +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.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.appearance.random.RandomNameFetcher; +import xyz.ineanto.nicko.config.Configuration; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class RandomNameTest { + private static NickoBukkit plugin; + + @BeforeAll + public static void setup() { + final Configuration config = Configuration.DEFAULT; + MockBukkit.mock(); + plugin = MockBukkit.load(NickoBukkit.class, config); + } + + @Test + @DisplayName("Get random name") + public void getRandomName() { + final RandomNameFetcher randomNameFetcher = new RandomNameFetcher(plugin); + assertNotNull(randomNameFetcher.getRandomUsername()); + } + + @AfterAll + public static void shutdown() { + MockBukkit.unmock(); + } +} diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java index 774059e..6f79018 100644 --- a/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java @@ -63,12 +63,12 @@ public class SQLStorageTest { assertNull(profile.getName()); assertNull(profile.getSkin()); assertEquals(profile.getLocale(), Locale.ENGLISH); - assertTrue(profile.isBungeecordTransfer()); + assertTrue(profile.isRandomSkin()); profile.setName("Notch"); profile.setSkin("Notch"); profile.setLocale(Locale.FRENCH); - profile.setBungeecordTransfer(false); + profile.setRandomSkin(false); final ActionResult result = dataStore.getStorage().store(uuid, profile); assertFalse(result.isError()); @@ -85,7 +85,7 @@ public class SQLStorageTest { assertEquals(updatedProfile.getName(), "Notch"); assertEquals(updatedProfile.getSkin(), "Notch"); assertEquals(updatedProfile.getLocale(), Locale.FRENCH); - assertFalse(updatedProfile.isBungeecordTransfer()); + assertFalse(updatedProfile.isRandomSkin()); } @Test From 83bc00aebe551aa3dcf39a757a62338826f9309b Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 22 Dec 2023 01:56:38 +0100 Subject: [PATCH 177/296] feat: translate random skin setting --- .../xyz/ineanto/nicko/anvil/AnvilManager.java | 4 +-- .../ineanto/nicko/command/NickoCommand.java | 2 +- .../nicko/event/PlayerJoinListener.java | 4 +-- .../java/xyz/ineanto/nicko/gui/AdminGUI.java | 2 +- .../ineanto/nicko/gui/CacheManagementGUI.java | 2 +- .../java/xyz/ineanto/nicko/gui/ChoiceGUI.java | 2 +- .../java/xyz/ineanto/nicko/gui/HomeGUI.java | 2 +- .../ineanto/nicko/gui/InvalidateSkinGUI.java | 2 +- .../xyz/ineanto/nicko/gui/PlayerCheckGUI.java | 2 +- .../xyz/ineanto/nicko/gui/SettingsGUI.java | 2 +- .../gui/items/admin/cache/CacheEntryItem.java | 2 +- .../admin/cache/InvalidateCacheItem.java | 2 +- .../admin/check/PlayerInformationItem.java | 2 +- .../gui/items/common/ScrollDownItem.java | 4 +-- .../nicko/gui/items/common/ScrollUpItem.java | 4 +-- .../nicko/gui/items/home/ResetItem.java | 6 ++-- .../items/settings/LanguageCyclingItem.java | 9 ++--- .../items/settings/RandomSkinCyclingItem.java | 17 +++++---- .../java/xyz/ineanto/nicko/i18n/I18N.java | 36 ++++++++++--------- .../java/xyz/ineanto/nicko/i18n/I18NDict.java | 3 ++ .../ineanto/nicko/i18n/ItemTranslation.java | 5 --- .../xyz/ineanto/nicko/i18n/Translation.java | 5 +++ src/main/resources/en.yml | 26 +++++++++----- src/main/resources/fr.yml | 16 ++++----- .../nicko/test/i18n/ItemTranslationTest.java | 11 ++++-- .../nicko/test/i18n/TranslationTest.java | 2 +- 26 files changed, 99 insertions(+), 75 deletions(-) delete mode 100644 src/main/java/xyz/ineanto/nicko/i18n/ItemTranslation.java create mode 100644 src/main/java/xyz/ineanto/nicko/i18n/Translation.java diff --git a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java index 4dd47ce..2662a53 100644 --- a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java @@ -115,9 +115,9 @@ public class AnvilManager { final I18N i18n = new I18N(player); final ActionResult actionResult = appearanceManager.updatePlayer(skinChange, false); if (!actionResult.isError()) { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.OK)); + player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Set.OK)); } else { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.ERROR, i18n.translatePrefixless(actionResult.getErrorKey()))); + player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Set.ERROR, i18n.translateStringWithoutPrefix(actionResult.getErrorKey()))); } return Collections.singletonList(AnvilGUI.ResponseAction.close()); } diff --git a/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java b/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java index 2f3e0c7..1ac6bf2 100644 --- a/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java +++ b/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java @@ -17,7 +17,7 @@ public class NickoCommand implements CommandExecutor { new HomeGUI(player).open(); } else { final I18N i18N = new I18N(player); - player.sendMessage(i18N.translate(I18NDict.Error.PERMISSION)); + player.sendMessage(i18N.translateString(I18NDict.Error.PERMISSION)); } return false; } diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java index 31a7d6b..0baa19e 100644 --- a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java @@ -45,9 +45,9 @@ public class PlayerJoinListener implements Listener { 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)); + player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Restore.OK)); } else { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Restore.ERROR, i18n.translatePrefixless(actionResult.getErrorKey()))); + player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Restore.ERROR, i18n.translateStringWithoutPrefix(actionResult.getErrorKey()))); } } }); diff --git a/src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java b/src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java index 1828ec4..126a436 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java @@ -18,7 +18,7 @@ public class AdminGUI { public AdminGUI(Player player) { final I18N i18n = new I18N(player); - this.title = i18n.translatePrefixless(I18NDict.GUI.Titles.ADMIN); + this.title = i18n.translateStringWithoutPrefix(I18NDict.GUI.Titles.ADMIN); final HomeGUI parent = new HomeGUI(player); final GoBackItem backItem = new GoBackItem(player); diff --git a/src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java b/src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java index 14d2812..21813b0 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java @@ -17,7 +17,7 @@ public class CacheManagementGUI { public CacheManagementGUI(Player player) { final I18N i18n = new I18N(player); - this.title = i18n.translatePrefixless(I18NDict.GUI.Titles.CACHE); + this.title = i18n.translateStringWithoutPrefix(I18NDict.GUI.Titles.CACHE); final AdminGUI parent = new AdminGUI(player); final GoBackItem backItem = new GoBackItem(player); diff --git a/src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java b/src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java index 3a2e045..f502433 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java @@ -22,7 +22,7 @@ public class ChoiceGUI { final ConfirmItem confirmItem = new ConfirmItem(player, callback); final CancelItem cancelItem = new CancelItem(player, callback); - this.title = i18n.translatePrefixless(I18NDict.GUI.Titles.CONFIRM); + this.title = i18n.translateStringWithoutPrefix(I18NDict.GUI.Titles.CONFIRM); this.gui = Gui.normal() .setStructure( "@ @ @ @ % & & & &", diff --git a/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java b/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java index b0c8612..24d9b06 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java @@ -29,7 +29,7 @@ public class HomeGUI { } final I18N i18n = new I18N(player); - this.title = i18n.translatePrefixless(I18NDict.GUI.Titles.HOME); + this.title = i18n.translateStringWithoutPrefix(I18NDict.GUI.Titles.HOME); final ExitItem exitItem = new ExitItem(player); final ResetItem resetItem = new ResetItem(player); diff --git a/src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java b/src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java index da49bc7..1371534 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java @@ -28,7 +28,7 @@ public class InvalidateSkinGUI { public InvalidateSkinGUI(Player player) { final I18N i18n = new I18N(player); - this.title = i18n.translatePrefixless(I18NDict.GUI.Titles.INVALIDATE_SKIN); + this.title = i18n.translateStringWithoutPrefix(I18NDict.GUI.Titles.INVALIDATE_SKIN); final ConcurrentMap> skins = NickoBukkit.getInstance().getMojangAPI().getSkinCache().asMap(); final List loadedSkins = skins.entrySet().stream() diff --git a/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java b/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java index c6dbe1d..c3bee6e 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java @@ -27,7 +27,7 @@ public class PlayerCheckGUI { public PlayerCheckGUI(Player player, Collection players) { final I18N i18n = new I18N(player); - this.title = i18n.translatePrefixless(I18NDict.GUI.Titles.CHECK); + this.title = i18n.translateStringWithoutPrefix(I18NDict.GUI.Titles.CHECK); final List items = players.stream() .map(Entity::getUniqueId) diff --git a/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java b/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java index 76079b7..c028d9d 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java @@ -22,7 +22,7 @@ public class SettingsGUI { }; final I18N i18n = new I18N(player); - this.title = i18n.translatePrefixless(I18NDict.GUI.Titles.SETTINGS); + this.title = i18n.translateStringWithoutPrefix(I18NDict.GUI.Titles.SETTINGS); final HomeGUI parent = new HomeGUI(player); final LanguageCyclingItem languageItem = new LanguageCyclingItem(player); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java index 28b9cf9..56a5cd1 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java @@ -50,7 +50,7 @@ public class CacheEntryItem extends AsyncItem { @Override public void onConfirm() { final I18N i18n = new I18N(player); - player.sendMessage(i18n.translate(I18NDict.Event.Admin.Cache.INVALIDATE_ENTRY, name)); + player.sendMessage(i18n.translateString(I18NDict.Event.Admin.Cache.INVALIDATE_ENTRY, name)); mojangAPI.eraseFromCache(uuid); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java index b2196af..14eddb3 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java @@ -27,7 +27,7 @@ public class InvalidateCacheItem { final Player player = click.getPlayer(); final I18N i18n = new I18N(player); - player.sendMessage(i18n.translate(I18NDict.Event.Admin.Cache.INVALIDATE_CACHE)); + player.sendMessage(i18n.translateString(I18NDict.Event.Admin.Cache.INVALIDATE_CACHE)); NickoBukkit.getInstance().getMojangAPI().getSkinCache().invalidateAll(); return true; } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java index 1ba5b43..d3f9ed3 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java @@ -78,7 +78,7 @@ public class PlayerInformationItem extends AsyncItem { public void onConfirm() { final AppearanceManager appearanceManager = new AppearanceManager(target); appearanceManager.reset(); - player.sendMessage(i18n.translate(I18NDict.Event.Admin.Check.REMOVE_SKIN, target.getName())); + player.sendMessage(i18n.translateString(I18NDict.Event.Admin.Check.REMOVE_SKIN, target.getName())); } @Override diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java index 40d5037..f836f78 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java @@ -3,7 +3,7 @@ package xyz.ineanto.nicko.gui.items.common; import org.bukkit.Material; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; -import xyz.ineanto.nicko.i18n.ItemTranslation; +import xyz.ineanto.nicko.i18n.Translation; import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.item.ItemProvider; import xyz.xenondevs.invui.item.builder.ItemBuilder; @@ -20,7 +20,7 @@ public class ScrollDownItem extends ScrollItem { @Override public ItemProvider getItemProvider(ScrollGui gui) { final ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); - final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.SCROLL_DOWN); + final Translation translation = i18n.translate(I18NDict.GUI.SCROLL_DOWN); builder.setDisplayName(translation.name()); if (!gui.canScroll(1)) translation.lore().forEach(builder::addLoreLines); return builder; diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java index 82ef82a..51dc950 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java @@ -3,7 +3,7 @@ package xyz.ineanto.nicko.gui.items.common; import org.bukkit.Material; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; -import xyz.ineanto.nicko.i18n.ItemTranslation; +import xyz.ineanto.nicko.i18n.Translation; import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.item.ItemProvider; import xyz.xenondevs.invui.item.builder.ItemBuilder; @@ -20,7 +20,7 @@ public class ScrollUpItem extends ScrollItem { @Override public ItemProvider getItemProvider(ScrollGui gui) { final ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE); - final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.SCROLL_UP); + final Translation translation = i18n.translate(I18NDict.GUI.SCROLL_UP); builder.setDisplayName(translation.name()); if (!gui.canScroll(-1)) translation.lore().forEach(builder::addLoreLines); return builder; diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java index c1c4523..f8bf299 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java @@ -30,16 +30,16 @@ public class ResetItem { final Optional optionalProfile = NickoProfile.get(player); optionalProfile.ifPresent(profile -> { if (!profile.hasData()) { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.MISSING)); + player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Remove.MISSING)); event.getEvent().getView().close(); return; } final AppearanceManager appearanceManager = new AppearanceManager(player); if (!appearanceManager.reset().isError()) { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.OK)); + player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Remove.OK)); } else { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.ERROR)); + player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Remove.ERROR)); profile.setSkin(null); profile.setName(null); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java index de5a31e..4a2946e 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java @@ -7,7 +7,7 @@ import xyz.ineanto.nicko.NickoBukkit; import xyz.ineanto.nicko.gui.SettingsGUI; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; -import xyz.ineanto.nicko.i18n.ItemTranslation; +import xyz.ineanto.nicko.i18n.Translation; import xyz.ineanto.nicko.i18n.Locale; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.PlayerDataStore; @@ -44,7 +44,7 @@ public class LanguageCyclingItem { nickoProfile.setLocale(Locale.values()[integer]); player.getOpenInventory().close(); if (dataStore.updateCache(player.getUniqueId(), nickoProfile).isError()) { - player.sendMessage(i18n.translate(I18NDict.Event.Settings.ERROR)); + player.sendMessage(i18n.translateString(I18NDict.Event.Settings.ERROR)); } else { new SettingsGUI(player).open(); } @@ -56,7 +56,8 @@ public class LanguageCyclingItem { private ItemProvider generateItem(Locale locale, List locales) { final ItemBuilder builder = new ItemBuilder(Material.OAK_SIGN); - final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.Settings.LANGUAGE); + final Translation translation = i18n.translate(I18NDict.GUI.Settings.LANGUAGE); + final Translation cyclingChoicesTranslation = i18n.translate(I18NDict.GUI.Settings.CYCLING_CHOICES); builder.setDisplayName(translation.name()); for (Locale value : locales) { @@ -66,7 +67,7 @@ public class LanguageCyclingItem { builder.addLoreLines("§6§l> §f" + value.getName()); } } - translation.lore().forEach(builder::addLoreLines); + cyclingChoicesTranslation.lore().forEach(builder::addLoreLines); return builder; } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java index 2261a8e..bedb4e0 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java @@ -5,7 +5,7 @@ import org.bukkit.entity.Player; import xyz.ineanto.nicko.NickoBukkit; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; -import xyz.ineanto.nicko.i18n.ItemTranslation; +import xyz.ineanto.nicko.i18n.Translation; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.PlayerDataStore; import xyz.xenondevs.invui.item.ItemProvider; @@ -40,7 +40,7 @@ public class RandomSkinCyclingItem { observer.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 0.707107f); // 0.707107 ~= C nickoProfile.setRandomSkin(integer != 1); if (dataStore.updateCache(player.getUniqueId(), nickoProfile).isError()) { - player.sendMessage(i18n.translate(I18NDict.Event.Settings.ERROR)); + player.sendMessage(i18n.translateString(I18NDict.Event.Settings.ERROR)); player.getOpenInventory().close(); } }, localeOrdinal, providers); @@ -52,13 +52,16 @@ public class RandomSkinCyclingItem { private ItemProvider getItemProviderForValue(boolean enabled) { final SkullBuilder.HeadTexture texture = new SkullBuilder.HeadTexture("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzgzMTEzOGMyMDYxMWQzMDJjNDIzZmEzMjM3MWE3NDNkMTc0MzdhMTg5NzNjMzUxOTczNDQ3MGE3YWJiNCJ9fX0="); final SkullBuilder builder = new SkullBuilder(texture); - final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.Settings.RANDOM_SKIN, - (enabled ? "§7> §cDisabled" : "§6§l> §c§lDisabled"), - (enabled ? "§6§l> §a§lEnabled" : "§7> §aEnabled") + final Translation randomSkinTranslation = i18n.translate(I18NDict.GUI.Settings.RANDOM_SKIN); + final Translation toggleableTranslation = i18n.translate(I18NDict.GUI.Settings.TOGGLEABLE_BUTTON, + (enabled ? "§7>§c" : "§6§l>§c§l"), + (enabled ? "§6§l>§a§l" : "§7>§a") ); + final Translation cyclingChoicesTranslation = i18n.translate(I18NDict.GUI.Settings.CYCLING_CHOICES); - builder.setDisplayName(translation.name()); - translation.lore().forEach(builder::addLoreLines); + builder.setDisplayName(randomSkinTranslation.name()); + toggleableTranslation.lore().forEach(builder::addLoreLines); + cyclingChoicesTranslation.lore().forEach(builder::addLoreLines); return builder; } } \ No newline at end of file diff --git a/src/main/java/xyz/ineanto/nicko/i18n/I18N.java b/src/main/java/xyz/ineanto/nicko/i18n/I18N.java index 9f512a4..1b1f14b 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/I18N.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/I18N.java @@ -8,9 +8,7 @@ import xyz.xenondevs.invui.item.builder.AbstractItemBuilder; import java.io.InputStream; import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Optional; +import java.util.*; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -19,7 +17,7 @@ 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 Pattern replacementPattern = Pattern.compile("(?ms)\\{\\d+}"); private final YamlConfig yamlConfig; private final Player player; private final Locale playerLocale; @@ -37,28 +35,28 @@ public class I18N { } public AbstractItemBuilder translateItem(AbstractItemBuilder item, String key, Object... args) { - final ItemTranslation translation = fetchTranslation(key, args); + final Translation translation = translate(key, args); item.setDisplayName(translation.name()); translation.lore().forEach(item::addLoreLines); return item; } - public ItemTranslation fetchTranslation(String key, Object... args) { + public Translation translate(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) { + if (name == null && lore == null) { logger.warning(nameKey + " doesn't exists! Is your language file outdated?"); - return new ItemTranslation(nameKey, new ArrayList<>() {{ - add(loreKey); - }}); + return new Translation(nameKey, new ArrayList<>(List.of(loreKey))); } // Add all elements to a list final ArrayList toTranslate = new ArrayList<>(); - toTranslate.add(name); + if (name != null) { + toTranslate.add(name); + } if (lore != null && !lore.isEmpty()) { toTranslate.addAll(lore); } @@ -91,13 +89,19 @@ public class I18N { lineIndex++; } - if (lore == null || lore.isEmpty()) { - return new ItemTranslation(toTranslate.get(0), new ArrayList<>()); + if (name == null && !lore.isEmpty()) { + // Empty name, valid lore + return new Translation(null, toTranslate); + } else if (name != null && (lore == null || lore.isEmpty())) { + // Valid name, empty lore + return new Translation(toTranslate.get(0), new ArrayList<>(Collections.emptyList())); + } else { + // Valid name, valid lore + return new Translation(toTranslate.get(0), new ArrayList<>(toTranslate.subList(1, toTranslate.size()))); } - return new ItemTranslation(toTranslate.get(0), new ArrayList<>(toTranslate.subList(1, toTranslate.size()))); } - public String translate(String key, Object... arguments) { + public String translateString(String key, Object... arguments) { final String translation = readString(key); try { formatter.applyPattern(translation); @@ -107,7 +111,7 @@ public class I18N { } } - public String translatePrefixless(String key, Object... arguments) { + public String translateStringWithoutPrefix(String key, Object... arguments) { final String translation = readString(key); try { formatter.applyPattern(translation); diff --git a/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java b/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java index 4ce1f45..0934179 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java @@ -111,6 +111,9 @@ public class I18NDict { public static class Settings { private static final String SETTINGS_KEY = GUI_KEY + "settings."; + public static final String CYCLING_CHOICES = SETTINGS_KEY + "cycling_choices"; + public static final String TOGGLEABLE_BUTTON = SETTINGS_KEY + "toggleable_button"; + public static final String LANGUAGE = SETTINGS_KEY + "language"; public static final String RANDOM_SKIN = SETTINGS_KEY + "random_skin"; } diff --git a/src/main/java/xyz/ineanto/nicko/i18n/ItemTranslation.java b/src/main/java/xyz/ineanto/nicko/i18n/ItemTranslation.java deleted file mode 100644 index e27d22e..0000000 --- a/src/main/java/xyz/ineanto/nicko/i18n/ItemTranslation.java +++ /dev/null @@ -1,5 +0,0 @@ -package xyz.ineanto.nicko.i18n; - -import java.util.ArrayList; - -public record ItemTranslation(String name, ArrayList lore) {} \ No newline at end of file diff --git a/src/main/java/xyz/ineanto/nicko/i18n/Translation.java b/src/main/java/xyz/ineanto/nicko/i18n/Translation.java new file mode 100644 index 0000000..2d610f6 --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/i18n/Translation.java @@ -0,0 +1,5 @@ +package xyz.ineanto.nicko.i18n; + +import java.util.ArrayList; + +public record Translation(String name, ArrayList lore) {} \ No newline at end of file diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 7297af5..4b46b11 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -39,6 +39,11 @@ gui: cache: "Nicko > Admin... > Cache" invalidate_skin: "... > Cache > Invalidate" + cycling_choices: + name: "IGNOREME" + lore: + - "§7§oGet through the values" + - "§7§oby left or right clicking." exit: name: "Exit" go_back: @@ -128,15 +133,18 @@ gui: lore: - "§7Click to invalidate..." settings: + toggleable_button: + name: "IGNORE_ME" + lore: + # {0}/{1} represents the carets that shows the current selected option. + - "§b{0} Disabled" + - "§b{1} Enabled" + cycling_choices: + name: "IGNORE_ME" + lore: + - "§7§oCycle through the values" + - "§7§oby left or right clicking." language: name: "Language" - lore: - - "§7§oGet through the values" - - "§7§oby left or right clicking." random_skin: - name: "Random skin on join" - lore: - - "{0}" - - "{1}" - - "§7§oGet through the values" - - "§7§oby left or right clicking." \ No newline at end of file + name: "Random skin on login" \ No newline at end of file diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 38a568a..9b01306 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -125,15 +125,15 @@ gui: lore: - "§7Cliquez pour invalider..." settings: - language: - name: "Langage" + toggleable_button: + lore: + - "{0} Désactivé" + - "{1} Activé" + cycling_choices: lore: - "§7§oParcourez les valeurs" - "§7§oavec un clique gauche/droit." + language: + name: "Langage" random_skin: - name: "Apparence aléatoire à la connexion" - lore: - - "{0}" - - "{1}" - - "§7§oParcourez les valeurs" - - "§7§oavec un clique gauche/droit." \ No newline at end of file + name: "Apparence aléatoire à la connexion" \ No newline at end of file diff --git a/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java b/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java index 50905c3..c38889e 100644 --- a/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java @@ -10,7 +10,7 @@ import xyz.ineanto.nicko.NickoBukkit; import xyz.ineanto.nicko.config.Configuration; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; -import xyz.ineanto.nicko.i18n.ItemTranslation; +import xyz.ineanto.nicko.i18n.Translation; import xyz.ineanto.nicko.i18n.Locale; import static org.junit.jupiter.api.Assertions.*; @@ -29,7 +29,7 @@ public class ItemTranslationTest { @DisplayName("Translate Item Without Lore") public void translateItemTranslationWithoutLore() { final I18N i18n = new I18N(Locale.FRENCH); - final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.GO_BACK); + final Translation translation = i18n.translate(I18NDict.GUI.GO_BACK); assertTrue(translation.lore().isEmpty()); assertEquals(translation.name(), "Retour"); } @@ -38,7 +38,12 @@ public class ItemTranslationTest { @DisplayName("Translate Item") public void translateItemLore() { final I18N i18n = new I18N(Locale.FRENCH); - final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.Admin.Cache.STATISTICS, "1", "1"); + + final Translation test = i18n.translate(I18NDict.GUI.Settings.TOGGLEABLE_BUTTON, "EST", "EST"); + test.lore().forEach(System.out::println); + + final Translation translation = i18n.translate(I18NDict.GUI.Admin.Cache.STATISTICS, "1", "1"); + translation.lore().forEach(System.out::println); assertFalse(translation.lore().isEmpty()); assertEquals("§fNombre de requêtes: §b1", translation.lore().get(0)); assertEquals("§fNb. de skin dans le cache: §b1", translation.lore().get(1)); diff --git a/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java b/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java index 759c4bd..7f68486 100644 --- a/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java @@ -25,7 +25,7 @@ public class TranslationTest { @DisplayName("Translate Line With Replacement") public void translateItemTranslationWithoutLore() { final I18N i18n = new I18N(Locale.FRENCH); - final String translation = i18n.translatePrefixless(I18NDict.Event.Settings.ERROR, "Test"); + final String translation = i18n.translateStringWithoutPrefix(I18NDict.Event.Settings.ERROR, "Test"); assertEquals("§cImpossible de mettre à jour vos paramètres. §7§o(Test)", translation); } From 153d666b78de5cf1e7863cc48b0ab28fa39e86df Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 22 Dec 2023 14:17:21 +0100 Subject: [PATCH 178/296] refactor: final var --- .../ineanto/nicko/appearance/random/RandomNameFetcher.java | 4 ++-- .../xyz/ineanto/nicko/test/appearance/RandomNameTest.java | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java b/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java index 0557047..b6778a4 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java @@ -24,13 +24,13 @@ public class RandomNameFetcher { try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource))) { String line; while ((line = reader.readLine()) != null) { - String[] values = line.split("\n"); + final String[] values = line.split("\n"); records.add(Arrays.asList(values)); } } catch (IOException e) { throw new RuntimeException(e); } - return records.get(new Random().nextInt(records.size() -1)).get(0); + return records.get(new Random().nextInt(records.size() - 1)).get(0); } } diff --git a/src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java b/src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java index c5486b6..008dcca 100644 --- a/src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java @@ -8,8 +8,9 @@ import org.junit.jupiter.api.Test; import xyz.ineanto.nicko.NickoBukkit; import xyz.ineanto.nicko.appearance.random.RandomNameFetcher; import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.mojang.MojangUtils; -import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.*; public class RandomNameTest { private static NickoBukkit plugin; @@ -25,7 +26,9 @@ public class RandomNameTest { @DisplayName("Get random name") public void getRandomName() { final RandomNameFetcher randomNameFetcher = new RandomNameFetcher(plugin); - assertNotNull(randomNameFetcher.getRandomUsername()); + final String username = randomNameFetcher.getRandomUsername(); + assertNotNull(username); + assertFalse(MojangUtils.isUsernameInvalid(username)); } @AfterAll From 30803363badecf759c2498915491693e26fc3500 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 22 Dec 2023 14:57:24 +0100 Subject: [PATCH 179/296] feat: random skin on join --- build.gradle.kts | 48 ++++---------- .../java/xyz/ineanto/nicko/NickoBukkit.java | 7 +++ .../nicko/event/PlayerJoinListener.java | 62 +++++++++++-------- 3 files changed, 54 insertions(+), 63 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 6dbf254..cbce73f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,11 +2,10 @@ plugins { id("java") id("io.github.goooler.shadow") version "8.1.2" id("xyz.jpenilla.run-paper") version "2.2.2" - id("jvm-test-suite") } group = "xyz.ineanto" -version = "1.1.0-RC1" +version = "1.1.1-RC1" val shadowImplementation: Configuration by configurations.creating configurations["implementation"].extendsFrom(shadowImplementation) @@ -55,7 +54,7 @@ dependencies { shadowImplementation("com.github.jsixface:yamlconfig:1.2") shadowImplementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.2") shadowImplementation("com.fasterxml.jackson.core:jackson-core:2.15.2") - shadowImplementation("com.mysql:mysql-connector-j:8.1.0") + shadowImplementation("com.mysql:mysql-connector-j:8.2.0") shadowImplementation("org.mariadb.jdbc:mariadb-java-client:3.3.1") shadowImplementation("redis.clients:jedis:4.4.3") shadowImplementation("com.google.code.gson:gson:2.10.1") @@ -80,7 +79,6 @@ tasks { } shadowJar { - mustRunAfter(test) configurations = listOf(shadowImplementation) // NAMING @@ -127,42 +125,20 @@ tasks { } } + jar { + enabled = false + } + + test { + useJUnitPlatform() + } + runServer { downloadPlugins { url("https://download.luckperms.net/1526/bukkit/loader/LuckPerms-Bukkit-5.4.113.jar") url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar") } - // Configure the Minecraft version for our task. - // This is the only required configuration besides applying the plugin. - // Your plugin's jar (or shadowJar if present) will be used automatically. + minecraftVersion("1.20.2") } -} - -tasks.named("jar").configure { - enabled = false -} - -tasks.test { - useJUnitPlatform() -} - -// For when Gradle 9.0 releases. -/** -testing { - suites { - val test by getting(JvmTestSuite::class) { - targets { - useJUnitJupiter() - } - - dependencies { - implementation(project()) - implementation("com.github.seeseemelk:MockBukkit-v1.20:3.58.0") - implementation("org.junit.jupiter:junit-jupiter-api:5.10.1") - implementation("org.junit.jupiter:junit-jupiter-engine:5.10.1") - implementation("org.junit.jupiter:junit-jupiter:5.10.1") - } - } - } -} */ \ No newline at end of file +} \ No newline at end of file diff --git a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java index 414a781..6ea29a3 100644 --- a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java +++ b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java @@ -6,6 +6,7 @@ import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.command.PluginCommand; import org.bukkit.plugin.java.JavaPlugin; +import xyz.ineanto.nicko.appearance.random.RandomNameFetcher; import xyz.ineanto.nicko.command.NickoCommand; import xyz.ineanto.nicko.config.Configuration; import xyz.ineanto.nicko.config.ConfigurationManager; @@ -38,6 +39,7 @@ public class NickoBukkit extends JavaPlugin { private Configuration configuration; private LocaleFileManager localeFileManager; private PlayerNameStore nameStore; + private RandomNameFetcher nameFetcher; private Metrics metrics; public NickoBukkit() { @@ -63,6 +65,7 @@ public class NickoBukkit extends JavaPlugin { mojangAPI = new MojangAPI(); dataStore = new PlayerDataStore(mojangAPI, getNickoConfig()); nameStore = new PlayerNameStore(); + nameFetcher = new RandomNameFetcher(this); if (!Bukkit.getOnlineMode()) { getLogger().warning("Nicko has not been tested using offline mode!"); @@ -178,6 +181,10 @@ public class NickoBukkit extends JavaPlugin { } } + public RandomNameFetcher getNameFetcher() { + return nameFetcher; + } + public PlayerDataStore getDataStore() { return dataStore; } diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java index 0baa19e..9921802 100644 --- a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java @@ -1,5 +1,6 @@ package xyz.ineanto.nicko.event; +import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -34,37 +35,44 @@ public class PlayerJoinListener implements Listener { final I18N i18n = new I18N(player); final PlayerNameStore nameStore = instance.getNameStore(); final PlayerDataStore dataStore = instance.getDataStore(); - nameStore.storeName(player); - Bukkit.getScheduler().runTaskLater(instance, () -> { - 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.translateString(I18NDict.Event.Appearance.Restore.OK)); - } else { - player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Restore.ERROR, i18n.translateStringWithoutPrefix(actionResult.getErrorKey()))); - } + final Optional optionalProfile = dataStore.getData(player.getUniqueId()); + optionalProfile.ifPresent(profile -> { + // Random Skin on connection feature + if (profile.isRandomSkin()) { + Bukkit.broadcast(Component.text("§c[ELITE DEBUG] §fJoined with Random Skin.")); + final String name = instance.getNameFetcher().getRandomUsername(); + final String skin = instance.getNameFetcher().getRandomUsername(); + profile.setName(name); + profile.setSkin(skin); + dataStore.updateCache(player.getUniqueId(), 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.translateString(I18NDict.Event.Appearance.Restore.OK)); + } else { + player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Restore.ERROR, i18n.translateStringWithoutPrefix(actionResult.getErrorKey()))); + } + } + }); + + for (Player online : Bukkit.getOnlinePlayers().stream().filter(op -> op.getUniqueId() != player.getUniqueId()).toList()) { + final Optional optionalOnlinePlayerProfile = dataStore.getData(online.getUniqueId()); + + optionalOnlinePlayerProfile.ifPresent(profile -> { + final AppearanceManager appearanceManager = new AppearanceManager(online); + final boolean needsASkinChange = profile.getSkin() != null && !profile.getSkin().equals(online.getName()); + final ActionResult actionResult = appearanceManager.updateForOthers(needsASkinChange, false); + if (actionResult.isError()) { + logger.warning("Something wrong happened while updating players to joining player (" + actionResult.getErrorKey() + ")"); } }); - - for (Player online : Bukkit.getOnlinePlayers().stream().filter(op -> op.getUniqueId() != player.getUniqueId()).toList()) { - final Optional optionalOnlinePlayerProfile = dataStore.getData(online.getUniqueId()); - - optionalOnlinePlayerProfile.ifPresent(profile -> { - final AppearanceManager appearanceManager = new AppearanceManager(online); - final boolean needsASkinChange = profile.getSkin() != null && !profile.getSkin().equals(online.getName()); - final ActionResult actionResult = appearanceManager.updateForOthers(needsASkinChange, false); - if (actionResult.isError()) { - logger.warning("Something wrong happened while updating players to joining player (" + actionResult.getErrorKey() + ")"); - } - }); - } - }, 20L); + } @SuppressWarnings("unchecked") final ArrayList viewers = (ArrayList) PlayerCheckGUIData.VIEWERS.clone(); viewers.forEach(uuid -> { From 3377dcf2bf1d5df0004d8d28b9a5c2933bfeabd0 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 22 Dec 2023 15:01:30 +0100 Subject: [PATCH 180/296] feat: error handling on invalid skin/name --- .../xyz/ineanto/nicko/appearance/AppearanceManager.java | 7 +++++++ .../java/xyz/ineanto/nicko/event/PlayerJoinListener.java | 2 -- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index 26dd09e..fa7bd53 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -114,15 +114,22 @@ public class AppearanceManager { properties.get("textures").clear(); properties.put("textures", new WrappedSignedProperty("textures", skinResult.value(), skinResult.signature())); } else { + profile.setSkin(null); + dataStore.updateCache(player.getUniqueId(), profile); return ActionResult.error(I18NDict.Error.MOJANG_SKIN); } } else { + profile.setName(null); + dataStore.updateCache(player.getUniqueId(), profile); return ActionResult.error(I18NDict.Error.MOJANG_NAME); } return ActionResult.ok(); } catch (ExecutionException e) { return ActionResult.error(I18NDict.Error.CACHE); } catch (IOException e) { + profile.setName(null); + profile.setSkin(null); + dataStore.updateCache(player.getUniqueId(), profile); return ActionResult.error(I18NDict.Error.MOJANG_NAME); } } diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java index 9921802..7e06e37 100644 --- a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java @@ -1,6 +1,5 @@ package xyz.ineanto.nicko.event; -import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -41,7 +40,6 @@ public class PlayerJoinListener implements Listener { optionalProfile.ifPresent(profile -> { // Random Skin on connection feature if (profile.isRandomSkin()) { - Bukkit.broadcast(Component.text("§c[ELITE DEBUG] §fJoined with Random Skin.")); final String name = instance.getNameFetcher().getRandomUsername(); final String skin = instance.getNameFetcher().getRandomUsername(); profile.setName(name); From 84e792880f73819ca1a2fe91caff029e19deb28a Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 22 Dec 2023 17:23:36 +0100 Subject: [PATCH 181/296] feat(i18n): move to adventure --- build.gradle.kts | 1 + .../nicko/appearance/AppearanceManager.java | 8 +- .../java/xyz/ineanto/nicko/gui/HomeGUI.java | 9 +- .../gui/items/admin/cache/CacheEntryItem.java | 25 +++--- .../gui/items/common/ScrollDownItem.java | 3 +- .../nicko/gui/items/common/ScrollUpItem.java | 3 +- .../nicko/gui/items/home/RandomSkinItem.java | 53 ++++++++++++ .../nicko/gui/items/home/ResetItem.java | 2 - .../items/settings/LanguageCyclingItem.java | 3 +- .../java/xyz/ineanto/nicko/i18n/I18N.java | 16 +++- .../java/xyz/ineanto/nicko/i18n/I18NDict.java | 1 + src/main/resources/en.yml | 85 +++++++++---------- src/main/resources/fr.yml | 76 +++++++++-------- 13 files changed, 175 insertions(+), 110 deletions(-) create mode 100644 src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java diff --git a/build.gradle.kts b/build.gradle.kts index cbce73f..39403a9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -49,6 +49,7 @@ dependencies { implementation("com.comphenix.protocol:ProtocolLib:5.1.1-SNAPSHOT") shadowImplementation("me.clip:placeholderapi:2.11.4") + shadowImplementation("net.kyori:adventure-api:4.14.0") shadowImplementation("xyz.xenondevs.invui:invui:1.23") shadowImplementation("net.wesjd:anvilgui:1.9.0-SNAPSHOT") shadowImplementation("com.github.jsixface:yamlconfig:1.2") diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index fa7bd53..c4cd1e0 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -40,13 +40,7 @@ public class AppearanceManager { profile.setName(defaultName); profile.setSkin(defaultName); dataStore.getCache().cache(player.getUniqueId(), profile); - final ActionResult actionResult = updatePlayer(true, true); - if (!actionResult.isError()) { - profile.setSkin(null); - profile.setName(null); - dataStore.getCache().cache(player.getUniqueId(), profile); - } - return actionResult; + return updatePlayer(true, true); } public ActionResult updatePlayer(boolean skinChange, boolean reset) { diff --git a/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java b/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java index 24d9b06..92e3d1b 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java @@ -4,10 +4,7 @@ import org.bukkit.entity.Player; import xyz.ineanto.nicko.gui.items.appearance.ChangeBothItem; import xyz.ineanto.nicko.gui.items.appearance.ChangeNameItem; import xyz.ineanto.nicko.gui.items.appearance.ChangeSkinItem; -import xyz.ineanto.nicko.gui.items.home.AdminAccessItem; -import xyz.ineanto.nicko.gui.items.home.ExitItem; -import xyz.ineanto.nicko.gui.items.home.ResetItem; -import xyz.ineanto.nicko.gui.items.home.SettingsAccessItem; +import xyz.ineanto.nicko.gui.items.home.*; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.gui.Gui; @@ -20,7 +17,7 @@ public class HomeGUI { public HomeGUI(Player player) { final String[] dynamicStructure = new String[]{ - "# # # # # # # # #", + "# # # # D # # # #", "A # # N B S # # #", "E P # # # # # # R"}; @@ -38,6 +35,7 @@ public class HomeGUI { final ChangeSkinItem changeSkinItem = new ChangeSkinItem(player); final SettingsAccessItem settingsAccessItem = new SettingsAccessItem(player); final AdminAccessItem adminAccessItem = new AdminAccessItem(player); + final RandomSkinItem randomSkinItem = new RandomSkinItem(player); this.gui = Gui.normal() .setStructure(dynamicStructure) @@ -48,6 +46,7 @@ public class HomeGUI { .addIngredient('S', changeSkinItem.get()) .addIngredient('P', settingsAccessItem.get()) .addIngredient('A', adminAccessItem.get()) + .addIngredient('D', randomSkinItem.get()) .build(); this.player = player; } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java index 56a5cd1..286cade 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java @@ -1,5 +1,6 @@ package xyz.ineanto.nicko.gui.items.admin.cache; +import net.kyori.adventure.text.Component; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; @@ -27,17 +28,19 @@ public class CacheEntryItem extends AsyncItem { private final MojangAPI mojangAPI = NickoBukkit.getInstance().getMojangAPI(); public CacheEntryItem(I18N i18n, String uuid) { - super(new ItemBuilder(Material.PAINTING).setDisplayName("§7§oLoading..."), () -> { - final String dashedUuid = uuid.replaceAll("(.{8})(.{4})(.{4})(.{4})(.+)", "$1-$2-$3-$4-$5"); - final UUID uuidObject = UUID.fromString(dashedUuid); - try { - final SkullBuilder skull = new SkullBuilder(uuidObject); - return i18n.translateItem(skull, I18NDict.GUI.Admin.Cache.ENTRY, NickoBukkit.getInstance().getMojangAPI().getUUIDName(uuid)); - } catch (MojangApiUtils.MojangApiException | IOException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to get Head texture for specified UUID (" + uuid + ")! (GUI/Cache/Entry)"); - return ItemDefaults.getErrorSkullItem(i18n, I18NDict.GUI.Admin.Cache.ENTRY, NickoBukkit.getInstance().getMojangAPI().getUUIDName(uuid)); - } - }); + super(new ItemBuilder(Material.PAINTING) + .setDisplayName(Component.text(i18n.translateStringWithoutPrefix(I18NDict.GUI.LOADING)).content()), + () -> { + final String dashedUuid = uuid.replaceAll("(.{8})(.{4})(.{4})(.{4})(.+)", "$1-$2-$3-$4-$5"); + final UUID uuidObject = UUID.fromString(dashedUuid); + try { + final SkullBuilder skull = new SkullBuilder(uuidObject); + return i18n.translateItem(skull, I18NDict.GUI.Admin.Cache.ENTRY, NickoBukkit.getInstance().getMojangAPI().getUUIDName(uuid)); + } catch (MojangApiUtils.MojangApiException | IOException e) { + NickoBukkit.getInstance().getLogger().warning("Unable to get Head texture for specified UUID (" + uuid + ")! (GUI/Cache/Entry)"); + return ItemDefaults.getErrorSkullItem(i18n, I18NDict.GUI.Admin.Cache.ENTRY, NickoBukkit.getInstance().getMojangAPI().getUUIDName(uuid)); + } + }); this.uuid = uuid; this.name = mojangAPI.getUUIDName(uuid); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java index f836f78..44b32ab 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java @@ -1,5 +1,6 @@ package xyz.ineanto.nicko.gui.items.common; +import net.kyori.adventure.text.Component; import org.bukkit.Material; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; @@ -21,7 +22,7 @@ public class ScrollDownItem extends ScrollItem { public ItemProvider getItemProvider(ScrollGui gui) { final ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); final Translation translation = i18n.translate(I18NDict.GUI.SCROLL_DOWN); - builder.setDisplayName(translation.name()); + builder.setDisplayName(Component.text(translation.name()).content()); if (!gui.canScroll(1)) translation.lore().forEach(builder::addLoreLines); return builder; } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java index 51dc950..0e60dfa 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java @@ -1,5 +1,6 @@ package xyz.ineanto.nicko.gui.items.common; +import net.kyori.adventure.text.Component; import org.bukkit.Material; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; @@ -21,7 +22,7 @@ public class ScrollUpItem extends ScrollItem { public ItemProvider getItemProvider(ScrollGui gui) { final ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE); final Translation translation = i18n.translate(I18NDict.GUI.SCROLL_UP); - builder.setDisplayName(translation.name()); + builder.setDisplayName(Component.text(translation.name()).content()); if (!gui.canScroll(-1)) translation.lore().forEach(builder::addLoreLines); return builder; } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java new file mode 100644 index 0000000..16d6675 --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java @@ -0,0 +1,53 @@ +package xyz.ineanto.nicko.gui.items.home; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.appearance.AppearanceManager; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.xenondevs.invui.item.builder.SkullBuilder; +import xyz.xenondevs.invui.item.impl.SuppliedItem; + +import java.util.Optional; + +public class RandomSkinItem { + private final I18N i18n; + private final NickoBukkit instance; + + public RandomSkinItem(Player player) { + this.instance = NickoBukkit.getInstance(); + this.i18n = new I18N(player); + } + + public SuppliedItem get() { + return new SuppliedItem(() -> { + final SkullBuilder.HeadTexture texture = new SkullBuilder.HeadTexture("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzgzMTEzOGMyMDYxMWQzMDJjNDIzZmEzMjM3MWE3NDNkMTc0MzdhMTg5NzNjMzUxOTczNDQ3MGE3YWJiNCJ9fX0="); + final SkullBuilder builder = new SkullBuilder(texture); + return i18n.translateItem(builder, I18NDict.GUI.Home.RANDOM_SKIN); + }, (event) -> { + final Player player = event.getPlayer(); + final ClickType clickType = event.getClickType(); + if (clickType.isLeftClick() || clickType.isRightClick()) { + final Optional optionalProfile = NickoProfile.get(player); + optionalProfile.ifPresent(profile -> { + final String name = instance.getNameFetcher().getRandomUsername(); + final String skin = instance.getNameFetcher().getRandomUsername(); + profile.setName(name); + profile.setSkin(skin); + instance.getDataStore().updateCache(player.getUniqueId(), profile); + + final AppearanceManager appearanceManager = new AppearanceManager(player); + if (!appearanceManager.updatePlayer(true, false).isError()) { + player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Set.OK)); + } else { + player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Set.ERROR)); + } + }); + return true; + } + return false; + }); + } +} diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java index f8bf299..4ee2bad 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java @@ -40,8 +40,6 @@ public class ResetItem { player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Remove.OK)); } else { player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Remove.ERROR)); - profile.setSkin(null); - profile.setName(null); } }); return true; diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java index 4a2946e..3fa196a 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java @@ -1,5 +1,6 @@ package xyz.ineanto.nicko.gui.items.settings; +import net.kyori.adventure.text.Component; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; @@ -59,7 +60,7 @@ public class LanguageCyclingItem { final Translation translation = i18n.translate(I18NDict.GUI.Settings.LANGUAGE); final Translation cyclingChoicesTranslation = i18n.translate(I18NDict.GUI.Settings.CYCLING_CHOICES); - builder.setDisplayName(translation.name()); + builder.setDisplayName(Component.text(translation.name()).content()); for (Locale value : locales) { if (locale != value) { builder.addLoreLines("§7> " + value.getName()); diff --git a/src/main/java/xyz/ineanto/nicko/i18n/I18N.java b/src/main/java/xyz/ineanto/nicko/i18n/I18N.java index 1b1f14b..fd33cec 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/I18N.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/I18N.java @@ -1,6 +1,9 @@ package xyz.ineanto.nicko.i18n; import com.github.jsixface.YamlConfig; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.entity.Player; import xyz.ineanto.nicko.NickoBukkit; import xyz.ineanto.nicko.profile.NickoProfile; @@ -36,7 +39,18 @@ public class I18N { public AbstractItemBuilder translateItem(AbstractItemBuilder item, String key, Object... args) { final Translation translation = translate(key, args); - item.setDisplayName(translation.name()); + + // Name serialization + final Component deserializedName = MiniMessage.miniMessage().deserialize(translation.name()); + final String serializedName = LegacyComponentSerializer.legacySection().serialize(deserializedName); + + // Lore serialization + translation.lore().replaceAll(s -> { + final Component deserializedLoreLine = MiniMessage.miniMessage().deserialize(s); + return LegacyComponentSerializer.legacySection().serialize(deserializedLoreLine); + }); + + item.setDisplayName(serializedName); translation.lore().forEach(item::addLoreLines); return item; } diff --git a/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java b/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java index 0934179..8055a4c 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java @@ -105,6 +105,7 @@ public class I18NDict { 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 RANDOM_SKIN = HOME_KEY + "random_skin"; public static final String SETTINGS = HOME_KEY + "settings"; } diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 4b46b11..c719d68 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -39,11 +39,6 @@ gui: cache: "Nicko > Admin... > Cache" invalidate_skin: "... > Cache > Invalidate" - cycling_choices: - name: "IGNOREME" - lore: - - "§7§oGet through the values" - - "§7§oby left or right clicking." exit: name: "Exit" go_back: @@ -51,99 +46,97 @@ gui: unavailable: name: "Unavailable" lore: - - "§7§oThis button is disabled." + - "This button is disabled." error: name: "Error!" lore: - - "§7" - - "§7The item texture failed to load, but it might still work." + - "The item texture failed to load, but it might still work." loading: - name: "§7§oLoading..." + name: "Loading..." choice: confirm: - name: "§aConfirm" + name: "Confirm" choose: - name: "§6§oChoose an option..." + name: "Choose an option..." cancel: - name: "§cCancel" + name: "Cancel" scroll_up: name: "Scroll up" lore: - - "§8§o(You can't scroll any higher.)" + - "(You can't scroll any higher.)" scroll_down: name: "Scroll down" lore: - - "§8§o(You can't scroll any further down.)" + - "(You can't scroll any further down.)" home: admin: name: "Administration panel" lore: - - "§7Configure and manage Nicko." + - "Configure and manage Nicko." settings: name: "Settings" lore: - - "§7Fine tune your experience with Nicko." + - "Fine tune your experience with Nicko." change_name: - name: "§6Nickname §fchange" + name: "Change your nickname" change_skin: - name: "§6Skin §fchange" + name: "Change your skin" change_both: - name: "Change §6both" + name: "Change both" + random_skin: + name: "Get a random appearance!" reset: name: "Reset appearance" lore: - - "§7Completely remove your disguise." + - "Completely remove your disguise." admin: manage_cache: - name: "Manage §6skin §fcache..." + name: "Manage the skin cache..." lore: - - "§7View and manage the skin cache." + - "View and manage the skin cache." manage_player: - name: "Check a player..." + name: "Inspect a player..." lore: - - "§7See players' disguise information." + - "See players' disguise information." check: - name: "§6{0}" + name: "{0}" lore: - - "§cNicked: §a{1}" - - "§cName: §6{2}" - - "§cSkin: §6{3}" + - "Nicked: {1}" + - "Name: {2}" + - "Skin: {3}" - " " - - "§7§oClick to remove skin!" + - "Click to remove skin!" cache: statistics: name: "Statistics" lore: - - "§fRequest count: §b{0}" - - "§fNumber of skin cached: §b{1}" - - "§8§oCache is cleared every 24 hours." + - "Request count: {0}" + - "Number of skin cached: {1}" + - "Cache 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." + - "NOT RECOMMENDED" + - "Invalidate the entirety of the skin cache." + - "This 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." + - "Select a specific skin to invalidate." + - "Useful if a skin has been recently updated." entry: - name: "§6{0}" + name: "{0}" lore: - - "§7Click to invalidate..." + - "Click to invalidate..." settings: toggleable_button: - name: "IGNORE_ME" lore: - # {0}/{1} represents the carets that shows the current selected option. - - "§b{0} Disabled" - - "§b{1} Enabled" + - "{0} Disabled" + - "{1} Enabled" cycling_choices: - name: "IGNORE_ME" lore: - - "§7§oCycle through the values" - - "§7§oby left or right clicking." + - "Cycle through the values" + - "by left or right clicking." language: name: "Language" random_skin: diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 9b01306..5532c1e 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -46,84 +46,90 @@ gui: unavailable: name: "Indisponible" lore: - - "§7§oCe boutton est désactivé." + - "Ce boutton est désactivé." + error: + name: "Erreur!" + lore: + - "La texture de l'objet n'a pas chargé" + - "correctement mais il fonctionne encore." loading: - name: "§7§oChargement..." + name: "Chargement..." choice: confirm: - name: "§aConfirmer" + name: "Confirmer" choose: - name: "§6§oChoisissez une option..." + name: "Choisissez une option..." cancel: - name: "§cAnnuler" + name: "Annuler" scroll_up: name: "Défiler vers le haut" lore: - - "§8§o(Impossible de défiler plus haut.)" + - "(Impossible de défiler plus haut.)" scroll_down: name: "Défiler vers le bas" lore: - - "§8§o(Impossible de défiler plus bas.)" + - "(Impossible de défiler plus bas.)" home: admin: name: "Panel d'administration" lore: - - "§7Configurez et gérez Nicko." + - "Configurez et gérez Nicko." settings: name: "Paramètres" lore: - - "§7Gérez votre expérience avec Nicko." + - "Gérez votre expérience avec Nicko." change_name: - name: "Changer le §6pseudo" + name: "Changer le pseudo" change_skin: - name: "Changer le §6skin" + name: "Changer le skin" change_both: - name: "Changer les §6deux" + name: "Changer les deux" + random_skin: + name: "Obtenir une apparence aléatoire !" reset: name: "Réinitialiser l'apparence" lore: - - "§7Supprime complètement votre déguisement." + - "Supprime complètement votre déguisement." admin: manage_cache: - name: "Gérer le cache de §6skin..." + name: "Gérer le cache de skin..." lore: - - "§7Consultez et gérez le cache de skin." + - "Consultez 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." + - "Vérifiez les informations de déguisement d'un joueur." check: - name: "§6{0}" + name: "{0}" lore: - - "§cDéguisé: §a{1}" - - "§cNom: §6{2}" - - "§cSkin: §6{3}" + - "Déguisé: {1}" + - "Nom: {2}" + - "Skin: {3}" - " " - - "§7§oCliquez pour retirer le skin!" + - "Cliquez pour retirer le skin !" 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." + - "Nombre de requêtes: {0}" + - "Nb. de skin dans le cache: {1}" + - "Le 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." + - "DÉCONSEILLÉ" + - "Invalide l'entièreté du cache des skin." + - "Ne retire pas les déguisements des joueurs." 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." + - "Sélectionnez une apparence spécifique à" + - "invalider. Utile dans le cas où un skin" + - "a récemment été mis à jour." entry: - name: "§6{0}" + name: "{0}" lore: - - "§7Cliquez pour invalider..." + - "Cliquez pour invalider..." settings: toggleable_button: lore: @@ -131,8 +137,8 @@ gui: - "{1} Activé" cycling_choices: lore: - - "§7§oParcourez les valeurs" - - "§7§oavec un clique gauche/droit." + - "Parcourez les valeurs" + - "avec un clique gauche/droit." language: name: "Langage" random_skin: From c78ba0c84a795fc6deca44e10ce88267058938e5 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 22 Dec 2023 17:44:29 +0100 Subject: [PATCH 182/296] feat(i18n): final touches from the move to adventure --- .../ineanto/nicko/appearance/AppearanceManager.java | 9 ++++++++- .../gui/items/admin/check/PlayerInformationItem.java | 6 +++--- .../nicko/gui/items/common/ScrollDownItem.java | 11 ++++++++++- .../ineanto/nicko/gui/items/common/ScrollUpItem.java | 11 ++++++++++- .../nicko/gui/items/settings/LanguageCyclingItem.java | 7 +++++++ .../gui/items/settings/RandomSkinCyclingItem.java | 8 ++++++++ src/main/resources/fr.yml | 2 +- .../ineanto/nicko/test/i18n/ItemTranslationTest.java | 6 +++--- 8 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index c4cd1e0..dd04abb 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -40,7 +40,14 @@ public class AppearanceManager { profile.setName(defaultName); profile.setSkin(defaultName); dataStore.getCache().cache(player.getUniqueId(), profile); - return updatePlayer(true, true); + + final ActionResult result = updatePlayer(true, true); + if (!result.isError()) { + profile.setName(null); + profile.setSkin(null); + dataStore.getCache().cache(player.getUniqueId(), profile); + } + return result; } public ActionResult updatePlayer(boolean skinChange, boolean reset) { diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java index d3f9ed3..7856b64 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java @@ -43,9 +43,9 @@ public class PlayerInformationItem extends AsyncItem { final NickoProfile profile = optionalProfile.get(); final AbstractItemBuilder headItem = i18n.translateItem(skull, I18NDict.GUI.Admin.CHECK, target.getName(), - (profile.hasData() ? "§a✔" : "§c❌"), - (profile.getName() == null ? "§7N/A" : profile.getName()), - (profile.getSkin() == null ? "§7N/A" : profile.getSkin())); + (profile.hasData() ? "" : ""), + (profile.getName() == null ? "N/A" : profile.getName()), + (profile.getSkin() == null ? "N/A" : profile.getSkin())); if (!profile.hasData()) { // Remove the last 2 lines of the lore. diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java index 44b32ab..4f8c333 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java @@ -1,6 +1,8 @@ package xyz.ineanto.nicko.gui.items.common; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.Material; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; @@ -23,7 +25,14 @@ public class ScrollDownItem extends ScrollItem { final ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); final Translation translation = i18n.translate(I18NDict.GUI.SCROLL_DOWN); builder.setDisplayName(Component.text(translation.name()).content()); - if (!gui.canScroll(1)) translation.lore().forEach(builder::addLoreLines); + if (!gui.canScroll(1)) { + // Lore serialization + translation.lore().replaceAll(s -> { + final Component deserializedLoreLine = MiniMessage.miniMessage().deserialize(s); + return LegacyComponentSerializer.legacySection().serialize(deserializedLoreLine); + }); + translation.lore().forEach(builder::addLoreLines); + } return builder; } } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java index 0e60dfa..d505432 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java @@ -1,6 +1,8 @@ package xyz.ineanto.nicko.gui.items.common; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.Material; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; @@ -23,7 +25,14 @@ public class ScrollUpItem extends ScrollItem { final ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE); final Translation translation = i18n.translate(I18NDict.GUI.SCROLL_UP); builder.setDisplayName(Component.text(translation.name()).content()); - if (!gui.canScroll(-1)) translation.lore().forEach(builder::addLoreLines); + if (!gui.canScroll(-1)) { + // Lore serialization + translation.lore().replaceAll(s -> { + final Component deserializedLoreLine = MiniMessage.miniMessage().deserialize(s); + return LegacyComponentSerializer.legacySection().serialize(deserializedLoreLine); + }); + translation.lore().forEach(builder::addLoreLines); + } return builder; } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java index 3fa196a..fc9fca8 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java @@ -1,6 +1,8 @@ package xyz.ineanto.nicko.gui.items.settings; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; @@ -68,6 +70,11 @@ public class LanguageCyclingItem { builder.addLoreLines("§6§l> §f" + value.getName()); } } + + cyclingChoicesTranslation.lore().replaceAll(s -> { + final Component deserializedLoreLine = MiniMessage.miniMessage().deserialize(s); + return LegacyComponentSerializer.legacySection().serialize(deserializedLoreLine); + }); cyclingChoicesTranslation.lore().forEach(builder::addLoreLines); return builder; } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java index bedb4e0..74c0546 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java @@ -1,5 +1,8 @@ package xyz.ineanto.nicko.gui.items.settings; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.Sound; import org.bukkit.entity.Player; import xyz.ineanto.nicko.NickoBukkit; @@ -61,6 +64,11 @@ public class RandomSkinCyclingItem { builder.setDisplayName(randomSkinTranslation.name()); toggleableTranslation.lore().forEach(builder::addLoreLines); + + cyclingChoicesTranslation.lore().replaceAll(s -> { + final Component deserializedLoreLine = MiniMessage.miniMessage().deserialize(s); + return LegacyComponentSerializer.legacySection().serialize(deserializedLoreLine); + }); cyclingChoicesTranslation.lore().forEach(builder::addLoreLines); return builder; } diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 5532c1e..491638d 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -35,7 +35,7 @@ gui: settings: "Nicko > Paramètres" admin: "Nicko > Administration" check: "Nicko > Admin... > Vérification" - confirm: "... > Confirmer l'action" + confirm: "... > Confirmer l''action" cache: "Nicko > Admin... > Cache" invalidate_skin: "... > Cache > Invalider" diff --git a/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java b/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java index c38889e..56b768c 100644 --- a/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java @@ -45,9 +45,9 @@ public class ItemTranslationTest { final Translation translation = i18n.translate(I18NDict.GUI.Admin.Cache.STATISTICS, "1", "1"); translation.lore().forEach(System.out::println); assertFalse(translation.lore().isEmpty()); - assertEquals("§fNombre de requêtes: §b1", translation.lore().get(0)); - assertEquals("§fNb. de skin dans le cache: §b1", translation.lore().get(1)); - assertEquals("§8§oLe cache est vidé toutes les 24 heures.", translation.lore().get(2)); + assertEquals("Nombre de requêtes: 1", translation.lore().get(0)); + assertEquals("Nb. de skin dans le cache: 1", translation.lore().get(1)); + assertEquals("Le cache est vidé toutes les 24 heures.", translation.lore().get(2)); } @AfterAll From 548d210a95e5d5b30f8f585fc0a06cf8c897880a Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 22 Dec 2023 21:23:04 +0100 Subject: [PATCH 183/296] feat: migrate custom locale --- .../java/xyz/ineanto/nicko/NickoBukkit.java | 51 ++++++------ .../xyz/ineanto/nicko/i18n/CustomLocale.java | 77 +++++++++++++++++++ .../java/xyz/ineanto/nicko/i18n/I18N.java | 2 +- .../java/xyz/ineanto/nicko/i18n/Locale.java | 4 + .../ineanto/nicko/i18n/LocaleFileManager.java | 46 ----------- .../migration/ConfigurationMigrator.java | 36 +++++++++ .../nicko/migration/CustomLocaleMigrator.java | 35 +++++++++ .../xyz/ineanto/nicko/migration/Migrator.java | 5 ++ src/main/resources/config.yml | 3 +- src/main/resources/en.yml | 5 ++ src/main/resources/fr.yml | 5 ++ 11 files changed, 196 insertions(+), 73 deletions(-) create mode 100644 src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java delete mode 100644 src/main/java/xyz/ineanto/nicko/i18n/LocaleFileManager.java create mode 100644 src/main/java/xyz/ineanto/nicko/migration/ConfigurationMigrator.java create mode 100644 src/main/java/xyz/ineanto/nicko/migration/CustomLocaleMigrator.java create mode 100644 src/main/java/xyz/ineanto/nicko/migration/Migrator.java diff --git a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java index 6ea29a3..2fb4a49 100644 --- a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java +++ b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java @@ -13,7 +13,10 @@ import xyz.ineanto.nicko.config.ConfigurationManager; import xyz.ineanto.nicko.event.PlayerJoinListener; import xyz.ineanto.nicko.event.PlayerQuitListener; import xyz.ineanto.nicko.i18n.Locale; -import xyz.ineanto.nicko.i18n.LocaleFileManager; +import xyz.ineanto.nicko.i18n.CustomLocale; +import xyz.ineanto.nicko.migration.ConfigurationMigrator; +import xyz.ineanto.nicko.migration.CustomLocaleMigrator; +import xyz.ineanto.nicko.migration.Migrator; import xyz.ineanto.nicko.mojang.MojangAPI; import xyz.ineanto.nicko.placeholder.NickoExpansion; import xyz.ineanto.nicko.storage.PlayerDataStore; @@ -24,9 +27,9 @@ import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SimpleItem; +import java.io.FileNotFoundException; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.StandardCopyOption; +import java.util.List; public class NickoBukkit extends JavaPlugin { private static NickoBukkit plugin; @@ -37,7 +40,7 @@ public class NickoBukkit extends JavaPlugin { private PlayerDataStore dataStore; private ConfigurationManager configurationManager; private Configuration configuration; - private LocaleFileManager localeFileManager; + private CustomLocale customLocale; private PlayerNameStore nameStore; private RandomNameFetcher nameFetcher; private Metrics metrics; @@ -95,19 +98,11 @@ public class NickoBukkit extends JavaPlugin { } if (!unitTesting) { - // Migrate configuration (1.0.8-RC1) - if (configuration.getVersion() == null - || configuration.getVersion().isEmpty() - || configuration.getVersionObject().compareTo(Configuration.VERSION) != 0) { - getLogger().info("Migrating configuration file from older version..."); - try { - Files.copy(configurationManager.getFile().toPath(), configurationManager.getBackupFile().toPath(), StandardCopyOption.REPLACE_EXISTING); - Files.delete(configurationManager.getFile().toPath()); - configurationManager.saveDefaultConfig(); - } catch (IOException e) { - getLogger().severe("Failed to migrate your configuration!"); - } - } + final List migrations = List.of( + new ConfigurationMigrator(this), + new CustomLocaleMigrator(this) + ); + migrations.forEach(Migrator::migrate); try { Class.forName("io.papermc.paper.threadedregions.RegionizedServerInitEvent"); @@ -116,11 +111,15 @@ public class NickoBukkit extends JavaPlugin { } catch (ClassNotFoundException ignored) { } if (configuration.isCustomLocale()) { - localeFileManager = new LocaleFileManager(); - if (localeFileManager.dumpFromLocale(Locale.ENGLISH)) { - getLogger().info("Successfully loaded custom language file."); - } else { - getLogger().severe("Failed to load custom language file!"); + try { + customLocale = new CustomLocale(this); + if (customLocale.dumpIntoFile(Locale.ENGLISH)) { + getLogger().info("Successfully loaded custom language file."); + } else { + getLogger().severe("Failed to load custom language file!"); + } + } catch (FileNotFoundException e) { + throw new RuntimeException(e); } } @@ -189,6 +188,10 @@ public class NickoBukkit extends JavaPlugin { return dataStore; } + public ConfigurationManager getConfigurationManager() { + return configurationManager; + } + public PlayerNameStore getNameStore() { return nameStore; } @@ -197,7 +200,7 @@ public class NickoBukkit extends JavaPlugin { return mojangAPI; } - public LocaleFileManager getLocaleFileManager() { - return localeFileManager; + public CustomLocale getCustomLocale() { + return customLocale; } } diff --git a/src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java b/src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java new file mode 100644 index 0000000..a70e504 --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java @@ -0,0 +1,77 @@ +package xyz.ineanto.nicko.i18n; + +import com.github.jsixface.YamlConfig; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.version.Version; +import xyz.xenondevs.invui.util.IOUtils; + +import java.io.*; +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.logging.Logger; + +public class CustomLocale { + private final Logger logger = Logger.getLogger("CustomLocale"); + private final File directory = new File(NickoBukkit.getInstance().getDataFolder() + "/lang/"); + + private final File file; + private final File backupFile; + private final NickoBukkit instance; + private final String version; + private final Version versionObject; + private final BufferedInputStream inputStream; + private final BufferedOutputStream outputStream; + private final YamlConfig yamlFile; + + public CustomLocale(NickoBukkit instance) throws FileNotFoundException { + this.instance = instance; + this.file = new File(directory, "lang.yml"); + final String date = Instant.now() + .atZone(ZoneId.systemDefault()) + .format(DateTimeFormatter.ofPattern("dd-MM-yyyy")); + this.backupFile = new File(directory, "lang.old-" + date + ".yml"); + this.inputStream = new BufferedInputStream(new FileInputStream(file)); + this.outputStream = new BufferedOutputStream(new FileOutputStream(file)); + this.yamlFile = new YamlConfig(inputStream); + this.version = yamlFile.getString("version"); + this.versionObject = Version.fromString(version); + } + + public boolean dumpIntoFile(Locale locale) { + if (locale == Locale.CUSTOM) return true; + if (file.exists()) return true; + + try { + if (directory.mkdirs()) { + if (file.createNewFile()) { + IOUtils.copy(inputStream, outputStream, 8192); + } + } + return true; + } catch (IOException e) { + logger.severe("Unable to dump Locale: " + locale.getCode() + "!"); + return false; + } + } + + public String getVersion() { + return version; + } + + public Version getVersionObject() { + return versionObject; + } + + public YamlConfig getYamlFile() { + return yamlFile; + } + + public File getBackupFile() { + return backupFile; + } + + public File getFile() { + return file; + } +} diff --git a/src/main/java/xyz/ineanto/nicko/i18n/I18N.java b/src/main/java/xyz/ineanto/nicko/i18n/I18N.java index fd33cec..24bddf6 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/I18N.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/I18N.java @@ -145,7 +145,7 @@ public class I18N { private YamlConfig getYamlConfig() { if (playerLocale == Locale.CUSTOM) { - return instance.getLocaleFileManager().getYamlFile(); + return instance.getCustomLocale().getYamlFile(); } else { final InputStream resource = instance.getResource(playerLocale.getCode() + ".yml"); return new YamlConfig(resource); diff --git a/src/main/java/xyz/ineanto/nicko/i18n/Locale.java b/src/main/java/xyz/ineanto/nicko/i18n/Locale.java index 3d8bd58..13a62c5 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/Locale.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/Locale.java @@ -1,5 +1,7 @@ package xyz.ineanto.nicko.i18n; +import xyz.ineanto.nicko.version.Version; + import java.io.Serializable; public enum Locale implements Serializable { @@ -7,6 +9,8 @@ public enum Locale implements Serializable { FRENCH("fr", "Français"), CUSTOM("cm", "Server Custom"); + public static final Version VERSION = new Version(1, 1, 0); + private final String code; private transient final String name; diff --git a/src/main/java/xyz/ineanto/nicko/i18n/LocaleFileManager.java b/src/main/java/xyz/ineanto/nicko/i18n/LocaleFileManager.java deleted file mode 100644 index e612ed8..0000000 --- a/src/main/java/xyz/ineanto/nicko/i18n/LocaleFileManager.java +++ /dev/null @@ -1,46 +0,0 @@ -package xyz.ineanto.nicko.i18n; - -import com.github.jsixface.YamlConfig; -import xyz.ineanto.nicko.NickoBukkit; -import xyz.xenondevs.invui.util.IOUtils; - -import java.io.*; -import java.nio.file.Files; -import java.util.logging.Logger; - -public class LocaleFileManager { - private final Logger logger = Logger.getLogger("LocaleFileManager"); - private final File folder = new File(NickoBukkit.getInstance().getDataFolder() + "/lang/"); - private final File file = new File(folder, "lang.yml"); - private YamlConfig yamlFile; - - public boolean dumpFromLocale(Locale locale) { - if (locale == Locale.CUSTOM) return true; - if (file.exists()) return true; - final InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(locale.getCode() + ".yml"); - try { - if (folder.mkdirs()) { - if (file.createNewFile()) { - try (FileOutputStream outputStream = new FileOutputStream(file)) { - IOUtils.copy(inputStream, outputStream, 8192); - } - } - } - return true; - } catch (IOException e) { - logger.severe("Unable to dump Locale: " + locale.getCode() + "!"); - return false; - } - } - - public YamlConfig getYamlFile() { - if (yamlFile == null) { - try (BufferedInputStream inputStream = new BufferedInputStream(Files.newInputStream(file.toPath()))) { - yamlFile = new YamlConfig(inputStream); - } catch (IOException ignored) { - return null; - } - } - return yamlFile; - } -} diff --git a/src/main/java/xyz/ineanto/nicko/migration/ConfigurationMigrator.java b/src/main/java/xyz/ineanto/nicko/migration/ConfigurationMigrator.java new file mode 100644 index 0000000..7ab3a10 --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/migration/ConfigurationMigrator.java @@ -0,0 +1,36 @@ +package xyz.ineanto.nicko.migration; + +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.config.ConfigurationManager; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; + +public class ConfigurationMigrator implements Migrator { + private final NickoBukkit instance; + + public ConfigurationMigrator(NickoBukkit instance) { + this.instance = instance; + } + + @Override + public void migrate() { + final Configuration configuration = instance.getNickoConfig(); + final ConfigurationManager configurationManager = instance.getConfigurationManager(); + + // Migrate configuration (1.0.8-RC1) + if (configuration.getVersion() == null + || configuration.getVersion().isEmpty() + || configuration.getVersionObject().compareTo(Configuration.VERSION) != 0) { + instance.getLogger().info("Migrating configuration file to match the current version..."); + try { + Files.copy(configurationManager.getFile().toPath(), configurationManager.getBackupFile().toPath(), StandardCopyOption.ATOMIC_MOVE); + configurationManager.saveDefaultConfig(); + } catch (IOException e) { + instance.getLogger().severe("Failed to migrate your configuration!"); + } + } + } +} diff --git a/src/main/java/xyz/ineanto/nicko/migration/CustomLocaleMigrator.java b/src/main/java/xyz/ineanto/nicko/migration/CustomLocaleMigrator.java new file mode 100644 index 0000000..2e9193b --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/migration/CustomLocaleMigrator.java @@ -0,0 +1,35 @@ +package xyz.ineanto.nicko.migration; + +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.i18n.CustomLocale; +import xyz.ineanto.nicko.i18n.Locale; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; + +public class CustomLocaleMigrator implements Migrator { + private final NickoBukkit instance; + + public CustomLocaleMigrator(NickoBukkit instance) { + this.instance = instance; + } + + @Override + public void migrate() { + final CustomLocale customLanguageFile = instance.getCustomLocale(); + + // Migrate custom locale (1.1.0-RC1) + if (customLanguageFile.getVersionObject() == null + || customLanguageFile.getVersion().isEmpty() + || customLanguageFile.getVersionObject().compareTo(Locale.VERSION) != 0) { + instance.getLogger().info("Migrating custom locale to match the current version..."); + try { + Files.copy(customLanguageFile.getFile().toPath(), customLanguageFile.getBackupFile().toPath(), StandardCopyOption.ATOMIC_MOVE); + customLanguageFile.dumpIntoFile(Locale.ENGLISH); + } catch (IOException e) { + instance.getLogger().severe("Failed to migrate your custom locale!"); + } + } + } +} diff --git a/src/main/java/xyz/ineanto/nicko/migration/Migrator.java b/src/main/java/xyz/ineanto/nicko/migration/Migrator.java new file mode 100644 index 0000000..89bb64e --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/migration/Migrator.java @@ -0,0 +1,5 @@ +package xyz.ineanto.nicko.migration; + +public interface Migrator { + void migrate(); +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 27cca69..92219c5 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,7 +1,6 @@ # Nicko ${version} - Config: -# Specifies the configuration version. -# Do NOT modify this field. +# Specifies the configuration version. (Don't change!) version: "1.0.8" ############ diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index c719d68..c6cb3a7 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -1,3 +1,8 @@ +# Nicko ${version} - Language File: + +# Specifies the configuration version, don't change. +version: "1.1.0" + error: generic: "An unknown error occurred." permission: "§cYou do not have the required permission." diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 491638d..e71d358 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -1,3 +1,8 @@ +# Nicko ${version} - Config: + +# Specifies the configuration version, don't change. +version: "1.1.0" + error: generic: "Une erreur inconnue c'est produite." permission: "§cVous ne possédez pas la permission." From ce8f21c2682a056a652c7a024f7e5869ea759dca Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 23 Dec 2023 00:00:24 +0100 Subject: [PATCH 184/296] feat(i18n): custom locale migration --- CHANGELOG.log | 20 ++++-- build.gradle.kts | 2 +- .../java/xyz/ineanto/nicko/NickoBukkit.java | 58 +++++++-------- .../appearance/random/RandomNameFetcher.java | 2 +- .../xyz/ineanto/nicko/i18n/CustomLocale.java | 55 ++++++-------- .../nicko/migration/CustomLocaleMigrator.java | 32 ++++++--- src/main/resources/{names.csv => names.txt} | 2 +- .../test/config/ConfigurationVersionTest.java | 4 +- .../nicko/test/i18n/ItemTranslationTest.java | 1 - .../nicko/test/migration/MigrationTest.java | 71 +++++++++++++++++++ src/test/resources/en.yml | 4 ++ 11 files changed, 165 insertions(+), 86 deletions(-) rename src/main/resources/{names.csv => names.txt} (99%) create mode 100644 src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java create mode 100644 src/test/resources/en.yml diff --git a/CHANGELOG.log b/CHANGELOG.log index fd7fe3c..1585289 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,13 +1,25 @@ -1.0.9-RC1: Update n°6 (20/12/23) +1.1.0-RC1: Update n°6 (XX/12/23) + [BREAKING] + - The language system has been updated to use the Adventure API (https://docs.advntr.dev/index.html). This results in custom locale now breaking + Nicko upon usage of legacy color codes (e.g., "§6Nicko"). Your custom locale will be backed up upon starting this version and you will be able to + use the new default English locale to help you make your locale compatible with the new formatting. + [FEATURES] - - + - Players can now choose to get a random appearance via a list of more than 400 usernames and skins associated. + - Players can now toggle a setting to automatically get a random appearance upon joining. + - Introduced a version string inside Nicko's language files to plan future updates to the file. (see [BREAKING]) + + (Note: the random skin functionality is still work-in-progress and might break or not work at all because of + the lack of time that I have to test all the usernames and skins associated.) [FIXES] - - bStats metrics should be properly sent now(?) + - Various optimizations and improvements. + - Internal refactoring + - bStats metrics are not minified anymore. 1.0.8-RC1: Update n°5 (19/12/23) [FEATURES] - - Introduced a version string inside Nicko's configuration to plan future updated to the file. Your previous configuration file will automatically be migrated to this current version (with the backup of your old one included!) + - Introduced a version string inside Nicko's configuration to plan future updates to the file. Your previous configuration file will automatically be migrated to this current version (with the backup of your old one included!) - Persistence and cache will now fallback to local alternatives when unreachable. - Player check GUI has been updated to better reflect the current state of player's disguises. - Developers can now listen to the PlayerDisguiseEvent and cancel the disguise process. diff --git a/build.gradle.kts b/build.gradle.kts index 39403a9..1f1ba0f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } group = "xyz.ineanto" -version = "1.1.1-RC1" +version = "1.1.0-RC1" val shadowImplementation: Configuration by configurations.creating configurations["implementation"].extendsFrom(shadowImplementation) diff --git a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java index 2fb4a49..2ec8bc6 100644 --- a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java +++ b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java @@ -12,11 +12,10 @@ import xyz.ineanto.nicko.config.Configuration; import xyz.ineanto.nicko.config.ConfigurationManager; import xyz.ineanto.nicko.event.PlayerJoinListener; import xyz.ineanto.nicko.event.PlayerQuitListener; -import xyz.ineanto.nicko.i18n.Locale; import xyz.ineanto.nicko.i18n.CustomLocale; +import xyz.ineanto.nicko.i18n.Locale; import xyz.ineanto.nicko.migration.ConfigurationMigrator; import xyz.ineanto.nicko.migration.CustomLocaleMigrator; -import xyz.ineanto.nicko.migration.Migrator; import xyz.ineanto.nicko.mojang.MojangAPI; import xyz.ineanto.nicko.placeholder.NickoExpansion; import xyz.ineanto.nicko.storage.PlayerDataStore; @@ -27,9 +26,7 @@ import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SimpleItem; -import java.io.FileNotFoundException; import java.io.IOException; -import java.util.List; public class NickoBukkit extends JavaPlugin { private static NickoBukkit plugin; @@ -65,15 +62,7 @@ public class NickoBukkit extends JavaPlugin { configurationManager = new ConfigurationManager(getDataFolder()); configurationManager.saveDefaultConfig(); - mojangAPI = new MojangAPI(); dataStore = new PlayerDataStore(mojangAPI, getNickoConfig()); - nameStore = new PlayerNameStore(); - nameFetcher = new RandomNameFetcher(this); - - if (!Bukkit.getOnlineMode()) { - getLogger().warning("Nicko has not been tested using offline mode!"); - getLogger().warning("Issues regarding Nicko being used in offline mode will be ignored for now."); - } if (!MinecraftVersion.WILD_UPDATE.atOrAbove()) { getLogger().severe("This version (" + MinecraftVersion.getCurrentVersion().getVersion() + ") is not supported by Nicko!"); @@ -81,6 +70,17 @@ public class NickoBukkit extends JavaPlugin { Bukkit.getPluginManager().disablePlugin(this); } + if (!Bukkit.getOnlineMode()) { + getLogger().warning("Nicko has not been tested using offline mode!"); + getLogger().warning("Issues regarding Nicko being used in offline mode will be ignored for now."); + } + + try { + Class.forName("io.papermc.paper.threadedregions.RegionizedServerInitEvent"); + getLogger().warning("Nicko has not been tested against Folia and might not work at all!"); + getLogger().warning("Issues regarding Nicko on Folia will be ignored for now."); + } catch (ClassNotFoundException ignored) { } + getLogger().info("Loading persistence..."); if (!dataStore.getStorage().getProvider().init()) { getLogger().severe("Couldn't connect to distant persistence, falling back on local persistence."); @@ -98,28 +98,20 @@ public class NickoBukkit extends JavaPlugin { } if (!unitTesting) { - final List migrations = List.of( - new ConfigurationMigrator(this), - new CustomLocaleMigrator(this) - ); - migrations.forEach(Migrator::migrate); + nameStore = new PlayerNameStore(); + mojangAPI = new MojangAPI(); + nameFetcher = new RandomNameFetcher(this); - try { - Class.forName("io.papermc.paper.threadedregions.RegionizedServerInitEvent"); - getLogger().warning("Nicko has not been tested against Folia and might not work at all!"); - getLogger().warning("Issues regarding Nicko on Folia will be ignored for now."); - } catch (ClassNotFoundException ignored) { } + new ConfigurationMigrator(this).migrate(); if (configuration.isCustomLocale()) { try { - customLocale = new CustomLocale(this); - if (customLocale.dumpIntoFile(Locale.ENGLISH)) { - getLogger().info("Successfully loaded custom language file."); - } else { - getLogger().severe("Failed to load custom language file!"); - } - } catch (FileNotFoundException e) { - throw new RuntimeException(e); + CustomLocale.dumpIntoFile(Locale.ENGLISH); + customLocale = new CustomLocale(); + new CustomLocaleMigrator(this, customLocale).migrate(); + getLogger().info("Successfully loaded the custom locale."); + } catch (IOException e) { + getLogger().severe("Failed to load the custom locale!"); } } @@ -147,7 +139,6 @@ public class NickoBukkit extends JavaPlugin { @Override public void onDisable() { if (!getDataStore().getStorage().isError()) { - nameStore.clearStoredNames(); Bukkit.getOnlinePlayers().forEach(player -> dataStore.saveData(player)); if (!dataStore.getStorage().getProvider().close()) { getLogger().severe("Failed to close persistence!"); @@ -156,7 +147,10 @@ public class NickoBukkit extends JavaPlugin { } } - if (!unitTesting) metrics.shutdown(); + if (!unitTesting) { + nameStore.clearStoredNames(); + metrics.shutdown(); + } getLogger().info("Nicko (Bukkit) has been disabled."); } diff --git a/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java b/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java index b6778a4..7549203 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java @@ -19,7 +19,7 @@ public class RandomNameFetcher { } public String getRandomUsername() { - final InputStream resource = instance.getResource("names.csv"); + final InputStream resource = instance.getResource("names.txt"); final List> records = new ArrayList<>(); try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource))) { String line; diff --git a/src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java b/src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java index a70e504..f172d27 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java @@ -3,55 +3,46 @@ package xyz.ineanto.nicko.i18n; import com.github.jsixface.YamlConfig; import xyz.ineanto.nicko.NickoBukkit; import xyz.ineanto.nicko.version.Version; -import xyz.xenondevs.invui.util.IOUtils; import java.io.*; -import java.time.Instant; -import java.time.ZoneId; -import java.time.format.DateTimeFormatter; +import java.nio.file.Files; import java.util.logging.Logger; public class CustomLocale { - private final Logger logger = Logger.getLogger("CustomLocale"); - private final File directory = new File(NickoBukkit.getInstance().getDataFolder() + "/lang/"); + private static final Logger logger = Logger.getLogger("CustomLocale"); + private static final File directory = new File(NickoBukkit.getInstance().getDataFolder(), "/locale/"); + private static final File file = new File(directory, "locale.yml"); - private final File file; - private final File backupFile; - private final NickoBukkit instance; private final String version; private final Version versionObject; - private final BufferedInputStream inputStream; - private final BufferedOutputStream outputStream; private final YamlConfig yamlFile; - public CustomLocale(NickoBukkit instance) throws FileNotFoundException { - this.instance = instance; - this.file = new File(directory, "lang.yml"); - final String date = Instant.now() - .atZone(ZoneId.systemDefault()) - .format(DateTimeFormatter.ofPattern("dd-MM-yyyy")); - this.backupFile = new File(directory, "lang.old-" + date + ".yml"); - this.inputStream = new BufferedInputStream(new FileInputStream(file)); - this.outputStream = new BufferedOutputStream(new FileOutputStream(file)); - this.yamlFile = new YamlConfig(inputStream); + public CustomLocale(InputStream input) throws IOException { + this.yamlFile = new YamlConfig(input); this.version = yamlFile.getString("version"); this.versionObject = Version.fromString(version); } - public boolean dumpIntoFile(Locale locale) { - if (locale == Locale.CUSTOM) return true; - if (file.exists()) return true; + public CustomLocale() throws IOException { + this.yamlFile = new YamlConfig(new FileInputStream(file)); + this.version = yamlFile.getString("version"); + this.versionObject = Version.fromString(version); + } + public static void dumpIntoFile(Locale locale) throws IOException { + if (locale == Locale.CUSTOM) return; + if (file.exists()) return; + if (!directory.exists()) directory.mkdirs(); + + final String localeFileName = locale.getCode() + ".yml"; try { - if (directory.mkdirs()) { - if (file.createNewFile()) { - IOUtils.copy(inputStream, outputStream, 8192); - } + final InputStream resource = NickoBukkit.getInstance().getResource(localeFileName); + if (resource != null) { + Files.copy(resource, file.toPath()); + resource.close(); } - return true; } catch (IOException e) { logger.severe("Unable to dump Locale: " + locale.getCode() + "!"); - return false; } } @@ -67,8 +58,8 @@ public class CustomLocale { return yamlFile; } - public File getBackupFile() { - return backupFile; + public File getDirectory() { + return directory; } public File getFile() { diff --git a/src/main/java/xyz/ineanto/nicko/migration/CustomLocaleMigrator.java b/src/main/java/xyz/ineanto/nicko/migration/CustomLocaleMigrator.java index 2e9193b..54279ea 100644 --- a/src/main/java/xyz/ineanto/nicko/migration/CustomLocaleMigrator.java +++ b/src/main/java/xyz/ineanto/nicko/migration/CustomLocaleMigrator.java @@ -4,31 +4,41 @@ import xyz.ineanto.nicko.NickoBukkit; import xyz.ineanto.nicko.i18n.CustomLocale; import xyz.ineanto.nicko.i18n.Locale; +import java.io.File; import java.io.IOException; import java.nio.file.Files; -import java.nio.file.StandardCopyOption; +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; public class CustomLocaleMigrator implements Migrator { private final NickoBukkit instance; + private final CustomLocale customLocale; - public CustomLocaleMigrator(NickoBukkit instance) { + public CustomLocaleMigrator(NickoBukkit instance, CustomLocale customLocale) { this.instance = instance; + this.customLocale = customLocale; } @Override public void migrate() { - final CustomLocale customLanguageFile = instance.getCustomLocale(); - // Migrate custom locale (1.1.0-RC1) - if (customLanguageFile.getVersionObject() == null - || customLanguageFile.getVersion().isEmpty() - || customLanguageFile.getVersionObject().compareTo(Locale.VERSION) != 0) { - instance.getLogger().info("Migrating custom locale to match the current version..."); + if (customLocale.getVersionObject() == null + || customLocale.getVersion().isEmpty() + || customLocale.getVersionObject().compareTo(Locale.VERSION) != 0) { + instance.getLogger().info("Migrating the custom locale (" + customLocale.getVersion() + ") to match the current version (" + Locale.VERSION + ")..."); + + final String date = Instant.now().atZone(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("dd-MM-yyyy")); + final File backupFile = new File(customLocale.getDirectory(), "locale-" + date + ".yml"); + try { - Files.copy(customLanguageFile.getFile().toPath(), customLanguageFile.getBackupFile().toPath(), StandardCopyOption.ATOMIC_MOVE); - customLanguageFile.dumpIntoFile(Locale.ENGLISH); + Files.copy(customLocale.getFile().toPath(), backupFile.toPath()); + if (customLocale.getFile().delete()) { + customLocale.dumpIntoFile(Locale.ENGLISH); + } + instance.getLogger().info("Successfully migrated the custom locale."); } catch (IOException e) { - instance.getLogger().severe("Failed to migrate your custom locale!"); + instance.getLogger().severe("Failed to migrate the custom locale!"); } } } diff --git a/src/main/resources/names.csv b/src/main/resources/names.txt similarity index 99% rename from src/main/resources/names.csv rename to src/main/resources/names.txt index 4eae88f..0d54e92 100644 --- a/src/main/resources/names.csv +++ b/src/main/resources/names.txt @@ -487,4 +487,4 @@ The42OWeedGOD CooperBee _MikuMiku_ althume -Tr3bba93 +Tr3bba93 \ No newline at end of file diff --git a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java b/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java index a1b55ba..3535d7d 100644 --- a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java @@ -12,13 +12,11 @@ import xyz.ineanto.nicko.config.DefaultDataSources; import static org.junit.jupiter.api.Assertions.assertEquals; public class ConfigurationVersionTest { - private static NickoBukkit plugin; - @BeforeAll public static void setup() { MockBukkit.mock(); final Configuration configuration = Configuration.DEFAULT; - plugin = MockBukkit.load(NickoBukkit.class, configuration); + MockBukkit.load(NickoBukkit.class, configuration); } @Test diff --git a/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java b/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java index 56b768c..b9a722e 100644 --- a/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java @@ -43,7 +43,6 @@ public class ItemTranslationTest { test.lore().forEach(System.out::println); final Translation translation = i18n.translate(I18NDict.GUI.Admin.Cache.STATISTICS, "1", "1"); - translation.lore().forEach(System.out::println); assertFalse(translation.lore().isEmpty()); assertEquals("Nombre de requêtes: 1", translation.lore().get(0)); assertEquals("Nb. de skin dans le cache: 1", translation.lore().get(1)); diff --git a/src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java b/src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java new file mode 100644 index 0000000..61ba6b3 --- /dev/null +++ b/src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java @@ -0,0 +1,71 @@ +package xyz.ineanto.nicko.test.migration; + +import be.seeseemelk.mockbukkit.MockBukkit; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.config.Configuration; +import xyz.ineanto.nicko.config.DefaultDataSources; +import xyz.ineanto.nicko.i18n.CustomLocale; +import xyz.ineanto.nicko.migration.CustomLocaleMigrator; + +import java.io.*; +import java.nio.charset.StandardCharsets; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class MigrationTest { + private static NickoBukkit plugin; + + private static File folder; + private static File localeFile; + + @BeforeAll + public static void setup() throws IOException { + MockBukkit.mock(); + final Configuration configuration = new Configuration(Configuration.VERSION.toString(), + DefaultDataSources.SQL_EMPTY, + DefaultDataSources.REDIS_EMPTY, + "§6Nicko §8§l| §r", + true); + plugin = MockBukkit.load(NickoBukkit.class, configuration); + folder = new File(plugin.getDataFolder(), "/locale/"); + localeFile = new File(folder, "locale.yml"); + folder.mkdirs(); + localeFile.createNewFile(); + } + + @Test + public void testLanguageFileMigration() throws IOException { + final String content = """ + # Nicko - Language File: + + # hello I'm the invalid version + version: "1.0.0" + """; + + BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(localeFile)); + outputStream.write(content.getBytes(StandardCharsets.UTF_8)); + outputStream.flush(); + + // Get wrong locale + final CustomLocale customLocaleBeforeMigration = new CustomLocale(new FileInputStream(localeFile)); + assertEquals(customLocaleBeforeMigration.getVersion(), "1.0.0"); + + // Migrate the wrong locale to the correct one + final CustomLocaleMigrator localeMigrator = new CustomLocaleMigrator(plugin, customLocaleBeforeMigration); + localeMigrator.migrate(); + + // Get the migrated locale + final CustomLocale customLocaleMigrated = new CustomLocale(new FileInputStream(localeFile)); + assertEquals(customLocaleMigrated.getVersion(), "1.1.0"); + } + + @AfterAll + public static void shutdown() { + MockBukkit.unmock(); + folder.delete(); + localeFile.delete(); + } +} diff --git a/src/test/resources/en.yml b/src/test/resources/en.yml new file mode 100644 index 0000000..7b83c58 --- /dev/null +++ b/src/test/resources/en.yml @@ -0,0 +1,4 @@ +# Nicko ${version} - Language File: + +# hello I'm the good version +version: "1.1.0" \ No newline at end of file From b394c7ef0c3c2b1a97f7726a2d3c3aa4c1c175b0 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 23 Dec 2023 00:02:49 +0100 Subject: [PATCH 185/296] refactor(build): expand to all yml (1.1.0-RC1) --- build.gradle.kts | 5 +---- src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java | 6 ++---- src/main/resources/config.yml | 2 +- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 1f1ba0f..b9bf803 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -71,10 +71,7 @@ tasks { processResources { from("src/main/resources") duplicatesStrategy = DuplicatesStrategy.EXCLUDE - filesMatching("config.yml") { - expand("version" to version) - } - filesMatching("plugin.yml") { + filesMatching("*.yml") { expand("version" to version) } } diff --git a/src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java b/src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java index f172d27..b1e429e 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java @@ -37,10 +37,8 @@ public class CustomLocale { final String localeFileName = locale.getCode() + ".yml"; try { final InputStream resource = NickoBukkit.getInstance().getResource(localeFileName); - if (resource != null) { - Files.copy(resource, file.toPath()); - resource.close(); - } + Files.copy(resource, file.toPath()); + resource.close(); } catch (IOException e) { logger.severe("Unable to dump Locale: " + locale.getCode() + "!"); } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 92219c5..e554244 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,6 +1,6 @@ # Nicko ${version} - Config: -# Specifies the configuration version. (Don't change!) +# Specifies the configuration version, don't change. version: "1.0.8" ############ From 95b4f4cdefe29d4827800ad275f6590e057db4cf Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 23 Dec 2023 00:06:30 +0100 Subject: [PATCH 186/296] refactor: remove unused constructor --- src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java | 6 ------ .../xyz/ineanto/nicko/test/migration/MigrationTest.java | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java b/src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java index b1e429e..5007070 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java @@ -17,12 +17,6 @@ public class CustomLocale { private final Version versionObject; private final YamlConfig yamlFile; - public CustomLocale(InputStream input) throws IOException { - this.yamlFile = new YamlConfig(input); - this.version = yamlFile.getString("version"); - this.versionObject = Version.fromString(version); - } - public CustomLocale() throws IOException { this.yamlFile = new YamlConfig(new FileInputStream(file)); this.version = yamlFile.getString("version"); diff --git a/src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java b/src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java index 61ba6b3..cdc12b0 100644 --- a/src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java @@ -50,7 +50,7 @@ public class MigrationTest { outputStream.flush(); // Get wrong locale - final CustomLocale customLocaleBeforeMigration = new CustomLocale(new FileInputStream(localeFile)); + final CustomLocale customLocaleBeforeMigration = new CustomLocale(); assertEquals(customLocaleBeforeMigration.getVersion(), "1.0.0"); // Migrate the wrong locale to the correct one @@ -58,7 +58,7 @@ public class MigrationTest { localeMigrator.migrate(); // Get the migrated locale - final CustomLocale customLocaleMigrated = new CustomLocale(new FileInputStream(localeFile)); + final CustomLocale customLocaleMigrated = new CustomLocale(); assertEquals(customLocaleMigrated.getVersion(), "1.1.0"); } From 3f038c6b3df71356c5c9e50b5ba7960d470d8797 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 23 Dec 2023 00:08:52 +0100 Subject: [PATCH 187/296] style: this is not an api --- CHANGELOG.log | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.log b/CHANGELOG.log index 1585289..9187ce7 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,6 +1,6 @@ 1.1.0-RC1: Update n°6 (XX/12/23) [BREAKING] - - The language system has been updated to use the Adventure API (https://docs.advntr.dev/index.html). This results in custom locale now breaking + - The language system has been updated to use the Adventure library (https://docs.advntr.dev/index.html). This results in the custom locale breaking Nicko upon usage of legacy color codes (e.g., "§6Nicko"). Your custom locale will be backed up upon starting this version and you will be able to use the new default English locale to help you make your locale compatible with the new formatting. From 2aab497d0a83c998c8aba042324274a355a1d114 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 23 Dec 2023 00:15:29 +0100 Subject: [PATCH 188/296] fix(test): assert sql following fallback implementation --- .../java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java | 2 ++ .../java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java index e9b2859..f6b1f2c 100644 --- a/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java @@ -11,6 +11,7 @@ import xyz.ineanto.nicko.config.DataSourceConfiguration; import xyz.ineanto.nicko.config.DefaultDataSources; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.PlayerDataStore; +import xyz.ineanto.nicko.storage.redis.RedisCacheProvider; import java.util.Optional; @@ -32,6 +33,7 @@ public class RedisCacheTest { final ServerMock server = MockBukkit.mock(); plugin = MockBukkit.load(NickoBukkit.class, config); player = server.addPlayer(); + assertInstanceOf(RedisCacheProvider.class, plugin.getDataStore().getCache().getProvider()); } @Test diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java index 6f79018..f7a0dc0 100644 --- a/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java @@ -10,6 +10,7 @@ import xyz.ineanto.nicko.config.SQLDataSourceConfiguration; import xyz.ineanto.nicko.i18n.Locale; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.PlayerDataStore; +import xyz.ineanto.nicko.storage.mariadb.MariaDBStorageProvider; import java.util.Optional; import java.util.UUID; @@ -35,6 +36,7 @@ public class SQLStorageTest { final NickoBukkit plugin = MockBukkit.load(NickoBukkit.class, config); dataStore = plugin.getDataStore(); uuid = UUID.randomUUID(); + assertInstanceOf(MariaDBStorageProvider.class, dataStore.getStorage().getProvider()); } @Test From ccac492dcdc2bf1310cdaf5590c807331d3d44f5 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 27 Dec 2023 18:19:12 +0100 Subject: [PATCH 189/296] feat: update to 1.20.4 --- build.gradle.kts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index b9bf803..f374145 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } group = "xyz.ineanto" -version = "1.1.0-RC1" +version = "1.1.1-RC1" val shadowImplementation: Configuration by configurations.creating configurations["implementation"].extendsFrom(shadowImplementation) @@ -45,13 +45,13 @@ repositories { } dependencies { - implementation("io.papermc.paper:paper-api:1.20.2-R0.1-SNAPSHOT") + implementation("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT") implementation("com.comphenix.protocol:ProtocolLib:5.1.1-SNAPSHOT") shadowImplementation("me.clip:placeholderapi:2.11.4") shadowImplementation("net.kyori:adventure-api:4.14.0") - shadowImplementation("xyz.xenondevs.invui:invui:1.23") - shadowImplementation("net.wesjd:anvilgui:1.9.0-SNAPSHOT") + shadowImplementation("xyz.xenondevs.invui:invui:1.24") + shadowImplementation("net.wesjd:anvilgui:1.9.2-SNAPSHOT") shadowImplementation("com.github.jsixface:yamlconfig:1.2") shadowImplementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.2") shadowImplementation("com.fasterxml.jackson.core:jackson-core:2.15.2") @@ -137,6 +137,6 @@ tasks { url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar") } - minecraftVersion("1.20.2") + minecraftVersion("1.20.4") } } \ No newline at end of file From ba9f39659b53cb57229b24de0e113f061bd3cb73 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 27 Dec 2023 18:22:08 +0100 Subject: [PATCH 190/296] feat: update changelog --- CHANGELOG.log | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.log b/CHANGELOG.log index 9187ce7..ebc8c70 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,4 +1,9 @@ -1.1.0-RC1: Update n°6 (XX/12/23) +1.1.1-RC1: Update n°7 (27/12/23) + [FEATURES] + - Made Nicko compatible with 1.20.3 and 1.20.4. + + +1.1.0-RC1: Update n°6 (23/12/23) [BREAKING] - The language system has been updated to use the Adventure library (https://docs.advntr.dev/index.html). This results in the custom locale breaking Nicko upon usage of legacy color codes (e.g., "§6Nicko"). Your custom locale will be backed up upon starting this version and you will be able to From aa9b71bc18d01967a19de0e84177cf176928d5ef Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 28 Dec 2023 21:02:09 +0100 Subject: [PATCH 191/296] refactor(i18n): optimizations --- build.gradle.kts | 4 ++- .../xyz/ineanto/nicko/anvil/AnvilManager.java | 9 +++-- .../nicko/event/PlayerJoinListener.java | 8 +++-- .../java/xyz/ineanto/nicko/gui/AdminGUI.java | 2 +- .../ineanto/nicko/gui/CacheManagementGUI.java | 2 +- .../java/xyz/ineanto/nicko/gui/ChoiceGUI.java | 2 +- .../java/xyz/ineanto/nicko/gui/HomeGUI.java | 2 +- .../ineanto/nicko/gui/InvalidateSkinGUI.java | 2 +- .../xyz/ineanto/nicko/gui/PlayerCheckGUI.java | 2 +- .../xyz/ineanto/nicko/gui/SettingsGUI.java | 2 +- .../gui/items/admin/cache/CacheEntryItem.java | 6 ++-- .../admin/check/PlayerInformationItem.java | 2 +- .../gui/items/common/ScrollDownItem.java | 2 +- .../nicko/gui/items/common/ScrollUpItem.java | 2 +- .../items/settings/LanguageCyclingItem.java | 4 +-- .../items/settings/RandomSkinCyclingItem.java | 6 ++-- .../java/xyz/ineanto/nicko/i18n/I18N.java | 35 ++++--------------- .../nicko/test/i18n/ItemTranslationTest.java | 6 ++-- .../nicko/test/i18n/TranslationTest.java | 2 +- 19 files changed, 46 insertions(+), 54 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index f374145..e356166 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -45,7 +45,7 @@ repositories { } dependencies { - implementation("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT") + implementation("io.papermc.paper:paper-api:1.20.2-R0.1-SNAPSHOT") implementation("com.comphenix.protocol:ProtocolLib:5.1.1-SNAPSHOT") shadowImplementation("me.clip:placeholderapi:2.11.4") @@ -132,6 +132,8 @@ tasks { } runServer { + dependsOn(shadowJar) + downloadPlugins { url("https://download.luckperms.net/1526/bukkit/loader/LuckPerms-Bukkit-5.4.113.jar") url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar") diff --git a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java index 2662a53..3d9553f 100644 --- a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java @@ -115,9 +115,14 @@ public class AnvilManager { final I18N i18n = new I18N(player); final ActionResult actionResult = appearanceManager.updatePlayer(skinChange, false); if (!actionResult.isError()) { - player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Set.OK)); + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.OK, true)); } else { - player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Set.ERROR, i18n.translateStringWithoutPrefix(actionResult.getErrorKey()))); + player.sendMessage( + i18n.translate( + I18NDict.Event.Appearance.Set.ERROR, + true, + i18n.translate(actionResult.getErrorKey(), false) + )); } return Collections.singletonList(AnvilGUI.ResponseAction.close()); } diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java index 7e06e37..0b20860 100644 --- a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java @@ -52,9 +52,13 @@ public class PlayerJoinListener implements Listener { final boolean needsASkinChange = profile.getSkin() != null && !profile.getSkin().equals(player.getName()); final ActionResult actionResult = appearanceManager.updatePlayer(needsASkinChange, false); if (!actionResult.isError()) { - player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Restore.OK)); + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Restore.OK, true)); } else { - player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Restore.ERROR, i18n.translateStringWithoutPrefix(actionResult.getErrorKey()))); + player.sendMessage( + i18n.translate(I18NDict.Event.Appearance.Restore.ERROR, + true, + i18n.translate(actionResult.getErrorKey(), false) + )); } } }); diff --git a/src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java b/src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java index 126a436..dbcc2be 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java @@ -18,7 +18,7 @@ public class AdminGUI { public AdminGUI(Player player) { final I18N i18n = new I18N(player); - this.title = i18n.translateStringWithoutPrefix(I18NDict.GUI.Titles.ADMIN); + this.title = i18n.translate(I18NDict.GUI.Titles.ADMIN, false); final HomeGUI parent = new HomeGUI(player); final GoBackItem backItem = new GoBackItem(player); diff --git a/src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java b/src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java index 21813b0..e8287e1 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java @@ -17,7 +17,7 @@ public class CacheManagementGUI { public CacheManagementGUI(Player player) { final I18N i18n = new I18N(player); - this.title = i18n.translateStringWithoutPrefix(I18NDict.GUI.Titles.CACHE); + this.title = i18n.translate(I18NDict.GUI.Titles.CACHE, false); final AdminGUI parent = new AdminGUI(player); final GoBackItem backItem = new GoBackItem(player); diff --git a/src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java b/src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java index f502433..15dbb4e 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java @@ -22,7 +22,7 @@ public class ChoiceGUI { final ConfirmItem confirmItem = new ConfirmItem(player, callback); final CancelItem cancelItem = new CancelItem(player, callback); - this.title = i18n.translateStringWithoutPrefix(I18NDict.GUI.Titles.CONFIRM); + this.title = i18n.translate(I18NDict.GUI.Titles.CONFIRM, false); this.gui = Gui.normal() .setStructure( "@ @ @ @ % & & & &", diff --git a/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java b/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java index 92e3d1b..a918e7b 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java @@ -26,7 +26,7 @@ public class HomeGUI { } final I18N i18n = new I18N(player); - this.title = i18n.translateStringWithoutPrefix(I18NDict.GUI.Titles.HOME); + this.title = i18n.translate(I18NDict.GUI.Titles.HOME, false); final ExitItem exitItem = new ExitItem(player); final ResetItem resetItem = new ResetItem(player); diff --git a/src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java b/src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java index 1371534..384bd9e 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java @@ -28,7 +28,7 @@ public class InvalidateSkinGUI { public InvalidateSkinGUI(Player player) { final I18N i18n = new I18N(player); - this.title = i18n.translateStringWithoutPrefix(I18NDict.GUI.Titles.INVALIDATE_SKIN); + this.title = i18n.translate(I18NDict.GUI.Titles.INVALIDATE_SKIN, false); final ConcurrentMap> skins = NickoBukkit.getInstance().getMojangAPI().getSkinCache().asMap(); final List loadedSkins = skins.entrySet().stream() diff --git a/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java b/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java index c3bee6e..a09c43f 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java @@ -27,7 +27,7 @@ public class PlayerCheckGUI { public PlayerCheckGUI(Player player, Collection players) { final I18N i18n = new I18N(player); - this.title = i18n.translateStringWithoutPrefix(I18NDict.GUI.Titles.CHECK); + this.title = i18n.translate(I18NDict.GUI.Titles.CHECK, false); final List items = players.stream() .map(Entity::getUniqueId) diff --git a/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java b/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java index c028d9d..f02100c 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java @@ -22,7 +22,7 @@ public class SettingsGUI { }; final I18N i18n = new I18N(player); - this.title = i18n.translateStringWithoutPrefix(I18NDict.GUI.Titles.SETTINGS); + this.title = i18n.translate(I18NDict.GUI.Titles.SETTINGS, false); final HomeGUI parent = new HomeGUI(player); final LanguageCyclingItem languageItem = new LanguageCyclingItem(player); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java index 286cade..89a37d5 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java @@ -29,7 +29,9 @@ public class CacheEntryItem extends AsyncItem { public CacheEntryItem(I18N i18n, String uuid) { super(new ItemBuilder(Material.PAINTING) - .setDisplayName(Component.text(i18n.translateStringWithoutPrefix(I18NDict.GUI.LOADING)).content()), + .setDisplayName( + Component.text(i18n.translate(I18NDict.GUI.LOADING, false)).content() + ), () -> { final String dashedUuid = uuid.replaceAll("(.{8})(.{4})(.{4})(.{4})(.+)", "$1-$2-$3-$4-$5"); final UUID uuidObject = UUID.fromString(dashedUuid); @@ -53,7 +55,7 @@ public class CacheEntryItem extends AsyncItem { @Override public void onConfirm() { final I18N i18n = new I18N(player); - player.sendMessage(i18n.translateString(I18NDict.Event.Admin.Cache.INVALIDATE_ENTRY, name)); + player.sendMessage(i18n.translate(I18NDict.Event.Admin.Cache.INVALIDATE_ENTRY, true, name)); mojangAPI.eraseFromCache(uuid); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java index 7856b64..9ea7dcb 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java @@ -78,7 +78,7 @@ public class PlayerInformationItem extends AsyncItem { public void onConfirm() { final AppearanceManager appearanceManager = new AppearanceManager(target); appearanceManager.reset(); - player.sendMessage(i18n.translateString(I18NDict.Event.Admin.Check.REMOVE_SKIN, target.getName())); + player.sendMessage(i18n.translate(I18NDict.Event.Admin.Check.REMOVE_SKIN, true, target.getName())); } @Override diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java index 4f8c333..9961660 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java @@ -23,7 +23,7 @@ public class ScrollDownItem extends ScrollItem { @Override public ItemProvider getItemProvider(ScrollGui gui) { final ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); - final Translation translation = i18n.translate(I18NDict.GUI.SCROLL_DOWN); + final Translation translation = i18n.translateAndReplace(I18NDict.GUI.SCROLL_DOWN); builder.setDisplayName(Component.text(translation.name()).content()); if (!gui.canScroll(1)) { // Lore serialization diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java index d505432..fb7d98a 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java @@ -23,7 +23,7 @@ public class ScrollUpItem extends ScrollItem { @Override public ItemProvider getItemProvider(ScrollGui gui) { final ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE); - final Translation translation = i18n.translate(I18NDict.GUI.SCROLL_UP); + final Translation translation = i18n.translateAndReplace(I18NDict.GUI.SCROLL_UP); builder.setDisplayName(Component.text(translation.name()).content()); if (!gui.canScroll(-1)) { // Lore serialization diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java index fc9fca8..71bb94d 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java @@ -59,8 +59,8 @@ public class LanguageCyclingItem { private ItemProvider generateItem(Locale locale, List locales) { final ItemBuilder builder = new ItemBuilder(Material.OAK_SIGN); - final Translation translation = i18n.translate(I18NDict.GUI.Settings.LANGUAGE); - final Translation cyclingChoicesTranslation = i18n.translate(I18NDict.GUI.Settings.CYCLING_CHOICES); + final Translation translation = i18n.translateAndReplace(I18NDict.GUI.Settings.LANGUAGE); + final Translation cyclingChoicesTranslation = i18n.translateAndReplace(I18NDict.GUI.Settings.CYCLING_CHOICES); builder.setDisplayName(Component.text(translation.name()).content()); for (Locale value : locales) { diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java index 74c0546..0a2be42 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java @@ -55,12 +55,12 @@ public class RandomSkinCyclingItem { private ItemProvider getItemProviderForValue(boolean enabled) { final SkullBuilder.HeadTexture texture = new SkullBuilder.HeadTexture("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzgzMTEzOGMyMDYxMWQzMDJjNDIzZmEzMjM3MWE3NDNkMTc0MzdhMTg5NzNjMzUxOTczNDQ3MGE3YWJiNCJ9fX0="); final SkullBuilder builder = new SkullBuilder(texture); - final Translation randomSkinTranslation = i18n.translate(I18NDict.GUI.Settings.RANDOM_SKIN); - final Translation toggleableTranslation = i18n.translate(I18NDict.GUI.Settings.TOGGLEABLE_BUTTON, + final Translation randomSkinTranslation = i18n.translateAndReplace(I18NDict.GUI.Settings.RANDOM_SKIN); + final Translation toggleableTranslation = i18n.translateAndReplace(I18NDict.GUI.Settings.TOGGLEABLE_BUTTON, (enabled ? "§7>§c" : "§6§l>§c§l"), (enabled ? "§6§l>§a§l" : "§7>§a") ); - final Translation cyclingChoicesTranslation = i18n.translate(I18NDict.GUI.Settings.CYCLING_CHOICES); + final Translation cyclingChoicesTranslation = i18n.translateAndReplace(I18NDict.GUI.Settings.CYCLING_CHOICES); builder.setDisplayName(randomSkinTranslation.name()); toggleableTranslation.lore().forEach(builder::addLoreLines); diff --git a/src/main/java/xyz/ineanto/nicko/i18n/I18N.java b/src/main/java/xyz/ineanto/nicko/i18n/I18N.java index 24bddf6..3cb0f7e 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/I18N.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/I18N.java @@ -22,23 +22,21 @@ public class I18N { private final NickoBukkit instance = NickoBukkit.getInstance(); private final Pattern replacementPattern = Pattern.compile("(?ms)\\{\\d+}"); private final YamlConfig yamlConfig; - private final Player player; private final Locale playerLocale; public I18N(Player player) { - this.player = player; - this.playerLocale = getPlayerLocale(); + final Optional optionalProfile = NickoProfile.get(player); + this.playerLocale = optionalProfile.map(NickoProfile::getLocale).orElse(Locale.ENGLISH); this.yamlConfig = getYamlConfig(); } public I18N(Locale locale) { - this.player = null; this.playerLocale = locale; this.yamlConfig = getYamlConfig(); } public AbstractItemBuilder translateItem(AbstractItemBuilder item, String key, Object... args) { - final Translation translation = translate(key, args); + final Translation translation = translateAndReplace(key, args); // Name serialization final Component deserializedName = MiniMessage.miniMessage().deserialize(translation.name()); @@ -55,7 +53,7 @@ public class I18N { return item; } - public Translation translate(String key, Object... args) { + public Translation translateAndReplace(String key, Object... args) { final String nameKey = key + ".name"; final String loreKey = key + ".lore"; final String name = readString(nameKey); @@ -115,23 +113,13 @@ public class I18N { } } - public String translateString(String key, Object... arguments) { + public String translate(String key, boolean prefix, Object... arguments) { final String translation = readString(key); try { formatter.applyPattern(translation); - return instance.getNickoConfig().getPrefix() + formatter.format(arguments); + return (prefix ? instance.getNickoConfig().getPrefix() : "") + formatter.format(arguments); } catch (Exception e) { - return instance.getNickoConfig().getPrefix() + key; - } - } - - public String translateStringWithoutPrefix(String key, Object... arguments) { - final String translation = readString(key); - try { - formatter.applyPattern(translation); - return formatter.format(arguments); - } catch (Exception e) { - return key; + return (prefix ? instance.getNickoConfig().getPrefix() : "") + key; } } @@ -151,13 +139,4 @@ public class I18N { return new YamlConfig(resource); } } - - public Locale getPlayerLocale() { - final Optional optionalProfile = NickoProfile.get(player); - if (optionalProfile.isPresent()) { - return optionalProfile.get().getLocale(); - } else { - return Locale.ENGLISH; - } - } } diff --git a/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java b/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java index b9a722e..5ea2322 100644 --- a/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java @@ -29,7 +29,7 @@ public class ItemTranslationTest { @DisplayName("Translate Item Without Lore") public void translateItemTranslationWithoutLore() { final I18N i18n = new I18N(Locale.FRENCH); - final Translation translation = i18n.translate(I18NDict.GUI.GO_BACK); + final Translation translation = i18n.translateAndReplace(I18NDict.GUI.GO_BACK); assertTrue(translation.lore().isEmpty()); assertEquals(translation.name(), "Retour"); } @@ -39,10 +39,10 @@ public class ItemTranslationTest { public void translateItemLore() { final I18N i18n = new I18N(Locale.FRENCH); - final Translation test = i18n.translate(I18NDict.GUI.Settings.TOGGLEABLE_BUTTON, "EST", "EST"); + final Translation test = i18n.translateAndReplace(I18NDict.GUI.Settings.TOGGLEABLE_BUTTON, "EST", "EST"); test.lore().forEach(System.out::println); - final Translation translation = i18n.translate(I18NDict.GUI.Admin.Cache.STATISTICS, "1", "1"); + final Translation translation = i18n.translateAndReplace(I18NDict.GUI.Admin.Cache.STATISTICS, "1", "1"); assertFalse(translation.lore().isEmpty()); assertEquals("Nombre de requêtes: 1", translation.lore().get(0)); assertEquals("Nb. de skin dans le cache: 1", translation.lore().get(1)); diff --git a/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java b/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java index 7f68486..6ed49c6 100644 --- a/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java @@ -25,7 +25,7 @@ public class TranslationTest { @DisplayName("Translate Line With Replacement") public void translateItemTranslationWithoutLore() { final I18N i18n = new I18N(Locale.FRENCH); - final String translation = i18n.translateStringWithoutPrefix(I18NDict.Event.Settings.ERROR, "Test"); + final String translation = i18n.translate(I18NDict.Event.Settings.ERROR, false, "Test"); assertEquals("§cImpossible de mettre à jour vos paramètres. §7§o(Test)", translation); } From ff22f5addf774a51511b750d4ce8a2185d16a641 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 28 Dec 2023 21:07:12 +0100 Subject: [PATCH 192/296] fix(i18n): update calls --- src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java | 1 + src/main/java/xyz/ineanto/nicko/command/NickoCommand.java | 2 +- .../nicko/gui/items/admin/cache/InvalidateCacheItem.java | 2 +- .../xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java | 4 ++-- .../java/xyz/ineanto/nicko/gui/items/home/ResetItem.java | 6 +++--- .../nicko/gui/items/settings/LanguageCyclingItem.java | 2 +- .../nicko/gui/items/settings/RandomSkinCyclingItem.java | 2 +- 7 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java index 3d9553f..e52ad99 100644 --- a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java @@ -130,6 +130,7 @@ public class AnvilManager { private ItemStack getLeftItem(boolean skin) { final ItemStack item = new ItemStack(Material.PAPER); final ItemMeta meta = item.getItemMeta(); + // TODO (Ineanto, 12/28/23): Translate this if (meta != null) meta.displayName(Component.text("New " + (skin ? "skin" : "name") + "...")); item.setItemMeta(meta); return item; diff --git a/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java b/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java index 1ac6bf2..40ffbbf 100644 --- a/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java +++ b/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java @@ -17,7 +17,7 @@ public class NickoCommand implements CommandExecutor { new HomeGUI(player).open(); } else { final I18N i18N = new I18N(player); - player.sendMessage(i18N.translateString(I18NDict.Error.PERMISSION)); + player.sendMessage(i18N.translate(I18NDict.Error.PERMISSION, true)); } return false; } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java index 14eddb3..16d2592 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java @@ -27,7 +27,7 @@ public class InvalidateCacheItem { final Player player = click.getPlayer(); final I18N i18n = new I18N(player); - player.sendMessage(i18n.translateString(I18NDict.Event.Admin.Cache.INVALIDATE_CACHE)); + player.sendMessage(i18n.translate(I18NDict.Event.Admin.Cache.INVALIDATE_CACHE, true)); NickoBukkit.getInstance().getMojangAPI().getSkinCache().invalidateAll(); return true; } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java index 16d6675..9a3e27e 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java @@ -40,9 +40,9 @@ public class RandomSkinItem { final AppearanceManager appearanceManager = new AppearanceManager(player); if (!appearanceManager.updatePlayer(true, false).isError()) { - player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Set.OK)); + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.OK, true)); } else { - player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Set.ERROR)); + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.ERROR, true)); } }); return true; diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java index 4ee2bad..b328a52 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java @@ -30,16 +30,16 @@ public class ResetItem { final Optional optionalProfile = NickoProfile.get(player); optionalProfile.ifPresent(profile -> { if (!profile.hasData()) { - player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Remove.MISSING)); + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.MISSING, true)); event.getEvent().getView().close(); return; } final AppearanceManager appearanceManager = new AppearanceManager(player); if (!appearanceManager.reset().isError()) { - player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Remove.OK)); + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.OK, true)); } else { - player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Remove.ERROR)); + player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.ERROR, true)); } }); return true; diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java index 71bb94d..9c691ec 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java @@ -47,7 +47,7 @@ public class LanguageCyclingItem { nickoProfile.setLocale(Locale.values()[integer]); player.getOpenInventory().close(); if (dataStore.updateCache(player.getUniqueId(), nickoProfile).isError()) { - player.sendMessage(i18n.translateString(I18NDict.Event.Settings.ERROR)); + player.sendMessage(i18n.translate(I18NDict.Event.Settings.ERROR, true)); } else { new SettingsGUI(player).open(); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java index 0a2be42..af62565 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java @@ -43,7 +43,7 @@ public class RandomSkinCyclingItem { observer.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 0.707107f); // 0.707107 ~= C nickoProfile.setRandomSkin(integer != 1); if (dataStore.updateCache(player.getUniqueId(), nickoProfile).isError()) { - player.sendMessage(i18n.translateString(I18NDict.Event.Settings.ERROR)); + player.sendMessage(i18n.translate(I18NDict.Event.Settings.ERROR, true)); player.getOpenInventory().close(); } }, localeOrdinal, providers); From 52edd9fa65506ebe4bd05aa6da34c15edb29d49d Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 28 Dec 2023 21:09:58 +0100 Subject: [PATCH 193/296] feat(event): add warning on load failure --- src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java index 0b20860..33ae8d0 100644 --- a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java @@ -37,7 +37,7 @@ public class PlayerJoinListener implements Listener { nameStore.storeName(player); final Optional optionalProfile = dataStore.getData(player.getUniqueId()); - optionalProfile.ifPresent(profile -> { + optionalProfile.ifPresentOrElse(profile -> { // Random Skin on connection feature if (profile.isRandomSkin()) { final String name = instance.getNameFetcher().getRandomUsername(); @@ -61,6 +61,8 @@ public class PlayerJoinListener implements Listener { )); } } + }, () -> { + instance.getLogger().warning("Failed to load data for " + player.getName()); }); for (Player online : Bukkit.getOnlinePlayers().stream().filter(op -> op.getUniqueId() != player.getUniqueId()).toList()) { From 1a0d2ffdf77f42d337165d399e8e3ce0681bd463 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 28 Dec 2023 21:17:16 +0100 Subject: [PATCH 194/296] fix(placeholder): wrong param --- src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java b/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java index 1200110..f2e9303 100644 --- a/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java +++ b/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java @@ -68,7 +68,7 @@ public class NickoExpansion extends PlaceholderExpansion { case "name" -> name; case "skin" -> skin; case "locale" -> locale; - case "bungeecord" -> String.valueOf(randomSkin); + case "random_skin" -> String.valueOf(randomSkin); default -> null; }; } From 61132a2c8807f610f10d1aeeff3460db1536ac24 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 28 Dec 2023 21:18:25 +0100 Subject: [PATCH 195/296] style(wrapper): update versions --- .../xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java index 18aea0f..35a7ab0 100644 --- a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java @@ -12,7 +12,7 @@ import org.bukkit.GameMode; import org.bukkit.World; /** - * PacketPlayServerRespawn Wrapper class (1.19 to 1.20.2) + * PacketPlayServerRespawn Wrapper class (1.19 to 1.20.4) * * @author ineanto, based on work from dmulloy2 and Kristian S. Strangeland *

@@ -34,7 +34,7 @@ public class WrapperPlayServerRespawn extends AbstractPacket { public void setDimension(World value) { if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { - // 1.20.2 + // 1.20.2 to 1.20.4 writeDimensionToStructure(value, commonPlayerSpawnInfoStructure.getStructures(), commonPlayerSpawnInfoStructure.getWorldKeys()); } else if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { // 1.19 to 1.20.1, props to lukalt for helping me figure this out. From 4f13d3fc2de205a9655c23c47b7f6b91b25bb149 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 28 Dec 2023 21:20:18 +0100 Subject: [PATCH 196/296] feat: actually reset --- .../ineanto/nicko/appearance/AppearanceManager.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index dd04abb..906bb88 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -115,22 +115,18 @@ public class AppearanceManager { properties.get("textures").clear(); properties.put("textures", new WrappedSignedProperty("textures", skinResult.value(), skinResult.signature())); } else { - profile.setSkin(null); - dataStore.updateCache(player.getUniqueId(), profile); + reset(); return ActionResult.error(I18NDict.Error.MOJANG_SKIN); } } else { - profile.setName(null); - dataStore.updateCache(player.getUniqueId(), profile); + reset(); return ActionResult.error(I18NDict.Error.MOJANG_NAME); } return ActionResult.ok(); } catch (ExecutionException e) { return ActionResult.error(I18NDict.Error.CACHE); } catch (IOException e) { - profile.setName(null); - profile.setSkin(null); - dataStore.updateCache(player.getUniqueId(), profile); + reset(); return ActionResult.error(I18NDict.Error.MOJANG_NAME); } } From 365ac9b2d93176627fc053a8d7b56b89b9d49d95 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 28 Dec 2023 21:21:44 +0100 Subject: [PATCH 197/296] refactor(appearance): update to jre17 --- .../xyz/ineanto/nicko/appearance/AppearanceManager.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index 906bb88..b614e98 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -2,7 +2,6 @@ package xyz.ineanto.nicko.appearance; import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.wrappers.*; -import com.google.common.collect.ImmutableList; import com.google.common.collect.Multimap; import it.unimi.dsi.fastutil.ints.IntList; import org.bukkit.Bukkit; @@ -20,6 +19,7 @@ import xyz.ineanto.nicko.wrapper.*; import java.io.IOException; import java.util.EnumSet; +import java.util.List; import java.util.Optional; import java.util.concurrent.ExecutionException; @@ -170,7 +170,7 @@ public class AppearanceManager { EnumWrappers.PlayerInfoAction.UPDATE_DISPLAY_NAME, EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE, EnumWrappers.PlayerInfoAction.UPDATE_LATENCY); - remove.setUUIDs(ImmutableList.of(player.getUniqueId())); + remove.setUUIDs(List.of(player.getUniqueId())); remove.broadcastPacket(); add.setActions(actions); } else { @@ -180,7 +180,7 @@ public class AppearanceManager { remove.broadcastPacket(); } - add.setData(ImmutableList.of(new PlayerInfoData( + add.setData(List.of(new PlayerInfoData( player.getUniqueId(), player.getPing(), true, From f14457fd8bf8f8283eb4fcd631a3d86935209407 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 28 Dec 2023 21:30:34 +0100 Subject: [PATCH 198/296] fix(appearance): show error reason --- .../ineanto/nicko/gui/items/home/RandomSkinItem.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java index 9a3e27e..35260a2 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java @@ -3,6 +3,7 @@ package xyz.ineanto.nicko.gui.items.home; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.appearance.AppearanceManager; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; @@ -39,10 +40,16 @@ public class RandomSkinItem { instance.getDataStore().updateCache(player.getUniqueId(), profile); final AppearanceManager appearanceManager = new AppearanceManager(player); - if (!appearanceManager.updatePlayer(true, false).isError()) { + final ActionResult result = appearanceManager.updatePlayer(true, false); + if (!result.isError()) { player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.OK, true)); } else { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.ERROR, true)); + player.sendMessage(i18n.translate( + I18NDict.Event.Appearance.Set.ERROR, + true, + i18n.translate(result.getErrorKey(), false) + ) + ); } }); return true; From ba753deafd67764c880c062d0634a36eca4bdf4b Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 28 Dec 2023 21:39:04 +0100 Subject: [PATCH 199/296] feat(i18n): Updated the localization files (#tf2) --- src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java | 2 +- .../xyz/ineanto/nicko/storage/PlayerDataStore.java | 2 +- .../nicko/storage/mariadb/MariaDBStorage.java | 10 +++++----- .../ineanto/nicko/storage/mysql/MySQLStorage.java | 10 +++++----- src/main/resources/fr.yml | 14 +++++++------- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java b/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java index 8055a4c..95a3398 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java @@ -9,7 +9,7 @@ public class I18NDict { 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"; - public static final String SQL = ERROR_KEY + "sql"; + public static final String DATABASE = ERROR_KEY + "database"; public static final String JSON = ERROR_KEY + "json"; } diff --git a/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java b/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java index e3b444b..81fae57 100644 --- a/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java +++ b/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java @@ -77,7 +77,7 @@ public class PlayerDataStore { } public ActionResult saveData(Player player) { - if (storage.isError()) return ActionResult.error(I18NDict.Error.SQL); + if (storage.isError()) return ActionResult.error(I18NDict.Error.DATABASE); if (cache.isError()) return ActionResult.error(I18NDict.Error.CACHE); if (!cache.isCached(player.getUniqueId())) return ActionResult.error(I18NDict.Error.CACHE); diff --git a/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java b/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java index f761f56..694e053 100644 --- a/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java +++ b/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java @@ -36,7 +36,7 @@ public class MariaDBStorage extends Storage { @Override public ActionResult store(UUID uuid, NickoProfile profile) { final Connection connection = getProvider().getConnection(); - if (connection == null) return ActionResult.error(I18NDict.Error.SQL); + if (connection == null) return ActionResult.error(I18NDict.Error.DATABASE); try { final PreparedStatement statement = isStored(uuid) ? @@ -45,7 +45,7 @@ public class MariaDBStorage extends Storage { return ActionResult.ok(); } catch (SQLException e) { logger.warning("Couldn't send SQL Request: " + e.getMessage()); - return ActionResult.error(I18NDict.Error.SQL); + return ActionResult.error(I18NDict.Error.DATABASE); } } @@ -103,17 +103,17 @@ public class MariaDBStorage extends Storage { @Override public ActionResult delete(UUID uuid) { final Connection connection = getProvider().getConnection(); - if (connection == null) return ActionResult.error(I18NDict.Error.SQL); + if (connection == null) return ActionResult.error(I18NDict.Error.DATABASE); try { final String sql = "DELETE FROM nicko.DATA WHERE uuid = ?"; final PreparedStatement statement = connection.prepareStatement(sql); statement.setString(1, uuid.toString()); int rows = statement.executeUpdate(); - return (rows == 1 ? ActionResult.ok() : ActionResult.error(I18NDict.Error.SQL)); + return (rows == 1 ? ActionResult.ok() : ActionResult.error(I18NDict.Error.DATABASE)); } catch (SQLException e) { logger.warning("Couldn't delete profile: " + e.getMessage()); - return ActionResult.error(I18NDict.Error.SQL); + return ActionResult.error(I18NDict.Error.DATABASE); } } diff --git a/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java b/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java index 490c8e1..102cdab 100644 --- a/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java +++ b/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java @@ -36,7 +36,7 @@ public class MySQLStorage extends Storage { @Override public ActionResult store(UUID uuid, NickoProfile profile) { final Connection connection = getProvider().getConnection(); - if (connection == null) return ActionResult.error(I18NDict.Error.SQL); + if (connection == null) return ActionResult.error(I18NDict.Error.DATABASE); try { final PreparedStatement statement = isStored(uuid) ? @@ -45,7 +45,7 @@ public class MySQLStorage extends Storage { return ActionResult.ok(); } catch (SQLException e) { logger.warning("Couldn't send SQL Request: " + e.getMessage()); - return ActionResult.error(I18NDict.Error.SQL); + return ActionResult.error(I18NDict.Error.DATABASE); } } @@ -103,17 +103,17 @@ public class MySQLStorage extends Storage { @Override public ActionResult delete(UUID uuid) { final Connection connection = getProvider().getConnection(); - if (connection == null) return ActionResult.error(I18NDict.Error.SQL); + if (connection == null) return ActionResult.error(I18NDict.Error.DATABASE); try { final String sql = "DELETE FROM nicko.DATA WHERE uuid = ?"; final PreparedStatement statement = connection.prepareStatement(sql); statement.setString(1, uuid.toString()); int rows = statement.executeUpdate(); - return (rows == 1 ? ActionResult.ok() : ActionResult.error(I18NDict.Error.SQL)); + return (rows == 1 ? ActionResult.ok() : ActionResult.error(I18NDict.Error.DATABASE)); } catch (SQLException e) { logger.warning("Couldn't delete profile: " + e.getMessage()); - return ActionResult.error(I18NDict.Error.SQL); + return ActionResult.error(I18NDict.Error.DATABASE); } } diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index e71d358..60682bb 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -1,16 +1,16 @@ -# Nicko ${version} - Config: +# Nicko ${version} - Fichier de langue: -# Specifies the configuration version, don't change. -version: "1.1.0" +# Précise la version de la configuration, ne pas changer. +version: "1.1.2" 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." - 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." - sql: "Erreur SQL" + mojang_name: "Compte Minecraft inexistant" + mojang_skin: "Skin Minecraft invalide" + cache: "Erreur du cache" + database: "Erreur SQL" json: "Erreur JSON" event: From af4625793cdcae3403c474dd74433524ba56184d Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 28 Dec 2023 21:40:35 +0100 Subject: [PATCH 200/296] fix(i18n): bump locale version --- src/main/java/xyz/ineanto/nicko/i18n/Locale.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/xyz/ineanto/nicko/i18n/Locale.java b/src/main/java/xyz/ineanto/nicko/i18n/Locale.java index 13a62c5..63be14a 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/Locale.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/Locale.java @@ -9,7 +9,7 @@ public enum Locale implements Serializable { FRENCH("fr", "Français"), CUSTOM("cm", "Server Custom"); - public static final Version VERSION = new Version(1, 1, 0); + public static final Version VERSION = new Version(1, 1, 1); private final String code; private transient final String name; From dde8ea48b92dde6e99bd4e78ae8fc15f120aa0fa Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 28 Dec 2023 21:54:33 +0100 Subject: [PATCH 201/296] feat(changelog): update (1.1.2-RC1) --- CHANGELOG.log | 11 +++++++++++ build.gradle.kts | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.log b/CHANGELOG.log index ebc8c70..7e1362a 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,3 +1,14 @@ +1.1.2-RC1: Update n°8 (28/12/23) + [FEATURES] + - Players now default back to their original appearance upon failure. + + [FIXES] + - Fixed an invalid placeholder parameter (%nicko_random_skin% now gets if the player has random skin on login set or not). + - Fixed the error reason not appearing upon failure. + - Fixed player profiles (name and skin associated) not being reset gracefully upon failure. + - Fixed error messages not being precise enough. + - Various optimizations and improvements. + 1.1.1-RC1: Update n°7 (27/12/23) [FEATURES] - Made Nicko compatible with 1.20.3 and 1.20.4. diff --git a/build.gradle.kts b/build.gradle.kts index e356166..3a7c4b9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } group = "xyz.ineanto" -version = "1.1.1-RC1" +version = "1.1.2-RC1" val shadowImplementation: Configuration by configurations.creating configurations["implementation"].extendsFrom(shadowImplementation) From 4d45c4660ad3af183ec610610fa373d761525033 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 28 Dec 2023 21:59:11 +0100 Subject: [PATCH 202/296] fix: locale wrong version (whoops) --- src/main/resources/en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index c6cb3a7..0e544f7 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -1,7 +1,7 @@ # Nicko ${version} - Language File: # Specifies the configuration version, don't change. -version: "1.1.0" +version: "1.1.2" error: generic: "An unknown error occurred." From f81ff8bd522b80a391927a9019d63ca0477a787f Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 28 Dec 2023 22:00:13 +0100 Subject: [PATCH 203/296] fix: update locale version constant --- src/main/java/xyz/ineanto/nicko/i18n/Locale.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/xyz/ineanto/nicko/i18n/Locale.java b/src/main/java/xyz/ineanto/nicko/i18n/Locale.java index 63be14a..f1d7f3d 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/Locale.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/Locale.java @@ -9,7 +9,7 @@ public enum Locale implements Serializable { FRENCH("fr", "Français"), CUSTOM("cm", "Server Custom"); - public static final Version VERSION = new Version(1, 1, 1); + public static final Version VERSION = new Version(1, 1, 2); private final String code; private transient final String name; From 68ad4ac9b5b7ee0dfd9a2c39965461b0e72747f5 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 28 Dec 2023 22:04:00 +0100 Subject: [PATCH 204/296] feat(changelog): hotfix (1.1.3-RC1) --- CHANGELOG.log | 4 ++++ build.gradle.kts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.log b/CHANGELOG.log index 7e1362a..f2924ac 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,3 +1,7 @@ +1.1.3-RC1: Hotfix n°4 (28/12/23) + [FIXES] + - Fixed the English Locale version being late. + 1.1.2-RC1: Update n°8 (28/12/23) [FEATURES] - Players now default back to their original appearance upon failure. diff --git a/build.gradle.kts b/build.gradle.kts index 3a7c4b9..bcbdb00 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } group = "xyz.ineanto" -version = "1.1.2-RC1" +version = "1.1.3-RC1" val shadowImplementation: Configuration by configurations.creating configurations["implementation"].extendsFrom(shadowImplementation) From d784ed448f8ad4320ae54c8f0d05889cd88dd018 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 25 Feb 2024 16:16:14 +0100 Subject: [PATCH 205/296] fix(random names): log error message upon failure --- .../ineanto/nicko/appearance/random/RandomNameFetcher.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java b/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java index 7549203..a11f477 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java @@ -27,10 +27,10 @@ public class RandomNameFetcher { final String[] values = line.split("\n"); records.add(Arrays.asList(values)); } + return records.get(new Random().nextInt(records.size() - 1)).get(0); } catch (IOException e) { - throw new RuntimeException(e); + instance.getLogger().severe("Unable to fetch random names."); + return "Ineanto"; } - - return records.get(new Random().nextInt(records.size() - 1)).get(0); } } From 59addc6ee33181cb0989f036ab59aa6081c93122 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 25 Feb 2024 16:27:46 +0100 Subject: [PATCH 206/296] feat: fetch skin in separate thread --- .../nicko/appearance/AppearanceManager.java | 2 + .../xyz/ineanto/nicko/mojang/MojangAPI.java | 73 ++++++++++--------- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index b614e98..66f020e 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -128,6 +128,8 @@ public class AppearanceManager { } catch (IOException e) { reset(); return ActionResult.error(I18NDict.Error.MOJANG_NAME); + } catch (InterruptedException e) { + return ActionResult.error(I18NDict.Error.GENERIC); } } return ActionResult.ok(); diff --git a/src/main/java/xyz/ineanto/nicko/mojang/MojangAPI.java b/src/main/java/xyz/ineanto/nicko/mojang/MojangAPI.java index a9e5706..a0abeba 100644 --- a/src/main/java/xyz/ineanto/nicko/mojang/MojangAPI.java +++ b/src/main/java/xyz/ineanto/nicko/mojang/MojangAPI.java @@ -17,6 +17,8 @@ import java.net.URL; import java.util.HashMap; import java.util.Optional; import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; @@ -26,6 +28,7 @@ public class MojangAPI { private final Logger logger = Logger.getLogger("MojangAPI"); private final HashMap uuidToName = new HashMap<>(); + private final ExecutorService worker = Executors.newFixedThreadPool(6); private final CacheLoader> skinLoader = new CacheLoader<>() { @Nonnull @@ -56,7 +59,7 @@ public class MojangAPI { return skinCache.get(uuid); } - public Optional getSkinWithoutCaching(String uuid) throws IOException { + public Optional getSkinWithoutCaching(String uuid) throws IOException, ExecutionException, InterruptedException { return getSkinFromMojang(uuid); } @@ -64,7 +67,7 @@ public class MojangAPI { return uuidCache.get(name); } - private Optional getUUIDFromMojang(String name) throws IOException { + private Optional getUUIDFromMojang(String name) throws ExecutionException, InterruptedException { final String parametrizedUrl = URL_NAME.replace("{name}", name); final JsonObject object = getRequestToUrl(parametrizedUrl); if (hasNoError(object)) { @@ -84,7 +87,7 @@ public class MojangAPI { uuidCache.invalidate(uuid); } - private Optional getSkinFromMojang(String uuid) throws IOException { + private Optional getSkinFromMojang(String uuid) throws ExecutionException, InterruptedException { final String parametrizedUrl = URL_SKIN.replace("{uuid}", uuid); final JsonObject object = getRequestToUrl(parametrizedUrl); if (hasNoError(object)) { @@ -98,39 +101,41 @@ public class MojangAPI { return uuidToName.get(uuid); } - private JsonObject getRequestToUrl(String parametrizedUrl) throws IOException { - final URL url = new URL(parametrizedUrl); - final HttpsURLConnection con = (HttpsURLConnection) url.openConnection(); - con.setDoInput(true); - con.setRequestMethod("GET"); + private JsonObject getRequestToUrl(String parametrizedUrl) throws ExecutionException, InterruptedException { + return worker.submit(() -> { + final URL url = new URL(parametrizedUrl); + final HttpsURLConnection con = (HttpsURLConnection) url.openConnection(); + con.setDoInput(true); + con.setRequestMethod("GET"); - switch (con.getResponseCode()) { - case 404: - case 400: - logger.warning("Failed to parse request: Invalid Name"); - return getErrorObject(); - case 429: - logger.warning("Failed to parse request: The connection is throttled."); - return getErrorObject(); - case 200: - final BufferedReader input = new BufferedReader(new InputStreamReader(con.getInputStream())); - final StringBuilder builder = new StringBuilder(); - String line; - while ((line = input.readLine()) != null) { - builder.append(line); - } - - try { - final JsonElement jsonElt = JsonParser.parseString(builder.toString()); - return jsonElt.getAsJsonObject(); - } catch (JsonParseException | IllegalStateException exception) { - logger.warning("Failed to parse request (" + parametrizedUrl + ")!"); + switch (con.getResponseCode()) { + case 404: + case 400: + logger.warning("Failed to parse request: Invalid Name"); return getErrorObject(); - } - default: - logger.warning("Unhandled response code from Mojang: " + con.getResponseCode()); - return getErrorObject(); - } + case 429: + logger.warning("Failed to parse request: The connection is throttled."); + return getErrorObject(); + case 200: + final BufferedReader input = new BufferedReader(new InputStreamReader(con.getInputStream())); + final StringBuilder builder = new StringBuilder(); + String line; + while ((line = input.readLine()) != null) { + builder.append(line); + } + + try { + final JsonElement jsonElt = JsonParser.parseString(builder.toString()); + return jsonElt.getAsJsonObject(); + } catch (JsonParseException | IllegalStateException exception) { + logger.warning("Failed to parse request (" + parametrizedUrl + ")!"); + return getErrorObject(); + } + default: + logger.warning("Unhandled response code from Mojang: " + con.getResponseCode()); + return getErrorObject(); + } + }).get(); } private JsonObject getErrorObject() { From c1c2d883c4eca97cd3f6d95c2bc81ca776e16c45 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 25 Feb 2024 16:28:41 +0100 Subject: [PATCH 207/296] feat: bump version (1.1.4-RC1) --- CHANGELOG.log | 4 ++++ build.gradle.kts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.log b/CHANGELOG.log index f2924ac..822a6a9 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,3 +1,7 @@ +1.1.4-RC1: Update n°9 (28/12/23) + [FEATURES] + - Various improvements to performance. + 1.1.3-RC1: Hotfix n°4 (28/12/23) [FIXES] - Fixed the English Locale version being late. diff --git a/build.gradle.kts b/build.gradle.kts index bcbdb00..d1e8304 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } group = "xyz.ineanto" -version = "1.1.3-RC1" +version = "1.1.4-RC1" val shadowImplementation: Configuration by configurations.creating configurations["implementation"].extendsFrom(shadowImplementation) From 89d2499fed12ef8b2943201a7581aa0d7206f8cf Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 25 Feb 2024 16:39:01 +0100 Subject: [PATCH 208/296] fix: change standardcopyoption --- .../java/xyz/ineanto/nicko/migration/ConfigurationMigrator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/xyz/ineanto/nicko/migration/ConfigurationMigrator.java b/src/main/java/xyz/ineanto/nicko/migration/ConfigurationMigrator.java index 7ab3a10..465392f 100644 --- a/src/main/java/xyz/ineanto/nicko/migration/ConfigurationMigrator.java +++ b/src/main/java/xyz/ineanto/nicko/migration/ConfigurationMigrator.java @@ -26,7 +26,7 @@ public class ConfigurationMigrator implements Migrator { || configuration.getVersionObject().compareTo(Configuration.VERSION) != 0) { instance.getLogger().info("Migrating configuration file to match the current version..."); try { - Files.copy(configurationManager.getFile().toPath(), configurationManager.getBackupFile().toPath(), StandardCopyOption.ATOMIC_MOVE); + Files.copy(configurationManager.getFile().toPath(), configurationManager.getBackupFile().toPath(), StandardCopyOption.REPLACE_EXISTING); configurationManager.saveDefaultConfig(); } catch (IOException e) { instance.getLogger().severe("Failed to migrate your configuration!"); From c8183ffe444352ef632859dc83cf1e7f90279d70 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 25 Feb 2024 17:46:26 +0100 Subject: [PATCH 209/296] fix: bumped version again, forgot the previous one --- CHANGELOG.log | 8 +++++++- build.gradle.kts | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.log b/CHANGELOG.log index 822a6a9..5d60e2c 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,6 +1,12 @@ -1.1.4-RC1: Update n°9 (28/12/23) +1.1.5-RC1: Update n°10 (28/12/23) [FEATURES] - Various improvements to performance. + [FIXES] + - Fixed a bug related to configuration migration. + +1.1.4-RC1: Update n°9 (07/02/23) + [OTHER] + - The repository hosting the previous version of Nicko had expired, this is now fixed. 1.1.3-RC1: Hotfix n°4 (28/12/23) [FIXES] diff --git a/build.gradle.kts b/build.gradle.kts index d1e8304..1e909fa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } group = "xyz.ineanto" -version = "1.1.4-RC1" +version = "1.1.5-RC1" val shadowImplementation: Configuration by configurations.creating configurations["implementation"].extendsFrom(shadowImplementation) From eb44504d6f0b0ce961e104923651075ffade2fe3 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 25 Feb 2024 17:46:47 +0100 Subject: [PATCH 210/296] fix: wrong date --- CHANGELOG.log | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.log b/CHANGELOG.log index 5d60e2c..0fe10e3 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,4 +1,4 @@ -1.1.5-RC1: Update n°10 (28/12/23) +1.1.5-RC1: Update n°10 (25/12/23) [FEATURES] - Various improvements to performance. [FIXES] From 5de0037d2c03857d49a6bc916c709397436bda63 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 4 May 2024 14:26:32 +0200 Subject: [PATCH 211/296] feat: updated dependencies --- .idea/misc.xml | 4 ---- build.gradle.kts | 24 ++++++++++++------------ docker-compose.yml | 8 -------- 3 files changed, 12 insertions(+), 24 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 5ce7e7e..43c96f4 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,9 +1,5 @@ - - \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 692026c..102fbb4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,7 @@ plugins { id("java") id("io.github.goooler.shadow") version "8.1.7" - id("xyz.jpenilla.run-paper") version "2.2.2" + id("xyz.jpenilla.run-paper") version "2.3.0" } group = "xyz.ineanto" @@ -45,9 +45,9 @@ dependencies { compileOnly("io.papermc.paper:paper-api:1.20.6-R0.1-SNAPSHOT") compileOnly("com.comphenix.protocol:ProtocolLib:5.2.0-SNAPSHOT") compileOnly("me.clip:placeholderapi:2.11.5") - compileOnly("net.kyori:adventure-api:4.14.0") + compileOnly("net.kyori:adventure-api:4.17.0") - implementation("xyz.xenondevs.invui:invui:1.30") + implementation("xyz.xenondevs.invui:invui:1.31") implementation("net.wesjd:anvilgui:1.9.4-SNAPSHOT") implementation("com.github.jsixface:yamlconfig:1.2") implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.2") @@ -58,7 +58,7 @@ dependencies { implementation("com.google.code.gson:gson:2.10.1") implementation("org.bstats:bstats-bukkit:3.0.2") - testImplementation("com.github.seeseemelk:MockBukkit-v1.20:3.86.0") + testImplementation("com.github.seeseemelk:MockBukkit-v1.20:3.89.0") testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.2") testImplementation("org.junit.jupiter:junit-jupiter-engine:5.10.2") testImplementation("org.junit.jupiter:junit-jupiter:5.10.2") From 34d1c5c7a027e1889fe71ef9534d40a4c76ab0af Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 8 Jun 2024 13:12:48 +0200 Subject: [PATCH 218/296] chore(deps): update server deps --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 102fbb4..ac7ba81 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -131,9 +131,9 @@ tasks { downloadPlugins { url("https://download.luckperms.net/1539/bukkit/loader/LuckPerms-Bukkit-5.4.126.jar") - url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar") + url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBu²ild/artifact/build/libs/ProtocolLib.jar") } - minecraftVersion("1.20.4") + minecraftVersion("1.20.6") } } \ No newline at end of file From 57ed1941220728e8dd9fe2c79be973863d9ed047 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 14 Jun 2024 22:47:11 +0200 Subject: [PATCH 219/296] feat(deps): base on latest master ProtocolLib commit --- build.gradle.kts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index ac7ba81..3e27456 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -18,10 +18,7 @@ java { repositories { mavenCentral() mavenLocal() - maven { - name = "dmulloy2" - url = uri("https://repo.dmulloy2.net/repository/public/") - } + maven { url = uri("https://jitpack.io") } maven { name = "xenondevs" url = uri("https://repo.xenondevs.xyz/releases") @@ -43,7 +40,7 @@ repositories { dependencies { // Nicko compileOnly("io.papermc.paper:paper-api:1.20.6-R0.1-SNAPSHOT") - compileOnly("com.comphenix.protocol:ProtocolLib:5.2.0-SNAPSHOT") + compileOnly("com.github.dmulloy2:ProtocolLib:master-SNAPSHOT") compileOnly("me.clip:placeholderapi:2.11.5") compileOnly("net.kyori:adventure-api:4.17.0") From 653c229b8570100b10d09b9fe55ff121bced4e07 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 14 Jun 2024 23:01:13 +0200 Subject: [PATCH 220/296] fix(build): typo --- build.gradle.kts | 2 +- src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3e27456..09f0919 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -128,7 +128,7 @@ tasks { downloadPlugins { url("https://download.luckperms.net/1539/bukkit/loader/LuckPerms-Bukkit-5.4.126.jar") - url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBu²ild/artifact/build/libs/ProtocolLib.jar") + url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar") } minecraftVersion("1.20.6") diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java index 33ae8d0..b28fb11 100644 --- a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java @@ -61,9 +61,7 @@ public class PlayerJoinListener implements Listener { )); } } - }, () -> { - instance.getLogger().warning("Failed to load data for " + player.getName()); - }); + }, () -> instance.getLogger().warning("Failed to load data for " + player.getName())); for (Player online : Bukkit.getOnlinePlayers().stream().filter(op -> op.getUniqueId() != player.getUniqueId()).toList()) { final Optional optionalOnlinePlayerProfile = dataStore.getData(online.getUniqueId()); From 278c801de1da4fac291963d2738129dcb8b459e4 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 14 Jun 2024 23:38:21 +0200 Subject: [PATCH 221/296] feat: tring to figure out 1.20.5-6/1.21 --- .../wrapper/WrapperPlayServerRespawn.java | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java index 35a7ab0..978dc84 100644 --- a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java @@ -22,24 +22,23 @@ import org.bukkit.World; public class WrapperPlayServerRespawn extends AbstractPacket { public static final PacketType TYPE = PacketType.Play.Server.RESPAWN; - private InternalStructure commonPlayerSpawnInfoStructure; + private final InternalStructure commonPlayerSpawnInfoStructure; public WrapperPlayServerRespawn() { super(new PacketContainer(TYPE), TYPE); handle.getModifier().writeDefaults(); - if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { - commonPlayerSpawnInfoStructure = handle.getStructures().read(0); - } + commonPlayerSpawnInfoStructure = handle.getStructures().readSafely(0); } public void setDimension(World value) { - if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { - // 1.20.2 to 1.20.4 - writeDimensionToStructure(value, commonPlayerSpawnInfoStructure.getStructures(), commonPlayerSpawnInfoStructure.getWorldKeys()); - } else if (MinecraftVersion.WILD_UPDATE.atOrAbove()) { + if (commonPlayerSpawnInfoStructure == null) { // 1.19 to 1.20.1, props to lukalt for helping me figure this out. writeDimensionToStructure(value, handle.getStructures(), handle.getWorldKeys()); + return; } + + // 1.20.2 to 1.21 + writeDimensionToStructure(value, commonPlayerSpawnInfoStructure.getStructures(), commonPlayerSpawnInfoStructure.getWorldKeys()); } public void setGameMode(GameMode value) { @@ -74,10 +73,15 @@ public class WrapperPlayServerRespawn extends AbstractPacket { } private void writeDimensionToStructure(World value, StructureModifier structures, StructureModifier worldKeys) { - final InternalStructure dimensionType = structures.read(0); - dimensionType.getMinecraftKeys().writeSafely(0, new MinecraftKey("minecraft", "dimension_type")); - dimensionType.getMinecraftKeys().writeSafely(1, new MinecraftKey("minecraft", "overworld")); - structures.writeSafely(0, dimensionType); + final InternalStructure dimensionType = structures.readSafely(0); + + if (dimensionType != null) { + // 1.20.2 to 1.20.5 + dimensionType.getMinecraftKeys().writeSafely(0, new MinecraftKey("minecraft", "dimension_type")); + dimensionType.getMinecraftKeys().writeSafely(1, new MinecraftKey("minecraft", "overworld")); + structures.writeSafely(0, dimensionType); + } + worldKeys.writeSafely(0, value); } } From db8ddbd5071b57707e7e9b88aafafe58433919bb Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 16 Jun 2024 02:07:46 +0200 Subject: [PATCH 222/296] feat: trying to figure out 1.20.5/1.21 --- .../wrapper/WrapperPlayServerRespawn.java | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java index 978dc84..6894a72 100644 --- a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java @@ -4,7 +4,9 @@ import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.InternalStructure; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.reflect.StructureModifier; +import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; +import com.comphenix.protocol.wrappers.BukkitConverters; import com.comphenix.protocol.wrappers.EnumWrappers; import com.comphenix.protocol.wrappers.MinecraftKey; import com.google.common.hash.Hashing; @@ -32,6 +34,7 @@ public class WrapperPlayServerRespawn extends AbstractPacket { public void setDimension(World value) { if (commonPlayerSpawnInfoStructure == null) { + System.out.println("cPSIS null"); // 1.19 to 1.20.1, props to lukalt for helping me figure this out. writeDimensionToStructure(value, handle.getStructures(), handle.getWorldKeys()); return; @@ -73,13 +76,18 @@ public class WrapperPlayServerRespawn extends AbstractPacket { } private void writeDimensionToStructure(World value, StructureModifier structures, StructureModifier worldKeys) { - final InternalStructure dimensionType = structures.readSafely(0); - - if (dimensionType != null) { - // 1.20.2 to 1.20.5 - dimensionType.getMinecraftKeys().writeSafely(0, new MinecraftKey("minecraft", "dimension_type")); - dimensionType.getMinecraftKeys().writeSafely(1, new MinecraftKey("minecraft", "overworld")); - structures.writeSafely(0, dimensionType); + if (MinecraftVersion.TRAILS_AND_TAILS.atOrAbove() && !MinecraftVersion.v1_20_5.atOrAbove()) { + final InternalStructure dimensionType = structures.readSafely(0); + if (dimensionType != null) { + // 1.20.2 to 1.20.5 + dimensionType.getMinecraftKeys().writeSafely(0, new MinecraftKey("minecraft", "dimension_type")); + dimensionType.getMinecraftKeys().writeSafely(1, new MinecraftKey("minecraft", "overworld")); + structures.writeSafely(0, dimensionType); + } + } else { + // 1.20.5/6 to 1.21 + final StructureModifier worldHolder = commonPlayerSpawnInfoStructure.getHolders(MinecraftReflection.getDimensionManager(), BukkitConverters.getDimensionConverter()); + worldHolder.writeSafely(0, value); } worldKeys.writeSafely(0, value); From 40401a1652c56134ee5cd2d4fd9085aeb3438585 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 16 Jun 2024 02:49:46 +0200 Subject: [PATCH 223/296] feat: why is protocollib api so complicated --- .../nicko/wrapper/WrapperPlayServerRespawn.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java index 6894a72..9d949b3 100644 --- a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java @@ -6,9 +6,7 @@ import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; -import com.comphenix.protocol.wrappers.BukkitConverters; -import com.comphenix.protocol.wrappers.EnumWrappers; -import com.comphenix.protocol.wrappers.MinecraftKey; +import com.comphenix.protocol.wrappers.*; import com.google.common.hash.Hashing; import org.bukkit.GameMode; import org.bukkit.World; @@ -86,7 +84,11 @@ public class WrapperPlayServerRespawn extends AbstractPacket { } } else { // 1.20.5/6 to 1.21 - final StructureModifier worldHolder = commonPlayerSpawnInfoStructure.getHolders(MinecraftReflection.getDimensionManager(), BukkitConverters.getDimensionConverter()); + final StructureModifier worldHolder = commonPlayerSpawnInfoStructure.getHolders( + MinecraftReflection.getDimensionManager(), + Converters.holder(BukkitConverters.getDimensionConverter(), + WrappedRegistry.getDimensionRegistry()) + ); worldHolder.writeSafely(0, value); } From 1133ac405222e23cf849bb8e1802f71c1d3bd176 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 16 Jun 2024 02:50:08 +0200 Subject: [PATCH 224/296] style: update docs --- .../xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java index 9d949b3..f24fed9 100644 --- a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java @@ -12,7 +12,7 @@ import org.bukkit.GameMode; import org.bukkit.World; /** - * PacketPlayServerRespawn Wrapper class (1.19 to 1.20.4) + * PacketPlayServerRespawn Wrapper class (1.19 to 1.21 (one day)) * * @author ineanto, based on work from dmulloy2 and Kristian S. Strangeland *

From d45ce65c3b2d90c96f0a1f333132c98e357bdbea Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 13 Aug 2024 18:24:53 +0200 Subject: [PATCH 225/296] chore(deps): update deps --- .idea/misc.xml | 2 +- build.gradle.kts | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index e964305..0ae20bf 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -4,7 +4,7 @@ - + \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 09f0919..924d32f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -39,13 +39,13 @@ repositories { dependencies { // Nicko - compileOnly("io.papermc.paper:paper-api:1.20.6-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT") compileOnly("com.github.dmulloy2:ProtocolLib:master-SNAPSHOT") compileOnly("me.clip:placeholderapi:2.11.5") compileOnly("net.kyori:adventure-api:4.17.0") - implementation("xyz.xenondevs.invui:invui:1.31") - implementation("net.wesjd:anvilgui:1.9.4-SNAPSHOT") + implementation("xyz.xenondevs.invui:invui:1.35") + implementation("net.wesjd:anvilgui:1.10.1-SNAPSHOT") implementation("com.github.jsixface:yamlconfig:1.2") implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.2") implementation("com.fasterxml.jackson.core:jackson-core:2.15.2") @@ -55,7 +55,7 @@ dependencies { implementation("com.google.code.gson:gson:2.10.1") implementation("org.bstats:bstats-bukkit:3.0.2") - testImplementation("com.github.seeseemelk:MockBukkit-v1.20:3.89.0") + testImplementation("com.github.MockBukkit:MockBukkit:v3.99.1") testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.2") testImplementation("org.junit.jupiter:junit-jupiter-engine:5.10.2") testImplementation("org.junit.jupiter:junit-jupiter:5.10.2") @@ -127,10 +127,10 @@ tasks { dependsOn(shadowJar) downloadPlugins { - url("https://download.luckperms.net/1539/bukkit/loader/LuckPerms-Bukkit-5.4.126.jar") + url("https://download.luckperms.net/1554/bukkit/loader/LuckPerms-Bukkit-5.4.139.jar") url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar") } - minecraftVersion("1.20.6") + minecraftVersion("1.21.1") } } \ No newline at end of file From a98d5a75bdc30686d9def1551c3322d6ccbb0ca8 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 20 Aug 2024 22:44:15 +0200 Subject: [PATCH 226/296] feat(wrapper): only support 1.20/1.21 (not working for >1.20.2?) --- .../java/xyz/ineanto/nicko/NickoBukkit.java | 3 +- .../nicko/appearance/AppearanceManager.java | 2 +- .../wrapper/WrapperPlayServerRespawn.java | 90 +++++++++---------- src/main/resources/plugin.yml | 2 +- 4 files changed, 45 insertions(+), 52 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java index 2ec8bc6..3073e52 100644 --- a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java +++ b/src/main/java/xyz/ineanto/nicko/NickoBukkit.java @@ -64,8 +64,9 @@ public class NickoBukkit extends JavaPlugin { dataStore = new PlayerDataStore(mojangAPI, getNickoConfig()); - if (!MinecraftVersion.WILD_UPDATE.atOrAbove()) { + if (!MinecraftVersion.TRAILS_AND_TAILS.atOrAbove()) { getLogger().severe("This version (" + MinecraftVersion.getCurrentVersion().getVersion() + ") is not supported by Nicko!"); + getLogger().severe("As of version 1.0.7, Nicko only supports the latest two majors Minecraft versions. (Currently 1.20.X-1.21.X)"); dataStore.getStorage().setError(true); Bukkit.getPluginManager().disablePlugin(this); } diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index 66f020e..3355aa9 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -151,7 +151,7 @@ public class AppearanceManager { respawn.setGameMode(player.getGameMode()); respawn.setPreviousGameMode(player.getGameMode()); respawn.setCopyMetadata(true); - respawn.sendPacket(player); + //respawn.sendPacket(player); player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); player.setAllowFlight(wasAllowedToFly); player.setFlying(wasFlying); diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java index f24fed9..44aa02a 100644 --- a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java @@ -3,95 +3,87 @@ package xyz.ineanto.nicko.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.InternalStructure; import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; -import com.comphenix.protocol.wrappers.*; +import com.comphenix.protocol.wrappers.BukkitConverters; +import com.comphenix.protocol.wrappers.EnumWrappers; +import com.comphenix.protocol.wrappers.MinecraftKey; import com.google.common.hash.Hashing; import org.bukkit.GameMode; import org.bukkit.World; /** - * PacketPlayServerRespawn Wrapper class (1.19 to 1.21 (one day)) - * - * @author ineanto, based on work from dmulloy2 and Kristian S. Strangeland + * PacketPlayServerRespawn Wrapper class (1.20.X to 1.21.X) *

- * In 1.20.2, all the fields were replaced with a - * single "CommonPlayerSpawnInfo" record object. + * In 1.20.2, all the fields were merged inside a + * single "CommonPlayerSpawnInfo" record. + * + * @author inenato (w/ additional help from lukalt), based on work from dmulloy2 and Kristian S. Strangeland */ public class WrapperPlayServerRespawn extends AbstractPacket { public static final PacketType TYPE = PacketType.Play.Server.RESPAWN; - private final InternalStructure commonPlayerSpawnInfoStructure; + private final InternalStructure spawnInfoStructure; public WrapperPlayServerRespawn() { super(new PacketContainer(TYPE), TYPE); handle.getModifier().writeDefaults(); - commonPlayerSpawnInfoStructure = handle.getStructures().readSafely(0); + spawnInfoStructure = handle.getStructures().readSafely(0); } public void setDimension(World value) { - if (commonPlayerSpawnInfoStructure == null) { - System.out.println("cPSIS null"); - // 1.19 to 1.20.1, props to lukalt for helping me figure this out. - writeDimensionToStructure(value, handle.getStructures(), handle.getWorldKeys()); + if (!MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { + // 1.20 to 1.20.1 (by lukalt) + final InternalStructure dimensionType = handle.getStructures().read(0); + dimensionType.getMinecraftKeys().writeSafely(0, new MinecraftKey("minecraft", "dimension_type")); + dimensionType.getMinecraftKeys().writeSafely(1, new MinecraftKey("minecraft", "overworld")); + handle.getStructures().writeSafely(0, dimensionType); + handle.getWorldKeys().writeSafely(0, value); return; } // 1.20.2 to 1.21 - writeDimensionToStructure(value, commonPlayerSpawnInfoStructure.getStructures(), commonPlayerSpawnInfoStructure.getWorldKeys()); + if (MinecraftVersion.TRAILS_AND_TAILS.atOrAbove() && !MinecraftVersion.v1_21_0.atOrAbove()) { + spawnInfoStructure.getHolders( + MinecraftReflection.getDimensionManager(), + BukkitConverters.getDimensionConverter() + ).write(0, value); + spawnInfoStructure.getWorldKeys().writeSafely(0, value); + handle.getStructures().writeSafely(0, spawnInfoStructure); + } } public void setGameMode(GameMode value) { - if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { - commonPlayerSpawnInfoStructure.getGameModes().writeSafely(0, EnumWrappers.NativeGameMode.fromBukkit(value)); + if (!MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { + // 1.20 to 1.20.1 + handle.getGameModes().writeSafely(0, EnumWrappers.NativeGameMode.fromBukkit(value)); return; } - handle.getGameModes().writeSafely(0, EnumWrappers.NativeGameMode.fromBukkit(value)); + + spawnInfoStructure.getGameModes().writeSafely(0, EnumWrappers.NativeGameMode.fromBukkit(value)); } public void setPreviousGameMode(GameMode value) { - if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { - commonPlayerSpawnInfoStructure.getGameModes().writeSafely(1, EnumWrappers.NativeGameMode.fromBukkit(value)); + if (!MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { + // 1.20 to 1.20.1 + handle.getGameModes().writeSafely(1, EnumWrappers.NativeGameMode.fromBukkit(value)); return; } - handle.getGameModes().writeSafely(1, EnumWrappers.NativeGameMode.fromBukkit(value)); + + spawnInfoStructure.getGameModes().writeSafely(1, EnumWrappers.NativeGameMode.fromBukkit(value)); } public void setCopyMetadata(boolean value) { - if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) return; - if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) { - handle.getBytes().writeSafely(0, ((byte) (value ? 0x01 : 0x00))); - } else { - handle.getBooleans().writeSafely(0, value); - } + if (!MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) return; + + // 1.20 to 1.20.1 + handle.getBooleans().writeSafely(0, value); } public void setSeed(long value) { - if (MinecraftVersion.WILD_UPDATE.atOrAbove() && !MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { + if (!MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { + // 1.20 to 1.20.1 handle.getLongs().writeSafely(0, Hashing.sha256().hashLong(value).asLong()); } } - - private void writeDimensionToStructure(World value, StructureModifier structures, StructureModifier worldKeys) { - if (MinecraftVersion.TRAILS_AND_TAILS.atOrAbove() && !MinecraftVersion.v1_20_5.atOrAbove()) { - final InternalStructure dimensionType = structures.readSafely(0); - if (dimensionType != null) { - // 1.20.2 to 1.20.5 - dimensionType.getMinecraftKeys().writeSafely(0, new MinecraftKey("minecraft", "dimension_type")); - dimensionType.getMinecraftKeys().writeSafely(1, new MinecraftKey("minecraft", "overworld")); - structures.writeSafely(0, dimensionType); - } - } else { - // 1.20.5/6 to 1.21 - final StructureModifier worldHolder = commonPlayerSpawnInfoStructure.getHolders( - MinecraftReflection.getDimensionManager(), - Converters.holder(BukkitConverters.getDimensionConverter(), - WrappedRegistry.getDimensionRegistry()) - ); - worldHolder.writeSafely(0, value); - } - - worldKeys.writeSafely(0, value); - } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 6ccf67a..7adaa7e 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -3,7 +3,7 @@ main: xyz.ineanto.nicko.NickoBukkit version: ${version} author: Ineanto description: "The feature packed, next generation disguise plugin for Minecraft." -api-version: 1.19 +api-version: 1.20 softdepend: [ PlaceholderAPI ] depend: - ProtocolLib From 23f9424fa9ec4bd0128e1facaa0a5cb988eee63b Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 26 Aug 2024 22:39:04 +0200 Subject: [PATCH 227/296] feat(wrapper): clean code for 1.20-1.20.4, untested 1.21 --- build.gradle.kts | 11 +++- .../nicko/appearance/AppearanceManager.java | 2 +- .../wrapper/WrapperPlayServerRespawn.java | 56 +++++++++++++------ 3 files changed, 48 insertions(+), 21 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 924d32f..a835108 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -39,7 +39,7 @@ repositories { dependencies { // Nicko - compileOnly("io.papermc.paper:paper-api:1.21-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT") compileOnly("com.github.dmulloy2:ProtocolLib:master-SNAPSHOT") compileOnly("me.clip:placeholderapi:2.11.5") compileOnly("net.kyori:adventure-api:4.17.0") @@ -128,9 +128,14 @@ tasks { downloadPlugins { url("https://download.luckperms.net/1554/bukkit/loader/LuckPerms-Bukkit-5.4.139.jar") - url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar") + + // 1.20 - 1.20.4 testing + url("https://github.com/dmulloy2/ProtocolLib/releases/download/5.2.0/ProtocolLib.jar") + + // 1.20.5 - latest testing + //url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar") } - minecraftVersion("1.21.1") + minecraftVersion("1.20.4") } } \ No newline at end of file diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index 3355aa9..66f020e 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -151,7 +151,7 @@ public class AppearanceManager { respawn.setGameMode(player.getGameMode()); respawn.setPreviousGameMode(player.getGameMode()); respawn.setCopyMetadata(true); - //respawn.sendPacket(player); + respawn.sendPacket(player); player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); player.setAllowFlight(wasAllowedToFly); player.setFlying(wasFlying); diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java index 44aa02a..bcb4ad6 100644 --- a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java @@ -3,9 +3,10 @@ package xyz.ineanto.nicko.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.InternalStructure; import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.reflect.StructureModifier; +import com.comphenix.protocol.reflect.accessors.Accessors; import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; -import com.comphenix.protocol.wrappers.BukkitConverters; import com.comphenix.protocol.wrappers.EnumWrappers; import com.comphenix.protocol.wrappers.MinecraftKey; import com.google.common.hash.Hashing; @@ -23,32 +24,53 @@ import org.bukkit.World; public class WrapperPlayServerRespawn extends AbstractPacket { public static final PacketType TYPE = PacketType.Play.Server.RESPAWN; - private final InternalStructure spawnInfoStructure; + private InternalStructure spawnInfoStructure = null; public WrapperPlayServerRespawn() { super(new PacketContainer(TYPE), TYPE); handle.getModifier().writeDefaults(); - spawnInfoStructure = handle.getStructures().readSafely(0); + if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { + spawnInfoStructure = handle.getStructures().read(0); + } } public void setDimension(World value) { - if (!MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { - // 1.20 to 1.20.1 (by lukalt) - final InternalStructure dimensionType = handle.getStructures().read(0); + final MinecraftVersion v1_20_5 = new MinecraftVersion(1, 20, 5); + + if (!MinecraftVersion.getCurrentVersion().isAtLeast(v1_20_5)) { + // 1.20.1 - 1.20.4 + final StructureModifier structureModifier = spawnInfoStructure == null ? + handle.getStructures() : spawnInfoStructure.getStructures(); + + final StructureModifier worldStructureModifier = spawnInfoStructure == null ? + handle.getWorldKeys() : spawnInfoStructure.getWorldKeys(); + + final InternalStructure dimensionType = structureModifier.read(0); dimensionType.getMinecraftKeys().writeSafely(0, new MinecraftKey("minecraft", "dimension_type")); dimensionType.getMinecraftKeys().writeSafely(1, new MinecraftKey("minecraft", "overworld")); - handle.getStructures().writeSafely(0, dimensionType); - handle.getWorldKeys().writeSafely(0, value); - return; - } + structureModifier.writeSafely(0, dimensionType); + worldStructureModifier.writeSafely(0, value); + } else { + // 1.20.5 to 1.21.1 + + // why is life so hard? + // Get the key from that class + final MinecraftKey key = MinecraftKey.fromHandle( + Accessors.getFieldAccessor( + TYPE.getPacketClass(), + MinecraftReflection.getResourceKey(), + true + ) + .get(spawnInfoStructure)); + + // Set the key + Accessors.getFieldAccessor( + spawnInfoStructure.getClass(), + MinecraftReflection.getResourceKey(), + true + ) + .set(spawnInfoStructure, key); - // 1.20.2 to 1.21 - if (MinecraftVersion.TRAILS_AND_TAILS.atOrAbove() && !MinecraftVersion.v1_21_0.atOrAbove()) { - spawnInfoStructure.getHolders( - MinecraftReflection.getDimensionManager(), - BukkitConverters.getDimensionConverter() - ).write(0, value); - spawnInfoStructure.getWorldKeys().writeSafely(0, value); handle.getStructures().writeSafely(0, spawnInfoStructure); } } From df988dbf87c5f9e5d47fa8f849385a6c94249c35 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 26 Aug 2024 22:39:39 +0200 Subject: [PATCH 228/296] fix(wrapper): 1.20 --- .../xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java index bcb4ad6..9b66380 100644 --- a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java @@ -38,7 +38,7 @@ public class WrapperPlayServerRespawn extends AbstractPacket { final MinecraftVersion v1_20_5 = new MinecraftVersion(1, 20, 5); if (!MinecraftVersion.getCurrentVersion().isAtLeast(v1_20_5)) { - // 1.20.1 - 1.20.4 + // 1.20 - 1.20.4 final StructureModifier structureModifier = spawnInfoStructure == null ? handle.getStructures() : spawnInfoStructure.getStructures(); From 5197fefdaf2b2336189cae297762650f23a8061f Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 27 Aug 2024 18:56:55 +0200 Subject: [PATCH 229/296] feat(error): simplify error management regarding data-related operations --- .../xyz/ineanto/nicko/appearance/ActionResult.java | 4 ++++ .../ineanto/nicko/appearance/AppearanceManager.java | 2 +- src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java | 3 --- .../xyz/ineanto/nicko/storage/PlayerDataStore.java | 8 ++++---- .../xyz/ineanto/nicko/storage/json/JSONStorage.java | 7 +++---- .../ineanto/nicko/storage/mariadb/MariaDBStorage.java | 11 +++++------ .../xyz/ineanto/nicko/storage/mysql/MySQLStorage.java | 11 +++++------ src/main/resources/en.yml | 5 +---- src/main/resources/fr.yml | 5 +---- 9 files changed, 24 insertions(+), 32 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/appearance/ActionResult.java b/src/main/java/xyz/ineanto/nicko/appearance/ActionResult.java index 18984c1..b7cd505 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/ActionResult.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/ActionResult.java @@ -8,6 +8,10 @@ public class ActionResult { return new ActionResult(); } + public static ActionResult error() { + return new ActionResult(null); + } + public static ActionResult error(String errorMessage) { return new ActionResult(errorMessage); } diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index 66f020e..7bc4319 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -129,7 +129,7 @@ public class AppearanceManager { reset(); return ActionResult.error(I18NDict.Error.MOJANG_NAME); } catch (InterruptedException e) { - return ActionResult.error(I18NDict.Error.GENERIC); + return ActionResult.error("Unknown error"); } } return ActionResult.ok(); diff --git a/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java b/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java index 26392de..674fe7c 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java @@ -4,13 +4,10 @@ public class I18NDict { public static class Error { 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"; - public static final String DATABASE = ERROR_KEY + "database"; - public static final String JSON = ERROR_KEY + "json"; } public static class Event { diff --git a/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java b/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java index 81fae57..94fca27 100644 --- a/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java +++ b/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java @@ -77,12 +77,12 @@ public class PlayerDataStore { } public ActionResult saveData(Player player) { - if (storage.isError()) return ActionResult.error(I18NDict.Error.DATABASE); - if (cache.isError()) return ActionResult.error(I18NDict.Error.CACHE); - if (!cache.isCached(player.getUniqueId())) return ActionResult.error(I18NDict.Error.CACHE); + if (storage.isError()) return ActionResult.error(); + if (cache.isError()) return ActionResult.error(); + if (!cache.isCached(player.getUniqueId())) return ActionResult.error(); final Optional cachedProfile = cache.retrieve(player.getUniqueId()); - if (cachedProfile.isEmpty()) return ActionResult.error(I18NDict.Error.CACHE); + if (cachedProfile.isEmpty()) return ActionResult.error(); cache.delete(player.getUniqueId()); return storage.store(player.getUniqueId(), cachedProfile.get()); diff --git a/src/main/java/xyz/ineanto/nicko/storage/json/JSONStorage.java b/src/main/java/xyz/ineanto/nicko/storage/json/JSONStorage.java index 301b000..b34a2e9 100644 --- a/src/main/java/xyz/ineanto/nicko/storage/json/JSONStorage.java +++ b/src/main/java/xyz/ineanto/nicko/storage/json/JSONStorage.java @@ -5,7 +5,6 @@ import com.google.gson.GsonBuilder; import xyz.ineanto.nicko.NickoBukkit; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.profile.NickoProfile; -import xyz.ineanto.nicko.i18n.I18NDict; import xyz.ineanto.nicko.storage.Storage; import xyz.ineanto.nicko.storage.StorageProvider; @@ -42,12 +41,12 @@ public class JSONStorage extends Storage { } } catch (IOException e) { logger.warning("Could not write to file."); - return ActionResult.error(I18NDict.Error.JSON); + return ActionResult.error(); } } } catch (IOException e) { logger.warning("Could not create file."); - return ActionResult.error(I18NDict.Error.JSON); + return ActionResult.error(); } return ActionResult.ok(); @@ -81,7 +80,7 @@ public class JSONStorage extends Storage { if (file.delete() || !file.exists()) { return ActionResult.ok(); } - return ActionResult.error(I18NDict.Error.JSON); + return ActionResult.error(); } private boolean checkFileExists(File file) throws IOException { diff --git a/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java b/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java index 694e053..ae33a46 100644 --- a/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java +++ b/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java @@ -2,7 +2,6 @@ package xyz.ineanto.nicko.storage.mariadb; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.i18n.I18NDict; import xyz.ineanto.nicko.i18n.Locale; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.Storage; @@ -36,7 +35,7 @@ public class MariaDBStorage extends Storage { @Override public ActionResult store(UUID uuid, NickoProfile profile) { final Connection connection = getProvider().getConnection(); - if (connection == null) return ActionResult.error(I18NDict.Error.DATABASE); + if (connection == null) return ActionResult.error(); try { final PreparedStatement statement = isStored(uuid) ? @@ -45,7 +44,7 @@ public class MariaDBStorage extends Storage { return ActionResult.ok(); } catch (SQLException e) { logger.warning("Couldn't send SQL Request: " + e.getMessage()); - return ActionResult.error(I18NDict.Error.DATABASE); + return ActionResult.error(); } } @@ -103,17 +102,17 @@ public class MariaDBStorage extends Storage { @Override public ActionResult delete(UUID uuid) { final Connection connection = getProvider().getConnection(); - if (connection == null) return ActionResult.error(I18NDict.Error.DATABASE); + if (connection == null) return ActionResult.error(); try { final String sql = "DELETE FROM nicko.DATA WHERE uuid = ?"; final PreparedStatement statement = connection.prepareStatement(sql); statement.setString(1, uuid.toString()); int rows = statement.executeUpdate(); - return (rows == 1 ? ActionResult.ok() : ActionResult.error(I18NDict.Error.DATABASE)); + return (rows == 1 ? ActionResult.ok() : ActionResult.error()); } catch (SQLException e) { logger.warning("Couldn't delete profile: " + e.getMessage()); - return ActionResult.error(I18NDict.Error.DATABASE); + return ActionResult.error(); } } diff --git a/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java b/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java index 102cdab..830b430 100644 --- a/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java +++ b/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java @@ -2,7 +2,6 @@ package xyz.ineanto.nicko.storage.mysql; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.i18n.I18NDict; import xyz.ineanto.nicko.i18n.Locale; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.Storage; @@ -36,7 +35,7 @@ public class MySQLStorage extends Storage { @Override public ActionResult store(UUID uuid, NickoProfile profile) { final Connection connection = getProvider().getConnection(); - if (connection == null) return ActionResult.error(I18NDict.Error.DATABASE); + if (connection == null) return ActionResult.error(); try { final PreparedStatement statement = isStored(uuid) ? @@ -45,7 +44,7 @@ public class MySQLStorage extends Storage { return ActionResult.ok(); } catch (SQLException e) { logger.warning("Couldn't send SQL Request: " + e.getMessage()); - return ActionResult.error(I18NDict.Error.DATABASE); + return ActionResult.error(); } } @@ -103,17 +102,17 @@ public class MySQLStorage extends Storage { @Override public ActionResult delete(UUID uuid) { final Connection connection = getProvider().getConnection(); - if (connection == null) return ActionResult.error(I18NDict.Error.DATABASE); + if (connection == null) return ActionResult.error(); try { final String sql = "DELETE FROM nicko.DATA WHERE uuid = ?"; final PreparedStatement statement = connection.prepareStatement(sql); statement.setString(1, uuid.toString()); int rows = statement.executeUpdate(); - return (rows == 1 ? ActionResult.ok() : ActionResult.error(I18NDict.Error.DATABASE)); + return (rows == 1 ? ActionResult.ok() : ActionResult.error()); } catch (SQLException e) { logger.warning("Couldn't delete profile: " + e.getMessage()); - return ActionResult.error(I18NDict.Error.DATABASE); + return ActionResult.error(); } } diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 2458b6a..a32d1df 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -1,17 +1,14 @@ # Nicko ${version} - Language File: # Specifies the configuration version, don't change. -version: "1.1.3" +version: "1.1.4" error: - generic: "An unknown error occurred." permission: "§cYou do not have the required permission." invalid_username: "§cThis is not a valid Minecraft username." mojang_name: "There is no Minecraft account with this name." mojang_skin: "This Minecraft account has no skin." cache: "Unable to get skin from the cache." - sql: "SQL Error" - json: "JSON Error" event: settings: diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index dc68fe3..dd9a400 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -1,17 +1,14 @@ # Nicko ${version} - Fichier de langue: # Précise la version de la configuration, ne pas changer. -version: "1.1.3" +version: "1.1.4" 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." mojang_name: "Compte Minecraft inexistant" mojang_skin: "Skin Minecraft invalide" cache: "Erreur du cache" - database: "Erreur SQL" - json: "Erreur JSON" event: settings: From 0ef5766004dde77f4837c47ebad4dea6b6923e17 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 27 Aug 2024 22:48:39 +0200 Subject: [PATCH 230/296] feat(language): reworked messages and formatting --- .gitignore | 3 +- CHANGELOG.secret.log | 116 ++++++++++++++++++ build.gradle.kts | 6 +- .../nicko/{NickoBukkit.java => Nicko.java} | 26 ++-- .../xyz/ineanto/nicko/anvil/AnvilManager.java | 30 ++--- .../nicko/appearance/AppearanceManager.java | 16 +-- .../appearance/random/RandomNameFetcher.java | 6 +- .../ineanto/nicko/command/NickoCommand.java | 8 +- .../ineanto/nicko/config/Configuration.java | 11 +- .../nicko/config/ConfigurationManager.java | 3 - .../nicko/event/PlayerJoinListener.java | 17 ++- .../nicko/event/PlayerQuitListener.java | 6 +- .../java/xyz/ineanto/nicko/gui/AdminGUI.java | 16 +-- .../ineanto/nicko/gui/CacheManagementGUI.java | 8 +- .../java/xyz/ineanto/nicko/gui/ChoiceGUI.java | 10 +- .../java/xyz/ineanto/nicko/gui/HomeGUI.java | 8 +- .../ineanto/nicko/gui/InvalidateSkinGUI.java | 20 +-- .../xyz/ineanto/nicko/gui/PlayerCheckGUI.java | 14 +-- .../xyz/ineanto/nicko/gui/SettingsGUI.java | 8 +- .../ineanto/nicko/gui/items/ItemDefaults.java | 12 +- .../gui/items/admin/ManageCacheItem.java | 16 +-- .../gui/items/admin/ManagePlayerItem.java | 12 +- .../gui/items/admin/cache/CacheEntryItem.java | 22 ++-- .../admin/cache/CacheStatisticsItem.java | 14 +-- .../admin/cache/InvalidateCacheItem.java | 18 +-- .../items/admin/cache/InvalidateSkinItem.java | 10 +- .../admin/check/PlayerInformationItem.java | 26 ++-- .../gui/items/appearance/ChangeBothItem.java | 10 +- .../gui/items/appearance/ChangeNameItem.java | 10 +- .../gui/items/appearance/ChangeSkinItem.java | 16 +-- .../nicko/gui/items/common/GoBackItem.java | 10 +- .../gui/items/common/ScrollDownItem.java | 14 +-- .../nicko/gui/items/common/ScrollUpItem.java | 14 +-- .../gui/items/common/choice/CancelItem.java | 10 +- .../gui/items/common/choice/ConfirmItem.java | 10 +- .../nicko/gui/items/home/AdminAccessItem.java | 10 +- .../nicko/gui/items/home/ExitItem.java | 10 +- .../nicko/gui/items/home/RandomSkinItem.java | 24 ++-- .../nicko/gui/items/home/ResetItem.java | 16 +-- .../gui/items/home/SettingsAccessItem.java | 10 +- .../items/settings/LanguageCyclingItem.java | 38 +++--- .../items/settings/RandomSkinCyclingItem.java | 22 ++-- .../CustomLanguage.java} | 27 ++-- .../Locale.java => language/Language.java} | 12 +- .../LanguageKey.java} | 8 +- .../PlayerLanguage.java} | 69 ++++++++--- .../nicko/{i18n => language}/Translation.java | 2 +- .../migration/ConfigurationMigrator.java | 13 +- .../nicko/migration/CustomLocaleMigrator.java | 34 ++--- .../nicko/placeholder/NickoExpansion.java | 6 +- .../ineanto/nicko/profile/NickoProfile.java | 24 ++-- .../nicko/storage/PlayerDataStore.java | 4 +- .../nicko/storage/json/JSONStorage.java | 10 +- .../nicko/storage/mariadb/MariaDBStorage.java | 4 +- .../nicko/storage/mysql/MySQLStorage.java | 4 +- .../nicko/storage/redis/RedisCache.java | 6 +- .../wrapper/WrapperPlayServerRespawn.java | 35 +++--- src/main/resources/config.yml | 21 ++-- src/main/resources/en.yml | 50 ++++---- src/main/resources/fr.yml | 54 ++++---- src/main/resources/plugin.yml | 2 +- .../ineanto/nicko/test/NickoPluginTest.java | 6 +- .../nicko/test/appearance/RandomNameTest.java | 6 +- .../nicko/test/config/ConfigurationTest.java | 6 +- .../test/config/ConfigurationVersionTest.java | 13 +- .../nicko/test/i18n/ItemTranslationTest.java | 22 ++-- .../nicko/test/i18n/TranslationTest.java | 14 +-- .../nicko/test/migration/MigrationTest.java | 28 +++-- .../nicko/test/storage/MapCacheTest.java | 6 +- .../nicko/test/storage/RedisCacheTest.java | 7 +- .../nicko/test/storage/SQLStorageTest.java | 13 +- 71 files changed, 670 insertions(+), 522 deletions(-) create mode 100644 CHANGELOG.secret.log rename src/main/java/xyz/ineanto/nicko/{NickoBukkit.java => Nicko.java} (91%) rename src/main/java/xyz/ineanto/nicko/{i18n/CustomLocale.java => language/CustomLanguage.java} (58%) rename src/main/java/xyz/ineanto/nicko/{i18n/Locale.java => language/Language.java} (64%) rename src/main/java/xyz/ineanto/nicko/{i18n/I18NDict.java => language/LanguageKey.java} (96%) rename src/main/java/xyz/ineanto/nicko/{i18n/I18N.java => language/PlayerLanguage.java} (69%) rename src/main/java/xyz/ineanto/nicko/{i18n => language}/Translation.java (72%) diff --git a/.gitignore b/.gitignore index 8a238de..bc8385d 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,5 @@ bin/ !**/src/test/**/bin/ ### Server ### -run/ \ No newline at end of file +run/ +CHANGELOG.secret.log \ No newline at end of file diff --git a/CHANGELOG.secret.log b/CHANGELOG.secret.log new file mode 100644 index 0000000..98b7f56 --- /dev/null +++ b/CHANGELOG.secret.log @@ -0,0 +1,116 @@ +1.2.0: Update n°13 (XX/XX/24) + [FEATURES] + - Players are now able to save disguises as presets. + + [FIXES] + - Fixed an oversight preventing the configuration from properly being migrated. + + [LANGUAGE] + - Moved the prefix to the language file. + - Updated the language files to modernize the messages. + + [OTHER] + - Dropped the release candidate status as Nicko is now considered stable. + +1.1.7-RC1: Hotfix n°5 (04/05/24) + [OTHER] + - Restored download link again on spigotmc.org + +1.1.6-RC1: Update n°11 (04/05/24) + [FEATURES] + - Update dependencies in preparation to the 1.20.5 update + + [OTHER] + - Restored download link on spigotmc.org + +1.1.5-RC1: Update n°10 (25/12/23) + [FEATURES] + - Various improvements to performance. + [FIXES] + - Fixed a bug related to configuration migration. + +1.1.4-RC1: Update n°9 (07/02/23) + [OTHER] + - The repository hosting the previous version of Nicko had expired, this is now fixed. + +1.1.3-RC1: Hotfix n°4 (28/12/23) + [FIXES] + - Fixed the English Locale version being late. + +1.1.2-RC1: Update n°8 (28/12/23) + [FEATURES] + - Players now default back to their original appearance upon failure. + + [FIXES] + - Fixed an invalid placeholder parameter (%nicko_random_skin% now gets if the player has random skin on login set or not). + - Fixed the error reason not appearing upon failure. + - Fixed player profiles (name and skin associated) not being reset gracefully upon failure. + - Fixed error messages not being precise enough. + - Various optimizations and improvements. + +1.1.1-RC1: Update n°7 (27/12/23) + [FEATURES] + - Made Nicko compatible with 1.20.3 and 1.20.4. + + +1.1.0-RC1: Update n°6 (23/12/23) + [BREAKING] + - The language system has been updated to use the Adventure library (https://docs.advntr.dev/index.html). This results in the custom locale breaking + Nicko upon usage of legacy color codes (e.g., "§6Nicko"). Your custom locale will be backed up upon starting this version and you will be able to + use the new default English locale to help you make your locale compatible with the new formatting. + + [FEATURES] + - Players can now choose to get a random appearance via a list of more than 400 usernames and skins associated. + - Players can now toggle a setting to automatically get a random appearance upon joining. + - Introduced a version string inside Nicko's language files to plan future updates to the file. (see [BREAKING]) + + (Note: the random skin functionality is still work-in-progress and might break or not work at all because of + the lack of time that I have to test all the usernames and skins associated.) + + [FIXES] + - Various optimizations and improvements. + - Internal refactoring + - bStats metrics are not minified anymore. + +1.0.8-RC1: Update n°5 (19/12/23) + [FEATURES] + - Introduced a version string inside Nicko's configuration to plan future updates to the file. Your previous configuration file will automatically be migrated to this current version (with the backup of your old one included!) + - Persistence and cache will now fallback to local alternatives when unreachable. + - Player check GUI has been updated to better reflect the current state of player's disguises. + - Developers can now listen to the PlayerDisguiseEvent and cancel the disguise process. + + [OTHER] + - Various optimizations and improvements. + - Internal refactoring + +1.0.7-RC1: Update n°4 (13/12/23) + [OTHER] + - In line with my thinking that Minecraft servers should always be in one of the latest versions to give developers more freedom and less maintenance hassle, Nicko will now only be supporting the current major version and the one before it. This results in this version of Nicko now needing at minimum Java version 17 and a server running 1.19. If you can't upgrade, consider myself sorry. + - Various optimizations and improvements following the upgrade to Java 17. + +1.0.6-RC1: Update n°3 (11/12/23) + [OTHER] + - Added telemetry via bStats to gather useful informations about Nicko. This feature is optional and can be disabled inside the "bStats" folder found in plugins folder. Informations gathered are public record and can be found at: https://bstats.org/plugin/bukkit/Nicko/20483. + +1.0.5-RC1: Update n°2 (11/12/23) + [OTHER] + - Moved plugin to the Gradle build chain, resulting in faster builds and smaller Jar. This has no consequences for players. + +1.0.4-RC1: + [FEATURES] + - The players check GUI is now updated upon player's joining and leaving + - Administrators are now able to remove a player's disguise through the player check GUI + +1.0.3-RC1: Hotfix n°3 (07/12/23) + [FIXES] + - Fixed a visual bug where players in survival mode were seeing themselves as having full health and hunger after disguising. + +1.0.2-RC1: Hotfix n°2 (06/12/23) + [OTHER] + - Internal refactoring + +1.0.1-RC1: Hotfix n°1 (06/12/23) + [FIXES] + - Fixed an issue when joining and players being disguised were not for the player joining. + + diff --git a/build.gradle.kts b/build.gradle.kts index a835108..18ed652 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -130,12 +130,12 @@ tasks { url("https://download.luckperms.net/1554/bukkit/loader/LuckPerms-Bukkit-5.4.139.jar") // 1.20 - 1.20.4 testing - url("https://github.com/dmulloy2/ProtocolLib/releases/download/5.2.0/ProtocolLib.jar") + //url("https://github.com/dmulloy2/ProtocolLib/releases/download/5.2.0/ProtocolLib.jar") // 1.20.5 - latest testing - //url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar") + url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar") } - minecraftVersion("1.20.4") + minecraftVersion("1.21.1") } } \ No newline at end of file diff --git a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java b/src/main/java/xyz/ineanto/nicko/Nicko.java similarity index 91% rename from src/main/java/xyz/ineanto/nicko/NickoBukkit.java rename to src/main/java/xyz/ineanto/nicko/Nicko.java index 3073e52..a0621bb 100644 --- a/src/main/java/xyz/ineanto/nicko/NickoBukkit.java +++ b/src/main/java/xyz/ineanto/nicko/Nicko.java @@ -12,8 +12,8 @@ import xyz.ineanto.nicko.config.Configuration; import xyz.ineanto.nicko.config.ConfigurationManager; import xyz.ineanto.nicko.event.PlayerJoinListener; import xyz.ineanto.nicko.event.PlayerQuitListener; -import xyz.ineanto.nicko.i18n.CustomLocale; -import xyz.ineanto.nicko.i18n.Locale; +import xyz.ineanto.nicko.language.CustomLanguage; +import xyz.ineanto.nicko.language.Language; import xyz.ineanto.nicko.migration.ConfigurationMigrator; import xyz.ineanto.nicko.migration.CustomLocaleMigrator; import xyz.ineanto.nicko.mojang.MojangAPI; @@ -28,8 +28,8 @@ import xyz.xenondevs.invui.item.impl.SimpleItem; import java.io.IOException; -public class NickoBukkit extends JavaPlugin { - private static NickoBukkit plugin; +public class Nicko extends JavaPlugin { + private static Nicko plugin; private final boolean unitTesting; @@ -37,19 +37,19 @@ public class NickoBukkit extends JavaPlugin { private PlayerDataStore dataStore; private ConfigurationManager configurationManager; private Configuration configuration; - private CustomLocale customLocale; + private CustomLanguage customLanguage; private PlayerNameStore nameStore; private RandomNameFetcher nameFetcher; private Metrics metrics; - public NickoBukkit() { + public Nicko() { this.unitTesting = false; } /** * Used by MockBukkit */ - protected NickoBukkit(Configuration configuration) { + protected Nicko(Configuration configuration) { this.unitTesting = true; this.configuration = configuration; getLogger().info("Unit Testing Mode enabled."); @@ -107,9 +107,9 @@ public class NickoBukkit extends JavaPlugin { if (configuration.isCustomLocale()) { try { - CustomLocale.dumpIntoFile(Locale.ENGLISH); - customLocale = new CustomLocale(); - new CustomLocaleMigrator(this, customLocale).migrate(); + CustomLanguage.dumpIntoFile(Language.ENGLISH); + customLanguage = new CustomLanguage(); + new CustomLocaleMigrator(this, customLanguage).migrate(); getLogger().info("Successfully loaded the custom locale."); } catch (IOException e) { getLogger().severe("Failed to load the custom locale!"); @@ -155,7 +155,7 @@ public class NickoBukkit extends JavaPlugin { getLogger().info("Nicko (Bukkit) has been disabled."); } - public static NickoBukkit getInstance() { + public static Nicko getInstance() { return plugin; } @@ -195,7 +195,7 @@ public class NickoBukkit extends JavaPlugin { return mojangAPI; } - public CustomLocale getCustomLocale() { - return customLocale; + public CustomLanguage getCustomLocale() { + return customLanguage; } } diff --git a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java index 2c2f7ce..38c7f73 100644 --- a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java @@ -7,12 +7,12 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.appearance.AppearanceManager; import xyz.ineanto.nicko.event.custom.PlayerDisguiseEvent; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.ineanto.nicko.mojang.MojangUtils; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.PlayerDataStore; @@ -24,13 +24,13 @@ import java.util.Optional; public class AnvilManager { private final Player player; private final AppearanceManager appearanceManager; - private final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore(); + private final PlayerDataStore dataStore = Nicko.getInstance().getDataStore(); private final NickoProfile profile; - private final I18N i18n; + private final PlayerLanguage playerLanguage; public AnvilManager(Player player) { this.player = player; - this.i18n = new I18N(player); + this.playerLanguage = new PlayerLanguage(player); final Optional optionalProfile = dataStore.getData(player.getUniqueId()); this.profile = optionalProfile.orElse(NickoProfile.EMPTY_PROFILE.clone()); @@ -51,7 +51,7 @@ public class AnvilManager { private AnvilGUI.Builder getNameThenSkinAnvil() { return new AnvilGUI.Builder() - .plugin(NickoBukkit.getInstance()) + .plugin(Nicko.getInstance()) .itemLeft(getLeftItem(false)) .interactableSlots(AnvilGUI.Slot.OUTPUT) .onClick((slot, snapshot) -> { @@ -71,7 +71,7 @@ public class AnvilManager { private AnvilGUI.Builder getNameAnvil() { return new AnvilGUI.Builder() - .plugin(NickoBukkit.getInstance()) + .plugin(Nicko.getInstance()) .itemLeft(getLeftItem(false)) .interactableSlots(AnvilGUI.Slot.OUTPUT) .onClick((slot, snapshot) -> { @@ -91,7 +91,7 @@ public class AnvilManager { private AnvilGUI.Builder getSkinAnvil() { return new AnvilGUI.Builder() - .plugin(NickoBukkit.getInstance()) + .plugin(Nicko.getInstance()) .itemLeft(getLeftItem(true)) .interactableSlots(AnvilGUI.Slot.OUTPUT) .onClick((slot, snapshot) -> { @@ -116,13 +116,13 @@ public class AnvilManager { final ActionResult actionResult = appearanceManager.updatePlayer(skinChange, false); if (!actionResult.isError()) { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.OK, true)); + player.sendMessage(playerLanguage.translate(LanguageKey.Event.Appearance.Set.OK, true)); } else { player.sendMessage( - i18n.translate( - I18NDict.Event.Appearance.Set.ERROR, + playerLanguage.translate( + LanguageKey.Event.Appearance.Set.ERROR, true, - i18n.translate(actionResult.getErrorKey(), false) + playerLanguage.translate(actionResult.getErrorKey(), false) )); } return Collections.singletonList(AnvilGUI.ResponseAction.close()); @@ -134,9 +134,9 @@ public class AnvilManager { if (meta != null) { if (skin) { - meta.displayName(Component.text(i18n.translate(I18NDict.GUI.NEW_SKIN, false))); + meta.displayName(Component.text(playerLanguage.translate(LanguageKey.GUI.NEW_SKIN, false))); } else { - meta.displayName(Component.text(i18n.translate(I18NDict.GUI.NEW_NAME, false))); + meta.displayName(Component.text(playerLanguage.translate(LanguageKey.GUI.NEW_NAME, false))); } } diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index 7bc4319..7b9fcd8 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -8,8 +8,8 @@ import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerTeleportEvent; -import xyz.ineanto.nicko.NickoBukkit; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.Nicko; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.ineanto.nicko.mojang.MojangAPI; import xyz.ineanto.nicko.mojang.MojangSkin; import xyz.ineanto.nicko.profile.NickoProfile; @@ -24,7 +24,7 @@ import java.util.Optional; import java.util.concurrent.ExecutionException; public class AppearanceManager { - private final NickoBukkit instance = NickoBukkit.getInstance(); + private final Nicko instance = Nicko.getInstance(); private final PlayerDataStore dataStore = instance.getDataStore(); private final PlayerNameStore nameStore = instance.getNameStore(); @@ -105,7 +105,7 @@ public class AppearanceManager { if (skinChange) { Optional skin; try { - final MojangAPI mojangAPI = NickoBukkit.getInstance().getMojangAPI(); + final MojangAPI mojangAPI = Nicko.getInstance().getMojangAPI(); final Optional uuid = mojangAPI.getUUID(profile.getSkin()); if (uuid.isPresent()) { skin = reset ? mojangAPI.getSkinWithoutCaching(uuid.get()) : mojangAPI.getSkin(uuid.get()); @@ -116,18 +116,18 @@ public class AppearanceManager { properties.put("textures", new WrappedSignedProperty("textures", skinResult.value(), skinResult.signature())); } else { reset(); - return ActionResult.error(I18NDict.Error.MOJANG_SKIN); + return ActionResult.error(LanguageKey.Error.MOJANG_SKIN); } } else { reset(); - return ActionResult.error(I18NDict.Error.MOJANG_NAME); + return ActionResult.error(LanguageKey.Error.MOJANG_NAME); } return ActionResult.ok(); } catch (ExecutionException e) { - return ActionResult.error(I18NDict.Error.CACHE); + return ActionResult.error(LanguageKey.Error.CACHE); } catch (IOException e) { reset(); - return ActionResult.error(I18NDict.Error.MOJANG_NAME); + return ActionResult.error(LanguageKey.Error.MOJANG_NAME); } catch (InterruptedException e) { return ActionResult.error("Unknown error"); } diff --git a/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java b/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java index c390f4a..3ff9574 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/random/RandomNameFetcher.java @@ -1,6 +1,6 @@ package xyz.ineanto.nicko.appearance.random; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import java.io.BufferedReader; import java.io.IOException; @@ -12,9 +12,9 @@ import java.util.List; import java.util.Random; public class RandomNameFetcher { - private final NickoBukkit instance; + private final Nicko instance; - public RandomNameFetcher(NickoBukkit instance) { + public RandomNameFetcher(Nicko instance) { this.instance = instance; } diff --git a/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java b/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java index 40ffbbf..118696e 100644 --- a/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java +++ b/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java @@ -6,8 +6,8 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import xyz.ineanto.nicko.gui.HomeGUI; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; public class NickoCommand implements CommandExecutor { @Override @@ -16,8 +16,8 @@ public class NickoCommand implements CommandExecutor { if (player.isOp() || player.hasPermission("nicko.use") || player.hasPermission("nicko.*")) { new HomeGUI(player).open(); } else { - final I18N i18N = new I18N(player); - player.sendMessage(i18N.translate(I18NDict.Error.PERMISSION, true)); + final PlayerLanguage playerLanguage = new PlayerLanguage(player); + player.sendMessage(playerLanguage.translate(LanguageKey.Error.PERMISSION, true)); } return false; } diff --git a/src/main/java/xyz/ineanto/nicko/config/Configuration.java b/src/main/java/xyz/ineanto/nicko/config/Configuration.java index a4958ad..b706f2f 100644 --- a/src/main/java/xyz/ineanto/nicko/config/Configuration.java +++ b/src/main/java/xyz/ineanto/nicko/config/Configuration.java @@ -4,11 +4,10 @@ import com.fasterxml.jackson.annotation.JsonProperty; import xyz.ineanto.nicko.version.Version; public class Configuration { - public static final Version VERSION = new Version(1, 0, 8); + public static final Version VERSION = new Version(1, 0, 9); public static final Configuration DEFAULT = new Configuration(VERSION.toString(), DefaultDataSources.SQL_EMPTY, DefaultDataSources.REDIS_EMPTY, - "§6Nicko §8§l| §r", false); private final transient Version versionObject; @@ -19,21 +18,17 @@ public class Configuration { private final SQLDataSourceConfiguration sqlConfiguration; @JsonProperty("redis") private final DataSourceConfiguration redisConfiguration; - @JsonProperty("prefix") - private final String prefix; @JsonProperty("customLocale") private final Boolean customLocale; public Configuration(@JsonProperty("version") String version, @JsonProperty("sql") SQLDataSourceConfiguration sqlConfiguration, @JsonProperty("redis") DataSourceConfiguration redisConfiguration, - @JsonProperty("prefix") String prefix, @JsonProperty("customLocale") Boolean customLocale) { this.version = version; this.versionObject = Version.fromString(version); this.sqlConfiguration = sqlConfiguration; this.redisConfiguration = redisConfiguration; - this.prefix = prefix; this.customLocale = customLocale; } @@ -53,10 +48,6 @@ public class Configuration { return redisConfiguration; } - public String getPrefix() { - return prefix; - } - public Boolean isCustomLocale() { return customLocale; } diff --git a/src/main/java/xyz/ineanto/nicko/config/ConfigurationManager.java b/src/main/java/xyz/ineanto/nicko/config/ConfigurationManager.java index 566d55e..de83afb 100644 --- a/src/main/java/xyz/ineanto/nicko/config/ConfigurationManager.java +++ b/src/main/java/xyz/ineanto/nicko/config/ConfigurationManager.java @@ -10,10 +10,8 @@ import java.nio.file.StandardCopyOption; import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; -import java.util.logging.Logger; public class ConfigurationManager { - private final Logger logger = Logger.getLogger("ConfigurationManager"); private final ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); private final File file; private final File backupFile; @@ -40,7 +38,6 @@ public class ConfigurationManager { try { final InputStream input = getClass().getResourceAsStream("/config.yml"); if (input != null) { - logger.info("Saved default configuration as config.yml"); Files.createDirectories(file.getParentFile().toPath()); Files.createFile(file.toPath()); Files.copy(input, file.toPath(), StandardCopyOption.REPLACE_EXISTING); diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java index b28fb11..b7e4408 100644 --- a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java @@ -6,13 +6,13 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.appearance.AppearanceManager; import xyz.ineanto.nicko.gui.PlayerCheckGUI; import xyz.ineanto.nicko.gui.PlayerCheckGUIData; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.PlayerDataStore; import xyz.ineanto.nicko.storage.name.PlayerNameStore; @@ -30,8 +30,8 @@ public class PlayerJoinListener implements Listener { @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onPlayerJoin(PlayerJoinEvent event) { final Player player = event.getPlayer(); - final NickoBukkit instance = NickoBukkit.getInstance(); - final I18N i18n = new I18N(player); + final Nicko instance = Nicko.getInstance(); + final PlayerLanguage playerLanguage = new PlayerLanguage(player); final PlayerNameStore nameStore = instance.getNameStore(); final PlayerDataStore dataStore = instance.getDataStore(); nameStore.storeName(player); @@ -52,12 +52,11 @@ public class PlayerJoinListener implements Listener { 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, true)); + player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Appearance.Restore.OK)); } else { player.sendMessage( - i18n.translate(I18NDict.Event.Appearance.Restore.ERROR, - true, - i18n.translate(actionResult.getErrorKey(), false) + playerLanguage.translateWithOops(LanguageKey.Event.Appearance.Restore.ERROR, + playerLanguage.translate(actionResult.getErrorKey(), false) )); } } diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java index 25ccb49..10160a4 100644 --- a/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java @@ -5,7 +5,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.gui.PlayerCheckGUI; import xyz.ineanto.nicko.gui.PlayerCheckGUIData; @@ -21,9 +21,9 @@ public class PlayerQuitListener implements Listener { @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { final Player player = event.getPlayer(); - final ActionResult result = NickoBukkit.getInstance().getDataStore().saveData(player); + final ActionResult result = Nicko.getInstance().getDataStore().saveData(player); if (result.isError()) { - NickoBukkit.getInstance().getLogger().warning("Failed to save data for " + player.getName()); + Nicko.getInstance().getLogger().warning("Failed to save data for " + player.getName()); } // This is a dirty way to do it but could be worse tbh diff --git a/src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java b/src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java index dbcc2be..2646836 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/AdminGUI.java @@ -5,8 +5,8 @@ import xyz.ineanto.nicko.gui.items.ItemDefaults; import xyz.ineanto.nicko.gui.items.admin.ManageCacheItem; import xyz.ineanto.nicko.gui.items.admin.ManagePlayerItem; import xyz.ineanto.nicko.gui.items.common.GoBackItem; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.item.impl.SimpleItem; import xyz.xenondevs.invui.window.Window; @@ -17,22 +17,22 @@ public class AdminGUI { private final String title; public AdminGUI(Player player) { - final I18N i18n = new I18N(player); - this.title = i18n.translate(I18NDict.GUI.Titles.ADMIN, false); + final PlayerLanguage playerLanguage = new PlayerLanguage(player); + this.title = playerLanguage.translate(LanguageKey.GUI.Titles.ADMIN, false); final HomeGUI parent = new HomeGUI(player); final GoBackItem backItem = new GoBackItem(player); - final ManagePlayerItem managePlayerItem = new ManagePlayerItem(i18n, player); + final ManagePlayerItem managePlayerItem = new ManagePlayerItem(playerLanguage, player); this.gui = Gui.normal() .setStructure( "# # # # # # # # #", - "# # # S C X # # #", + "# # # S C U # # #", "B # # # # # # # #" ) - .addIngredient('S', new ManageCacheItem(i18n)) + .addIngredient('S', new ManageCacheItem(playerLanguage)) .addIngredient('C', managePlayerItem.get()) - .addIngredient('U', new SimpleItem(ItemDefaults.getUnavailableItem(i18n))) + .addIngredient('U', new SimpleItem(ItemDefaults.getUnavailableItem(playerLanguage))) .addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle())) .build(); this.player = player; diff --git a/src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java b/src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java index e8287e1..a44d47f 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/CacheManagementGUI.java @@ -5,8 +5,8 @@ import xyz.ineanto.nicko.gui.items.admin.cache.CacheStatisticsItem; import xyz.ineanto.nicko.gui.items.admin.cache.InvalidateCacheItem; import xyz.ineanto.nicko.gui.items.admin.cache.InvalidateSkinItem; import xyz.ineanto.nicko.gui.items.common.GoBackItem; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; @@ -16,8 +16,8 @@ public class CacheManagementGUI { private final String title; public CacheManagementGUI(Player player) { - final I18N i18n = new I18N(player); - this.title = i18n.translate(I18NDict.GUI.Titles.CACHE, false); + final PlayerLanguage playerLanguage = new PlayerLanguage(player); + this.title = playerLanguage.translate(LanguageKey.GUI.Titles.CACHE, false); final AdminGUI parent = new AdminGUI(player); final GoBackItem backItem = new GoBackItem(player); diff --git a/src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java b/src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java index 15dbb4e..44c0527 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/ChoiceGUI.java @@ -5,8 +5,8 @@ import org.bukkit.entity.Player; import xyz.ineanto.nicko.gui.items.common.choice.CancelItem; import xyz.ineanto.nicko.gui.items.common.choice.ChoiceCallback; import xyz.ineanto.nicko.gui.items.common.choice.ConfirmItem; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SimpleItem; @@ -18,11 +18,11 @@ public class ChoiceGUI { private final String title; public ChoiceGUI(Player player, ChoiceCallback callback) { - final I18N i18n = new I18N(player); + final PlayerLanguage playerLanguage = new PlayerLanguage(player); final ConfirmItem confirmItem = new ConfirmItem(player, callback); final CancelItem cancelItem = new CancelItem(player, callback); - this.title = i18n.translate(I18NDict.GUI.Titles.CONFIRM, false); + this.title = playerLanguage.translate(LanguageKey.GUI.Titles.CONFIRM, false); this.gui = Gui.normal() .setStructure( "@ @ @ @ % & & & &", @@ -31,7 +31,7 @@ public class ChoiceGUI { ) .addIngredient('@', confirmItem.get()) .addIngredient('&', cancelItem.get()) - .addIngredient('I', new SimpleItem(i18n.translateItem(new ItemBuilder(Material.PAPER), I18NDict.GUI.Choice.CHOOSE))) + .addIngredient('I', new SimpleItem(playerLanguage.translateItem(new ItemBuilder(Material.PAPER), LanguageKey.GUI.Choice.CHOOSE))) .build(); this.player = player; } diff --git a/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java b/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java index a918e7b..321b55e 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java @@ -5,8 +5,8 @@ import xyz.ineanto.nicko.gui.items.appearance.ChangeBothItem; import xyz.ineanto.nicko.gui.items.appearance.ChangeNameItem; import xyz.ineanto.nicko.gui.items.appearance.ChangeSkinItem; import xyz.ineanto.nicko.gui.items.home.*; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; @@ -25,8 +25,8 @@ public class HomeGUI { dynamicStructure[2] = dynamicStructure[2].replace("A", "#"); } - final I18N i18n = new I18N(player); - this.title = i18n.translate(I18NDict.GUI.Titles.HOME, false); + final PlayerLanguage playerLanguage = new PlayerLanguage(player); + this.title = playerLanguage.translate(LanguageKey.GUI.Titles.HOME, false); final ExitItem exitItem = new ExitItem(player); final ResetItem resetItem = new ResetItem(player); diff --git a/src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java b/src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java index 384bd9e..a2d3e31 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/InvalidateSkinGUI.java @@ -2,14 +2,14 @@ package xyz.ineanto.nicko.gui; import xyz.ineanto.nicko.gui.items.common.GoBackItem; import xyz.ineanto.nicko.gui.items.common.ScrollUpItem; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.ineanto.nicko.mojang.MojangSkin; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.gui.structure.Markers; import xyz.xenondevs.invui.item.Item; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.gui.items.admin.cache.CacheEntryItem; import xyz.ineanto.nicko.gui.items.common.ScrollDownItem; import org.bukkit.entity.Player; @@ -27,22 +27,22 @@ public class InvalidateSkinGUI { private final String title; public InvalidateSkinGUI(Player player) { - final I18N i18n = new I18N(player); - this.title = i18n.translate(I18NDict.GUI.Titles.INVALIDATE_SKIN, false); + final PlayerLanguage playerLanguage = new PlayerLanguage(player); + this.title = playerLanguage.translate(LanguageKey.GUI.Titles.INVALIDATE_SKIN, false); - final ConcurrentMap> skins = NickoBukkit.getInstance().getMojangAPI().getSkinCache().asMap(); + final ConcurrentMap> skins = Nicko.getInstance().getMojangAPI().getSkinCache().asMap(); final List loadedSkins = skins.entrySet().stream() .filter(entry -> entry.getValue().isPresent()) .map(Map.Entry::getKey) - .collect(Collectors.toList()); + .toList(); final List items = loadedSkins.stream() - .map(uuid -> new CacheEntryItem(i18n, uuid)) + .map(uuid -> new CacheEntryItem(playerLanguage, uuid)) .collect(Collectors.toList()); final CacheManagementGUI parent = new CacheManagementGUI(player); - final ScrollUpItem scrollUpItem = new ScrollUpItem(i18n); - final ScrollDownItem scrollDownItem = new ScrollDownItem(i18n); + final ScrollUpItem scrollUpItem = new ScrollUpItem(playerLanguage); + final ScrollDownItem scrollDownItem = new ScrollDownItem(playerLanguage); final GoBackItem backItem = new GoBackItem(player); gui = ScrollGui.items(guiItemBuilder -> { diff --git a/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java b/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java index a09c43f..13ff451 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/PlayerCheckGUI.java @@ -7,8 +7,8 @@ import xyz.ineanto.nicko.gui.items.admin.check.PlayerInformationItem; import xyz.ineanto.nicko.gui.items.common.GoBackItem; import xyz.ineanto.nicko.gui.items.common.ScrollDownItem; import xyz.ineanto.nicko.gui.items.common.ScrollUpItem; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.gui.ScrollGui; import xyz.xenondevs.invui.gui.structure.Markers; @@ -26,20 +26,20 @@ public class PlayerCheckGUI { private final String title; public PlayerCheckGUI(Player player, Collection players) { - final I18N i18n = new I18N(player); - this.title = i18n.translate(I18NDict.GUI.Titles.CHECK, false); + final PlayerLanguage playerLanguage = new PlayerLanguage(player); + this.title = playerLanguage.translate(LanguageKey.GUI.Titles.CHECK, false); final List items = players.stream() .map(Entity::getUniqueId) .map(Bukkit::getPlayer) .filter(Objects::nonNull) - .map(mappedPlayer -> new PlayerInformationItem(i18n, mappedPlayer)) + .map(mappedPlayer -> new PlayerInformationItem(playerLanguage, mappedPlayer)) .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); + final ScrollUpItem scrollUpItem = new ScrollUpItem(playerLanguage); + final ScrollDownItem scrollDownItem = new ScrollDownItem(playerLanguage); gui = ScrollGui.items(guiItemBuilder -> { guiItemBuilder.setStructure( diff --git a/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java b/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java index f02100c..ee08ba1 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/SettingsGUI.java @@ -4,8 +4,8 @@ import org.bukkit.entity.Player; import xyz.ineanto.nicko.gui.items.common.GoBackItem; import xyz.ineanto.nicko.gui.items.settings.LanguageCyclingItem; import xyz.ineanto.nicko.gui.items.settings.RandomSkinCyclingItem; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.gui.Gui; import xyz.xenondevs.invui.window.Window; @@ -21,8 +21,8 @@ public class SettingsGUI { "B # # # # # # # #" }; - final I18N i18n = new I18N(player); - this.title = i18n.translate(I18NDict.GUI.Titles.SETTINGS, false); + final PlayerLanguage playerLanguage = new PlayerLanguage(player); + this.title = playerLanguage.translate(LanguageKey.GUI.Titles.SETTINGS, false); final HomeGUI parent = new HomeGUI(player); final LanguageCyclingItem languageItem = new LanguageCyclingItem(player); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/ItemDefaults.java b/src/main/java/xyz/ineanto/nicko/gui/items/ItemDefaults.java index 88ed8f5..6529e12 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/ItemDefaults.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/ItemDefaults.java @@ -1,22 +1,22 @@ package xyz.ineanto.nicko.gui.items; import org.bukkit.Material; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.item.builder.AbstractItemBuilder; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.builder.SkullBuilder; public class ItemDefaults { - public static AbstractItemBuilder getErrorSkullItem(I18N i18n, String key, Object... args) { + public static AbstractItemBuilder getErrorSkullItem(PlayerLanguage playerLanguage, String key, Object... args) { // "Missing Value" (Valve's signature missing texture) Texture Value final SkullBuilder.HeadTexture headTexture = new SkullBuilder.HeadTexture("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNjNmZTU5YjJhMWQyYmYzMjcwNDA2OGVmYzg2MGM3NWY5MjEyYzIzMTBiNDNkMDdjNGJiYTRiNGViMjM0ZTY4NCJ9fX0="); final SkullBuilder builder = new SkullBuilder(headTexture); - return i18n.translateItem(builder, key, args); + return playerLanguage.translateItem(builder, key, args); } - public static AbstractItemBuilder getUnavailableItem(I18N i18n) { + public static AbstractItemBuilder getUnavailableItem(PlayerLanguage playerLanguage) { final ItemBuilder builder = new ItemBuilder(Material.RED_TERRACOTTA); - return i18n.translateItem(builder, I18NDict.GUI.UNAVAILABLE); + return playerLanguage.translateItem(builder, LanguageKey.GUI.UNAVAILABLE); } } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java index 81a48cb..ac9d4a4 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java @@ -5,11 +5,11 @@ import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; import org.jetbrains.annotations.NotNull; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.gui.CacheManagementGUI; import xyz.ineanto.nicko.gui.items.ItemDefaults; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.builder.SkullBuilder; import xyz.xenondevs.invui.item.impl.AsyncItem; @@ -19,18 +19,18 @@ import xyz.xenondevs.invui.util.MojangApiUtils; import java.io.IOException; public class ManageCacheItem extends AsyncItem { - public ManageCacheItem(I18N i18n) { + public ManageCacheItem(PlayerLanguage playerLanguage) { super(new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.PAINTING); - return i18n.translateItem(builder, I18NDict.GUI.LOADING); + return playerLanguage.translateItem(builder, LanguageKey.GUI.LOADING); }, (click -> true)).getItemProvider(), () -> { try { final SkullBuilder builder = new SkullBuilder("Notch"); - return i18n.translateItem(builder, I18NDict.GUI.Admin.MANAGE_CACHE); + return playerLanguage.translateItem(builder, LanguageKey.GUI.Admin.MANAGE_CACHE); } catch (MojangApiUtils.MojangApiException | IOException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to get Head texture for Notch! (GUI/ManageCache)"); - return ItemDefaults.getErrorSkullItem(i18n, I18NDict.GUI.Admin.MANAGE_CACHE); + Nicko.getInstance().getLogger().warning("Unable to get Head texture for Notch! (GUI/ManageCache)"); + return ItemDefaults.getErrorSkullItem(playerLanguage, LanguageKey.GUI.Admin.MANAGE_CACHE); } }); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManagePlayerItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManagePlayerItem.java index adde45b..7cec662 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManagePlayerItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManagePlayerItem.java @@ -4,24 +4,24 @@ import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; import xyz.ineanto.nicko.gui.PlayerCheckGUI; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; public class ManagePlayerItem { private final Player player; - private final I18N i18n; + private final PlayerLanguage playerLanguage; - public ManagePlayerItem(I18N i18n, Player player) { - this.i18n = i18n; + public ManagePlayerItem(PlayerLanguage playerLanguage, Player player) { + this.playerLanguage = playerLanguage; this.player = player; } public SuppliedItem get() { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.WRITABLE_BOOK); - return i18n.translateItem(builder, I18NDict.GUI.Admin.MANAGE_PLAYER); + return playerLanguage.translateItem(builder, LanguageKey.GUI.Admin.MANAGE_PLAYER); }, click -> { new PlayerCheckGUI(player, Bukkit.getOnlinePlayers()).open(); return true; diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java index 89a37d5..cdf7c90 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java @@ -6,13 +6,13 @@ import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; import org.jetbrains.annotations.NotNull; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.gui.ChoiceGUI; import xyz.ineanto.nicko.gui.InvalidateSkinGUI; import xyz.ineanto.nicko.gui.items.ItemDefaults; import xyz.ineanto.nicko.gui.items.common.choice.ChoiceCallback; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.language.PlayerLanguage; import xyz.ineanto.nicko.mojang.MojangAPI; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.builder.SkullBuilder; @@ -25,22 +25,22 @@ import java.util.UUID; public class CacheEntryItem extends AsyncItem { private final String name; private final String uuid; - private final MojangAPI mojangAPI = NickoBukkit.getInstance().getMojangAPI(); + private final MojangAPI mojangAPI = Nicko.getInstance().getMojangAPI(); - public CacheEntryItem(I18N i18n, String uuid) { + public CacheEntryItem(PlayerLanguage playerLanguage, String uuid) { super(new ItemBuilder(Material.PAINTING) .setDisplayName( - Component.text(i18n.translate(I18NDict.GUI.LOADING, false)).content() + Component.text(playerLanguage.translate(LanguageKey.GUI.LOADING, false)).content() ), () -> { final String dashedUuid = uuid.replaceAll("(.{8})(.{4})(.{4})(.{4})(.+)", "$1-$2-$3-$4-$5"); final UUID uuidObject = UUID.fromString(dashedUuid); try { final SkullBuilder skull = new SkullBuilder(uuidObject); - return i18n.translateItem(skull, I18NDict.GUI.Admin.Cache.ENTRY, NickoBukkit.getInstance().getMojangAPI().getUUIDName(uuid)); + return playerLanguage.translateItem(skull, LanguageKey.GUI.Admin.Cache.ENTRY, Nicko.getInstance().getMojangAPI().getUUIDName(uuid)); } catch (MojangApiUtils.MojangApiException | IOException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to get Head texture for specified UUID (" + uuid + ")! (GUI/Cache/Entry)"); - return ItemDefaults.getErrorSkullItem(i18n, I18NDict.GUI.Admin.Cache.ENTRY, NickoBukkit.getInstance().getMojangAPI().getUUIDName(uuid)); + Nicko.getInstance().getLogger().warning("Unable to get Head texture for specified UUID (" + uuid + ")! (GUI/Cache/Entry)"); + return ItemDefaults.getErrorSkullItem(playerLanguage, LanguageKey.GUI.Admin.Cache.ENTRY, Nicko.getInstance().getMojangAPI().getUUIDName(uuid)); } }); this.uuid = uuid; @@ -54,8 +54,8 @@ public class CacheEntryItem extends AsyncItem { new ChoiceGUI(player, new ChoiceCallback() { @Override public void onConfirm() { - final I18N i18n = new I18N(player); - player.sendMessage(i18n.translate(I18NDict.Event.Admin.Cache.INVALIDATE_ENTRY, true, name)); + final PlayerLanguage playerLanguage = new PlayerLanguage(player); + player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Admin.Cache.INVALIDATE_ENTRY, name)); mojangAPI.eraseFromCache(uuid); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheStatisticsItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheStatisticsItem.java index 71feec5..6e4653a 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheStatisticsItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheStatisticsItem.java @@ -4,9 +4,9 @@ import com.google.common.cache.CacheStats; import com.google.common.cache.LoadingCache; import org.bukkit.Material; import org.bukkit.entity.Player; -import xyz.ineanto.nicko.NickoBukkit; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.Nicko; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.ineanto.nicko.mojang.MojangSkin; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; @@ -14,19 +14,19 @@ import xyz.xenondevs.invui.item.impl.SuppliedItem; import java.util.Optional; public class CacheStatisticsItem { - private final I18N i18n; + private final PlayerLanguage playerLanguage; public CacheStatisticsItem(Player player) { - this.i18n = new I18N(player); + this.playerLanguage = new PlayerLanguage(player); } public SuppliedItem get() { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.BOOK); - final LoadingCache> cache = NickoBukkit.getInstance().getMojangAPI().getSkinCache(); + final LoadingCache> cache = Nicko.getInstance().getMojangAPI().getSkinCache(); final CacheStats stats = cache.stats(); - return i18n.translateItem(builder, I18NDict.GUI.Admin.Cache.STATISTICS, + return playerLanguage.translateItem(builder, LanguageKey.GUI.Admin.Cache.STATISTICS, stats.requestCount(), Math.round(cache.size()) ); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java index 16d2592..55ffbf9 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java @@ -3,32 +3,32 @@ package xyz.ineanto.nicko.gui.items.admin.cache; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; -import xyz.ineanto.nicko.NickoBukkit; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.Nicko; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; public class InvalidateCacheItem { - private final I18N i18n; + private final PlayerLanguage playerLanguage; public InvalidateCacheItem(Player player) { - this.i18n = new I18N(player); + this.playerLanguage = new PlayerLanguage(player); } public SuppliedItem get() { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.TNT); - return i18n.translateItem(builder, I18NDict.GUI.Admin.Cache.INVALIDATE_CACHE); + return playerLanguage.translateItem(builder, LanguageKey.GUI.Admin.Cache.INVALIDATE_CACHE); }, (click) -> { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { click.getEvent().getView().close(); final Player player = click.getPlayer(); - final I18N i18n = new I18N(player); - player.sendMessage(i18n.translate(I18NDict.Event.Admin.Cache.INVALIDATE_CACHE, true)); - NickoBukkit.getInstance().getMojangAPI().getSkinCache().invalidateAll(); + final PlayerLanguage playerLanguage = new PlayerLanguage(player); + player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Admin.Cache.INVALIDATE_CACHE)); + Nicko.getInstance().getMojangAPI().getSkinCache().invalidateAll(); return true; } return false; diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateSkinItem.java index cbf690c..f39034d 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateSkinItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateSkinItem.java @@ -4,22 +4,22 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import xyz.ineanto.nicko.gui.InvalidateSkinGUI; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; public class InvalidateSkinItem { - private final I18N i18n; + private final PlayerLanguage playerLanguage; public InvalidateSkinItem(Player player) { - this.i18n = new I18N(player); + this.playerLanguage = new PlayerLanguage(player); } public SuppliedItem get() { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.PAPER); - return i18n.translateItem(builder, I18NDict.GUI.Admin.Cache.INVALIDATE_SKIN); + return playerLanguage.translateItem(builder, LanguageKey.GUI.Admin.Cache.INVALIDATE_SKIN); }, (click) -> { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java index 9ea7dcb..a439944 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java @@ -6,14 +6,14 @@ import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; import org.jetbrains.annotations.NotNull; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.appearance.AppearanceManager; import xyz.ineanto.nicko.gui.ChoiceGUI; import xyz.ineanto.nicko.gui.PlayerCheckGUI; import xyz.ineanto.nicko.gui.items.ItemDefaults; import xyz.ineanto.nicko.gui.items.common.choice.ChoiceCallback; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.xenondevs.invui.item.builder.AbstractItemBuilder; import xyz.xenondevs.invui.item.builder.ItemBuilder; @@ -28,20 +28,20 @@ import java.util.Optional; public class PlayerInformationItem extends AsyncItem { private final Player target; private final NickoProfile profile; - private final I18N i18n; + private final PlayerLanguage playerLanguage; - public PlayerInformationItem(I18N i18n, Player target) { + public PlayerInformationItem(PlayerLanguage playerLanguage, Player target) { super(new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.PAINTING); - return i18n.translateItem(builder, I18NDict.GUI.LOADING); + return playerLanguage.translateItem(builder, LanguageKey.GUI.LOADING); }, (click -> true)).getItemProvider(), () -> { try { final SkullBuilder skull = new SkullBuilder(target.getUniqueId()); - final Optional optionalProfile = NickoBukkit.getInstance().getDataStore().getData(target.getUniqueId()); + final Optional optionalProfile = Nicko.getInstance().getDataStore().getData(target.getUniqueId()); if (optionalProfile.isPresent()) { final NickoProfile profile = optionalProfile.get(); - final AbstractItemBuilder headItem = i18n.translateItem(skull, I18NDict.GUI.Admin.CHECK, + final AbstractItemBuilder headItem = playerLanguage.translateItem(skull, LanguageKey.GUI.Admin.CHECK, target.getName(), (profile.hasData() ? "" : ""), (profile.getName() == null ? "N/A" : profile.getName()), @@ -56,16 +56,16 @@ public class PlayerInformationItem extends AsyncItem { return headItem; } } catch (MojangApiUtils.MojangApiException | IOException e) { - NickoBukkit.getInstance().getLogger().severe("Unable to get head for specified UUID ( " + target.getUniqueId() + ")! (GUI/PlayerCheck)"); + Nicko.getInstance().getLogger().severe("Unable to get head for specified UUID ( " + target.getUniqueId() + ")! (GUI/PlayerCheck)"); } - return ItemDefaults.getErrorSkullItem(i18n, I18NDict.GUI.Admin.CHECK, + return ItemDefaults.getErrorSkullItem(playerLanguage, LanguageKey.GUI.Admin.CHECK, "§c§l?!?", "§7N/A", "§7N/A", "§7N/A" ); }); - this.i18n = i18n; + this.playerLanguage = playerLanguage; this.target = target; - this.profile = NickoBukkit.getInstance().getDataStore().getData(target.getUniqueId()).orElse(NickoProfile.EMPTY_PROFILE); + this.profile = Nicko.getInstance().getDataStore().getData(target.getUniqueId()).orElse(NickoProfile.EMPTY_PROFILE); } @Override @@ -78,7 +78,7 @@ public class PlayerInformationItem extends AsyncItem { public void onConfirm() { final AppearanceManager appearanceManager = new AppearanceManager(target); appearanceManager.reset(); - player.sendMessage(i18n.translate(I18NDict.Event.Admin.Check.REMOVE_SKIN, true, target.getName())); + player.sendMessage(playerLanguage.translate(LanguageKey.Event.Admin.Check.REMOVE_SKIN, true, target.getName())); } @Override diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java index 0308eef..2e19cf2 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java @@ -4,22 +4,22 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import xyz.ineanto.nicko.anvil.AnvilManager; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; public class ChangeBothItem { - private final I18N i18n; + private final PlayerLanguage playerLanguage; public ChangeBothItem(Player player) { - this.i18n = new I18N(player); + this.playerLanguage = new PlayerLanguage(player); } public SuppliedItem get() { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.TOTEM_OF_UNDYING); - return i18n.translateItem(builder, I18NDict.GUI.Home.CHANGE_BOTH); + return playerLanguage.translateItem(builder, LanguageKey.GUI.Home.CHANGE_BOTH); }, click -> { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java index 0f83859..744851c 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java @@ -4,22 +4,22 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import xyz.ineanto.nicko.anvil.AnvilManager; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; public class ChangeNameItem { - private final I18N i18n; + private final PlayerLanguage playerLanguage; public ChangeNameItem(Player player) { - this.i18n = new I18N(player); + this.playerLanguage = new PlayerLanguage(player); } public SuppliedItem get() { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.NAME_TAG); - return i18n.translateItem(builder, I18NDict.GUI.Home.CHANGE_NAME); + return playerLanguage.translateItem(builder, LanguageKey.GUI.Home.CHANGE_NAME); }, click -> { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java index 7e6e865..6c78cc8 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java @@ -2,11 +2,11 @@ package xyz.ineanto.nicko.gui.items.appearance; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.anvil.AnvilManager; import xyz.ineanto.nicko.gui.items.ItemDefaults; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.item.builder.SkullBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; import xyz.xenondevs.invui.util.MojangApiUtils; @@ -14,11 +14,11 @@ import xyz.xenondevs.invui.util.MojangApiUtils; import java.io.IOException; public class ChangeSkinItem { - private final I18N i18n; + private final PlayerLanguage playerLanguage; private final Player player; public ChangeSkinItem(Player player) { - this.i18n = new I18N(player); + this.playerLanguage = new PlayerLanguage(player); this.player = player; } @@ -26,10 +26,10 @@ public class ChangeSkinItem { return new SuppliedItem(() -> { try { final SkullBuilder builder = new SkullBuilder(player.getName()); - return i18n.translateItem(builder, I18NDict.GUI.Home.CHANGE_SKIN); + return playerLanguage.translateItem(builder, LanguageKey.GUI.Home.CHANGE_SKIN); } catch (MojangApiUtils.MojangApiException | IOException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to get Head texture for specified player (" + player.getName() + ")! (GUI/Home)"); - return ItemDefaults.getErrorSkullItem(i18n, I18NDict.GUI.Home.CHANGE_SKIN); + Nicko.getInstance().getLogger().warning("Unable to get Head texture for specified player (" + player.getName() + ")! (GUI/Home)"); + return ItemDefaults.getErrorSkullItem(playerLanguage, LanguageKey.GUI.Home.CHANGE_SKIN); } }, click -> { final ClickType clickType = click.getClickType(); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/GoBackItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/GoBackItem.java index afd1e3d..1dc7752 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/common/GoBackItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/GoBackItem.java @@ -2,24 +2,24 @@ package xyz.ineanto.nicko.gui.items.common; import org.bukkit.Material; import org.bukkit.entity.Player; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; 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 { - private final I18N i18n; + private final PlayerLanguage playerLanguage; public GoBackItem(Player player) { - this.i18n = new I18N(player); + this.playerLanguage = new PlayerLanguage(player); } public SuppliedItem get(Gui gui, String parentTitle) { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.ARROW); - return i18n.translateItem(builder, I18NDict.GUI.GO_BACK); + return playerLanguage.translateItem(builder, LanguageKey.GUI.GO_BACK); }, click -> { click.getEvent().getView().close(); Window.single().setGui(gui).setTitle(parentTitle).open(click.getPlayer()); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java index 9961660..64054d9 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java @@ -4,26 +4,26 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.Material; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; -import xyz.ineanto.nicko.i18n.Translation; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.language.Translation; 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; + final PlayerLanguage playerLanguage; - public ScrollDownItem(I18N i18n) { + public ScrollDownItem(PlayerLanguage playerLanguage) { super(1); - this.i18n = i18n; + this.playerLanguage = playerLanguage; } @Override public ItemProvider getItemProvider(ScrollGui gui) { final ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); - final Translation translation = i18n.translateAndReplace(I18NDict.GUI.SCROLL_DOWN); + final Translation translation = playerLanguage.translateAndReplace(LanguageKey.GUI.SCROLL_DOWN); builder.setDisplayName(Component.text(translation.name()).content()); if (!gui.canScroll(1)) { // Lore serialization diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java index fb7d98a..8f1fe88 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java @@ -4,26 +4,26 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.Material; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; -import xyz.ineanto.nicko.i18n.Translation; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.language.Translation; 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; + final PlayerLanguage playerLanguage; - public ScrollUpItem(I18N i18n) { + public ScrollUpItem(PlayerLanguage playerLanguage) { super(-1); - this.i18n = i18n; + this.playerLanguage = playerLanguage; } @Override public ItemProvider getItemProvider(ScrollGui gui) { final ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE); - final Translation translation = i18n.translateAndReplace(I18NDict.GUI.SCROLL_UP); + final Translation translation = playerLanguage.translateAndReplace(LanguageKey.GUI.SCROLL_UP); builder.setDisplayName(Component.text(translation.name()).content()); if (!gui.canScroll(-1)) { // Lore serialization diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/CancelItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/CancelItem.java index 257b2ae..8fa5c40 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/CancelItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/CancelItem.java @@ -2,24 +2,24 @@ package xyz.ineanto.nicko.gui.items.common.choice; import org.bukkit.Material; import org.bukkit.entity.Player; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; public class CancelItem { - private final I18N i18n; + private final PlayerLanguage playerLanguage; private final ChoiceCallback callback; public CancelItem(Player player, ChoiceCallback callback) { - this.i18n = new I18N(player); + this.playerLanguage = new PlayerLanguage(player); this.callback = callback; } public SuppliedItem get() { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE); - return i18n.translateItem(builder, I18NDict.GUI.Choice.CANCEL); + return playerLanguage.translateItem(builder, LanguageKey.GUI.Choice.CANCEL); }, click -> { click.getEvent().getView().close(); callback.onCancel(); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/ConfirmItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/ConfirmItem.java index 397b839..95fcacb 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/ConfirmItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/choice/ConfirmItem.java @@ -2,24 +2,24 @@ package xyz.ineanto.nicko.gui.items.common.choice; import org.bukkit.Material; import org.bukkit.entity.Player; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; public class ConfirmItem { - private final I18N i18n; + private final PlayerLanguage playerLanguage; private final ChoiceCallback callback; public ConfirmItem(Player player, ChoiceCallback callback) { - this.i18n = new I18N(player); + this.playerLanguage = new PlayerLanguage(player); this.callback = callback; } public SuppliedItem get() { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); - return i18n.translateItem(builder, I18NDict.GUI.Choice.CONFIRM); + return playerLanguage.translateItem(builder, LanguageKey.GUI.Choice.CONFIRM); }, click -> { click.getEvent().getView().close(); callback.onConfirm(); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java index a0b0873..478431d 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java @@ -4,22 +4,22 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import xyz.ineanto.nicko.gui.AdminGUI; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; public class AdminAccessItem { - private final I18N i18n; + private final PlayerLanguage playerLanguage; public AdminAccessItem(Player player) { - this.i18n = new I18N(player); + this.playerLanguage = new PlayerLanguage(player); } public SuppliedItem get() { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.COMMAND_BLOCK_MINECART); - return i18n.translateItem(builder, I18NDict.GUI.Home.ADMIN); + return playerLanguage.translateItem(builder, LanguageKey.GUI.Home.ADMIN); }, click -> { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/ExitItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/ExitItem.java index c78a230..2d04be3 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/ExitItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/ExitItem.java @@ -3,22 +3,22 @@ package xyz.ineanto.nicko.gui.items.home; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; public class ExitItem { - private final I18N i18n; + private final PlayerLanguage playerLanguage; public ExitItem(Player player) { - this.i18n = new I18N(player); + this.playerLanguage = new PlayerLanguage(player); } public SuppliedItem get() { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.OAK_DOOR); - return i18n.translateItem(builder, I18NDict.GUI.EXIT); + return playerLanguage.translateItem(builder, LanguageKey.GUI.EXIT); }, click -> { click.getEvent().getView().close(); final ClickType clickType = click.getClickType(); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java index 35260a2..9ddd6af 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java @@ -2,11 +2,11 @@ package xyz.ineanto.nicko.gui.items.home; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.appearance.AppearanceManager; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.xenondevs.invui.item.builder.SkullBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; @@ -14,19 +14,19 @@ import xyz.xenondevs.invui.item.impl.SuppliedItem; import java.util.Optional; public class RandomSkinItem { - private final I18N i18n; - private final NickoBukkit instance; + private final PlayerLanguage playerLanguage; + private final Nicko instance; public RandomSkinItem(Player player) { - this.instance = NickoBukkit.getInstance(); - this.i18n = new I18N(player); + this.instance = Nicko.getInstance(); + this.playerLanguage = new PlayerLanguage(player); } public SuppliedItem get() { return new SuppliedItem(() -> { final SkullBuilder.HeadTexture texture = new SkullBuilder.HeadTexture("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzgzMTEzOGMyMDYxMWQzMDJjNDIzZmEzMjM3MWE3NDNkMTc0MzdhMTg5NzNjMzUxOTczNDQ3MGE3YWJiNCJ9fX0="); final SkullBuilder builder = new SkullBuilder(texture); - return i18n.translateItem(builder, I18NDict.GUI.Home.RANDOM_SKIN); + return playerLanguage.translateItem(builder, LanguageKey.GUI.Home.RANDOM_SKIN); }, (event) -> { final Player player = event.getPlayer(); final ClickType clickType = event.getClickType(); @@ -42,12 +42,12 @@ public class RandomSkinItem { final AppearanceManager appearanceManager = new AppearanceManager(player); final ActionResult result = appearanceManager.updatePlayer(true, false); if (!result.isError()) { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.OK, true)); + player.sendMessage(playerLanguage.translate(LanguageKey.Event.Appearance.Set.OK, true)); } else { - player.sendMessage(i18n.translate( - I18NDict.Event.Appearance.Set.ERROR, + player.sendMessage(playerLanguage.translate( + LanguageKey.Event.Appearance.Set.ERROR, true, - i18n.translate(result.getErrorKey(), false) + playerLanguage.translate(result.getErrorKey(), false) ) ); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java index b328a52..f00a806 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java @@ -4,8 +4,8 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import xyz.ineanto.nicko.appearance.AppearanceManager; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; @@ -13,16 +13,16 @@ import xyz.xenondevs.invui.item.impl.SuppliedItem; import java.util.Optional; public class ResetItem { - private final I18N i18n; + private final PlayerLanguage playerLanguage; public ResetItem(Player player) { - this.i18n = new I18N(player); + this.playerLanguage = new PlayerLanguage(player); } public SuppliedItem get() { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.TNT); - return i18n.translateItem(builder, I18NDict.GUI.Home.RESET); + return playerLanguage.translateItem(builder, LanguageKey.GUI.Home.RESET); }, (event) -> { final Player player = event.getPlayer(); final ClickType clickType = event.getClickType(); @@ -30,16 +30,16 @@ public class ResetItem { final Optional optionalProfile = NickoProfile.get(player); optionalProfile.ifPresent(profile -> { if (!profile.hasData()) { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.MISSING, true)); + player.sendMessage(playerLanguage.translate(LanguageKey.Event.Appearance.Remove.MISSING, true)); event.getEvent().getView().close(); return; } final AppearanceManager appearanceManager = new AppearanceManager(player); if (!appearanceManager.reset().isError()) { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.OK, true)); + player.sendMessage(playerLanguage.translate(LanguageKey.Event.Appearance.Remove.OK, true)); } else { - player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.ERROR, true)); + player.sendMessage(playerLanguage.translate(LanguageKey.Event.Appearance.Remove.ERROR, true)); } }); return true; diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/SettingsAccessItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/SettingsAccessItem.java index 06aa368..ea3f849 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/SettingsAccessItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/SettingsAccessItem.java @@ -4,22 +4,22 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import xyz.ineanto.nicko.gui.SettingsGUI; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; public class SettingsAccessItem { - private final I18N i18n; + private final PlayerLanguage playerLanguage; public SettingsAccessItem(Player player) { - this.i18n = new I18N(player); + this.playerLanguage = new PlayerLanguage(player); } public SuppliedItem get() { return new SuppliedItem(() -> { final ItemBuilder builder = new ItemBuilder(Material.COMPARATOR); - return i18n.translateItem(builder, I18NDict.GUI.Home.SETTINGS); + return playerLanguage.translateItem(builder, LanguageKey.GUI.Home.SETTINGS); }, click -> { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java index 9c691ec..b836991 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java @@ -6,12 +6,12 @@ import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.gui.SettingsGUI; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; -import xyz.ineanto.nicko.i18n.Translation; -import xyz.ineanto.nicko.i18n.Locale; +import xyz.ineanto.nicko.language.Language; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.language.Translation; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.PlayerDataStore; import xyz.xenondevs.invui.item.ItemProvider; @@ -28,26 +28,26 @@ import java.util.Optional; public class LanguageCyclingItem { private final Player player; private final ItemProvider[] providers; - private final I18N i18n; + private final PlayerLanguage playerLanguage; public LanguageCyclingItem(Player player) { this.player = player; - this.i18n = new I18N(player); + this.playerLanguage = new PlayerLanguage(player); this.providers = getItems(); } public AbstractItem get() { - final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore(); + final PlayerDataStore dataStore = Nicko.getInstance().getDataStore(); final Optional profile = dataStore.getData(player.getUniqueId()); if (profile.isPresent()) { final NickoProfile nickoProfile = profile.get(); int localeOrdinal = nickoProfile.getLocale().ordinal(); return CycleItem.withStateChangeHandler((observer, integer) -> { observer.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 0.707107f); // 0.707107 ~= C - nickoProfile.setLocale(Locale.values()[integer]); + nickoProfile.setLocale(Language.values()[integer]); player.getOpenInventory().close(); if (dataStore.updateCache(player.getUniqueId(), nickoProfile).isError()) { - player.sendMessage(i18n.translate(I18NDict.Event.Settings.ERROR, true)); + player.sendMessage(playerLanguage.translate(LanguageKey.Event.Settings.ERROR, true)); } else { new SettingsGUI(player).open(); } @@ -57,14 +57,14 @@ public class LanguageCyclingItem { return new SimpleItem(ItemProvider.EMPTY); } - private ItemProvider generateItem(Locale locale, List locales) { + private ItemProvider generateItem(Language language, List languages) { final ItemBuilder builder = new ItemBuilder(Material.OAK_SIGN); - final Translation translation = i18n.translateAndReplace(I18NDict.GUI.Settings.LANGUAGE); - final Translation cyclingChoicesTranslation = i18n.translateAndReplace(I18NDict.GUI.Settings.CYCLING_CHOICES); + final Translation translation = playerLanguage.translateAndReplace(LanguageKey.GUI.Settings.LANGUAGE); + final Translation cyclingChoicesTranslation = playerLanguage.translateAndReplace(LanguageKey.GUI.Settings.CYCLING_CHOICES); builder.setDisplayName(Component.text(translation.name()).content()); - for (Locale value : locales) { - if (locale != value) { + for (Language value : languages) { + if (language != value) { builder.addLoreLines("§7> " + value.getName()); } else { builder.addLoreLines("§6§l> §f" + value.getName()); @@ -80,13 +80,13 @@ public class LanguageCyclingItem { } private ItemProvider[] getItems() { - final NickoBukkit instance = NickoBukkit.getInstance(); + final Nicko instance = Nicko.getInstance(); final ArrayList items = new ArrayList<>(); - final ArrayList localesToGenerate = new ArrayList<>(); + final ArrayList localesToGenerate = new ArrayList<>(); - Collections.addAll(localesToGenerate, Locale.values()); + Collections.addAll(localesToGenerate, Language.values()); if (!instance.getNickoConfig().isCustomLocale()) { - localesToGenerate.remove(Locale.CUSTOM); + localesToGenerate.remove(Language.CUSTOM); } localesToGenerate.forEach(locale -> items.add(generateItem(locale, localesToGenerate))); return items.toArray(new ItemProvider[]{}); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java index af62565..abe356a 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/settings/RandomSkinCyclingItem.java @@ -5,10 +5,10 @@ import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.Sound; import org.bukkit.entity.Player; -import xyz.ineanto.nicko.NickoBukkit; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; -import xyz.ineanto.nicko.i18n.Translation; +import xyz.ineanto.nicko.Nicko; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.language.Translation; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.PlayerDataStore; import xyz.xenondevs.invui.item.ItemProvider; @@ -22,11 +22,11 @@ import java.util.Optional; public class RandomSkinCyclingItem { private final Player player; private final ItemProvider[] providers; - private final I18N i18n; + private final PlayerLanguage playerLanguage; public RandomSkinCyclingItem(Player player) { this.player = player; - this.i18n = new I18N(player); + this.playerLanguage = new PlayerLanguage(player); this.providers = new ItemProvider[]{ getItemProviderForValue(true), getItemProviderForValue(false) @@ -34,7 +34,7 @@ public class RandomSkinCyclingItem { } public AbstractItem get() { - final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore(); + final PlayerDataStore dataStore = Nicko.getInstance().getDataStore(); final Optional profile = dataStore.getData(player.getUniqueId()); if (profile.isPresent()) { final NickoProfile nickoProfile = profile.get(); @@ -43,7 +43,7 @@ public class RandomSkinCyclingItem { observer.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 0.707107f); // 0.707107 ~= C nickoProfile.setRandomSkin(integer != 1); if (dataStore.updateCache(player.getUniqueId(), nickoProfile).isError()) { - player.sendMessage(i18n.translate(I18NDict.Event.Settings.ERROR, true)); + player.sendMessage(playerLanguage.translate(LanguageKey.Event.Settings.ERROR, true)); player.getOpenInventory().close(); } }, localeOrdinal, providers); @@ -55,12 +55,12 @@ public class RandomSkinCyclingItem { private ItemProvider getItemProviderForValue(boolean enabled) { final SkullBuilder.HeadTexture texture = new SkullBuilder.HeadTexture("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzgzMTEzOGMyMDYxMWQzMDJjNDIzZmEzMjM3MWE3NDNkMTc0MzdhMTg5NzNjMzUxOTczNDQ3MGE3YWJiNCJ9fX0="); final SkullBuilder builder = new SkullBuilder(texture); - final Translation randomSkinTranslation = i18n.translateAndReplace(I18NDict.GUI.Settings.RANDOM_SKIN); - final Translation toggleableTranslation = i18n.translateAndReplace(I18NDict.GUI.Settings.TOGGLEABLE_BUTTON, + final Translation randomSkinTranslation = playerLanguage.translateAndReplace(LanguageKey.GUI.Settings.RANDOM_SKIN); + final Translation toggleableTranslation = playerLanguage.translateAndReplace(LanguageKey.GUI.Settings.TOGGLEABLE_BUTTON, (enabled ? "§7>§c" : "§6§l>§c§l"), (enabled ? "§6§l>§a§l" : "§7>§a") ); - final Translation cyclingChoicesTranslation = i18n.translateAndReplace(I18NDict.GUI.Settings.CYCLING_CHOICES); + final Translation cyclingChoicesTranslation = playerLanguage.translateAndReplace(LanguageKey.GUI.Settings.CYCLING_CHOICES); builder.setDisplayName(randomSkinTranslation.name()); toggleableTranslation.lore().forEach(builder::addLoreLines); diff --git a/src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java b/src/main/java/xyz/ineanto/nicko/language/CustomLanguage.java similarity index 58% rename from src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java rename to src/main/java/xyz/ineanto/nicko/language/CustomLanguage.java index 5007070..23e5c7e 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/CustomLocale.java +++ b/src/main/java/xyz/ineanto/nicko/language/CustomLanguage.java @@ -1,40 +1,41 @@ -package xyz.ineanto.nicko.i18n; +package xyz.ineanto.nicko.language; import com.github.jsixface.YamlConfig; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.version.Version; -import java.io.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; import java.nio.file.Files; -import java.util.logging.Logger; -public class CustomLocale { - private static final Logger logger = Logger.getLogger("CustomLocale"); - private static final File directory = new File(NickoBukkit.getInstance().getDataFolder(), "/locale/"); +public class CustomLanguage { + private static final File directory = new File(Nicko.getInstance().getDataFolder(), "/locale/"); private static final File file = new File(directory, "locale.yml"); private final String version; private final Version versionObject; private final YamlConfig yamlFile; - public CustomLocale() throws IOException { + public CustomLanguage() throws IOException { this.yamlFile = new YamlConfig(new FileInputStream(file)); this.version = yamlFile.getString("version"); this.versionObject = Version.fromString(version); } - public static void dumpIntoFile(Locale locale) throws IOException { - if (locale == Locale.CUSTOM) return; + public static void dumpIntoFile(Language language) throws IOException { + if (language == Language.CUSTOM) return; if (file.exists()) return; if (!directory.exists()) directory.mkdirs(); - final String localeFileName = locale.getCode() + ".yml"; + final String localeFileName = language.getCode() + ".yml"; try { - final InputStream resource = NickoBukkit.getInstance().getResource(localeFileName); + final InputStream resource = Nicko.getInstance().getResource(localeFileName); Files.copy(resource, file.toPath()); resource.close(); } catch (IOException e) { - logger.severe("Unable to dump Locale: " + locale.getCode() + "!"); + Nicko.getInstance().getLogger().severe("Unable to dump Locale: " + language.getCode() + "!"); } } diff --git a/src/main/java/xyz/ineanto/nicko/i18n/Locale.java b/src/main/java/xyz/ineanto/nicko/language/Language.java similarity index 64% rename from src/main/java/xyz/ineanto/nicko/i18n/Locale.java rename to src/main/java/xyz/ineanto/nicko/language/Language.java index e548692..a13b78d 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/Locale.java +++ b/src/main/java/xyz/ineanto/nicko/language/Language.java @@ -1,26 +1,26 @@ -package xyz.ineanto.nicko.i18n; +package xyz.ineanto.nicko.language; import xyz.ineanto.nicko.version.Version; import java.io.Serializable; -public enum Locale implements Serializable { +public enum Language implements Serializable { ENGLISH("en", "English"), FRENCH("fr", "Français"), CUSTOM("cm", "Server Custom"); - public static final Version VERSION = new Version(1, 1, 3); + public static final Version VERSION = new Version(1, 1, 4); private final String code; private transient final String name; - Locale(String code, String name) { + Language(String code, String name) { this.code = code; this.name = name; } - public static Locale fromCode(String code) { - for (Locale value : values()) { + public static Language fromCode(String code) { + for (Language value : values()) { if (code.equals(value.code)) return value; } return ENGLISH; diff --git a/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java b/src/main/java/xyz/ineanto/nicko/language/LanguageKey.java similarity index 96% rename from src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java rename to src/main/java/xyz/ineanto/nicko/language/LanguageKey.java index 674fe7c..0dea8af 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/ineanto/nicko/language/LanguageKey.java @@ -1,6 +1,10 @@ -package xyz.ineanto.nicko.i18n; +package xyz.ineanto.nicko.language; + +public class LanguageKey { + public static final String PREFIX = "prefix"; + public static final String WHOOSH = "whoosh"; + public static final String OOPS = "oops"; -public class I18NDict { public static class Error { public static final String ERROR_KEY = "error."; diff --git a/src/main/java/xyz/ineanto/nicko/i18n/I18N.java b/src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java similarity index 69% rename from src/main/java/xyz/ineanto/nicko/i18n/I18N.java rename to src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java index df2f440..94e1785 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/I18N.java +++ b/src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java @@ -1,11 +1,11 @@ -package xyz.ineanto.nicko.i18n; +package xyz.ineanto.nicko.language; import com.github.jsixface.YamlConfig; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.entity.Player; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.xenondevs.invui.item.builder.AbstractItemBuilder; @@ -16,22 +16,22 @@ import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class I18N { +public class PlayerLanguage { private final MessageFormat formatter = new MessageFormat(""); private final Logger logger = Logger.getLogger("I18N"); - private final NickoBukkit instance = NickoBukkit.getInstance(); + private final Nicko instance = Nicko.getInstance(); private final Pattern replacementPattern = Pattern.compile("(?ms)\\{\\d+}"); private final YamlConfig yamlConfig; - private final Locale playerLocale; + private final Language playerLanguage; - public I18N(Player player) { + public PlayerLanguage(Player player) { final Optional optionalProfile = NickoProfile.get(player); - this.playerLocale = optionalProfile.map(NickoProfile::getLocale).orElse(Locale.ENGLISH); + this.playerLanguage = optionalProfile.map(NickoProfile::getLocale).orElse(Language.ENGLISH); this.yamlConfig = getYamlConfig(); } - public I18N(Locale locale) { - this.playerLocale = locale; + public PlayerLanguage(Language language) { + this.playerLanguage = language; this.yamlConfig = getYamlConfig(); } @@ -60,7 +60,7 @@ public class I18N { final ArrayList lore = readList(loreKey); if (name == null && lore == null) { - logger.warning(nameKey + " doesn't exists! Is your language file outdated?"); + Nicko.getInstance().getLogger().warning(nameKey + " doesn't exists! Is your language file outdated?"); return new Translation(nameKey, new ArrayList<>(List.of(loreKey))); } @@ -92,7 +92,7 @@ public class I18N { // 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 + // Replace it with the corresponding varargs index toTranslate.set(lineIndex, currentLine.replace("{" + replacementIndex + "}", args[replacementIndex].toString())); replacementIndex++; } @@ -115,11 +115,34 @@ public class I18N { public String translate(String key, boolean prefix, Object... arguments) { final String translation = readString(key); + try { formatter.applyPattern(translation); - return (prefix ? instance.getNickoConfig().getPrefix() : "") + formatter.format(arguments); + return (prefix ? getPrefix() + " " : "") + formatter.format(arguments); } catch (Exception e) { - return (prefix ? instance.getNickoConfig().getPrefix() : "") + key; + return (prefix ? getPrefix() + " " : "") + key; + } + } + + public String translateWithWhoosh(String key, Object... arguments) { + final String translation = readStringWithMiniMessage(key); + + try { + formatter.applyPattern(translation); + return getWhoosh() + " " + formatter.format(arguments); + } catch (Exception e) { + return getWhoosh() + " " + key; + } + } + + public String translateWithOops(String key, Object... arguments) { + final String translation = readStringWithMiniMessage(key); + + try { + formatter.applyPattern(translation); + return getOops() + " " + formatter.format(arguments); + } catch (Exception e) { + return getOops() + " " + key; } } @@ -127,15 +150,31 @@ public class I18N { return yamlConfig.getString(key); } + private String readStringWithMiniMessage(String key) { + return LegacyComponentSerializer.legacySection().serialize(MiniMessage.miniMessage().deserialize(readString(key))); + } + private ArrayList readList(String key) { return yamlConfig.getStringList(key); } + private String getPrefix() { + return readStringWithMiniMessage(LanguageKey.PREFIX); + } + + private String getWhoosh() { + return readStringWithMiniMessage(LanguageKey.WHOOSH); + } + + private String getOops() { + return readStringWithMiniMessage(LanguageKey.OOPS); + } + private YamlConfig getYamlConfig() { - if (playerLocale == Locale.CUSTOM) { + if (playerLanguage == Language.CUSTOM) { return instance.getCustomLocale().getYamlFile(); } else { - final InputStream resource = instance.getResource(playerLocale.getCode() + ".yml"); + final InputStream resource = instance.getResource(playerLanguage.getCode() + ".yml"); return new YamlConfig(resource); } } diff --git a/src/main/java/xyz/ineanto/nicko/i18n/Translation.java b/src/main/java/xyz/ineanto/nicko/language/Translation.java similarity index 72% rename from src/main/java/xyz/ineanto/nicko/i18n/Translation.java rename to src/main/java/xyz/ineanto/nicko/language/Translation.java index 2d610f6..13d295b 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/Translation.java +++ b/src/main/java/xyz/ineanto/nicko/language/Translation.java @@ -1,4 +1,4 @@ -package xyz.ineanto.nicko.i18n; +package xyz.ineanto.nicko.language; import java.util.ArrayList; diff --git a/src/main/java/xyz/ineanto/nicko/migration/ConfigurationMigrator.java b/src/main/java/xyz/ineanto/nicko/migration/ConfigurationMigrator.java index 465392f..9a47db5 100644 --- a/src/main/java/xyz/ineanto/nicko/migration/ConfigurationMigrator.java +++ b/src/main/java/xyz/ineanto/nicko/migration/ConfigurationMigrator.java @@ -1,6 +1,6 @@ package xyz.ineanto.nicko.migration; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.config.Configuration; import xyz.ineanto.nicko.config.ConfigurationManager; @@ -9,9 +9,9 @@ import java.nio.file.Files; import java.nio.file.StandardCopyOption; public class ConfigurationMigrator implements Migrator { - private final NickoBukkit instance; + private final Nicko instance; - public ConfigurationMigrator(NickoBukkit instance) { + public ConfigurationMigrator(Nicko instance) { this.instance = instance; } @@ -27,7 +27,12 @@ public class ConfigurationMigrator implements Migrator { instance.getLogger().info("Migrating configuration file to match the current version..."); try { Files.copy(configurationManager.getFile().toPath(), configurationManager.getBackupFile().toPath(), StandardCopyOption.REPLACE_EXISTING); - configurationManager.saveDefaultConfig(); + if (configurationManager.getFile().delete()) { + configurationManager.saveDefaultConfig(); + instance.getLogger().info("Successfully migrated your configuration file!"); + } else { + instance.getLogger().severe("Failed to migrate your configuration!"); + } } catch (IOException e) { instance.getLogger().severe("Failed to migrate your configuration!"); } diff --git a/src/main/java/xyz/ineanto/nicko/migration/CustomLocaleMigrator.java b/src/main/java/xyz/ineanto/nicko/migration/CustomLocaleMigrator.java index 35f12ee..073df5f 100644 --- a/src/main/java/xyz/ineanto/nicko/migration/CustomLocaleMigrator.java +++ b/src/main/java/xyz/ineanto/nicko/migration/CustomLocaleMigrator.java @@ -1,8 +1,8 @@ package xyz.ineanto.nicko.migration; -import xyz.ineanto.nicko.NickoBukkit; -import xyz.ineanto.nicko.i18n.CustomLocale; -import xyz.ineanto.nicko.i18n.Locale; +import xyz.ineanto.nicko.Nicko; +import xyz.ineanto.nicko.language.CustomLanguage; +import xyz.ineanto.nicko.language.Language; import java.io.File; import java.io.IOException; @@ -12,31 +12,33 @@ import java.time.ZoneId; import java.time.format.DateTimeFormatter; public class CustomLocaleMigrator implements Migrator { - private final NickoBukkit instance; - private final CustomLocale customLocale; + private final Nicko instance; + private final CustomLanguage customLanguage; - public CustomLocaleMigrator(NickoBukkit instance, CustomLocale customLocale) { + public CustomLocaleMigrator(Nicko instance, CustomLanguage customLanguage) { this.instance = instance; - this.customLocale = customLocale; + this.customLanguage = customLanguage; } @Override public void migrate() { // Migrate custom locale (1.1.0-RC1) - if (customLocale.getVersionObject() == null - || customLocale.getVersion().isEmpty() - || customLocale.getVersionObject().compareTo(Locale.VERSION) != 0) { - instance.getLogger().info("Migrating the custom locale (" + customLocale.getVersion() + ") to match the current version (" + Locale.VERSION + ")..."); + if (customLanguage.getVersionObject() == null + || customLanguage.getVersion().isEmpty() + || customLanguage.getVersionObject().compareTo(Language.VERSION) != 0) { + instance.getLogger().info("Migrating the custom locale (" + customLanguage.getVersion() + ") to match the current version (" + Language.VERSION + ")..."); final String date = Instant.now().atZone(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("dd-MM-yyyy")); - final File backupFile = new File(customLocale.getDirectory(), "locale-" + date + ".yml"); + final File backupFile = new File(customLanguage.getDirectory(), "locale-" + date + ".yml"); try { - Files.copy(customLocale.getFile().toPath(), backupFile.toPath()); - if (customLocale.getFile().delete()) { - CustomLocale.dumpIntoFile(Locale.ENGLISH); + Files.copy(customLanguage.getFile().toPath(), backupFile.toPath()); + if (customLanguage.getFile().delete()) { + CustomLanguage.dumpIntoFile(Language.ENGLISH); + instance.getLogger().info("Successfully migrated the custom locale."); + } else { + instance.getLogger().severe("Failed to migrate the custom locale!"); } - instance.getLogger().info("Successfully migrated the custom locale."); } catch (IOException e) { instance.getLogger().severe("Failed to migrate the custom locale!"); } diff --git a/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java b/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java index f2e9303..a592b8d 100644 --- a/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java +++ b/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java @@ -4,16 +4,16 @@ import me.clip.placeholderapi.expansion.PlaceholderExpansion; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.profile.NickoProfile; import java.util.Optional; public class NickoExpansion extends PlaceholderExpansion { - private final NickoBukkit instance; + private final Nicko instance; - public NickoExpansion(NickoBukkit instance) { + public NickoExpansion(Nicko instance) { this.instance = instance; } diff --git a/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java b/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java index d70f7ff..27c5c3c 100644 --- a/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java +++ b/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java @@ -1,26 +1,26 @@ package xyz.ineanto.nicko.profile; import org.bukkit.entity.Player; -import xyz.ineanto.nicko.NickoBukkit; -import xyz.ineanto.nicko.i18n.Locale; +import xyz.ineanto.nicko.Nicko; +import xyz.ineanto.nicko.language.Language; import xyz.ineanto.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); + public static final PlayerDataStore dataStore = Nicko.getInstance().getDataStore(); + public static final NickoProfile EMPTY_PROFILE = new NickoProfile(null, null, Language.ENGLISH, true); private String name; private String skin; - private Locale locale; + private Language language; private boolean randomSkin; - public NickoProfile(String name, String skin, Locale locale, boolean randomSkin) { + public NickoProfile(String name, String skin, Language language, boolean randomSkin) { this.name = name; this.skin = skin; - this.locale = locale; + this.language = language; this.randomSkin = randomSkin; } @@ -52,12 +52,12 @@ public class NickoProfile implements Cloneable { this.skin = skin; } - public Locale getLocale() { - return locale; + public Language getLocale() { + return language; } - public void setLocale(Locale locale) { - this.locale = locale; + public void setLocale(Language language) { + this.language = language; } public boolean isRandomSkin() { @@ -73,7 +73,7 @@ public class NickoProfile implements Cloneable { return "NickoProfile{" + "name='" + name + '\'' + ", skin='" + skin + '\'' + - ", locale=" + locale + + ", locale=" + language + ", randomSkin=" + randomSkin + '}'; } diff --git a/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java b/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java index 94fca27..2ba648f 100644 --- a/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java +++ b/src/main/java/xyz/ineanto/nicko/storage/PlayerDataStore.java @@ -3,7 +3,7 @@ package xyz.ineanto.nicko.storage; import org.bukkit.entity.Player; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.ineanto.nicko.mojang.MojangAPI; import xyz.ineanto.nicko.mojang.MojangUtils; import xyz.ineanto.nicko.profile.NickoProfile; @@ -34,7 +34,7 @@ public class PlayerDataStore { public ActionResult updateCache(UUID uuid, NickoProfile profile) { if (storage.isError() || cache.isError()) { - return ActionResult.error(I18NDict.Error.CACHE); + return ActionResult.error(LanguageKey.Error.CACHE); } getCache().cache(uuid, profile); diff --git a/src/main/java/xyz/ineanto/nicko/storage/json/JSONStorage.java b/src/main/java/xyz/ineanto/nicko/storage/json/JSONStorage.java index b34a2e9..7e804be 100644 --- a/src/main/java/xyz/ineanto/nicko/storage/json/JSONStorage.java +++ b/src/main/java/xyz/ineanto/nicko/storage/json/JSONStorage.java @@ -2,7 +2,7 @@ package xyz.ineanto.nicko.storage.json; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.Storage; @@ -16,7 +16,7 @@ import java.util.logging.Logger; public class JSONStorage extends Storage { private final Logger logger = Logger.getLogger("JSONStorage"); private final Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create(); - private final File directory = new File(NickoBukkit.getInstance().getDataFolder() + "/players/"); + private final File directory = new File(Nicko.getInstance().getDataFolder() + "/players/"); private JSONStorageProvider provider; @@ -54,14 +54,14 @@ public class JSONStorage extends Storage { @Override public boolean isStored(UUID uuid) { - final File directory = new File(NickoBukkit.getInstance().getDataFolder() + "/players/"); + final File directory = new File(Nicko.getInstance().getDataFolder() + "/players/"); final File file = new File(directory, uuid.toString() + ".json"); return file.exists(); } @Override public Optional retrieve(UUID uuid) { - final File directory = new File(NickoBukkit.getInstance().getDataFolder() + "/players/"); + final File directory = new File(Nicko.getInstance().getDataFolder() + "/players/"); final File file = new File(directory, uuid.toString() + ".json"); try (FileReader fileReader = new FileReader(file)) { try (BufferedReader reader = new BufferedReader(fileReader)) { @@ -75,7 +75,7 @@ public class JSONStorage extends Storage { @Override public ActionResult delete(UUID uuid) { - final File directory = new File(NickoBukkit.getInstance().getDataFolder() + "/players/"); + final File directory = new File(Nicko.getInstance().getDataFolder() + "/players/"); final File file = new File(directory, uuid.toString() + ".json"); if (file.delete() || !file.exists()) { return ActionResult.ok(); diff --git a/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java b/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java index ae33a46..f2590a1 100644 --- a/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java +++ b/src/main/java/xyz/ineanto/nicko/storage/mariadb/MariaDBStorage.java @@ -2,7 +2,7 @@ package xyz.ineanto.nicko.storage.mariadb; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.i18n.Locale; +import xyz.ineanto.nicko.language.Language; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.Storage; @@ -91,7 +91,7 @@ public class MariaDBStorage extends Storage { bungeecord = resultSet.getBoolean("bungeecord"); } - final NickoProfile profile = new NickoProfile(name, skin, Locale.fromCode(locale), bungeecord); + final NickoProfile profile = new NickoProfile(name, skin, Language.fromCode(locale), bungeecord); return Optional.of(profile); } catch (SQLException e) { logger.warning("Couldn't fetch profile: " + e.getMessage()); diff --git a/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java b/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java index 830b430..bd3d22a 100644 --- a/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java +++ b/src/main/java/xyz/ineanto/nicko/storage/mysql/MySQLStorage.java @@ -2,7 +2,7 @@ package xyz.ineanto.nicko.storage.mysql; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.i18n.Locale; +import xyz.ineanto.nicko.language.Language; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.Storage; @@ -91,7 +91,7 @@ public class MySQLStorage extends Storage { bungeecord = resultSet.getBoolean("bungeecord"); } - final NickoProfile profile = new NickoProfile(name, skin, Locale.fromCode(locale), bungeecord); + final NickoProfile profile = new NickoProfile(name, skin, Language.fromCode(locale), bungeecord); return Optional.of(profile); } catch (SQLException e) { logger.warning("Couldn't fetch profile: " + e.getMessage()); diff --git a/src/main/java/xyz/ineanto/nicko/storage/redis/RedisCache.java b/src/main/java/xyz/ineanto/nicko/storage/redis/RedisCache.java index a3c0525..7cdfa35 100644 --- a/src/main/java/xyz/ineanto/nicko/storage/redis/RedisCache.java +++ b/src/main/java/xyz/ineanto/nicko/storage/redis/RedisCache.java @@ -6,7 +6,7 @@ import redis.clients.jedis.Jedis; import redis.clients.jedis.exceptions.JedisException; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.language.LanguageKey; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.Cache; import xyz.ineanto.nicko.storage.CacheProvider; @@ -40,7 +40,7 @@ public class RedisCache extends Cache { jedis.set("nicko:" + uuid.toString(), gson.toJson(profile)); return ActionResult.ok(); } catch (JedisException exception) { - return ActionResult.error(I18NDict.Error.CACHE); + return ActionResult.error(LanguageKey.Error.CACHE); } } @@ -72,7 +72,7 @@ public class RedisCache extends Cache { jedis.del("nicko:" + uuid.toString()); return ActionResult.ok(); } catch (JedisException exception) { - return ActionResult.error(I18NDict.Error.CACHE); + return ActionResult.error(LanguageKey.Error.CACHE); } } } diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java index 9b66380..02a8d06 100644 --- a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java @@ -4,8 +4,6 @@ import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.InternalStructure; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.reflect.StructureModifier; -import com.comphenix.protocol.reflect.accessors.Accessors; -import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.wrappers.EnumWrappers; import com.comphenix.protocol.wrappers.MinecraftKey; @@ -54,24 +52,23 @@ public class WrapperPlayServerRespawn extends AbstractPacket { // 1.20.5 to 1.21.1 // why is life so hard? - // Get the key from that class - final MinecraftKey key = MinecraftKey.fromHandle( - Accessors.getFieldAccessor( - TYPE.getPacketClass(), - MinecraftReflection.getResourceKey(), - true - ) - .get(spawnInfoStructure)); + /**final Class commonPlayerInfoClazz = MinecraftReflection.getMinecraftClass("network.protocol.game.CommonPlayerSpawnInfo"); + Object commonSpawnData = Accessors.getFieldAccessor(TYPE.getPacketClass(), commonPlayerInfoClazz, true).getField().get(TYPE.getPacketClass()); + final MinecraftKey key = MinecraftKey.fromHandle( + Accessors.getFieldAccessor( + commonPlayerInfoClazz, + MinecraftReflection.getResourceKey(), + true + ) + .get(spawnInfoStructure)); - // Set the key - Accessors.getFieldAccessor( - spawnInfoStructure.getClass(), - MinecraftReflection.getResourceKey(), - true - ) - .set(spawnInfoStructure, key); - - handle.getStructures().writeSafely(0, spawnInfoStructure); + // Set the key + Accessors.getFieldAccessor( + commonPlayerInfoClazz, + MinecraftReflection.getResourceKey(), + true + ) + .set(commonSpawnData, key);*/ } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index e554244..5f56371 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,15 +1,11 @@ # Nicko ${version} - Config: # Specifies the configuration version, don't change. -version: "1.0.8" +version: "1.0.9" -############ -# LANGUAGE # -############ - -# Nicko's messages prefix. -# Accepted values: any string -prefix: "§6Nicko §8§l| §r" +# +# Language +# # Nicko will copy the English locale as "lang.yml" # and will use the translations in that file when "Server Custom" @@ -17,11 +13,10 @@ prefix: "§6Nicko §8§l| §r" # Accepted values: false (Disabled), true (Enabled) customLocale: false -########### -# STORAGE # -########### +# +# Storage +# -# This configuration section manages SQL. sql: # Indicates wherever the data will be stored locally # inside a .json file or in an SQL database. @@ -44,7 +39,7 @@ sql: # Accepted values: any string password: "password" -# This configuration section manages Redis (BungeeCord support). +# This configuration section manages Redis (enabled BungeeCord support). # It is used to transfer data between multiple servers. redis: # Indicates wherever the data will be stored through diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index a32d1df..1a6027e 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -3,43 +3,47 @@ # Specifies the configuration version, don't change. version: "1.1.4" +prefix: "NICKO" +whoosh: "WHOOSH!" +oops: "OOPS!" + error: - permission: "§cYou do not have the required permission." - invalid_username: "§cThis is not a valid Minecraft username." - mojang_name: "There is no Minecraft account with this name." - mojang_skin: "This Minecraft account has no skin." - cache: "Unable to get skin from the cache." + permission: "You're missing the permission to do that." + invalid_username: "This is an invalid Minecraft username." + mojang_name: "There's is not Minecraft account with this username." + mojang_skin: "This Minecraft account has no skin." + cache: "Unable to get data from the cache." event: settings: - error: "§cUnable to update your settings. §7§o({0})" + error: "Wasn't able to update your settings! ({0})" appearance: set: - error: "§cUnable to apply your disguise. §7§o({0})" - ok: "§fDisguise applied." + error: "Wasn't able to apply your disguise! ({0})" + ok: "You're now disguised." restore: - error: "§cUnable to apply your previous disguise back. §7§o({0})" - ok: "§aYour previous active disguise has been applied." + error: "Wasn't able to apply the previous disguise! ({0})" + ok: "Disguise restored from last time." remove: - error: "§cUnable to remove your disguise. It will be reset on your next login." - missing: "§cYou are not under a disguise." - ok: "§fDisguise removed." + error: "Wasn't able to remove your disguise!." + missing: "You're not currently disguised." + ok: "Undisguised successfully." admin: cache: - invalidate_cache: "§fComplete cache invalidated." - invalidate_entry: "§6{0} §fhas been invalidated." + invalidate_cache: "Cache purged." + invalidate_entry: "{0} was purged." check: - remove_skin: "§fSkin removed from player." + remove_skin: "Skin removed from player." gui: title: home: "Nicko - Home" - settings: "Nicko > Settings" - admin: "Nicko > Administration" - check: "Nicko > Admin... > Check" - confirm: "... > Confirm action" - cache: "Nicko > Admin... > Cache" - invalidate_skin: "... > Cache > Invalidate" + settings: "Settings" + admin: "Administration" + check: "Player Management" + confirm: "Are you sure?" + cache: "Cache Management" + invalidate_skin: "Purge cache..." exit: name: "Exit" @@ -52,7 +56,7 @@ gui: error: name: "Error!" lore: - - "The item texture failed to load, but it might still work." + - "The item failed to load, but it might still work." loading: name: "Loading..." choice: diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index dd9a400..9f9419f 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -3,43 +3,47 @@ # Précise la version de la configuration, ne pas changer. version: "1.1.4" +prefix: "NICKO" +whoosh: "WHOOSH!" +oops: "OOPS!" + error: - permission: "§cVous ne possédez pas la permission." - invalid_username: "§cLe pseudo n'est pas un pseudo Minecraft valide." - mojang_name: "Compte Minecraft inexistant" - mojang_skin: "Skin Minecraft invalide" - cache: "Erreur du cache" + permission: "Vous n'avez pas la permission de faire cela." + invalid_username: "Nom d'utilisateur Minecraft invalide." + mojang_name: "Aucun compte Minecraft associé à ce nom d'utilisateur." + mojang_skin: "Ce compte Minecraft n'a pas de skin." + cache: "Impossible de récupérer les données depuis le cache." event: settings: - error: "§cImpossible de mettre à jour vos paramètres. §7§o({0})" + error: "Impossible de mettre à jour vos paramètres ! ({0})" appearance: set: - error: "§cImpossible d''appliquer votre déguisement. §7§o({0})" - ok: "§fDéguisement appliqué." + error: "Impossible d''appliquer votre déguisement ! ({0})" + ok: "Déguisement appliqué avec succès." restore: - error: "§cImpossible d''appliquer votre précédent déguisement. §7§o({0})" - ok: "§aVotre précédent déguisement a été appliqué." + error: "Impossible d''appliquer le précédent déguisement ! ({0})" + ok: "Votre précédent déguisement a été appliqué." remove: - error: "§cImpossible de retirer votre déguisement. Il sera réinitialisé à votre prochaine reconnexion." - missing: "§cVous n''avez pas de déguisement." - ok: "§fDéguisement retiré." + error: "Impossible de retirer votre déguisement." + missing: "Vous n''avez pas de déguisement." + ok: "Déguisement retiré." admin: cache: - invalidate_cache: "§fCache complet invalidé." - invalidate_entry: "§6{0} §fa été invalidé." + invalidate_cache: "Cache complet invalidé." + invalidate_entry: "{0} a été invalidé." check: - remove_skin: "§fSkin retiré du joueur." + remove_skin: "Déguisement retiré au joueur." gui: title: home: "Nicko - Accueil" - settings: "Nicko > Paramètres" - admin: "Nicko > Administration" - check: "Nicko > Admin... > Vérification" - confirm: "... > Confirmer l''action" - cache: "Nicko > Admin... > Cache" - invalidate_skin: "... > Cache > Invalider" + settings: "Paramètres" + admin: "Administration" + check: "Gestion des Joueurs" + confirm: "Êtes-vous sûr ?" + cache: "Gestion du Cache" + invalidate_skin: "Purge du cache..." exit: name: "Quitter" @@ -50,7 +54,7 @@ gui: lore: - "Ce boutton est désactivé." error: - name: "Erreur!" + name: "Erreur !" lore: - "La texture de l'objet n'a pas chargé" - "correctement mais il fonctionne encore." @@ -121,10 +125,10 @@ gui: - "Nb. de skin dans le cache: {1}" - "Le cache est vidé toutes les 24 heures." invalidate_cache: - name: "Invalider le cache" + name: "Purger le cache" lore: - "DÉCONSEILLÉ" - - "Invalide l'entièreté du cache des skin." + - "Purge l'entièreté du cache des skin." - "Ne retire pas les déguisements des joueurs." invalidate_skin: name: "Invalider un skin..." diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 7adaa7e..6f525c4 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: Nicko -main: xyz.ineanto.nicko.NickoBukkit +main: xyz.ineanto.nicko.Nicko version: ${version} author: Ineanto description: "The feature packed, next generation disguise plugin for Minecraft." diff --git a/src/test/java/xyz/ineanto/nicko/test/NickoPluginTest.java b/src/test/java/xyz/ineanto/nicko/test/NickoPluginTest.java index 8b848dd..5ce3aea 100644 --- a/src/test/java/xyz/ineanto/nicko/test/NickoPluginTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/NickoPluginTest.java @@ -5,19 +5,19 @@ 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.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.config.Configuration; import static org.junit.jupiter.api.Assertions.assertNotNull; public class NickoPluginTest { - private static NickoBukkit plugin; + private static Nicko plugin; @BeforeAll public static void setup() { final Configuration config = Configuration.DEFAULT; MockBukkit.mock(); - plugin = MockBukkit.load(NickoBukkit.class, config); + plugin = MockBukkit.load(Nicko.class, config); } @Test diff --git a/src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java b/src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java index 008dcca..057c076 100644 --- a/src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java @@ -5,7 +5,7 @@ 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.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.appearance.random.RandomNameFetcher; import xyz.ineanto.nicko.config.Configuration; import xyz.ineanto.nicko.mojang.MojangUtils; @@ -13,13 +13,13 @@ import xyz.ineanto.nicko.mojang.MojangUtils; import static org.junit.jupiter.api.Assertions.*; public class RandomNameTest { - private static NickoBukkit plugin; + private static Nicko plugin; @BeforeAll public static void setup() { final Configuration config = Configuration.DEFAULT; MockBukkit.mock(); - plugin = MockBukkit.load(NickoBukkit.class, config); + plugin = MockBukkit.load(Nicko.class, config); } @Test diff --git a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java b/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java index cd78d77..4a371fa 100644 --- a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java @@ -5,19 +5,19 @@ 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.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.config.Configuration; import static org.junit.jupiter.api.Assertions.assertFalse; public class ConfigurationTest { - private static NickoBukkit plugin; + private static Nicko plugin; @BeforeAll public static void setup() { MockBukkit.mock(); final Configuration config = Configuration.DEFAULT; - plugin = MockBukkit.load(NickoBukkit.class, config); + plugin = MockBukkit.load(Nicko.class, config); } @Test diff --git a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java b/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java index 3535d7d..d13fa80 100644 --- a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java @@ -5,7 +5,7 @@ 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.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.config.Configuration; import xyz.ineanto.nicko.config.DefaultDataSources; @@ -16,17 +16,13 @@ public class ConfigurationVersionTest { public static void setup() { MockBukkit.mock(); final Configuration configuration = Configuration.DEFAULT; - MockBukkit.load(NickoBukkit.class, configuration); + MockBukkit.load(Nicko.class, configuration); } @Test @DisplayName("Compare configuration version") public void compareConfigurationVersion() { - final Configuration configuration = new Configuration(Configuration.VERSION.toString(), - DefaultDataSources.SQL_EMPTY, - DefaultDataSources.REDIS_EMPTY, - "", - false); + final Configuration configuration = Configuration.DEFAULT; assertEquals(configuration.getVersionObject().compareTo(Configuration.VERSION), 0); } @@ -36,7 +32,6 @@ public class ConfigurationVersionTest { final Configuration configuration = new Configuration("24.1.0", DefaultDataSources.SQL_EMPTY, DefaultDataSources.REDIS_EMPTY, - "", false); assertEquals(configuration.getVersionObject().compareTo(Configuration.VERSION), 1); } @@ -47,7 +42,6 @@ public class ConfigurationVersionTest { final Configuration configuration = new Configuration("0.23.3", DefaultDataSources.SQL_EMPTY, DefaultDataSources.REDIS_EMPTY, - "", false); assertEquals(configuration.getVersionObject().compareTo(Configuration.VERSION), -1); } @@ -58,7 +52,6 @@ public class ConfigurationVersionTest { final Configuration configuration = new Configuration(null, DefaultDataSources.SQL_EMPTY, DefaultDataSources.REDIS_EMPTY, - "", false); assertEquals(configuration.getVersionObject().compareTo(Configuration.VERSION), -1); } diff --git a/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java b/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java index 5ea2322..3c17c5d 100644 --- a/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java @@ -6,12 +6,12 @@ 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.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; -import xyz.ineanto.nicko.i18n.Translation; -import xyz.ineanto.nicko.i18n.Locale; +import xyz.ineanto.nicko.language.Language; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.language.Translation; import static org.junit.jupiter.api.Assertions.*; @@ -22,14 +22,14 @@ public class ItemTranslationTest { public static void setup() { final Configuration config = Configuration.DEFAULT; MockBukkit.mock(); - MockBukkit.load(NickoBukkit.class, config); + MockBukkit.load(Nicko.class, config); } @Test @DisplayName("Translate Item Without Lore") public void translateItemTranslationWithoutLore() { - final I18N i18n = new I18N(Locale.FRENCH); - final Translation translation = i18n.translateAndReplace(I18NDict.GUI.GO_BACK); + final PlayerLanguage playerLanguage = new PlayerLanguage(Language.FRENCH); + final Translation translation = playerLanguage.translateAndReplace(LanguageKey.GUI.GO_BACK); assertTrue(translation.lore().isEmpty()); assertEquals(translation.name(), "Retour"); } @@ -37,12 +37,12 @@ public class ItemTranslationTest { @Test @DisplayName("Translate Item") public void translateItemLore() { - final I18N i18n = new I18N(Locale.FRENCH); + final PlayerLanguage playerLanguage = new PlayerLanguage(Language.FRENCH); - final Translation test = i18n.translateAndReplace(I18NDict.GUI.Settings.TOGGLEABLE_BUTTON, "EST", "EST"); + final Translation test = playerLanguage.translateAndReplace(LanguageKey.GUI.Settings.TOGGLEABLE_BUTTON, "EST", "EST"); test.lore().forEach(System.out::println); - final Translation translation = i18n.translateAndReplace(I18NDict.GUI.Admin.Cache.STATISTICS, "1", "1"); + final Translation translation = playerLanguage.translateAndReplace(LanguageKey.GUI.Admin.Cache.STATISTICS, "1", "1"); assertFalse(translation.lore().isEmpty()); assertEquals("Nombre de requêtes: 1", translation.lore().get(0)); assertEquals("Nb. de skin dans le cache: 1", translation.lore().get(1)); diff --git a/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java b/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java index 6ed49c6..bac0c45 100644 --- a/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java @@ -5,11 +5,11 @@ 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.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.i18n.I18N; -import xyz.ineanto.nicko.i18n.I18NDict; -import xyz.ineanto.nicko.i18n.Locale; +import xyz.ineanto.nicko.language.Language; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.language.LanguageKey; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -18,14 +18,14 @@ public class TranslationTest { public static void setup() { final Configuration config = Configuration.DEFAULT; MockBukkit.mock(); - MockBukkit.load(NickoBukkit.class, config); + MockBukkit.load(Nicko.class, config); } @Test @DisplayName("Translate Line With Replacement") public void translateItemTranslationWithoutLore() { - final I18N i18n = new I18N(Locale.FRENCH); - final String translation = i18n.translate(I18NDict.Event.Settings.ERROR, false, "Test"); + final PlayerLanguage playerLanguage = new PlayerLanguage(Language.FRENCH); + final String translation = playerLanguage.translate(LanguageKey.Event.Settings.ERROR, false, "Test"); assertEquals("§cImpossible de mettre à jour vos paramètres. §7§o(Test)", translation); } diff --git a/src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java b/src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java index cdc12b0..170f367 100644 --- a/src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java @@ -4,19 +4,22 @@ import be.seeseemelk.mockbukkit.MockBukkit; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.config.Configuration; import xyz.ineanto.nicko.config.DefaultDataSources; -import xyz.ineanto.nicko.i18n.CustomLocale; +import xyz.ineanto.nicko.language.CustomLanguage; import xyz.ineanto.nicko.migration.CustomLocaleMigrator; -import java.io.*; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; import java.nio.charset.StandardCharsets; import static org.junit.jupiter.api.Assertions.assertEquals; public class MigrationTest { - private static NickoBukkit plugin; + private static Nicko plugin; private static File folder; private static File localeFile; @@ -27,9 +30,8 @@ public class MigrationTest { final Configuration configuration = new Configuration(Configuration.VERSION.toString(), DefaultDataSources.SQL_EMPTY, DefaultDataSources.REDIS_EMPTY, - "§6Nicko §8§l| §r", true); - plugin = MockBukkit.load(NickoBukkit.class, configuration); + plugin = MockBukkit.load(Nicko.class, configuration); folder = new File(plugin.getDataFolder(), "/locale/"); localeFile = new File(folder, "locale.yml"); folder.mkdirs(); @@ -40,26 +42,26 @@ public class MigrationTest { public void testLanguageFileMigration() throws IOException { final String content = """ # Nicko - Language File: - + # hello I'm the invalid version version: "1.0.0" - """; + """; BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(localeFile)); outputStream.write(content.getBytes(StandardCharsets.UTF_8)); outputStream.flush(); // Get wrong locale - final CustomLocale customLocaleBeforeMigration = new CustomLocale(); - assertEquals(customLocaleBeforeMigration.getVersion(), "1.0.0"); + final CustomLanguage customLanguageBeforeMigration = new CustomLanguage(); + assertEquals(customLanguageBeforeMigration.getVersion(), "1.0.0"); // Migrate the wrong locale to the correct one - final CustomLocaleMigrator localeMigrator = new CustomLocaleMigrator(plugin, customLocaleBeforeMigration); + final CustomLocaleMigrator localeMigrator = new CustomLocaleMigrator(plugin, customLanguageBeforeMigration); localeMigrator.migrate(); // Get the migrated locale - final CustomLocale customLocaleMigrated = new CustomLocale(); - assertEquals(customLocaleMigrated.getVersion(), "1.1.0"); + final CustomLanguage customLanguageMigrated = new CustomLanguage(); + assertEquals(customLanguageMigrated.getVersion(), "1.1.0"); } @AfterAll diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/MapCacheTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/MapCacheTest.java index d1dc888..2cc8ca7 100644 --- a/src/test/java/xyz/ineanto/nicko/test/storage/MapCacheTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/storage/MapCacheTest.java @@ -7,7 +7,7 @@ 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.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.config.Configuration; import xyz.ineanto.nicko.profile.NickoProfile; @@ -16,14 +16,14 @@ import java.util.Optional; import static org.junit.jupiter.api.Assertions.assertTrue; public class MapCacheTest { - private static NickoBukkit plugin; + private static Nicko plugin; private static PlayerMock player; @BeforeAll public static void setup() { final Configuration config = Configuration.DEFAULT; final ServerMock server = MockBukkit.mock(); - plugin = MockBukkit.load(NickoBukkit.class, config); + plugin = MockBukkit.load(Nicko.class, config); player = server.addPlayer(); } diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java index f6b1f2c..a5ce971 100644 --- a/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java @@ -4,7 +4,7 @@ import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; import be.seeseemelk.mockbukkit.entity.PlayerMock; import org.junit.jupiter.api.*; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.config.Configuration; import xyz.ineanto.nicko.config.DataSourceConfiguration; @@ -19,7 +19,7 @@ import static org.junit.jupiter.api.Assertions.*; @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class RedisCacheTest { - private static NickoBukkit plugin; + private static Nicko plugin; private static PlayerMock player; @BeforeAll @@ -28,10 +28,9 @@ public class RedisCacheTest { "", DefaultDataSources.SQL_EMPTY, new DataSourceConfiguration(true, "127.0.0.1", 6379, "", ""), - "", false); final ServerMock server = MockBukkit.mock(); - plugin = MockBukkit.load(NickoBukkit.class, config); + plugin = MockBukkit.load(Nicko.class, config); player = server.addPlayer(); assertInstanceOf(RedisCacheProvider.class, plugin.getDataStore().getCache().getProvider()); } diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java index f7a0dc0..0bd04ba 100644 --- a/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java +++ b/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java @@ -2,12 +2,12 @@ package xyz.ineanto.nicko.test.storage; import be.seeseemelk.mockbukkit.MockBukkit; import org.junit.jupiter.api.*; -import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.config.Configuration; import xyz.ineanto.nicko.config.DefaultDataSources; import xyz.ineanto.nicko.config.SQLDataSourceConfiguration; -import xyz.ineanto.nicko.i18n.Locale; +import xyz.ineanto.nicko.language.Language; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.PlayerDataStore; import xyz.ineanto.nicko.storage.mariadb.MariaDBStorageProvider; @@ -28,12 +28,11 @@ public class SQLStorageTest { "", new SQLDataSourceConfiguration(true, "127.0.0.1", 3306, "root", "12345", true), DefaultDataSources.REDIS_EMPTY, - "", false); MockBukkit.mock(); - final NickoBukkit plugin = MockBukkit.load(NickoBukkit.class, config); + final Nicko plugin = MockBukkit.load(Nicko.class, config); dataStore = plugin.getDataStore(); uuid = UUID.randomUUID(); assertInstanceOf(MariaDBStorageProvider.class, dataStore.getStorage().getProvider()); @@ -64,12 +63,12 @@ public class SQLStorageTest { final NickoProfile profile = optionalProfile.get(); assertNull(profile.getName()); assertNull(profile.getSkin()); - assertEquals(profile.getLocale(), Locale.ENGLISH); + assertEquals(profile.getLocale(), Language.ENGLISH); assertTrue(profile.isRandomSkin()); profile.setName("Notch"); profile.setSkin("Notch"); - profile.setLocale(Locale.FRENCH); + profile.setLocale(Language.FRENCH); profile.setRandomSkin(false); final ActionResult result = dataStore.getStorage().store(uuid, profile); @@ -86,7 +85,7 @@ public class SQLStorageTest { final NickoProfile updatedProfile = optionalProfile.get(); assertEquals(updatedProfile.getName(), "Notch"); assertEquals(updatedProfile.getSkin(), "Notch"); - assertEquals(updatedProfile.getLocale(), Locale.FRENCH); + assertEquals(updatedProfile.getLocale(), Language.FRENCH); assertFalse(updatedProfile.isRandomSkin()); } From c99c31ba37676aff72d395d13e69edb2fd5d4da8 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 29 Aug 2024 16:02:36 +0200 Subject: [PATCH 231/296] fix: messages not read with MiniMessage --- .../nicko/gui/items/home/ResetItem.java | 6 ++--- .../nicko/language/PlayerLanguage.java | 2 +- src/main/resources/en.yml | 22 +++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java index f00a806..2e8fb1c 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java @@ -30,16 +30,16 @@ public class ResetItem { final Optional optionalProfile = NickoProfile.get(player); optionalProfile.ifPresent(profile -> { if (!profile.hasData()) { - player.sendMessage(playerLanguage.translate(LanguageKey.Event.Appearance.Remove.MISSING, true)); + player.sendMessage(playerLanguage.translateWithOops(LanguageKey.Event.Appearance.Remove.MISSING)); event.getEvent().getView().close(); return; } final AppearanceManager appearanceManager = new AppearanceManager(player); if (!appearanceManager.reset().isError()) { - player.sendMessage(playerLanguage.translate(LanguageKey.Event.Appearance.Remove.OK, true)); + player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Appearance.Remove.OK)); } else { - player.sendMessage(playerLanguage.translate(LanguageKey.Event.Appearance.Remove.ERROR, true)); + player.sendMessage(playerLanguage.translateWithOops(LanguageKey.Event.Appearance.Remove.ERROR)); } }); return true; diff --git a/src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java b/src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java index 94e1785..ed74d2f 100644 --- a/src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java +++ b/src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java @@ -114,7 +114,7 @@ public class PlayerLanguage { } public String translate(String key, boolean prefix, Object... arguments) { - final String translation = readString(key); + final String translation = readStringWithMiniMessage(key); try { formatter.applyPattern(translation); diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 1a6027e..91704f4 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -8,25 +8,25 @@ whoosh: "WHOOSH!" oops: "OOPS!" error: - permission: "You're missing the permission to do that." - invalid_username: "This is an invalid Minecraft username." - mojang_name: "There's is not Minecraft account with this username." - mojang_skin: "This Minecraft account has no skin." - cache: "Unable to get data from the cache." + permission: "You're missing the permission to do that." + invalid_username: "This is an invalid Minecraft username." + mojang_name: "There's is not Minecraft account with this username." + mojang_skin: "This Minecraft account has no skin." + cache: "Unable to get data from the cache." event: settings: - error: "Wasn't able to update your settings! ({0})" + error: "Wasn''t able to update your settings! ({0})" appearance: set: - error: "Wasn't able to apply your disguise! ({0})" + error: "Wasn''t able to apply your disguise! ({0})" ok: "You're now disguised." restore: - error: "Wasn't able to apply the previous disguise! ({0})" - ok: "Disguise restored from last time." + error: "Wasn''t able to apply the previous disguise! ({0})" + ok: "Disguise restored from last time." remove: - error: "Wasn't able to remove your disguise!." - missing: "You're not currently disguised." + error: "Wasn''t able to remove your disguise!." + missing: "You''re not currently disguised." ok: "Undisguised successfully." admin: cache: From 20af9e732875a0ff0c46fed7806a9f93ee8f78e9 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 29 Aug 2024 16:02:57 +0200 Subject: [PATCH 232/296] feat(wrapper): trying to debug the issue --- src/main/java/xyz/ineanto/nicko/Nicko.java | 36 ++++++++++++++++++ .../nicko/appearance/AppearanceManager.java | 4 +- .../wrapper/WrapperPlayServerRespawn.java | 38 +++++++++++-------- 3 files changed, 60 insertions(+), 18 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/Nicko.java b/src/main/java/xyz/ineanto/nicko/Nicko.java index a0621bb..5778698 100644 --- a/src/main/java/xyz/ineanto/nicko/Nicko.java +++ b/src/main/java/xyz/ineanto/nicko/Nicko.java @@ -1,9 +1,19 @@ package xyz.ineanto.nicko; +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.reflect.accessors.Accessors; +import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; +import com.comphenix.protocol.wrappers.MinecraftKey; +import net.kyori.adventure.text.Component; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.World; import org.bukkit.command.PluginCommand; import org.bukkit.plugin.java.JavaPlugin; import xyz.ineanto.nicko.appearance.random.RandomNameFetcher; @@ -132,6 +142,32 @@ public class Nicko extends JavaPlugin { getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this); getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this); metrics = new Metrics(this, 20483); + + ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(this, + ListenerPriority.HIGH, + PacketType.Play.Server.RESPAWN + ) { + @Override + public void onPacketSending(PacketEvent event) { + try { + Bukkit.broadcast(Component.text("intercepting packet...")); + Class commonPlayerInfoClazz = MinecraftReflection.getMinecraftClass("network.protocol.game.CommonPlayerSpawnInfo"); + // access CommonPlayerSpawnInfo, first field of that type in the Respawn / Login packets + Object commonSpawnData = Accessors.getFieldAccessor(event.getPacket().getClass(), commonPlayerInfoClazz, true).getField().get(event.getPacket()); + // get the key of the level the player is joining. Second field in the object. First of type ResourceKey + MinecraftKey key = MinecraftKey.fromHandle(Accessors.getFieldAccessor(commonPlayerInfoClazz, MinecraftReflection.getResourceKey(), true).get(commonSpawnData)); // wrap to ProtocolLib handle + for (World world : Bukkit.getWorlds()) { + if (key.getPrefix().equals(world.getKey().getNamespace()) && key.getKey().equals(world.getKey().getKey())) { + Bukkit.broadcast(Component.text("found world!")); + } else { + Bukkit.broadcast(Component.text("whoops, no matching world found")); + } + } + } catch (IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + }); } getLogger().info("Nicko has been enabled."); diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index 7b9fcd8..eaa1dc9 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -146,12 +146,12 @@ public class AppearanceManager { final boolean wasAllowedToFly = player.getAllowFlight(); final int foodLevel = player.getFoodLevel(); final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(); - respawn.setDimension(world); + //respawn.setDimension(world); respawn.setSeed(world.getSeed()); respawn.setGameMode(player.getGameMode()); respawn.setPreviousGameMode(player.getGameMode()); respawn.setCopyMetadata(true); - respawn.sendPacket(player); + //respawn.sendPacket(player); player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); player.setAllowFlight(wasAllowedToFly); player.setFlying(wasFlying); diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java index 02a8d06..6fd7b95 100644 --- a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java @@ -4,6 +4,8 @@ import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.InternalStructure; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.reflect.StructureModifier; +import com.comphenix.protocol.reflect.accessors.Accessors; +import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.wrappers.EnumWrappers; import com.comphenix.protocol.wrappers.MinecraftKey; @@ -52,23 +54,27 @@ public class WrapperPlayServerRespawn extends AbstractPacket { // 1.20.5 to 1.21.1 // why is life so hard? - /**final Class commonPlayerInfoClazz = MinecraftReflection.getMinecraftClass("network.protocol.game.CommonPlayerSpawnInfo"); - Object commonSpawnData = Accessors.getFieldAccessor(TYPE.getPacketClass(), commonPlayerInfoClazz, true).getField().get(TYPE.getPacketClass()); - final MinecraftKey key = MinecraftKey.fromHandle( - Accessors.getFieldAccessor( - commonPlayerInfoClazz, - MinecraftReflection.getResourceKey(), - true - ) - .get(spawnInfoStructure)); + final Class commonPlayerInfoClazz = MinecraftReflection.getMinecraftClass("network.protocol.game.CommonPlayerSpawnInfo"); + try { + final Object commonSpawnData = Accessors.getFieldAccessor(TYPE.getPacketClass(), commonPlayerInfoClazz, true).getField() + .get(this); + final MinecraftKey key = MinecraftKey.fromHandle( + Accessors.getFieldAccessor( + commonPlayerInfoClazz, + MinecraftReflection.getResourceKey(), + true + ) + .get(spawnInfoStructure)); - // Set the key - Accessors.getFieldAccessor( - commonPlayerInfoClazz, - MinecraftReflection.getResourceKey(), - true - ) - .set(commonSpawnData, key);*/ + Accessors.getFieldAccessor( + commonPlayerInfoClazz, + MinecraftReflection.getResourceKey(), + true + ) + .set(commonSpawnData, key); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } } } From 144245fc5a8785b9d7994674b70c2d5735fcb4b7 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 29 Aug 2024 16:41:27 +0200 Subject: [PATCH 233/296] feat: remove test code --- src/main/java/xyz/ineanto/nicko/Nicko.java | 36 ---------------------- 1 file changed, 36 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/Nicko.java b/src/main/java/xyz/ineanto/nicko/Nicko.java index 5778698..a0621bb 100644 --- a/src/main/java/xyz/ineanto/nicko/Nicko.java +++ b/src/main/java/xyz/ineanto/nicko/Nicko.java @@ -1,19 +1,9 @@ package xyz.ineanto.nicko; -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.ProtocolLibrary; -import com.comphenix.protocol.events.ListenerPriority; -import com.comphenix.protocol.events.PacketAdapter; -import com.comphenix.protocol.events.PacketEvent; -import com.comphenix.protocol.reflect.accessors.Accessors; -import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; -import com.comphenix.protocol.wrappers.MinecraftKey; -import net.kyori.adventure.text.Component; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.Material; -import org.bukkit.World; import org.bukkit.command.PluginCommand; import org.bukkit.plugin.java.JavaPlugin; import xyz.ineanto.nicko.appearance.random.RandomNameFetcher; @@ -142,32 +132,6 @@ public class Nicko extends JavaPlugin { getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this); getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this); metrics = new Metrics(this, 20483); - - ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(this, - ListenerPriority.HIGH, - PacketType.Play.Server.RESPAWN - ) { - @Override - public void onPacketSending(PacketEvent event) { - try { - Bukkit.broadcast(Component.text("intercepting packet...")); - Class commonPlayerInfoClazz = MinecraftReflection.getMinecraftClass("network.protocol.game.CommonPlayerSpawnInfo"); - // access CommonPlayerSpawnInfo, first field of that type in the Respawn / Login packets - Object commonSpawnData = Accessors.getFieldAccessor(event.getPacket().getClass(), commonPlayerInfoClazz, true).getField().get(event.getPacket()); - // get the key of the level the player is joining. Second field in the object. First of type ResourceKey - MinecraftKey key = MinecraftKey.fromHandle(Accessors.getFieldAccessor(commonPlayerInfoClazz, MinecraftReflection.getResourceKey(), true).get(commonSpawnData)); // wrap to ProtocolLib handle - for (World world : Bukkit.getWorlds()) { - if (key.getPrefix().equals(world.getKey().getNamespace()) && key.getKey().equals(world.getKey().getKey())) { - Bukkit.broadcast(Component.text("found world!")); - } else { - Bukkit.broadcast(Component.text("whoops, no matching world found")); - } - } - } catch (IllegalAccessException exception) { - throw new RuntimeException(exception); - } - } - }); } getLogger().info("Nicko has been enabled."); From 18afb84caac46557265ad31a8d8958672cc83219 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 29 Sep 2024 17:35:09 +0200 Subject: [PATCH 234/296] feat: WE MAKING PROGRESS CHAT --- build.gradle.kts | 21 ++--- gradle/wrapper/gradle-wrapper.properties | 2 +- src/main/java/xyz/ineanto/nicko/Nicko.java | 4 + .../nicko/appearance/AppearanceManager.java | 31 +++---- .../ineanto/nicko/config/Configuration.java | 2 +- .../nicko/debug/RespawnPacketListener.java | 86 +++++++++++++++++++ .../gui/items/admin/ManageCacheItem.java | 17 +--- .../gui/items/appearance/ChangeBothItem.java | 2 +- .../gui/items/appearance/ChangeSkinItem.java | 21 ++--- .../nicko/gui/items/home/AdminAccessItem.java | 2 +- .../nicko/gui/items/home/RandomSkinItem.java | 8 +- .../xyz/ineanto/nicko/language/Language.java | 2 +- .../wrapper/WrapperPlayServerRespawn.java | 10 ++- src/main/resources/config.yml | 12 +-- src/main/resources/en.yml | 2 +- src/main/resources/fr.yml | 2 +- 16 files changed, 133 insertions(+), 91 deletions(-) create mode 100644 src/main/java/xyz/ineanto/nicko/debug/RespawnPacketListener.java diff --git a/build.gradle.kts b/build.gradle.kts index 18ed652..0823cc1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,11 +1,11 @@ plugins { id("java") - id("io.github.goooler.shadow") version "8.1.7" + id("com.gradleup.shadow") version "8.3.2" id("xyz.jpenilla.run-paper") version "2.3.0" } group = "xyz.ineanto" -version = "1.1.8" +version = "1.2.0" java { sourceCompatibility = JavaVersion.VERSION_21 @@ -38,14 +38,13 @@ repositories { } dependencies { - // Nicko - compileOnly("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT") - compileOnly("com.github.dmulloy2:ProtocolLib:master-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.21.1-R0.1-SNAPSHOT") + compileOnly("com.github.dmulloy2:ProtocolLib:-SNAPSHOT") compileOnly("me.clip:placeholderapi:2.11.5") compileOnly("net.kyori:adventure-api:4.17.0") - implementation("xyz.xenondevs.invui:invui:1.35") - implementation("net.wesjd:anvilgui:1.10.1-SNAPSHOT") + implementation("xyz.xenondevs.invui:invui:1.36") + implementation("net.wesjd:anvilgui:1.10.2-SNAPSHOT") implementation("com.github.jsixface:yamlconfig:1.2") implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.2") implementation("com.fasterxml.jackson.core:jackson-core:2.15.2") @@ -115,14 +114,6 @@ tasks { } } - jar { - enabled = false - } - - test { - useJUnitPlatform() - } - runServer { dependsOn(shadowJar) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f31fb9b..1edb788 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Mon Dec 11 00:36:17 CET 2023 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/xyz/ineanto/nicko/Nicko.java b/src/main/java/xyz/ineanto/nicko/Nicko.java index a0621bb..40c6fb5 100644 --- a/src/main/java/xyz/ineanto/nicko/Nicko.java +++ b/src/main/java/xyz/ineanto/nicko/Nicko.java @@ -1,5 +1,6 @@ package xyz.ineanto.nicko; +import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.utility.MinecraftVersion; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; @@ -10,6 +11,7 @@ import xyz.ineanto.nicko.appearance.random.RandomNameFetcher; import xyz.ineanto.nicko.command.NickoCommand; import xyz.ineanto.nicko.config.Configuration; import xyz.ineanto.nicko.config.ConfigurationManager; +import xyz.ineanto.nicko.debug.RespawnPacketListener; import xyz.ineanto.nicko.event.PlayerJoinListener; import xyz.ineanto.nicko.event.PlayerQuitListener; import xyz.ineanto.nicko.language.CustomLanguage; @@ -132,6 +134,8 @@ public class Nicko extends JavaPlugin { getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this); getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this); metrics = new Metrics(this, 20483); + + ProtocolLibrary.getProtocolManager().addPacketListener(new RespawnPacketListener()); } getLogger().info("Nicko has been enabled."); diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index eaa1dc9..effd2f0 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -1,6 +1,5 @@ package xyz.ineanto.nicko.appearance; -import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.wrappers.*; import com.google.common.collect.Multimap; import it.unimi.dsi.fastutil.ints.IntList; @@ -160,27 +159,19 @@ public class AppearanceManager { player.setFoodLevel(foodLevel); } - @SuppressWarnings("deprecation") private void updateTabList(WrappedGameProfile gameProfile, String displayName) { final WrapperPlayerServerPlayerInfo add = new WrapperPlayerServerPlayerInfo(); - if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) { - final WrapperPlayerServerPlayerInfoRemove remove = new WrapperPlayerServerPlayerInfoRemove(); - final EnumSet actions = EnumSet.of( - EnumWrappers.PlayerInfoAction.ADD_PLAYER, - EnumWrappers.PlayerInfoAction.INITIALIZE_CHAT, - EnumWrappers.PlayerInfoAction.UPDATE_LISTED, - EnumWrappers.PlayerInfoAction.UPDATE_DISPLAY_NAME, - EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE, - EnumWrappers.PlayerInfoAction.UPDATE_LATENCY); - remove.setUUIDs(List.of(player.getUniqueId())); - remove.broadcastPacket(); - add.setActions(actions); - } else { - final WrapperPlayerServerPlayerInfo remove = new WrapperPlayerServerPlayerInfo(); - remove.setActions(EnumSet.of(EnumWrappers.PlayerInfoAction.REMOVE_PLAYER)); - add.setActions(EnumSet.of(EnumWrappers.PlayerInfoAction.ADD_PLAYER)); - remove.broadcastPacket(); - } + final WrapperPlayerServerPlayerInfoRemove remove = new WrapperPlayerServerPlayerInfoRemove(); + final EnumSet actions = EnumSet.of( + EnumWrappers.PlayerInfoAction.ADD_PLAYER, + EnumWrappers.PlayerInfoAction.INITIALIZE_CHAT, + EnumWrappers.PlayerInfoAction.UPDATE_LISTED, + EnumWrappers.PlayerInfoAction.UPDATE_DISPLAY_NAME, + EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE, + EnumWrappers.PlayerInfoAction.UPDATE_LATENCY); + remove.setUUIDs(List.of(player.getUniqueId())); + remove.broadcastPacket(); + add.setActions(actions); add.setData(List.of(new PlayerInfoData( player.getUniqueId(), diff --git a/src/main/java/xyz/ineanto/nicko/config/Configuration.java b/src/main/java/xyz/ineanto/nicko/config/Configuration.java index b706f2f..d112559 100644 --- a/src/main/java/xyz/ineanto/nicko/config/Configuration.java +++ b/src/main/java/xyz/ineanto/nicko/config/Configuration.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import xyz.ineanto.nicko.version.Version; public class Configuration { - public static final Version VERSION = new Version(1, 0, 9); + public static final Version VERSION = new Version(1, 2, 0); public static final Configuration DEFAULT = new Configuration(VERSION.toString(), DefaultDataSources.SQL_EMPTY, DefaultDataSources.REDIS_EMPTY, diff --git a/src/main/java/xyz/ineanto/nicko/debug/RespawnPacketListener.java b/src/main/java/xyz/ineanto/nicko/debug/RespawnPacketListener.java new file mode 100644 index 0000000..fa37b6b --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/debug/RespawnPacketListener.java @@ -0,0 +1,86 @@ +package xyz.ineanto.nicko.debug; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.ListeningWhitelist; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.events.PacketListener; +import com.comphenix.protocol.utility.MinecraftReflection; +import com.comphenix.protocol.wrappers.MinecraftKey; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.NamespacedKey; +import org.bukkit.World; +import org.bukkit.plugin.Plugin; +import xyz.ineanto.nicko.Nicko; + +import java.util.Arrays; +import java.util.Optional; + +public class RespawnPacketListener implements PacketListener { + @Override + public void onPacketSending(PacketEvent event) { + try { + final Optional world = getWorld(event); + if (world.isEmpty()) { + Bukkit.broadcast(Component.text("did not find the world the player was in")); + return; + } + + Bukkit.broadcast(Component.text("found " + world.get().getName() + "!")); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + + @Override + public void onPacketReceiving(PacketEvent event) { + + } + + @Override + public ListeningWhitelist getSendingWhitelist() { + return ListeningWhitelist.newBuilder().types(PacketType.Play.Server.RESPAWN).build(); + } + + @Override + public ListeningWhitelist getReceivingWhitelist() { + return ListeningWhitelist.EMPTY_WHITELIST; + } + + @Override + public Plugin getPlugin() { + return Nicko.getInstance(); + } + + private boolean keysEquals(MinecraftKey wrappedKey, NamespacedKey bukkitKey) { + // compare bukkit minecraft key and NMS wrapped minecraft key + return wrappedKey.getPrefix().equals(bukkitKey.getNamespace()) && wrappedKey.getKey().equals(bukkitKey.getKey()); + } + + public Optional getWorld(PacketEvent event) throws Throwable { + final Class commonPlayerInfoClazz = MinecraftReflection.getMinecraftClass("network.protocol.game.CommonPlayerSpawnInfo"); + // access CommonPlayerSpawnInfo, first field of that type in the Respawn / Login packets + final Object packetHandle = event.getPacket().getHandle(); + final Object commonSpawnData = packetHandle.getClass().getRecordComponents()[0].getAccessor().invoke(packetHandle); + + Arrays.stream(commonSpawnData.getClass().getRecordComponents()).forEach(component -> { + component.getAccessor().setAccessible(true); + System.out.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-"); + System.out.println(component.getName()); + System.out.println(component.getType().getSimpleName()); + System.out.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-"); + component.getAccessor().setAccessible(false); + } + ); + + // get the key of the level the player is joining. Second field in the object. First of type ResourceKey + /**MinecraftKey key = MinecraftKey.fromHandle(Accessors.getFieldAccessor(commonSpawnData.getClass(), MinecraftReflection.getResourceKey(), true) + .get(commonSpawnData)); // wrap to ProtocolLib handle + for (World world : Bukkit.getWorlds()) { + if (keysEquals(key, world.getKey())) { + return Optional.of(world); + } + }*/ + return Optional.empty(); + } +} diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java index ac9d4a4..a14baa5 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java @@ -5,18 +5,12 @@ import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; import org.jetbrains.annotations.NotNull; -import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.gui.CacheManagementGUI; -import xyz.ineanto.nicko.gui.items.ItemDefaults; -import xyz.ineanto.nicko.language.PlayerLanguage; import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.language.PlayerLanguage; 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 xyz.xenondevs.invui.util.MojangApiUtils; - -import java.io.IOException; public class ManageCacheItem extends AsyncItem { public ManageCacheItem(PlayerLanguage playerLanguage) { @@ -25,13 +19,8 @@ public class ManageCacheItem extends AsyncItem { return playerLanguage.translateItem(builder, LanguageKey.GUI.LOADING); }, (click -> true)).getItemProvider(), () -> { - try { - final SkullBuilder builder = new SkullBuilder("Notch"); - return playerLanguage.translateItem(builder, LanguageKey.GUI.Admin.MANAGE_CACHE); - } catch (MojangApiUtils.MojangApiException | IOException e) { - Nicko.getInstance().getLogger().warning("Unable to get Head texture for Notch! (GUI/ManageCache)"); - return ItemDefaults.getErrorSkullItem(playerLanguage, LanguageKey.GUI.Admin.MANAGE_CACHE); - } + final ItemBuilder builder = new ItemBuilder(Material.PLAYER_HEAD); + return playerLanguage.translateItem(builder, LanguageKey.GUI.Admin.MANAGE_CACHE); }); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java index 2e19cf2..a076ab1 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java @@ -18,7 +18,7 @@ public class ChangeBothItem { public SuppliedItem get() { return new SuppliedItem(() -> { - final ItemBuilder builder = new ItemBuilder(Material.TOTEM_OF_UNDYING); + final ItemBuilder builder = new ItemBuilder(Material.ARMOR_STAND); return playerLanguage.translateItem(builder, LanguageKey.GUI.Home.CHANGE_BOTH); }, click -> { final ClickType clickType = click.getClickType(); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java index 6c78cc8..24927b3 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java @@ -1,36 +1,25 @@ package xyz.ineanto.nicko.gui.items.appearance; +import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; -import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.anvil.AnvilManager; -import xyz.ineanto.nicko.gui.items.ItemDefaults; -import xyz.ineanto.nicko.language.PlayerLanguage; import xyz.ineanto.nicko.language.LanguageKey; -import xyz.xenondevs.invui.item.builder.SkullBuilder; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; -import xyz.xenondevs.invui.util.MojangApiUtils; - -import java.io.IOException; public class ChangeSkinItem { private final PlayerLanguage playerLanguage; - private final Player player; public ChangeSkinItem(Player player) { this.playerLanguage = new PlayerLanguage(player); - this.player = player; } public SuppliedItem get() { return new SuppliedItem(() -> { - try { - final SkullBuilder builder = new SkullBuilder(player.getName()); - return playerLanguage.translateItem(builder, LanguageKey.GUI.Home.CHANGE_SKIN); - } catch (MojangApiUtils.MojangApiException | IOException e) { - Nicko.getInstance().getLogger().warning("Unable to get Head texture for specified player (" + player.getName() + ")! (GUI/Home)"); - return ItemDefaults.getErrorSkullItem(playerLanguage, LanguageKey.GUI.Home.CHANGE_SKIN); - } + final ItemBuilder builder = new ItemBuilder(Material.PLAYER_HEAD); + return playerLanguage.translateItem(builder, LanguageKey.GUI.Home.CHANGE_SKIN); }, click -> { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java index 478431d..107db6f 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java @@ -18,7 +18,7 @@ public class AdminAccessItem { public SuppliedItem get() { return new SuppliedItem(() -> { - final ItemBuilder builder = new ItemBuilder(Material.COMMAND_BLOCK_MINECART); + final ItemBuilder builder = new ItemBuilder(Material.SCAFFOLDING); return playerLanguage.translateItem(builder, LanguageKey.GUI.Home.ADMIN); }, click -> { final ClickType clickType = click.getClickType(); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java index 9ddd6af..0306017 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java @@ -1,14 +1,15 @@ package xyz.ineanto.nicko.gui.items.home; +import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.appearance.AppearanceManager; -import xyz.ineanto.nicko.language.PlayerLanguage; import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.language.PlayerLanguage; import xyz.ineanto.nicko.profile.NickoProfile; -import xyz.xenondevs.invui.item.builder.SkullBuilder; +import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; import java.util.Optional; @@ -24,8 +25,7 @@ public class RandomSkinItem { public SuppliedItem get() { return new SuppliedItem(() -> { - final SkullBuilder.HeadTexture texture = new SkullBuilder.HeadTexture("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzgzMTEzOGMyMDYxMWQzMDJjNDIzZmEzMjM3MWE3NDNkMTc0MzdhMTg5NzNjMzUxOTczNDQ3MGE3YWJiNCJ9fX0="); - final SkullBuilder builder = new SkullBuilder(texture); + final ItemBuilder builder = new ItemBuilder(Material.SPAWNER); return playerLanguage.translateItem(builder, LanguageKey.GUI.Home.RANDOM_SKIN); }, (event) -> { final Player player = event.getPlayer(); diff --git a/src/main/java/xyz/ineanto/nicko/language/Language.java b/src/main/java/xyz/ineanto/nicko/language/Language.java index a13b78d..049039c 100644 --- a/src/main/java/xyz/ineanto/nicko/language/Language.java +++ b/src/main/java/xyz/ineanto/nicko/language/Language.java @@ -9,7 +9,7 @@ public enum Language implements Serializable { FRENCH("fr", "Français"), CUSTOM("cm", "Server Custom"); - public static final Version VERSION = new Version(1, 1, 4); + public static final Version VERSION = new Version(1, 2, 0); private final String code; private transient final String name; diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java index 6fd7b95..707258c 100644 --- a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java @@ -13,6 +13,8 @@ import com.google.common.hash.Hashing; import org.bukkit.GameMode; import org.bukkit.World; +import java.lang.reflect.Field; + /** * PacketPlayServerRespawn Wrapper class (1.20.X to 1.21.X) *

@@ -53,11 +55,11 @@ public class WrapperPlayServerRespawn extends AbstractPacket { } else { // 1.20.5 to 1.21.1 - // why is life so hard? final Class commonPlayerInfoClazz = MinecraftReflection.getMinecraftClass("network.protocol.game.CommonPlayerSpawnInfo"); try { - final Object commonSpawnData = Accessors.getFieldAccessor(TYPE.getPacketClass(), commonPlayerInfoClazz, true).getField() - .get(this); + final Field commonSpawnDataField = Accessors.getFieldAccessor(TYPE.getPacketClass(), commonPlayerInfoClazz, true).getField(); + commonSpawnDataField.setAccessible(true); + final MinecraftKey key = MinecraftKey.fromHandle( Accessors.getFieldAccessor( commonPlayerInfoClazz, @@ -71,7 +73,7 @@ public class WrapperPlayServerRespawn extends AbstractPacket { MinecraftReflection.getResourceKey(), true ) - .set(commonSpawnData, key); + .set(commonSpawnDataField.get(this), key); } catch (IllegalAccessException e) { throw new RuntimeException(e); } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 5f56371..0ed717d 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,11 +1,7 @@ # Nicko ${version} - Config: # Specifies the configuration version, don't change. -version: "1.0.9" - -# -# Language -# +version: "1.2.0" # Nicko will copy the English locale as "lang.yml" # and will use the translations in that file when "Server Custom" @@ -13,10 +9,6 @@ version: "1.0.9" # Accepted values: false (Disabled), true (Enabled) customLocale: false -# -# Storage -# - sql: # Indicates wherever the data will be stored locally # inside a .json file or in an SQL database. @@ -39,8 +31,6 @@ sql: # Accepted values: any string password: "password" -# This configuration section manages Redis (enabled BungeeCord support). -# It is used to transfer data between multiple servers. redis: # Indicates wherever the data will be stored through # Redis to transfer whenever a player switches server. diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 91704f4..14248b6 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -1,7 +1,7 @@ # Nicko ${version} - Language File: # Specifies the configuration version, don't change. -version: "1.1.4" +version: "1.2.0" prefix: "NICKO" whoosh: "WHOOSH!" diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 9f9419f..a17c532 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -1,7 +1,7 @@ # Nicko ${version} - Fichier de langue: # Précise la version de la configuration, ne pas changer. -version: "1.1.4" +version: "1.2.0" prefix: "NICKO" whoosh: "WHOOSH!" From 230acf439ec4475dd96427ac761ab03eb64ec22f Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 29 Sep 2024 20:31:07 +0200 Subject: [PATCH 235/296] feat: we're not making progress chat :( --- .../nicko/appearance/AppearanceManager.java | 4 +-- .../nicko/debug/RespawnPacketListener.java | 17 ++++------ .../wrapper/WrapperCommonPlayerSpawnInfo.java | 11 +++++++ .../wrapper/WrapperPlayServerRespawn.java | 32 +++++++------------ 4 files changed, 31 insertions(+), 33 deletions(-) create mode 100644 src/main/java/xyz/ineanto/nicko/wrapper/WrapperCommonPlayerSpawnInfo.java diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index effd2f0..94ca38f 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -145,12 +145,12 @@ public class AppearanceManager { final boolean wasAllowedToFly = player.getAllowFlight(); final int foodLevel = player.getFoodLevel(); final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(); - //respawn.setDimension(world); + respawn.setDimension(world); respawn.setSeed(world.getSeed()); respawn.setGameMode(player.getGameMode()); respawn.setPreviousGameMode(player.getGameMode()); respawn.setCopyMetadata(true); - //respawn.sendPacket(player); + respawn.sendPacket(player); player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); player.setAllowFlight(wasAllowedToFly); player.setFlying(wasFlying); diff --git a/src/main/java/xyz/ineanto/nicko/debug/RespawnPacketListener.java b/src/main/java/xyz/ineanto/nicko/debug/RespawnPacketListener.java index fa37b6b..f65d10e 100644 --- a/src/main/java/xyz/ineanto/nicko/debug/RespawnPacketListener.java +++ b/src/main/java/xyz/ineanto/nicko/debug/RespawnPacketListener.java @@ -4,7 +4,6 @@ import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.ListeningWhitelist; import com.comphenix.protocol.events.PacketEvent; import com.comphenix.protocol.events.PacketListener; -import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.wrappers.MinecraftKey; import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; @@ -58,7 +57,6 @@ public class RespawnPacketListener implements PacketListener { } public Optional getWorld(PacketEvent event) throws Throwable { - final Class commonPlayerInfoClazz = MinecraftReflection.getMinecraftClass("network.protocol.game.CommonPlayerSpawnInfo"); // access CommonPlayerSpawnInfo, first field of that type in the Respawn / Login packets final Object packetHandle = event.getPacket().getHandle(); final Object commonSpawnData = packetHandle.getClass().getRecordComponents()[0].getAccessor().invoke(packetHandle); @@ -68,19 +66,18 @@ public class RespawnPacketListener implements PacketListener { System.out.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-"); System.out.println(component.getName()); System.out.println(component.getType().getSimpleName()); - System.out.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-"); component.getAccessor().setAccessible(false); } ); // get the key of the level the player is joining. Second field in the object. First of type ResourceKey - /**MinecraftKey key = MinecraftKey.fromHandle(Accessors.getFieldAccessor(commonSpawnData.getClass(), MinecraftReflection.getResourceKey(), true) - .get(commonSpawnData)); // wrap to ProtocolLib handle - for (World world : Bukkit.getWorlds()) { - if (keysEquals(key, world.getKey())) { - return Optional.of(world); - } - }*/ + MinecraftKey key = MinecraftKey.fromHandle(commonSpawnData.getClass().getRecordComponents()[1]); + System.out.println(key.getPrefix() + " / " + key.getKey() + " (" + key.getFullKey() + ")"); + for (World world : Bukkit.getWorlds()) { + if (keysEquals(key, world.getKey())) { + return Optional.of(world); + } + } return Optional.empty(); } } diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperCommonPlayerSpawnInfo.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperCommonPlayerSpawnInfo.java new file mode 100644 index 0000000..e91a109 --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperCommonPlayerSpawnInfo.java @@ -0,0 +1,11 @@ +package xyz.ineanto.nicko.wrapper; + +public class WrapperCommonPlayerSpawnInfo { + private final Object handle; + + public WrapperCommonPlayerSpawnInfo(Object handle) { + this.handle = handle; + } + + +} diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java index 707258c..1ed2ec8 100644 --- a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java @@ -4,16 +4,17 @@ import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.InternalStructure; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.reflect.StructureModifier; -import com.comphenix.protocol.reflect.accessors.Accessors; -import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; +import com.comphenix.protocol.wrappers.BukkitConverters; import com.comphenix.protocol.wrappers.EnumWrappers; import com.comphenix.protocol.wrappers.MinecraftKey; import com.google.common.hash.Hashing; +import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.World; import java.lang.reflect.Field; +import java.lang.reflect.RecordComponent; /** * PacketPlayServerRespawn Wrapper class (1.20.X to 1.21.X) @@ -55,27 +56,16 @@ public class WrapperPlayServerRespawn extends AbstractPacket { } else { // 1.20.5 to 1.21.1 - final Class commonPlayerInfoClazz = MinecraftReflection.getMinecraftClass("network.protocol.game.CommonPlayerSpawnInfo"); try { - final Field commonSpawnDataField = Accessors.getFieldAccessor(TYPE.getPacketClass(), commonPlayerInfoClazz, true).getField(); - commonSpawnDataField.setAccessible(true); + final Object spawnInfoStructureHandle = spawnInfoStructure.getHandle(); + final RecordComponent[] components = spawnInfoStructureHandle.getClass().getRecordComponents(); - final MinecraftKey key = MinecraftKey.fromHandle( - Accessors.getFieldAccessor( - commonPlayerInfoClazz, - MinecraftReflection.getResourceKey(), - true - ) - .get(spawnInfoStructure)); - - Accessors.getFieldAccessor( - commonPlayerInfoClazz, - MinecraftReflection.getResourceKey(), - true - ) - .set(commonSpawnDataField.get(this), key); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); + // Doesn't work! + final Field levelKeyField = spawnInfoStructureHandle.getClass().getDeclaredField(components[1].getAccessor().getName()); + levelKeyField.setAccessible(true); + levelKeyField.set(spawnInfoStructureHandle, BukkitConverters.getWorldKeyConverter().getGeneric(Bukkit.getWorld("world"))); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException(); } } } From 95a5e9903885170181580af543a62f506ef704e1 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 29 Sep 2024 20:32:11 +0200 Subject: [PATCH 236/296] refactor: doing a little cleaning of the test code --- .../ineanto/nicko/debug/RespawnPacketListener.java | 3 +-- .../nicko/wrapper/WrapperCommonPlayerSpawnInfo.java | 11 ----------- 2 files changed, 1 insertion(+), 13 deletions(-) delete mode 100644 src/main/java/xyz/ineanto/nicko/wrapper/WrapperCommonPlayerSpawnInfo.java diff --git a/src/main/java/xyz/ineanto/nicko/debug/RespawnPacketListener.java b/src/main/java/xyz/ineanto/nicko/debug/RespawnPacketListener.java index f65d10e..653c178 100644 --- a/src/main/java/xyz/ineanto/nicko/debug/RespawnPacketListener.java +++ b/src/main/java/xyz/ineanto/nicko/debug/RespawnPacketListener.java @@ -71,8 +71,7 @@ public class RespawnPacketListener implements PacketListener { ); // get the key of the level the player is joining. Second field in the object. First of type ResourceKey - MinecraftKey key = MinecraftKey.fromHandle(commonSpawnData.getClass().getRecordComponents()[1]); - System.out.println(key.getPrefix() + " / " + key.getKey() + " (" + key.getFullKey() + ")"); + final MinecraftKey key = MinecraftKey.fromHandle(commonSpawnData.getClass().getRecordComponents()[1]); for (World world : Bukkit.getWorlds()) { if (keysEquals(key, world.getKey())) { return Optional.of(world); diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperCommonPlayerSpawnInfo.java b/src/main/java/xyz/ineanto/nicko/wrapper/WrapperCommonPlayerSpawnInfo.java deleted file mode 100644 index e91a109..0000000 --- a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperCommonPlayerSpawnInfo.java +++ /dev/null @@ -1,11 +0,0 @@ -package xyz.ineanto.nicko.wrapper; - -public class WrapperCommonPlayerSpawnInfo { - private final Object handle; - - public WrapperCommonPlayerSpawnInfo(Object handle) { - this.handle = handle; - } - - -} From 77e8844eee8483a65d0d8b50b463907cb6a0c5f9 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 29 Sep 2024 20:33:52 +0200 Subject: [PATCH 237/296] feat(changelog): updated the changelog to reflect upcoming changes --- CHANGELOG.log | 11 ++++ CHANGELOG.secret.log | 116 ------------------------------------------- 2 files changed, 11 insertions(+), 116 deletions(-) delete mode 100644 CHANGELOG.secret.log diff --git a/CHANGELOG.log b/CHANGELOG.log index 30044c1..7f84db4 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,3 +1,14 @@ +1.2.0: Update n°13 (XX/XX/24) + [FEATURES] + - Players are now able to save disguises as presets. + - Modernized the messages and added various sound effects upon interacting with the plugin. + + [FIXES] + - Fixed an oversight preventing the configuration from properly being migrated. + + [LANGUAGE] + - Moved the prefix to the language file. + 1.1.8: Update n°12 (XX/XX/24) [FEATURES] diff --git a/CHANGELOG.secret.log b/CHANGELOG.secret.log deleted file mode 100644 index 98b7f56..0000000 --- a/CHANGELOG.secret.log +++ /dev/null @@ -1,116 +0,0 @@ -1.2.0: Update n°13 (XX/XX/24) - [FEATURES] - - Players are now able to save disguises as presets. - - [FIXES] - - Fixed an oversight preventing the configuration from properly being migrated. - - [LANGUAGE] - - Moved the prefix to the language file. - - Updated the language files to modernize the messages. - - [OTHER] - - Dropped the release candidate status as Nicko is now considered stable. - -1.1.7-RC1: Hotfix n°5 (04/05/24) - [OTHER] - - Restored download link again on spigotmc.org - -1.1.6-RC1: Update n°11 (04/05/24) - [FEATURES] - - Update dependencies in preparation to the 1.20.5 update - - [OTHER] - - Restored download link on spigotmc.org - -1.1.5-RC1: Update n°10 (25/12/23) - [FEATURES] - - Various improvements to performance. - [FIXES] - - Fixed a bug related to configuration migration. - -1.1.4-RC1: Update n°9 (07/02/23) - [OTHER] - - The repository hosting the previous version of Nicko had expired, this is now fixed. - -1.1.3-RC1: Hotfix n°4 (28/12/23) - [FIXES] - - Fixed the English Locale version being late. - -1.1.2-RC1: Update n°8 (28/12/23) - [FEATURES] - - Players now default back to their original appearance upon failure. - - [FIXES] - - Fixed an invalid placeholder parameter (%nicko_random_skin% now gets if the player has random skin on login set or not). - - Fixed the error reason not appearing upon failure. - - Fixed player profiles (name and skin associated) not being reset gracefully upon failure. - - Fixed error messages not being precise enough. - - Various optimizations and improvements. - -1.1.1-RC1: Update n°7 (27/12/23) - [FEATURES] - - Made Nicko compatible with 1.20.3 and 1.20.4. - - -1.1.0-RC1: Update n°6 (23/12/23) - [BREAKING] - - The language system has been updated to use the Adventure library (https://docs.advntr.dev/index.html). This results in the custom locale breaking - Nicko upon usage of legacy color codes (e.g., "§6Nicko"). Your custom locale will be backed up upon starting this version and you will be able to - use the new default English locale to help you make your locale compatible with the new formatting. - - [FEATURES] - - Players can now choose to get a random appearance via a list of more than 400 usernames and skins associated. - - Players can now toggle a setting to automatically get a random appearance upon joining. - - Introduced a version string inside Nicko's language files to plan future updates to the file. (see [BREAKING]) - - (Note: the random skin functionality is still work-in-progress and might break or not work at all because of - the lack of time that I have to test all the usernames and skins associated.) - - [FIXES] - - Various optimizations and improvements. - - Internal refactoring - - bStats metrics are not minified anymore. - -1.0.8-RC1: Update n°5 (19/12/23) - [FEATURES] - - Introduced a version string inside Nicko's configuration to plan future updates to the file. Your previous configuration file will automatically be migrated to this current version (with the backup of your old one included!) - - Persistence and cache will now fallback to local alternatives when unreachable. - - Player check GUI has been updated to better reflect the current state of player's disguises. - - Developers can now listen to the PlayerDisguiseEvent and cancel the disguise process. - - [OTHER] - - Various optimizations and improvements. - - Internal refactoring - -1.0.7-RC1: Update n°4 (13/12/23) - [OTHER] - - In line with my thinking that Minecraft servers should always be in one of the latest versions to give developers more freedom and less maintenance hassle, Nicko will now only be supporting the current major version and the one before it. This results in this version of Nicko now needing at minimum Java version 17 and a server running 1.19. If you can't upgrade, consider myself sorry. - - Various optimizations and improvements following the upgrade to Java 17. - -1.0.6-RC1: Update n°3 (11/12/23) - [OTHER] - - Added telemetry via bStats to gather useful informations about Nicko. This feature is optional and can be disabled inside the "bStats" folder found in plugins folder. Informations gathered are public record and can be found at: https://bstats.org/plugin/bukkit/Nicko/20483. - -1.0.5-RC1: Update n°2 (11/12/23) - [OTHER] - - Moved plugin to the Gradle build chain, resulting in faster builds and smaller Jar. This has no consequences for players. - -1.0.4-RC1: - [FEATURES] - - The players check GUI is now updated upon player's joining and leaving - - Administrators are now able to remove a player's disguise through the player check GUI - -1.0.3-RC1: Hotfix n°3 (07/12/23) - [FIXES] - - Fixed a visual bug where players in survival mode were seeing themselves as having full health and hunger after disguising. - -1.0.2-RC1: Hotfix n°2 (06/12/23) - [OTHER] - - Internal refactoring - -1.0.1-RC1: Hotfix n°1 (06/12/23) - [FIXES] - - Fixed an issue when joining and players being disguised were not for the player joining. - - From d804fb1207658ead1801ee39a06a102dedab2ba0 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sun, 29 Sep 2024 20:35:15 +0200 Subject: [PATCH 238/296] feat: updated readme --- .gitignore | 3 +-- README.md | 14 ++------------ docker-compose.yml | 25 ------------------------- 3 files changed, 3 insertions(+), 39 deletions(-) delete mode 100644 docker-compose.yml diff --git a/.gitignore b/.gitignore index bc8385d..8a238de 100644 --- a/.gitignore +++ b/.gitignore @@ -26,5 +26,4 @@ bin/ !**/src/test/**/bin/ ### Server ### -run/ -CHANGELOG.secret.log \ No newline at end of file +run/ \ No newline at end of file diff --git a/README.md b/README.md index 6ff3cc5..1d25acd 100644 --- a/README.md +++ b/README.md @@ -19,21 +19,11 @@ https://www.spigotmc.org/resources/nicko.113868/ --- -## Q/A - -Q: Players are getting kicked when they send a message on versions above 1.19.2! - -A: -This should not happen. -Try installing [NoEncryption](https://www.spigotmc.org/resources/noencryption.102902/). - ---- - #### Version compatibility table | Version | Plugin | |---------------|----------------------------------------------------------------------------| | 1.7 and lower | Unsupported | | 1.8 - 1.12.2 | Use [NickReloaded](https://www.spigotmc.org/resources/nickreloaded.46335/) | -| 1.13 to 1.18 | Unsupported | -| 1.19 - 1.20 | Use Nicko | +| 1.13 to 1.19 | Unsupported | +| 1.20 - 1.21 | Use Nicko | diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 810aba5..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,25 +0,0 @@ -# Nicko's docker-compose.yml -# Used for debug and test purposes. -version: '3.1' - -services: - - db: - image: mariadb:latest - restart: no - environment: - MARIADB_DB: db - MARIADB_ROOT_PASSWORD: 12345 - volumes: - - mysql:/var/lib/mysql - ports: - - "3306:3306" - - redis: - image: redis - restart: no - ports: - - "6379:6379" - -volumes: - mysql: \ No newline at end of file From fe33a003eac324e62f6ac8ba16be00e0feaba62d Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 31 Oct 2024 17:52:30 +0100 Subject: [PATCH 239/296] feat: disabled the respawn packet --- build.gradle.kts | 8 ++++---- .../xyz/ineanto/nicko/appearance/AppearanceManager.java | 6 ++++-- src/main/java/xyz/ineanto/nicko/packet/PacketSender.java | 4 ++++ 3 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 src/main/java/xyz/ineanto/nicko/packet/PacketSender.java diff --git a/build.gradle.kts b/build.gradle.kts index 0823cc1..5a2401e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -38,12 +38,12 @@ repositories { } dependencies { - compileOnly("io.papermc.paper:paper-api:1.21.1-R0.1-SNAPSHOT") - compileOnly("com.github.dmulloy2:ProtocolLib:-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.21.3-R0.1-SNAPSHOT") + compileOnly("com.github.dmulloy2:ProtocolLib:5.3.0") compileOnly("me.clip:placeholderapi:2.11.5") compileOnly("net.kyori:adventure-api:4.17.0") - implementation("xyz.xenondevs.invui:invui:1.36") + implementation("xyz.xenondevs.invui:invui:1.39") implementation("net.wesjd:anvilgui:1.10.2-SNAPSHOT") implementation("com.github.jsixface:yamlconfig:1.2") implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.2") @@ -54,7 +54,7 @@ dependencies { implementation("com.google.code.gson:gson:2.10.1") implementation("org.bstats:bstats-bukkit:3.0.2") - testImplementation("com.github.MockBukkit:MockBukkit:v3.99.1") + testImplementation("com.github.MockBukkit:MockBukkit:v3.133.2") testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.2") testImplementation("org.junit.jupiter:junit-jupiter-engine:5.10.2") testImplementation("org.junit.jupiter:junit-jupiter:5.10.2") diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index 94ca38f..7e705f6 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -144,13 +144,15 @@ public class AppearanceManager { final boolean wasFlying = player.isFlying(); final boolean wasAllowedToFly = player.getAllowFlight(); final int foodLevel = player.getFoodLevel(); + final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(); - respawn.setDimension(world); + //respawn.setDimension(world); respawn.setSeed(world.getSeed()); respawn.setGameMode(player.getGameMode()); respawn.setPreviousGameMode(player.getGameMode()); respawn.setCopyMetadata(true); - respawn.sendPacket(player); + //respawn.sendPacket(player); + player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); player.setAllowFlight(wasAllowedToFly); player.setFlying(wasFlying); diff --git a/src/main/java/xyz/ineanto/nicko/packet/PacketSender.java b/src/main/java/xyz/ineanto/nicko/packet/PacketSender.java new file mode 100644 index 0000000..f801398 --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/packet/PacketSender.java @@ -0,0 +1,4 @@ +package xyz.ineanto.nicko.packet; + +public interface PacketSender { +} From f72d5c0948534286707b390684b64bd3b49fe838 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 31 Oct 2024 20:05:22 +0100 Subject: [PATCH 240/296] feat: implemented NMS packet sender --- build.gradle.kts | 4 +- src/main/java/xyz/ineanto/nicko/Nicko.java | 4 - .../xyz/ineanto/nicko/anvil/AnvilManager.java | 2 +- .../nicko/appearance/AppearanceManager.java | 151 +++--------------- .../nicko/event/PlayerJoinListener.java | 4 +- .../nicko/gui/items/home/RandomSkinItem.java | 2 +- .../nicko/packet/InternalPacketSender.java | 125 +++++++++++++++ .../ineanto/nicko/packet/PacketSender.java | 11 ++ .../nicko/packet/WrapperPacketSender.java | 139 ++++++++++++++++ .../debug/RespawnPacketListener.java | 2 +- .../{ => packet}/wrapper/AbstractPacket.java | 2 +- .../WrapperPlayServerEntityDestroy.java | 2 +- .../wrapper/WrapperPlayServerRespawn.java | 13 +- .../wrapper/WrapperPlayServerSpawnEntity.java | 2 +- .../WrapperPlayerServerPlayerInfo.java | 2 +- .../WrapperPlayerServerPlayerInfoRemove.java | 2 +- .../ineanto/nicko/profile/NickoProfile.java | 7 +- 17 files changed, 325 insertions(+), 149 deletions(-) create mode 100644 src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java create mode 100644 src/main/java/xyz/ineanto/nicko/packet/WrapperPacketSender.java rename src/main/java/xyz/ineanto/nicko/{ => packet}/debug/RespawnPacketListener.java (98%) rename src/main/java/xyz/ineanto/nicko/{ => packet}/wrapper/AbstractPacket.java (98%) rename src/main/java/xyz/ineanto/nicko/{ => packet}/wrapper/WrapperPlayServerEntityDestroy.java (95%) rename src/main/java/xyz/ineanto/nicko/{ => packet}/wrapper/WrapperPlayServerRespawn.java (89%) rename src/main/java/xyz/ineanto/nicko/{ => packet}/wrapper/WrapperPlayServerSpawnEntity.java (98%) rename src/main/java/xyz/ineanto/nicko/{ => packet}/wrapper/WrapperPlayerServerPlayerInfo.java (96%) rename src/main/java/xyz/ineanto/nicko/{ => packet}/wrapper/WrapperPlayerServerPlayerInfoRemove.java (94%) diff --git a/build.gradle.kts b/build.gradle.kts index 5a2401e..8a6d329 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,6 +2,7 @@ plugins { id("java") id("com.gradleup.shadow") version "8.3.2" id("xyz.jpenilla.run-paper") version "2.3.0" + id("io.papermc.paperweight.userdev") version "1.7.4" } group = "xyz.ineanto" @@ -38,7 +39,8 @@ repositories { } dependencies { - compileOnly("io.papermc.paper:paper-api:1.21.3-R0.1-SNAPSHOT") + paperweight.paperDevBundle("1.21.3-R0.1-SNAPSHOT") + compileOnly("com.github.dmulloy2:ProtocolLib:5.3.0") compileOnly("me.clip:placeholderapi:2.11.5") compileOnly("net.kyori:adventure-api:4.17.0") diff --git a/src/main/java/xyz/ineanto/nicko/Nicko.java b/src/main/java/xyz/ineanto/nicko/Nicko.java index 40c6fb5..a0621bb 100644 --- a/src/main/java/xyz/ineanto/nicko/Nicko.java +++ b/src/main/java/xyz/ineanto/nicko/Nicko.java @@ -1,6 +1,5 @@ package xyz.ineanto.nicko; -import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.utility.MinecraftVersion; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; @@ -11,7 +10,6 @@ import xyz.ineanto.nicko.appearance.random.RandomNameFetcher; import xyz.ineanto.nicko.command.NickoCommand; import xyz.ineanto.nicko.config.Configuration; import xyz.ineanto.nicko.config.ConfigurationManager; -import xyz.ineanto.nicko.debug.RespawnPacketListener; import xyz.ineanto.nicko.event.PlayerJoinListener; import xyz.ineanto.nicko.event.PlayerQuitListener; import xyz.ineanto.nicko.language.CustomLanguage; @@ -134,8 +132,6 @@ public class Nicko extends JavaPlugin { getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this); getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this); metrics = new Metrics(this, 20483); - - ProtocolLibrary.getProtocolManager().addPacketListener(new RespawnPacketListener()); } getLogger().info("Nicko has been enabled."); diff --git a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java index 38c7f73..db7a7cd 100644 --- a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java @@ -114,7 +114,7 @@ public class AnvilManager { Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { return Collections.singletonList(AnvilGUI.ResponseAction.close()); } - final ActionResult actionResult = appearanceManager.updatePlayer(skinChange, false); + final ActionResult actionResult = appearanceManager.update(skinChange, false); if (!actionResult.isError()) { player.sendMessage(playerLanguage.translate(LanguageKey.Event.Appearance.Set.OK, true)); } else { diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index 7e705f6..fba9286 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -1,36 +1,27 @@ package xyz.ineanto.nicko.appearance; -import com.comphenix.protocol.wrappers.*; -import com.google.common.collect.Multimap; -import it.unimi.dsi.fastutil.ints.IntList; -import org.bukkit.Bukkit; -import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerTeleportEvent; import xyz.ineanto.nicko.Nicko; -import xyz.ineanto.nicko.language.LanguageKey; -import xyz.ineanto.nicko.mojang.MojangAPI; -import xyz.ineanto.nicko.mojang.MojangSkin; +import xyz.ineanto.nicko.packet.InternalPacketSender; +import xyz.ineanto.nicko.packet.PacketSender; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.PlayerDataStore; import xyz.ineanto.nicko.storage.name.PlayerNameStore; -import xyz.ineanto.nicko.wrapper.*; -import java.io.IOException; -import java.util.EnumSet; -import java.util.List; import java.util.Optional; -import java.util.concurrent.ExecutionException; public class AppearanceManager { private final Nicko instance = Nicko.getInstance(); private final PlayerDataStore dataStore = instance.getDataStore(); private final PlayerNameStore nameStore = instance.getNameStore(); + private final PacketSender packetSender; private final Player player; public AppearanceManager(Player player) { this.player = player; + this.packetSender = new InternalPacketSender(player, getNickoProfile()); } public ActionResult reset() { @@ -40,7 +31,7 @@ public class AppearanceManager { profile.setSkin(defaultName); dataStore.getCache().cache(player.getUniqueId(), profile); - final ActionResult result = updatePlayer(true, true); + final ActionResult result = update(true, true); if (!result.isError()) { profile.setName(null); profile.setSkin(null); @@ -49,109 +40,28 @@ public class AppearanceManager { return result; } - public ActionResult updatePlayer(boolean skinChange, boolean reset) { + public ActionResult update(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); - if (!result.isError()) { - updateMetadata(); - updateTabList(gameProfile, displayName); - respawnPlayer(); - respawnEntityForOthers(); - } + + final ActionResult result = packetSender.sendGameProfileUpdate(displayName, skinChange, reset); + + if (result.isError()) { reset(); } + + packetSender.sendEntityMetadataUpdate(); + packetSender.sendTabListUpdate(displayName); + respawnPlayer(); + packetSender.sendEntityRespawn(); + return result; } - public ActionResult updateForOthers(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); - if (!result.isError()) { - updateMetadata(); - updateTabList(gameProfile, displayName); - respawnEntityForOthers(); - } - return result; - } - - private NickoProfile getNickoProfile() { - final Optional optionalProfile = dataStore.getData(player.getUniqueId()); - return optionalProfile.orElse(NickoProfile.EMPTY_PROFILE.clone()); - } - - public void respawnEntityForOthers() { - final NickoProfile nickoProfile = getNickoProfile(); - if (!nickoProfile.hasData()) return; - - final WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy(); - final WrapperPlayServerSpawnEntity spawn = new WrapperPlayServerSpawnEntity(); - destroy.setEntityIds(IntList.of(player.getEntityId())); - spawn.setEntityId(player.getEntityId()); - spawn.setLocation(player.getLocation()); - spawn.setPlayerId(player.getUniqueId()); - Bukkit.getOnlinePlayers().stream().filter(receiver -> receiver.getUniqueId() != player.getUniqueId()).forEach(receiver -> { - destroy.sendPacket(receiver); - spawn.sendPacket(receiver); - }); - } - - - private ActionResult updateGameProfileSkin(WrappedGameProfile gameProfile, boolean skinChange, boolean reset) { - final NickoProfile profile = getNickoProfile(); - - if (skinChange) { - Optional skin; - try { - final MojangAPI mojangAPI = Nicko.getInstance().getMojangAPI(); - final Optional uuid = mojangAPI.getUUID(profile.getSkin()); - if (uuid.isPresent()) { - skin = reset ? mojangAPI.getSkinWithoutCaching(uuid.get()) : mojangAPI.getSkin(uuid.get()); - if (skin.isPresent()) { - final MojangSkin skinResult = skin.get(); - final Multimap properties = gameProfile.getProperties(); - properties.get("textures").clear(); - properties.put("textures", new WrappedSignedProperty("textures", skinResult.value(), skinResult.signature())); - } else { - reset(); - return ActionResult.error(LanguageKey.Error.MOJANG_SKIN); - } - } else { - reset(); - return ActionResult.error(LanguageKey.Error.MOJANG_NAME); - } - return ActionResult.ok(); - } catch (ExecutionException e) { - return ActionResult.error(LanguageKey.Error.CACHE); - } catch (IOException e) { - reset(); - return ActionResult.error(LanguageKey.Error.MOJANG_NAME); - } catch (InterruptedException e) { - return ActionResult.error("Unknown error"); - } - } - return ActionResult.ok(); - } - - private void updateMetadata() { - final WrappedDataWatcher entityWatcher = WrappedDataWatcher.getEntityWatcher(player); - entityWatcher.setObject(17, (byte) 0x7f, true); - } - private void respawnPlayer() { - final World world = player.getWorld(); final boolean wasFlying = player.isFlying(); final boolean wasAllowedToFly = player.getAllowFlight(); final int foodLevel = player.getFoodLevel(); - final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(); - //respawn.setDimension(world); - respawn.setSeed(world.getSeed()); - respawn.setGameMode(player.getGameMode()); - respawn.setPreviousGameMode(player.getGameMode()); - respawn.setCopyMetadata(true); - //respawn.sendPacket(player); + packetSender.sendPlayerRespawn(); player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); player.setAllowFlight(wasAllowedToFly); @@ -161,29 +71,8 @@ public class AppearanceManager { player.setFoodLevel(foodLevel); } - private void updateTabList(WrappedGameProfile gameProfile, String displayName) { - final WrapperPlayerServerPlayerInfo add = new WrapperPlayerServerPlayerInfo(); - final WrapperPlayerServerPlayerInfoRemove remove = new WrapperPlayerServerPlayerInfoRemove(); - final EnumSet actions = EnumSet.of( - EnumWrappers.PlayerInfoAction.ADD_PLAYER, - EnumWrappers.PlayerInfoAction.INITIALIZE_CHAT, - EnumWrappers.PlayerInfoAction.UPDATE_LISTED, - EnumWrappers.PlayerInfoAction.UPDATE_DISPLAY_NAME, - EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE, - EnumWrappers.PlayerInfoAction.UPDATE_LATENCY); - remove.setUUIDs(List.of(player.getUniqueId())); - remove.broadcastPacket(); - add.setActions(actions); - - add.setData(List.of(new PlayerInfoData( - player.getUniqueId(), - player.getPing(), - true, - EnumWrappers.NativeGameMode.fromBukkit(player.getGameMode()), - gameProfile, - WrappedChatComponent.fromText(displayName), - WrappedRemoteChatSessionData.fromPlayer(player) - ))); - add.broadcastPacket(); + private NickoProfile getNickoProfile() { + final Optional optionalProfile = dataStore.getData(player.getUniqueId()); + return optionalProfile.orElse(NickoProfile.EMPTY_PROFILE.clone()); } } \ No newline at end of file diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java index b7e4408..28171f5 100644 --- a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java @@ -50,7 +50,7 @@ public class PlayerJoinListener implements Listener { 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); + final ActionResult actionResult = appearanceManager.update(needsASkinChange, false); if (!actionResult.isError()) { player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Appearance.Restore.OK)); } else { @@ -68,7 +68,7 @@ public class PlayerJoinListener implements Listener { optionalOnlinePlayerProfile.ifPresent(profile -> { final AppearanceManager appearanceManager = new AppearanceManager(online); final boolean needsASkinChange = profile.getSkin() != null && !profile.getSkin().equals(online.getName()); - final ActionResult actionResult = appearanceManager.updateForOthers(needsASkinChange, false); + final ActionResult actionResult = appearanceManager.update(needsASkinChange, false); if (actionResult.isError()) { logger.warning("Something wrong happened while updating players to joining player (" + actionResult.getErrorKey() + ")"); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java index 0306017..9753c3c 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java @@ -40,7 +40,7 @@ public class RandomSkinItem { instance.getDataStore().updateCache(player.getUniqueId(), profile); final AppearanceManager appearanceManager = new AppearanceManager(player); - final ActionResult result = appearanceManager.updatePlayer(true, false); + final ActionResult result = appearanceManager.update(true, false); if (!result.isError()) { player.sendMessage(playerLanguage.translate(LanguageKey.Event.Appearance.Set.OK, true)); } else { diff --git a/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java b/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java new file mode 100644 index 0000000..3fb5bd3 --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java @@ -0,0 +1,125 @@ +package xyz.ineanto.nicko.packet; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; +import it.unimi.dsi.fastutil.ints.IntList; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; +import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; +import net.minecraft.network.protocol.game.ClientboundRespawnPacket; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.EntityDataSerializers; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import xyz.ineanto.nicko.Nicko; +import xyz.ineanto.nicko.appearance.ActionResult; +import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.mojang.MojangAPI; +import xyz.ineanto.nicko.mojang.MojangSkin; +import xyz.ineanto.nicko.profile.NickoProfile; + +import java.io.IOException; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.ExecutionException; + +/** + * Look at this Mojang. + * I want you to really stare at this code. + * You made me do this. + */ +public class InternalPacketSender implements PacketSender { + private final Player player; + private final NickoProfile profile; + + public InternalPacketSender(Player player, NickoProfile profile) { + this.player = player; + this.profile = profile; + } + + @Override + public void sendEntityRespawn() { + if (!profile.hasData()) return; + + final Entity entityPlayer = (Entity) player; + + final ClientboundRemoveEntitiesPacket destroy = new ClientboundRemoveEntitiesPacket(IntList.of(player.getEntityId())); + final ClientboundAddEntityPacket add = new ClientboundAddEntityPacket(entityPlayer, 0, entityPlayer.getOnPos()); + + Bukkit.getOnlinePlayers().stream().filter(receiver -> receiver.getUniqueId() != player.getUniqueId()).forEach(receiver -> { + sendPacket(destroy, player); + sendPacket(add, player); + }); + } + + @Override + public ActionResult sendGameProfileUpdate(String name, boolean skinChange, boolean reset) { + final GameProfile gameProfile = ((ServerPlayer) player).gameProfile; + + // TODO (Ineanto, 31/10/2024): Could this be refactored to get rid of the boolean? + if (skinChange) { + Optional skin; + try { + final MojangAPI mojangAPI = Nicko.getInstance().getMojangAPI(); + final Optional uuid = mojangAPI.getUUID(profile.getSkin()); + if (uuid.isPresent()) { + skin = reset ? mojangAPI.getSkinWithoutCaching(uuid.get()) : mojangAPI.getSkin(uuid.get()); + if (skin.isPresent()) { + final MojangSkin skinResult = skin.get(); + final PropertyMap properties = gameProfile.getProperties(); + properties.get("textures").clear(); + properties.put("textures", new Property("textures", skinResult.value(), skinResult.signature())); + } else { + return ActionResult.error(LanguageKey.Error.MOJANG_SKIN); + } + } else { + return ActionResult.error(LanguageKey.Error.MOJANG_NAME); + } + return ActionResult.ok(); + } catch (ExecutionException e) { + return ActionResult.error(LanguageKey.Error.CACHE); + } catch (IOException e) { + return ActionResult.error(LanguageKey.Error.MOJANG_NAME); + } catch (InterruptedException e) { + return ActionResult.error("Unknown error"); + } + } + return ActionResult.ok(); + } + + @Override + public void sendEntityMetadataUpdate() { + final SynchedEntityData.DataValue dataValueComponent = + new SynchedEntityData.DataItem<>( + new EntityDataAccessor<>(17, EntityDataSerializers.BYTE), + (byte) 0x7f + ).value(); + + final ClientboundSetEntityDataPacket data = new ClientboundSetEntityDataPacket(player.getEntityId(), List.of(dataValueComponent)); + sendPacket(data, player); + } + + @Override + public void sendPlayerRespawn() { + final ServerPlayer serverPlayer = (ServerPlayer) player; + final ServerLevel world = (ServerLevel) player.getWorld(); + + final ClientboundRespawnPacket respawn = new ClientboundRespawnPacket(serverPlayer.createCommonSpawnInfo(world), (byte) 0x03); + sendPacket(respawn, player); + } + + @Override + public void sendTabListUpdate(String displayName) { + + } + + private void sendPacket(Packet packet, Player player) { + ((ServerPlayer) player).connection.send(packet); + } +} diff --git a/src/main/java/xyz/ineanto/nicko/packet/PacketSender.java b/src/main/java/xyz/ineanto/nicko/packet/PacketSender.java index f801398..ef93153 100644 --- a/src/main/java/xyz/ineanto/nicko/packet/PacketSender.java +++ b/src/main/java/xyz/ineanto/nicko/packet/PacketSender.java @@ -1,4 +1,15 @@ package xyz.ineanto.nicko.packet; +import xyz.ineanto.nicko.appearance.ActionResult; + public interface PacketSender { + void sendEntityRespawn(); + + ActionResult sendGameProfileUpdate(String name, boolean skinChange, boolean reset); + + void sendEntityMetadataUpdate(); + + void sendPlayerRespawn(); + + void sendTabListUpdate(String displayName); } diff --git a/src/main/java/xyz/ineanto/nicko/packet/WrapperPacketSender.java b/src/main/java/xyz/ineanto/nicko/packet/WrapperPacketSender.java new file mode 100644 index 0000000..fc2b140 --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/packet/WrapperPacketSender.java @@ -0,0 +1,139 @@ +package xyz.ineanto.nicko.packet; + +import com.comphenix.protocol.wrappers.*; +import com.google.common.collect.Multimap; +import it.unimi.dsi.fastutil.ints.IntList; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.entity.Player; +import xyz.ineanto.nicko.Nicko; +import xyz.ineanto.nicko.appearance.ActionResult; +import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.mojang.MojangAPI; +import xyz.ineanto.nicko.mojang.MojangSkin; +import xyz.ineanto.nicko.packet.wrapper.*; +import xyz.ineanto.nicko.profile.NickoProfile; + +import java.io.IOException; +import java.util.EnumSet; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.ExecutionException; + +public class WrapperPacketSender implements PacketSender { + private final Player player; + private final NickoProfile profile; + + private WrappedGameProfile gameProfile; + + public WrapperPacketSender(Player player, NickoProfile profile) { + this.player = player; + this.profile = profile; + } + + @Override + public void sendEntityRespawn() { + if (!profile.hasData()) return; + + final WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy(); + final WrapperPlayServerSpawnEntity spawn = new WrapperPlayServerSpawnEntity(); + destroy.setEntityIds(IntList.of(player.getEntityId())); + spawn.setEntityId(player.getEntityId()); + spawn.setLocation(player.getLocation()); + spawn.setPlayerId(player.getUniqueId()); + Bukkit.getOnlinePlayers().stream().filter(receiver -> receiver.getUniqueId() != player.getUniqueId()).forEach(receiver -> { + destroy.sendPacket(receiver); + spawn.sendPacket(receiver); + }); + } + + @Override + public ActionResult sendGameProfileUpdate(String name, boolean skinChange, boolean reset) { + this.gameProfile = WrappedGameProfile.fromPlayer(player).withName(name); + + // TODO (Ineanto, 31/10/2024): Could get refactored to omit this boolean? + if (skinChange) { + Optional skin; + try { + final MojangAPI mojangAPI = Nicko.getInstance().getMojangAPI(); + final Optional uuid = mojangAPI.getUUID(profile.getSkin()); + if (uuid.isPresent()) { + skin = reset ? mojangAPI.getSkinWithoutCaching(uuid.get()) : mojangAPI.getSkin(uuid.get()); + if (skin.isPresent()) { + final MojangSkin skinResult = skin.get(); + final Multimap properties = gameProfile.getProperties(); + properties.get("textures").clear(); + properties.put("textures", new WrappedSignedProperty("textures", skinResult.value(), skinResult.signature())); + } else { + return ActionResult.error(LanguageKey.Error.MOJANG_SKIN); + } + } else { + return ActionResult.error(LanguageKey.Error.MOJANG_NAME); + } + return ActionResult.ok(); + } catch (ExecutionException e) { + return ActionResult.error(LanguageKey.Error.CACHE); + } catch (IOException e) { + return ActionResult.error(LanguageKey.Error.MOJANG_NAME); + } catch (InterruptedException e) { + return ActionResult.error("Unknown error"); + } + } + return ActionResult.ok(); + } + + + @Override + public void sendEntityMetadataUpdate() { + final WrappedDataWatcher entityWatcher = WrappedDataWatcher.getEntityWatcher(player); + entityWatcher.setObject(17, (byte) 0x7f, true); + } + + @Override + public void sendPlayerRespawn() { + final World world = player.getWorld(); + + final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(); + respawn.setDimension(world); + respawn.setSeed(world.getSeed()); + respawn.setGameMode(player.getGameMode()); + respawn.setPreviousGameMode(player.getGameMode()); + respawn.setCopyMetadata(true); + respawn.sendPacket(player); + } + + @Override + public void sendTabListUpdate(String displayName) { + if (gameProfile == null) { + Nicko.getInstance().getLogger().warning("Hello. I sincerely hope you're doing great out there."); + Nicko.getInstance().getLogger().warning("If you see this message, I've failed at my task and I'm a terrible programmer."); + Nicko.getInstance().getLogger().warning("Report this issue on https://git.ineanto.xyz/ineanto/nicko, thank you!"); + return; + } + + final WrapperPlayerServerPlayerInfo add = new WrapperPlayerServerPlayerInfo(); + final WrapperPlayerServerPlayerInfoRemove remove = new WrapperPlayerServerPlayerInfoRemove(); + final EnumSet actions = EnumSet.of( + EnumWrappers.PlayerInfoAction.ADD_PLAYER, + EnumWrappers.PlayerInfoAction.INITIALIZE_CHAT, + EnumWrappers.PlayerInfoAction.UPDATE_LISTED, + EnumWrappers.PlayerInfoAction.UPDATE_DISPLAY_NAME, + EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE, + EnumWrappers.PlayerInfoAction.UPDATE_LATENCY); + remove.setUUIDs(List.of(player.getUniqueId())); + remove.broadcastPacket(); + add.setActions(actions); + + add.setData(List.of(new PlayerInfoData( + player.getUniqueId(), + player.getPing(), + true, + EnumWrappers.NativeGameMode.fromBukkit(player.getGameMode()), + gameProfile, + WrappedChatComponent.fromText(displayName), + WrappedRemoteChatSessionData.fromPlayer(player) + ))); + + add.broadcastPacket(); + } +} diff --git a/src/main/java/xyz/ineanto/nicko/debug/RespawnPacketListener.java b/src/main/java/xyz/ineanto/nicko/packet/debug/RespawnPacketListener.java similarity index 98% rename from src/main/java/xyz/ineanto/nicko/debug/RespawnPacketListener.java rename to src/main/java/xyz/ineanto/nicko/packet/debug/RespawnPacketListener.java index 653c178..5222dd0 100644 --- a/src/main/java/xyz/ineanto/nicko/debug/RespawnPacketListener.java +++ b/src/main/java/xyz/ineanto/nicko/packet/debug/RespawnPacketListener.java @@ -1,4 +1,4 @@ -package xyz.ineanto.nicko.debug; +package xyz.ineanto.nicko.packet.debug; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.ListeningWhitelist; diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/AbstractPacket.java b/src/main/java/xyz/ineanto/nicko/packet/wrapper/AbstractPacket.java similarity index 98% rename from src/main/java/xyz/ineanto/nicko/wrapper/AbstractPacket.java rename to src/main/java/xyz/ineanto/nicko/packet/wrapper/AbstractPacket.java index 1d90240..42e138b 100644 --- a/src/main/java/xyz/ineanto/nicko/wrapper/AbstractPacket.java +++ b/src/main/java/xyz/ineanto/nicko/packet/wrapper/AbstractPacket.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package xyz.ineanto.nicko.wrapper; +package xyz.ineanto.nicko.packet.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.ProtocolLibrary; diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerEntityDestroy.java b/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerEntityDestroy.java similarity index 95% rename from src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerEntityDestroy.java rename to src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerEntityDestroy.java index bc94876..a23f1a6 100644 --- a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerEntityDestroy.java +++ b/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerEntityDestroy.java @@ -1,4 +1,4 @@ -package xyz.ineanto.nicko.wrapper; +package xyz.ineanto.nicko.packet.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.PacketContainer; diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerRespawn.java similarity index 89% rename from src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java rename to src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerRespawn.java index 1ed2ec8..dc71b1f 100644 --- a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerRespawn.java @@ -1,4 +1,4 @@ -package xyz.ineanto.nicko.wrapper; +package xyz.ineanto.nicko.packet.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.InternalStructure; @@ -56,11 +56,20 @@ public class WrapperPlayServerRespawn extends AbstractPacket { } else { // 1.20.5 to 1.21.1 + /* + Honestly, I've tried everything to make this work. + Fields inside the CommonPlayerSpawnInfo are Record Components and are + marked final. + + This would work with some trickery involved, but here's the + caveat: Record Components/Fields and are immutable by DESIGN. + So... here we are now, stopped right in my track by Java's language design and Mojang themselves. + */ + try { final Object spawnInfoStructureHandle = spawnInfoStructure.getHandle(); final RecordComponent[] components = spawnInfoStructureHandle.getClass().getRecordComponents(); - // Doesn't work! final Field levelKeyField = spawnInfoStructureHandle.getClass().getDeclaredField(components[1].getAccessor().getName()); levelKeyField.setAccessible(true); levelKeyField.set(spawnInfoStructureHandle, BukkitConverters.getWorldKeyConverter().getGeneric(Bukkit.getWorld("world"))); diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerSpawnEntity.java b/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerSpawnEntity.java similarity index 98% rename from src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerSpawnEntity.java rename to src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerSpawnEntity.java index 7f09a16..0512717 100644 --- a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayServerSpawnEntity.java +++ b/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerSpawnEntity.java @@ -1,4 +1,4 @@ -package xyz.ineanto.nicko.wrapper; +package xyz.ineanto.nicko.packet.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.PacketContainer; diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfo.java b/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayerServerPlayerInfo.java similarity index 96% rename from src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfo.java rename to src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayerServerPlayerInfo.java index 3347f98..ca37dc0 100644 --- a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfo.java +++ b/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayerServerPlayerInfo.java @@ -1,4 +1,4 @@ -package xyz.ineanto.nicko.wrapper; +package xyz.ineanto.nicko.packet.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.PacketContainer; diff --git a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java b/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayerServerPlayerInfoRemove.java similarity index 94% rename from src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java rename to src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayerServerPlayerInfoRemove.java index a619249..2273c48 100644 --- a/src/main/java/xyz/ineanto/nicko/wrapper/WrapperPlayerServerPlayerInfoRemove.java +++ b/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayerServerPlayerInfoRemove.java @@ -1,4 +1,4 @@ -package xyz.ineanto.nicko.wrapper; +package xyz.ineanto.nicko.packet.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.PacketContainer; diff --git a/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java b/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java index 27c5c3c..9f1460f 100644 --- a/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java +++ b/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java @@ -4,14 +4,19 @@ import org.bukkit.entity.Player; import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.language.Language; import xyz.ineanto.nicko.storage.PlayerDataStore; +import xyz.ineanto.nicko.storage.name.PlayerNameStore; import java.util.Optional; import java.util.UUID; public class NickoProfile implements Cloneable { - public static final PlayerDataStore dataStore = Nicko.getInstance().getDataStore(); public static final NickoProfile EMPTY_PROFILE = new NickoProfile(null, null, Language.ENGLISH, true); + private static final Nicko instance = Nicko.getInstance(); + private static final PlayerDataStore dataStore = instance.getDataStore(); + + private final PlayerNameStore nameStore = instance.getNameStore(); + private String name; private String skin; private Language language; From 9b64ec18ba61ac777cc68dc1fd00c9111a5cf1d3 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 31 Oct 2024 20:35:58 +0100 Subject: [PATCH 241/296] fix: jackson relocating --- build.gradle.kts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 8a6d329..0dcc0cc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -48,8 +48,8 @@ dependencies { implementation("xyz.xenondevs.invui:invui:1.39") implementation("net.wesjd:anvilgui:1.10.2-SNAPSHOT") implementation("com.github.jsixface:yamlconfig:1.2") - implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.15.2") - implementation("com.fasterxml.jackson.core:jackson-core:2.15.2") + implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.18.1") + implementation("com.fasterxml.jackson.core:jackson-core:2.18.1") implementation("com.mysql:mysql-connector-j:8.2.0") implementation("org.mariadb.jdbc:mariadb-java-client:3.3.1") implementation("redis.clients:jedis:5.1.2") @@ -83,8 +83,7 @@ tasks { relocate("me.clip", "xyz.ineanto.nicko.libs.placeholderapi") relocate("net.wesjd", "xyz.ineanto.nicko.libs.anvilgui") relocate("com.github.jsixface", "xyz.ineanto.nicko.libs.yaml") - relocate("com.fasterxml.jackson.dataformat", "xyz.ineanto.nicko.libs.jackson.yaml") - relocate("com.fasterxml.jackson.core", "xyz.ineanto.nicko.libs.jackson.core") + relocate("com.fasterxml.jackson", "xyz.ineanto.nicko.libs.jacksonpr") relocate("com.mysql", "xyz.ineanto.nicko.libs.mysql") relocate("org.mariadb.jdbc", "xyz.ineanto.nicko.libs.mariadb") relocate("redis.clients", "xyz.ineanto.nicko.libs.redis") @@ -129,6 +128,6 @@ tasks { url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar") } - minecraftVersion("1.21.1") + minecraftVersion("1.21.3") } } \ No newline at end of file From 3440f1fad167eb16161255df5d7e9a407817af04 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 14 Nov 2024 20:11:13 +0100 Subject: [PATCH 242/296] feat: internal packet sender is now functional --- src/main/java/xyz/ineanto/nicko/Nicko.java | 2 +- .../nicko/language/PlayerLanguage.java | 2 - .../nicko/packet/InternalPacketSender.java | 67 +++++++++++++++---- .../ineanto/nicko/profile/NickoProfile.java | 3 - 4 files changed, 55 insertions(+), 19 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/Nicko.java b/src/main/java/xyz/ineanto/nicko/Nicko.java index a0621bb..2d26f84 100644 --- a/src/main/java/xyz/ineanto/nicko/Nicko.java +++ b/src/main/java/xyz/ineanto/nicko/Nicko.java @@ -66,7 +66,7 @@ public class Nicko extends JavaPlugin { if (!MinecraftVersion.TRAILS_AND_TAILS.atOrAbove()) { getLogger().severe("This version (" + MinecraftVersion.getCurrentVersion().getVersion() + ") is not supported by Nicko!"); - getLogger().severe("As of version 1.0.7, Nicko only supports the latest two majors Minecraft versions. (Currently 1.20.X-1.21.X)"); + getLogger().severe("As of version 1.2.0, Nicko only supports the latest Minecraft versions. (Currently 1.21.3)"); dataStore.getStorage().setError(true); Bukkit.getPluginManager().disablePlugin(this); } diff --git a/src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java b/src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java index ed74d2f..ca22bd9 100644 --- a/src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java +++ b/src/main/java/xyz/ineanto/nicko/language/PlayerLanguage.java @@ -12,13 +12,11 @@ import xyz.xenondevs.invui.item.builder.AbstractItemBuilder; import java.io.InputStream; import java.text.MessageFormat; import java.util.*; -import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; public class PlayerLanguage { private final MessageFormat formatter = new MessageFormat(""); - private final Logger logger = Logger.getLogger("I18N"); private final Nicko instance = Nicko.getInstance(); private final Pattern replacementPattern = Pattern.compile("(?ms)\\{\\d+}"); private final YamlConfig yamlConfig; diff --git a/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java b/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java index 3fb5bd3..6af2f67 100644 --- a/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java +++ b/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java @@ -4,18 +4,19 @@ import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; import com.mojang.authlib.properties.PropertyMap; import it.unimi.dsi.fastutil.ints.IntList; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.contents.PlainTextContents; import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; -import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; -import net.minecraft.network.protocol.game.ClientboundRespawnPacket; -import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; +import net.minecraft.network.protocol.game.*; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.phys.Vec3; import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.entity.Player; import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.appearance.ActionResult; @@ -25,8 +26,10 @@ import xyz.ineanto.nicko.mojang.MojangSkin; import xyz.ineanto.nicko.profile.NickoProfile; import java.io.IOException; +import java.util.EnumSet; import java.util.List; import java.util.Optional; +import java.util.Random; import java.util.concurrent.ExecutionException; /** @@ -47,10 +50,20 @@ public class InternalPacketSender implements PacketSender { public void sendEntityRespawn() { if (!profile.hasData()) return; - final Entity entityPlayer = (Entity) player; - final ClientboundRemoveEntitiesPacket destroy = new ClientboundRemoveEntitiesPacket(IntList.of(player.getEntityId())); - final ClientboundAddEntityPacket add = new ClientboundAddEntityPacket(entityPlayer, 0, entityPlayer.getOnPos()); + final ClientboundAddEntityPacket add = new ClientboundAddEntityPacket( + new Random().nextInt(9999), + player.getUniqueId(), + player.getX(), + player.getY(), + player.getZ(), + player.getPitch(), + player.getYaw(), + EntityType.PLAYER, + 0, + Vec3.ZERO, + player.getBodyYaw() + ); Bukkit.getOnlinePlayers().stream().filter(receiver -> receiver.getUniqueId() != player.getUniqueId()).forEach(receiver -> { sendPacket(destroy, player); @@ -60,7 +73,7 @@ public class InternalPacketSender implements PacketSender { @Override public ActionResult sendGameProfileUpdate(String name, boolean skinChange, boolean reset) { - final GameProfile gameProfile = ((ServerPlayer) player).gameProfile; + final GameProfile gameProfile = ((CraftPlayer) player).getProfile(); // TODO (Ineanto, 31/10/2024): Could this be refactored to get rid of the boolean? if (skinChange) { @@ -75,6 +88,7 @@ public class InternalPacketSender implements PacketSender { final PropertyMap properties = gameProfile.getProperties(); properties.get("textures").clear(); properties.put("textures", new Property("textures", skinResult.value(), skinResult.signature())); + ((CraftPlayer) player).getHandle().gameProfile = gameProfile; } else { return ActionResult.error(LanguageKey.Error.MOJANG_SKIN); } @@ -107,19 +121,46 @@ public class InternalPacketSender implements PacketSender { @Override public void sendPlayerRespawn() { - final ServerPlayer serverPlayer = (ServerPlayer) player; - final ServerLevel world = (ServerLevel) player.getWorld(); + final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + final ServerLevel level = serverPlayer.serverLevel(); - final ClientboundRespawnPacket respawn = new ClientboundRespawnPacket(serverPlayer.createCommonSpawnInfo(world), (byte) 0x03); + final ClientboundRespawnPacket respawn = new ClientboundRespawnPacket(serverPlayer.createCommonSpawnInfo(level), (byte) 0x03); sendPacket(respawn, player); } @Override public void sendTabListUpdate(String displayName) { + final ServerPlayer serverPlayer = (((CraftPlayer) player)).getHandle(); + final EnumSet actions = EnumSet.of( + ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, + ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT, + ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED, + ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME, + ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, + ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY); + + final List entries = List.of(new ClientboundPlayerInfoUpdatePacket.Entry( + player.getUniqueId(), + serverPlayer.gameProfile, + true, + player.getPing(), + serverPlayer.gameMode.getGameModeForPlayer(), + MutableComponent.create(new PlainTextContents.LiteralContents(displayName)), + 1, + null + )); + + final ClientboundPlayerInfoUpdatePacket update = new ClientboundPlayerInfoUpdatePacket(actions, entries); + final ClientboundPlayerInfoRemovePacket remove = new ClientboundPlayerInfoRemovePacket(List.of(player.getUniqueId())); + + Bukkit.getOnlinePlayers().forEach(onlinePlayer -> { + sendPacket(remove, onlinePlayer); + sendPacket(update, onlinePlayer); + }); } private void sendPacket(Packet packet, Player player) { - ((ServerPlayer) player).connection.send(packet); + (((CraftPlayer) player).getHandle()).connection.send(packet); } } diff --git a/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java b/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java index 9f1460f..bc75f78 100644 --- a/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java +++ b/src/main/java/xyz/ineanto/nicko/profile/NickoProfile.java @@ -4,7 +4,6 @@ import org.bukkit.entity.Player; import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.language.Language; import xyz.ineanto.nicko.storage.PlayerDataStore; -import xyz.ineanto.nicko.storage.name.PlayerNameStore; import java.util.Optional; import java.util.UUID; @@ -15,8 +14,6 @@ public class NickoProfile implements Cloneable { private static final Nicko instance = Nicko.getInstance(); private static final PlayerDataStore dataStore = instance.getDataStore(); - private final PlayerNameStore nameStore = instance.getNameStore(); - private String name; private String skin; private Language language; From a1919caa2ab65752f2ffe655abae5a0f620e6f41 Mon Sep 17 00:00:00 2001 From: ineanto Date: Sat, 16 Nov 2024 18:10:57 +0100 Subject: [PATCH 243/296] feat: removed Metrics, updated loc files, enabled skulls again in GUI --- build.gradle.kts | 54 ++++++++++++++----- src/main/java/xyz/ineanto/nicko/Nicko.java | 6 +-- .../nicko/appearance/AppearanceManager.java | 11 ++-- .../gui/items/admin/ManageCacheItem.java | 14 ++++- .../gui/items/appearance/ChangeSkinItem.java | 16 +++++- src/main/resources/en.yml | 4 +- src/main/resources/plugin.yml | 2 +- 7 files changed, 79 insertions(+), 28 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 0dcc0cc..9d58da8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,7 @@ +import io.papermc.paperweight.userdev.ReobfArtifactConfiguration +import io.papermc.paperweight.util.path +import xyz.jpenilla.runtask.RunExtension + plugins { id("java") id("com.gradleup.shadow") version "8.3.2" @@ -45,16 +49,17 @@ dependencies { compileOnly("me.clip:placeholderapi:2.11.5") compileOnly("net.kyori:adventure-api:4.17.0") - implementation("xyz.xenondevs.invui:invui:1.39") - implementation("net.wesjd:anvilgui:1.10.2-SNAPSHOT") + implementation("xyz.xenondevs.invui:invui-core:1.41") + implementation("xyz.xenondevs.invui:inventory-access-r21:1.41") + + implementation("net.wesjd:anvilgui:1.10.3-SNAPSHOT") implementation("com.github.jsixface:yamlconfig:1.2") implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.18.1") implementation("com.fasterxml.jackson.core:jackson-core:2.18.1") - implementation("com.mysql:mysql-connector-j:8.2.0") - implementation("org.mariadb.jdbc:mariadb-java-client:3.3.1") - implementation("redis.clients:jedis:5.1.2") + implementation("com.mysql:mysql-connector-j:9.1.0") + implementation("org.mariadb.jdbc:mariadb-java-client:3.5.0") + implementation("redis.clients:jedis:5.2.0") implementation("com.google.code.gson:gson:2.10.1") - implementation("org.bstats:bstats-bukkit:3.0.2") testImplementation("com.github.MockBukkit:MockBukkit:v3.133.2") testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.2") @@ -62,7 +67,12 @@ dependencies { testImplementation("org.junit.jupiter:junit-jupiter:5.10.2") } +paperweight { + reobfArtifactConfiguration = ReobfArtifactConfiguration.REOBF_PRODUCTION +} + tasks { + processResources { from("src/main/resources") duplicatesStrategy = DuplicatesStrategy.EXCLUDE @@ -72,12 +82,6 @@ tasks { } shadowJar { - // NAMING - archiveBaseName.set("nicko") - archiveVersion.set(version.toString()) - archiveAppendix.set("") - archiveClassifier.set("") - // RELOCATIONS relocate("xyz.xenondevs", "xyz.ineanto.nicko.libs.invui") relocate("me.clip", "xyz.ineanto.nicko.libs.placeholderapi") @@ -113,10 +117,30 @@ tasks { exclude(dependency("net.wesjd:.*")) exclude(dependency("org.bstats:.*")) } + + manifest { + attributes["paperweight-mappings-namespace"] = "spigot" + } } runServer { - dependsOn(shadowJar) + dependsOn(reobfJar) + + + /** + * https://github.com/jpenilla/run-task/issues/56 + * + * jpenilla: + * "On 1.20.5+ it makes no sense to waste time obfuscating the jar in development + * just for it to be immediately deobfuscated. + * If you have an edge case setup where this makes sense somehow, + * you can disable plugin jar detection and configure the plugin jars collection yourself." + * + * Well, Nicko is an edge case. + * AnvilGUI and InvUI are still using Spigot Mappings, + * and I'm stuck using them until they push a major, breaking update. + */ + args("-add-plugin=${reobfJar.get().outputJar.path.toAbsolutePath()}") downloadPlugins { url("https://download.luckperms.net/1554/bukkit/loader/LuckPerms-Bukkit-5.4.139.jar") @@ -130,4 +154,8 @@ tasks { minecraftVersion("1.21.3") } +} + +extensions.configure { + disablePluginJarDetection() } \ No newline at end of file diff --git a/src/main/java/xyz/ineanto/nicko/Nicko.java b/src/main/java/xyz/ineanto/nicko/Nicko.java index 2d26f84..fcd8a3c 100644 --- a/src/main/java/xyz/ineanto/nicko/Nicko.java +++ b/src/main/java/xyz/ineanto/nicko/Nicko.java @@ -1,7 +1,6 @@ package xyz.ineanto.nicko; import com.comphenix.protocol.utility.MinecraftVersion; -import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.command.PluginCommand; @@ -40,7 +39,6 @@ public class Nicko extends JavaPlugin { private CustomLanguage customLanguage; private PlayerNameStore nameStore; private RandomNameFetcher nameFetcher; - private Metrics metrics; public Nicko() { this.unitTesting = false; @@ -66,7 +64,7 @@ public class Nicko extends JavaPlugin { if (!MinecraftVersion.TRAILS_AND_TAILS.atOrAbove()) { getLogger().severe("This version (" + MinecraftVersion.getCurrentVersion().getVersion() + ") is not supported by Nicko!"); - getLogger().severe("As of version 1.2.0, Nicko only supports the latest Minecraft versions. (Currently 1.21.3)"); + getLogger().severe("As of version 1.2.0, Nicko only supports the latest Minecraft version. (Currently 1.21.3)"); dataStore.getStorage().setError(true); Bukkit.getPluginManager().disablePlugin(this); } @@ -131,7 +129,6 @@ public class Nicko extends JavaPlugin { getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this); getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this); - metrics = new Metrics(this, 20483); } getLogger().info("Nicko has been enabled."); @@ -150,7 +147,6 @@ public class Nicko extends JavaPlugin { if (!unitTesting) { nameStore.clearStoredNames(); - metrics.shutdown(); } getLogger().info("Nicko (Bukkit) has been disabled."); } diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index fba9286..c959219 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -27,16 +27,17 @@ public class AppearanceManager { public ActionResult reset() { final NickoProfile profile = getNickoProfile(); final String defaultName = nameStore.getStoredName(player); + profile.setName(defaultName); profile.setSkin(defaultName); dataStore.getCache().cache(player.getUniqueId(), profile); final ActionResult result = update(true, true); - if (!result.isError()) { - profile.setName(null); - profile.setSkin(null); - dataStore.getCache().cache(player.getUniqueId(), profile); - } + + profile.setName(null); + profile.setSkin(null); + dataStore.getCache().cache(player.getUniqueId(), profile); + return result; } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java index a14baa5..4cad150 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/ManageCacheItem.java @@ -8,9 +8,14 @@ import org.jetbrains.annotations.NotNull; import xyz.ineanto.nicko.gui.CacheManagementGUI; import xyz.ineanto.nicko.language.LanguageKey; import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.xenondevs.invui.item.builder.AbstractItemBuilder; 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 xyz.xenondevs.invui.util.MojangApiUtils; + +import java.io.IOException; public class ManageCacheItem extends AsyncItem { public ManageCacheItem(PlayerLanguage playerLanguage) { @@ -19,7 +24,14 @@ public class ManageCacheItem extends AsyncItem { return playerLanguage.translateItem(builder, LanguageKey.GUI.LOADING); }, (click -> true)).getItemProvider(), () -> { - final ItemBuilder builder = new ItemBuilder(Material.PLAYER_HEAD); + AbstractItemBuilder builder; + + try { + builder = new SkullBuilder("Notch"); + } catch (MojangApiUtils.MojangApiException | IOException e) { + builder = new ItemBuilder(Material.PLAYER_HEAD); + } + return playerLanguage.translateItem(builder, LanguageKey.GUI.Admin.MANAGE_CACHE); }); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java index 24927b3..e334b7f 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java @@ -6,19 +6,33 @@ import org.bukkit.event.inventory.ClickType; import xyz.ineanto.nicko.anvil.AnvilManager; import xyz.ineanto.nicko.language.LanguageKey; import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.xenondevs.invui.item.builder.AbstractItemBuilder; import xyz.xenondevs.invui.item.builder.ItemBuilder; +import xyz.xenondevs.invui.item.builder.SkullBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; +import xyz.xenondevs.invui.util.MojangApiUtils; + +import java.io.IOException; public class ChangeSkinItem { private final PlayerLanguage playerLanguage; + private final Player player; public ChangeSkinItem(Player player) { this.playerLanguage = new PlayerLanguage(player); + this.player = player; } public SuppliedItem get() { return new SuppliedItem(() -> { - final ItemBuilder builder = new ItemBuilder(Material.PLAYER_HEAD); + AbstractItemBuilder builder; + + try { + builder = new SkullBuilder(player.getName()); + } catch (MojangApiUtils.MojangApiException | IOException e) { + builder = new ItemBuilder(Material.PLAYER_HEAD); + } + return playerLanguage.translateItem(builder, LanguageKey.GUI.Home.CHANGE_SKIN); }, click -> { final ClickType clickType = click.getClickType(); diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 14248b6..a31e7b4 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -20,10 +20,10 @@ event: appearance: set: error: "Wasn''t able to apply your disguise! ({0})" - ok: "You're now disguised." + ok: "You''re now disguised." restore: error: "Wasn''t able to apply the previous disguise! ({0})" - ok: "Disguise restored from last time." + ok: "Previous disguise restored." remove: error: "Wasn''t able to remove your disguise!." missing: "You''re not currently disguised." diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 6f525c4..08b70ce 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -3,7 +3,7 @@ main: xyz.ineanto.nicko.Nicko version: ${version} author: Ineanto description: "The feature packed, next generation disguise plugin for Minecraft." -api-version: 1.20 +api-version: 1.21 softdepend: [ PlaceholderAPI ] depend: - ProtocolLib From ea3fa9b52ecb1526e3f5a96f99befc82e9b585c3 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 20 Nov 2024 20:22:47 +0100 Subject: [PATCH 244/296] feat: removed deadlock from reset/update, updated items/translations --- .../xyz/ineanto/nicko/anvil/AnvilManager.java | 10 ++++++---- .../nicko/appearance/AppearanceManager.java | 20 ++++++++++++------- .../gui/items/admin/cache/CacheEntryItem.java | 4 +++- .../admin/cache/InvalidateCacheItem.java | 2 ++ .../admin/check/PlayerInformationItem.java | 4 +++- .../gui/items/appearance/ChangeSkinItem.java | 6 +++++- .../nicko/gui/items/home/AdminAccessItem.java | 2 +- .../nicko/gui/items/home/RandomSkinItem.java | 8 ++++---- .../nicko/gui/items/home/ResetItem.java | 2 +- .../nicko/packet/InternalPacketSender.java | 2 +- src/main/resources/en.yml | 2 +- src/main/resources/fr.yml | 2 +- 12 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java index db7a7cd..7e6fc26 100644 --- a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java @@ -4,6 +4,7 @@ import net.kyori.adventure.text.Component; import net.wesjd.anvilgui.AnvilGUI; import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.Sound; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; @@ -11,8 +12,8 @@ import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.appearance.AppearanceManager; import xyz.ineanto.nicko.event.custom.PlayerDisguiseEvent; -import xyz.ineanto.nicko.language.PlayerLanguage; import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.language.PlayerLanguage; import xyz.ineanto.nicko.mojang.MojangUtils; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.PlayerDataStore; @@ -116,14 +117,15 @@ public class AnvilManager { final ActionResult actionResult = appearanceManager.update(skinChange, false); if (!actionResult.isError()) { - player.sendMessage(playerLanguage.translate(LanguageKey.Event.Appearance.Set.OK, true)); + player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Appearance.Set.OK)); + player.playSound(player, Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1, 1f); } else { player.sendMessage( - playerLanguage.translate( + playerLanguage.translateWithOops( LanguageKey.Event.Appearance.Set.ERROR, - true, playerLanguage.translate(actionResult.getErrorKey(), false) )); + player.playSound(player, Sound.BLOCK_ANVIL_PLACE, 0.5f, 1f); } return Collections.singletonList(AnvilGUI.ResponseAction.close()); } diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index c959219..465ccf7 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -24,7 +24,7 @@ public class AppearanceManager { this.packetSender = new InternalPacketSender(player, getNickoProfile()); } - public ActionResult reset() { + public ActionResult reset(boolean apply) { final NickoProfile profile = getNickoProfile(); final String defaultName = nameStore.getStoredName(player); @@ -32,13 +32,17 @@ public class AppearanceManager { profile.setSkin(defaultName); dataStore.getCache().cache(player.getUniqueId(), profile); - final ActionResult result = update(true, true); + if (apply) { + final ActionResult result = update(true, true); - profile.setName(null); - profile.setSkin(null); - dataStore.getCache().cache(player.getUniqueId(), profile); + profile.setName(null); + profile.setSkin(null); + dataStore.getCache().cache(player.getUniqueId(), profile); - return result; + return result; + } + + return ActionResult.ok(); } public ActionResult update(boolean skinChange, boolean reset) { @@ -47,7 +51,9 @@ public class AppearanceManager { final ActionResult result = packetSender.sendGameProfileUpdate(displayName, skinChange, reset); - if (result.isError()) { reset(); } + if (result.isError()) { + return reset(false); + } packetSender.sendEntityMetadataUpdate(); packetSender.sendTabListUpdate(displayName); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java index cdf7c90..e7207d2 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java @@ -2,6 +2,7 @@ package xyz.ineanto.nicko.gui.items.admin.cache; import net.kyori.adventure.text.Component; import org.bukkit.Material; +import org.bukkit.Sound; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; @@ -55,7 +56,8 @@ public class CacheEntryItem extends AsyncItem { @Override public void onConfirm() { final PlayerLanguage playerLanguage = new PlayerLanguage(player); - player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Admin.Cache.INVALIDATE_ENTRY, name)); + player.sendMessage(playerLanguage.translate(LanguageKey.Event.Admin.Cache.INVALIDATE_ENTRY, true, name)); + player.playSound(player, Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1, 1f); mojangAPI.eraseFromCache(uuid); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java index 55ffbf9..be4a0ac 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java @@ -1,6 +1,7 @@ package xyz.ineanto.nicko.gui.items.admin.cache; import org.bukkit.Material; +import org.bukkit.Sound; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import xyz.ineanto.nicko.Nicko; @@ -28,6 +29,7 @@ public class InvalidateCacheItem { final Player player = click.getPlayer(); final PlayerLanguage playerLanguage = new PlayerLanguage(player); player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Admin.Cache.INVALIDATE_CACHE)); + player.playSound(player, Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1, 1f); Nicko.getInstance().getMojangAPI().getSkinCache().invalidateAll(); return true; } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java index a439944..ff0a506 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java @@ -2,6 +2,7 @@ package xyz.ineanto.nicko.gui.items.admin.check; import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.Sound; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; @@ -77,7 +78,8 @@ public class PlayerInformationItem extends AsyncItem { @Override public void onConfirm() { final AppearanceManager appearanceManager = new AppearanceManager(target); - appearanceManager.reset(); + appearanceManager.reset(true); + player.playSound(player, Sound.ENTITY_VILLAGER_TRADE, 1, 1f); player.sendMessage(playerLanguage.translate(LanguageKey.Event.Admin.Check.REMOVE_SKIN, true, target.getName())); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java index e334b7f..8753fff 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java @@ -3,9 +3,11 @@ package xyz.ineanto.nicko.gui.items.appearance; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.anvil.AnvilManager; import xyz.ineanto.nicko.language.LanguageKey; import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.storage.name.PlayerNameStore; import xyz.xenondevs.invui.item.builder.AbstractItemBuilder; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.builder.SkullBuilder; @@ -16,10 +18,12 @@ import java.io.IOException; public class ChangeSkinItem { private final PlayerLanguage playerLanguage; + private final PlayerNameStore playerNameStore; private final Player player; public ChangeSkinItem(Player player) { this.playerLanguage = new PlayerLanguage(player); + this.playerNameStore = Nicko.getInstance().getNameStore(); this.player = player; } @@ -28,7 +32,7 @@ public class ChangeSkinItem { AbstractItemBuilder builder; try { - builder = new SkullBuilder(player.getName()); + builder = new SkullBuilder(playerNameStore.getStoredName(player)); } catch (MojangApiUtils.MojangApiException | IOException e) { builder = new ItemBuilder(Material.PLAYER_HEAD); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java index 107db6f..3510058 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/AdminAccessItem.java @@ -18,7 +18,7 @@ public class AdminAccessItem { public SuppliedItem get() { return new SuppliedItem(() -> { - final ItemBuilder builder = new ItemBuilder(Material.SCAFFOLDING); + final ItemBuilder builder = new ItemBuilder(Material.COMMAND_BLOCK); return playerLanguage.translateItem(builder, LanguageKey.GUI.Home.ADMIN); }, click -> { final ClickType clickType = click.getClickType(); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java index 9753c3c..d15cee5 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java @@ -25,7 +25,7 @@ public class RandomSkinItem { public SuppliedItem get() { return new SuppliedItem(() -> { - final ItemBuilder builder = new ItemBuilder(Material.SPAWNER); + final ItemBuilder builder = new ItemBuilder(Material.WIND_CHARGE); return playerLanguage.translateItem(builder, LanguageKey.GUI.Home.RANDOM_SKIN); }, (event) -> { final Player player = event.getPlayer(); @@ -42,14 +42,14 @@ public class RandomSkinItem { final AppearanceManager appearanceManager = new AppearanceManager(player); final ActionResult result = appearanceManager.update(true, false); if (!result.isError()) { - player.sendMessage(playerLanguage.translate(LanguageKey.Event.Appearance.Set.OK, true)); + player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Appearance.Set.OK)); } else { - player.sendMessage(playerLanguage.translate( + player.sendMessage(playerLanguage.translateWithOops( LanguageKey.Event.Appearance.Set.ERROR, - true, playerLanguage.translate(result.getErrorKey(), false) ) ); + appearanceManager.reset(false); } }); return true; diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java index 2e8fb1c..2903caf 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java @@ -36,7 +36,7 @@ public class ResetItem { } final AppearanceManager appearanceManager = new AppearanceManager(player); - if (!appearanceManager.reset().isError()) { + if (!appearanceManager.reset(true).isError()) { player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Appearance.Remove.OK)); } else { player.sendMessage(playerLanguage.translateWithOops(LanguageKey.Event.Appearance.Remove.ERROR)); diff --git a/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java b/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java index 6af2f67..5626bab 100644 --- a/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java +++ b/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java @@ -73,7 +73,7 @@ public class InternalPacketSender implements PacketSender { @Override public ActionResult sendGameProfileUpdate(String name, boolean skinChange, boolean reset) { - final GameProfile gameProfile = ((CraftPlayer) player).getProfile(); + final GameProfile gameProfile = new GameProfile(player.getUniqueId(), name); // TODO (Ineanto, 31/10/2024): Could this be refactored to get rid of the boolean? if (skinChange) { diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index a31e7b4..887ebce 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -94,7 +94,7 @@ gui: change_both: name: "Change both" random_skin: - name: "Get a random appearance!" + name: "I feel lucky!" reset: name: "Reset appearance" lore: diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index a17c532..eb92b7b 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -95,7 +95,7 @@ gui: change_both: name: "Changer les deux" random_skin: - name: "Obtenir une apparence aléatoire !" + name: "Je me sens chanceux !" reset: name: "Réinitialiser l'apparence" lore: From 3d5ef0f0205594355df7ee0c98703acc39029370 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 21 Nov 2024 12:43:06 +0100 Subject: [PATCH 245/296] fix: play sound at location --- src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java | 4 ++-- .../ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java | 2 +- .../nicko/gui/items/admin/cache/InvalidateCacheItem.java | 2 +- .../nicko/gui/items/admin/check/PlayerInformationItem.java | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java index 7e6fc26..5e326d6 100644 --- a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java +++ b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java @@ -118,14 +118,14 @@ public class AnvilManager { final ActionResult actionResult = appearanceManager.update(skinChange, false); if (!actionResult.isError()) { player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Appearance.Set.OK)); - player.playSound(player, Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1, 1f); + player.playSound(player.getLocation(), Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1, 1f); } else { player.sendMessage( playerLanguage.translateWithOops( LanguageKey.Event.Appearance.Set.ERROR, playerLanguage.translate(actionResult.getErrorKey(), false) )); - player.playSound(player, Sound.BLOCK_ANVIL_PLACE, 0.5f, 1f); + player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_PLACE, 1f, 1f); } return Collections.singletonList(AnvilGUI.ResponseAction.close()); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java index e7207d2..4fee213 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java @@ -57,7 +57,7 @@ public class CacheEntryItem extends AsyncItem { public void onConfirm() { final PlayerLanguage playerLanguage = new PlayerLanguage(player); player.sendMessage(playerLanguage.translate(LanguageKey.Event.Admin.Cache.INVALIDATE_ENTRY, true, name)); - player.playSound(player, Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1, 1f); + player.playSound(player.getLocation(), Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1, 1f); mojangAPI.eraseFromCache(uuid); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java index be4a0ac..2614497 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/InvalidateCacheItem.java @@ -29,7 +29,7 @@ public class InvalidateCacheItem { final Player player = click.getPlayer(); final PlayerLanguage playerLanguage = new PlayerLanguage(player); player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Admin.Cache.INVALIDATE_CACHE)); - player.playSound(player, Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1, 1f); + player.playSound(player.getLocation(), Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1, 1f); Nicko.getInstance().getMojangAPI().getSkinCache().invalidateAll(); return true; } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java index ff0a506..bc01434 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java @@ -13,8 +13,8 @@ import xyz.ineanto.nicko.gui.ChoiceGUI; import xyz.ineanto.nicko.gui.PlayerCheckGUI; import xyz.ineanto.nicko.gui.items.ItemDefaults; import xyz.ineanto.nicko.gui.items.common.choice.ChoiceCallback; -import xyz.ineanto.nicko.language.PlayerLanguage; import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.language.PlayerLanguage; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.xenondevs.invui.item.builder.AbstractItemBuilder; import xyz.xenondevs.invui.item.builder.ItemBuilder; @@ -79,7 +79,7 @@ public class PlayerInformationItem extends AsyncItem { public void onConfirm() { final AppearanceManager appearanceManager = new AppearanceManager(target); appearanceManager.reset(true); - player.playSound(player, Sound.ENTITY_VILLAGER_TRADE, 1, 1f); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_TRADE, 1, 1f); player.sendMessage(playerLanguage.translate(LanguageKey.Event.Admin.Check.REMOVE_SKIN, true, target.getName())); } From 7ba8a26af6429dfd00836caf9356846ef4f7c88c Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 25 Nov 2024 20:49:24 +0100 Subject: [PATCH 246/296] fix: chat session no longer broken and item translated correctly --- CHANGELOG.log | 4 +++- .../nicko/gui/items/admin/cache/CacheEntryItem.java | 10 +++++----- .../xyz/ineanto/nicko/packet/InternalPacketSender.java | 10 ++++++---- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.log b/CHANGELOG.log index 7f84db4..3cd81a6 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,10 +1,12 @@ 1.2.0: Update n°13 (XX/XX/24) [FEATURES] - - Players are now able to save disguises as presets. + - Players are now able to mark disguises as favorites. - Modernized the messages and added various sound effects upon interacting with the plugin. + - Made GUIs names cleaner. [FIXES] - Fixed an oversight preventing the configuration from properly being migrated. + - Fixed the placeholder item in the skin cache invalidation not being translated. [LANGUAGE] - Moved the prefix to the language file. diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java index 4fee213..ae8a9d6 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java @@ -1,6 +1,5 @@ package xyz.ineanto.nicko.gui.items.admin.cache; -import net.kyori.adventure.text.Component; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; @@ -18,6 +17,7 @@ import xyz.ineanto.nicko.mojang.MojangAPI; 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 xyz.xenondevs.invui.util.MojangApiUtils; import java.io.IOException; @@ -29,10 +29,10 @@ public class CacheEntryItem extends AsyncItem { private final MojangAPI mojangAPI = Nicko.getInstance().getMojangAPI(); public CacheEntryItem(PlayerLanguage playerLanguage, String uuid) { - super(new ItemBuilder(Material.PAINTING) - .setDisplayName( - Component.text(playerLanguage.translate(LanguageKey.GUI.LOADING, false)).content() - ), + super(new SuppliedItem(() -> { + final ItemBuilder builder = new ItemBuilder(Material.PAINTING); + return playerLanguage.translateItem(builder, LanguageKey.GUI.LOADING); + }, (click -> true)).getItemProvider(), () -> { final String dashedUuid = uuid.replaceAll("(.{8})(.{4})(.{4})(.{4})(.+)", "$1-$2-$3-$4-$5"); final UUID uuidObject = UUID.fromString(dashedUuid); diff --git a/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java b/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java index 5626bab..bbb41a3 100644 --- a/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java +++ b/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java @@ -4,7 +4,9 @@ import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; import com.mojang.authlib.properties.PropertyMap; import it.unimi.dsi.fastutil.ints.IntList; +import net.minecraft.Optionull; import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.RemoteChatSession; import net.minecraft.network.chat.contents.PlainTextContents; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.*; @@ -141,14 +143,14 @@ public class InternalPacketSender implements PacketSender { ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY); final List entries = List.of(new ClientboundPlayerInfoUpdatePacket.Entry( - player.getUniqueId(), + serverPlayer.getUUID(), serverPlayer.gameProfile, true, - player.getPing(), + serverPlayer.connection.latency(), serverPlayer.gameMode.getGameModeForPlayer(), MutableComponent.create(new PlainTextContents.LiteralContents(displayName)), - 1, - null + serverPlayer.getTabListOrder(), + Optionull.map(serverPlayer.getChatSession(), RemoteChatSession::asData) )); final ClientboundPlayerInfoUpdatePacket update = new ClientboundPlayerInfoUpdatePacket(actions, entries); From ff892a7451ae882879e9b220134a5bca283677f0 Mon Sep 17 00:00:00 2001 From: ineanto Date: Tue, 26 Nov 2024 09:03:46 +0100 Subject: [PATCH 247/296] feat: papi expension --- .../ineanto/nicko/placeholder/NickoExpansion.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java b/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java index a592b8d..b51455a 100644 --- a/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java +++ b/src/main/java/xyz/ineanto/nicko/placeholder/NickoExpansion.java @@ -29,7 +29,7 @@ public class NickoExpansion extends PlaceholderExpansion { @Override public @NotNull String getVersion() { - return "1.0.0"; + return "1.0.1"; } @Override @@ -51,15 +51,8 @@ public class NickoExpansion extends PlaceholderExpansion { final Optional optionalProfile = instance.getDataStore().getData(player.getUniqueId()); if (optionalProfile.isPresent()) { final NickoProfile profile = optionalProfile.get(); - if (profile.hasData()) { - if (profile.getName() != null) { - name = profile.getName(); - } - - if (profile.getSkin() != null) { - skin = profile.getSkin(); - } - } + name = profile.getName() == null ? player.getName() : profile.getName(); + skin = profile.getSkin() == null ? player.getName() : profile.getSkin(); locale = profile.getLocale().getName(); randomSkin = profile.isRandomSkin(); } From a996858ba99ec1d7add5f9c86925b3551fda82a9 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 20 Mar 2025 18:50:06 +0100 Subject: [PATCH 248/296] feat: switch to paperweight and create plugin loader --- .gitignore | 5 +- .idea/gradle.xml | 1 + build.gradle.kts | 99 +++++------------ gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 5 +- gradlew | 43 +++++--- gradlew.bat | 37 ++++--- .../nicko/loader/NickoPluginLoader.java | 20 ++++ .../nicko/packet/InternalPacketSender.java | 3 +- .../wrapper/WrapperPlayServerRespawn.java | 64 ++++++++--- .../ineanto/nicko/test/NickoPluginTest.java | 33 ------ .../nicko/test/appearance/RandomNameTest.java | 38 ------- .../nicko/test/config/ConfigurationTest.java | 35 ------ .../test/config/ConfigurationVersionTest.java | 63 ----------- .../nicko/test/i18n/ItemTranslationTest.java | 56 ---------- .../nicko/test/i18n/TranslationTest.java | 36 ------ .../nicko/test/migration/MigrationTest.java | 73 ------------ .../nicko/test/storage/MapCacheTest.java | 42 ------- .../nicko/test/storage/RedisCacheTest.java | 78 ------------- .../nicko/test/storage/SQLStorageTest.java | 104 ------------------ 20 files changed, 155 insertions(+), 680 deletions(-) create mode 100644 src/main/java/xyz/ineanto/nicko/loader/NickoPluginLoader.java delete mode 100644 src/test/java/xyz/ineanto/nicko/test/NickoPluginTest.java delete mode 100644 src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java delete mode 100644 src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java delete mode 100644 src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java delete mode 100644 src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java delete mode 100644 src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java delete mode 100644 src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java delete mode 100644 src/test/java/xyz/ineanto/nicko/test/storage/MapCacheTest.java delete mode 100644 src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java delete mode 100644 src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java diff --git a/.gitignore b/.gitignore index 8a238de..077cc42 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,7 @@ bin/ !**/src/test/**/bin/ ### Server ### -run/ \ No newline at end of file +run/ + +### Private ### +TODO \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 89022a7..1b86f21 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -5,6 +5,7 @@

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 /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +133,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,11 +200,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ @@ -205,6 +216,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index ac1b06f..9b42019 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,8 +13,10 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +27,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -56,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -75,13 +78,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/src/main/java/xyz/ineanto/nicko/loader/NickoPluginLoader.java b/src/main/java/xyz/ineanto/nicko/loader/NickoPluginLoader.java new file mode 100644 index 0000000..1f0f511 --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/loader/NickoPluginLoader.java @@ -0,0 +1,20 @@ +package xyz.ineanto.nicko.loader; + +import io.papermc.paper.plugin.loader.PluginClasspathBuilder; +import io.papermc.paper.plugin.loader.PluginLoader; +import io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.repository.RemoteRepository; + +public class NickoPluginLoader implements PluginLoader { + @Override + public void classloader(PluginClasspathBuilder pluginClasspathBuilder) { + final MavenLibraryResolver resolver = new MavenLibraryResolver(); + resolver.addRepository(new RemoteRepository.Builder("xenondevs", "default", "https://repo.xenondevs.xyz/releases/").build()); + resolver.addRepository(new RemoteRepository.Builder("wesjd", "default", "https://repo.codemc.io/repository/maven-snapshots/").build()); + resolver.addDependency(new Dependency(new DefaultArtifact("xyz.xenondevs.invui:invui:pom:1.44"), null)); + resolver.addDependency(new Dependency(new DefaultArtifact("net:wesjd:anvilgui:1.10.4-SNAPSHOT"), null)); + pluginClasspathBuilder.addLibrary(resolver); + } +} diff --git a/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java b/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java index bbb41a3..d1796cb 100644 --- a/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java +++ b/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java @@ -149,6 +149,7 @@ public class InternalPacketSender implements PacketSender { serverPlayer.connection.latency(), serverPlayer.gameMode.getGameModeForPlayer(), MutableComponent.create(new PlainTextContents.LiteralContents(displayName)), + true, serverPlayer.getTabListOrder(), Optionull.map(serverPlayer.getChatSession(), RemoteChatSession::asData) )); @@ -165,4 +166,4 @@ public class InternalPacketSender implements PacketSender { private void sendPacket(Packet packet, Player player) { (((CraftPlayer) player).getHandle()).connection.send(packet); } -} +} \ No newline at end of file diff --git a/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerRespawn.java b/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerRespawn.java index dc71b1f..f746450 100644 --- a/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerRespawn.java +++ b/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerRespawn.java @@ -3,7 +3,11 @@ package xyz.ineanto.nicko.packet.wrapper; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.events.InternalStructure; import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.StructureModifier; +import com.comphenix.protocol.reflect.accessors.Accessors; +import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; +import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.wrappers.BukkitConverters; import com.comphenix.protocol.wrappers.EnumWrappers; @@ -13,8 +17,11 @@ import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.World; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.RecordComponent; +import java.util.Arrays; /** * PacketPlayServerRespawn Wrapper class (1.20.X to 1.21.X) @@ -56,24 +63,49 @@ public class WrapperPlayServerRespawn extends AbstractPacket { } else { // 1.20.5 to 1.21.1 - /* - Honestly, I've tried everything to make this work. - Fields inside the CommonPlayerSpawnInfo are Record Components and are - marked final. - - This would work with some trickery involved, but here's the - caveat: Record Components/Fields and are immutable by DESIGN. - So... here we are now, stopped right in my track by Java's language design and Mojang themselves. - */ - try { - final Object spawnInfoStructureHandle = spawnInfoStructure.getHandle(); - final RecordComponent[] components = spawnInfoStructureHandle.getClass().getRecordComponents(); + final Class spawnInfoClass = MinecraftReflection.getMinecraftClass("network.protocol.game.CommonPlayerSpawnInfo"); - final Field levelKeyField = spawnInfoStructureHandle.getClass().getDeclaredField(components[1].getAccessor().getName()); - levelKeyField.setAccessible(true); - levelKeyField.set(spawnInfoStructureHandle, BukkitConverters.getWorldKeyConverter().getGeneric(Bukkit.getWorld("world"))); - } catch (NoSuchFieldException | IllegalAccessException e) { + Class[] componentTypes = Arrays.stream(spawnInfoClass.getRecordComponents()) + .map(RecordComponent::getType) + .toArray(Class[]::new); + final Constructor spawnInfoConstructor = spawnInfoClass.getDeclaredConstructor(componentTypes); + + /** + * Holder dimensionType, + * ResourceKey dimension, + * long seed, + * GameType gameType, + * GameType previousGameType, + * boolean isDebug, + * boolean isFlat, + * Optional lastDeathLocation, + * int portalCooldown + */ + + final World world = Bukkit.getWorld("world"); + + FuzzyReflection.fromClass(spawnInfoClass).getConstructor( + FuzzyMethodContract + .newBuilder() + .build() + ); + + final Object spawnInfo = spawnInfoConstructor.newInstance( + BukkitConverters.getDimensionConverter().getGeneric(world), + BukkitConverters.getWorldKeyConverter().getGeneric(world), + world.getSeed(), + EnumWrappers.getGameModeConverter().getGeneric(EnumWrappers.NativeGameMode.fromBukkit(GameMode.SURVIVAL)), + EnumWrappers.getGameModeConverter().getGeneric(EnumWrappers.NativeGameMode.fromBukkit(GameMode.SURVIVAL)), + false, + false, + BukkitConverters.getSectionPositionConverter() + ); + + final Field commonSpawnDataField = Accessors.getFieldAccessor(TYPE.getPacketClass(), spawnInfoClass, true).getField(); + commonSpawnDataField.set(spawnInfoStructure.getHandle(), spawnInfo); + } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException | + InstantiationException e) { throw new RuntimeException(); } } diff --git a/src/test/java/xyz/ineanto/nicko/test/NickoPluginTest.java b/src/test/java/xyz/ineanto/nicko/test/NickoPluginTest.java deleted file mode 100644 index 5ce3aea..0000000 --- a/src/test/java/xyz/ineanto/nicko/test/NickoPluginTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package xyz.ineanto.nicko.test; - -import be.seeseemelk.mockbukkit.MockBukkit; -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.ineanto.nicko.Nicko; -import xyz.ineanto.nicko.config.Configuration; - -import static org.junit.jupiter.api.Assertions.assertNotNull; - -public class NickoPluginTest { - private static Nicko plugin; - - @BeforeAll - public static void setup() { - final Configuration config = Configuration.DEFAULT; - MockBukkit.mock(); - plugin = MockBukkit.load(Nicko.class, config); - } - - @Test - @DisplayName("Plugin Initialization") - public void initializePlugin() { - assertNotNull(plugin); - } - - @AfterAll - public static void shutdown() { - MockBukkit.unmock(); - } -} diff --git a/src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java b/src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java deleted file mode 100644 index 057c076..0000000 --- a/src/test/java/xyz/ineanto/nicko/test/appearance/RandomNameTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package xyz.ineanto.nicko.test.appearance; - -import be.seeseemelk.mockbukkit.MockBukkit; -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.ineanto.nicko.Nicko; -import xyz.ineanto.nicko.appearance.random.RandomNameFetcher; -import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.mojang.MojangUtils; - -import static org.junit.jupiter.api.Assertions.*; - -public class RandomNameTest { - private static Nicko plugin; - - @BeforeAll - public static void setup() { - final Configuration config = Configuration.DEFAULT; - MockBukkit.mock(); - plugin = MockBukkit.load(Nicko.class, config); - } - - @Test - @DisplayName("Get random name") - public void getRandomName() { - final RandomNameFetcher randomNameFetcher = new RandomNameFetcher(plugin); - final String username = randomNameFetcher.getRandomUsername(); - assertNotNull(username); - assertFalse(MojangUtils.isUsernameInvalid(username)); - } - - @AfterAll - public static void shutdown() { - MockBukkit.unmock(); - } -} diff --git a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java b/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java deleted file mode 100644 index 4a371fa..0000000 --- a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package xyz.ineanto.nicko.test.config; - -import be.seeseemelk.mockbukkit.MockBukkit; -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.ineanto.nicko.Nicko; -import xyz.ineanto.nicko.config.Configuration; - -import static org.junit.jupiter.api.Assertions.assertFalse; - -public class ConfigurationTest { - private static Nicko plugin; - - @BeforeAll - public static void setup() { - MockBukkit.mock(); - final Configuration config = Configuration.DEFAULT; - plugin = MockBukkit.load(Nicko.class, config); - } - - @Test - @DisplayName("Read configuration") - public void readConfiguration() { - final Configuration configuration = plugin.getNickoConfig(); - assertFalse(configuration.getSqlConfiguration().isEnabled()); - assertFalse(configuration.getRedisConfiguration().isEnabled()); - } - - @AfterAll - public static void shutdown() { - MockBukkit.unmock(); - } -} diff --git a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java b/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java deleted file mode 100644 index d13fa80..0000000 --- a/src/test/java/xyz/ineanto/nicko/test/config/ConfigurationVersionTest.java +++ /dev/null @@ -1,63 +0,0 @@ -package xyz.ineanto.nicko.test.config; - -import be.seeseemelk.mockbukkit.MockBukkit; -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.ineanto.nicko.Nicko; -import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.config.DefaultDataSources; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class ConfigurationVersionTest { - @BeforeAll - public static void setup() { - MockBukkit.mock(); - final Configuration configuration = Configuration.DEFAULT; - MockBukkit.load(Nicko.class, configuration); - } - - @Test - @DisplayName("Compare configuration version") - public void compareConfigurationVersion() { - final Configuration configuration = Configuration.DEFAULT; - assertEquals(configuration.getVersionObject().compareTo(Configuration.VERSION), 0); - } - - @Test - @DisplayName("Compare newer configuration version") - public void compareNewerConfigurationVersion() { - final Configuration configuration = new Configuration("24.1.0", - DefaultDataSources.SQL_EMPTY, - DefaultDataSources.REDIS_EMPTY, - false); - assertEquals(configuration.getVersionObject().compareTo(Configuration.VERSION), 1); - } - - @Test - @DisplayName("Compare older configuration version") - public void compareOlderConfigurationVersion() { - final Configuration configuration = new Configuration("0.23.3", - DefaultDataSources.SQL_EMPTY, - DefaultDataSources.REDIS_EMPTY, - false); - assertEquals(configuration.getVersionObject().compareTo(Configuration.VERSION), -1); - } - - @Test - @DisplayName("Compare unknown configuration version") - public void compareUnknownConfigurationVersion() { - final Configuration configuration = new Configuration(null, - DefaultDataSources.SQL_EMPTY, - DefaultDataSources.REDIS_EMPTY, - false); - assertEquals(configuration.getVersionObject().compareTo(Configuration.VERSION), -1); - } - - @AfterAll - public static void shutdown() { - MockBukkit.unmock(); - } -} diff --git a/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java b/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java deleted file mode 100644 index 3c17c5d..0000000 --- a/src/test/java/xyz/ineanto/nicko/test/i18n/ItemTranslationTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package xyz.ineanto.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.ineanto.nicko.Nicko; -import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.language.Language; -import xyz.ineanto.nicko.language.PlayerLanguage; -import xyz.ineanto.nicko.language.LanguageKey; -import xyz.ineanto.nicko.language.Translation; - -import static org.junit.jupiter.api.Assertions.*; - -public class ItemTranslationTest { - private static PlayerMock player; - - @BeforeAll - public static void setup() { - final Configuration config = Configuration.DEFAULT; - MockBukkit.mock(); - MockBukkit.load(Nicko.class, config); - } - - @Test - @DisplayName("Translate Item Without Lore") - public void translateItemTranslationWithoutLore() { - final PlayerLanguage playerLanguage = new PlayerLanguage(Language.FRENCH); - final Translation translation = playerLanguage.translateAndReplace(LanguageKey.GUI.GO_BACK); - assertTrue(translation.lore().isEmpty()); - assertEquals(translation.name(), "Retour"); - } - - @Test - @DisplayName("Translate Item") - public void translateItemLore() { - final PlayerLanguage playerLanguage = new PlayerLanguage(Language.FRENCH); - - final Translation test = playerLanguage.translateAndReplace(LanguageKey.GUI.Settings.TOGGLEABLE_BUTTON, "EST", "EST"); - test.lore().forEach(System.out::println); - - final Translation translation = playerLanguage.translateAndReplace(LanguageKey.GUI.Admin.Cache.STATISTICS, "1", "1"); - assertFalse(translation.lore().isEmpty()); - assertEquals("Nombre de requêtes: 1", translation.lore().get(0)); - assertEquals("Nb. de skin dans le cache: 1", translation.lore().get(1)); - assertEquals("Le cache est vidé toutes les 24 heures.", translation.lore().get(2)); - } - - @AfterAll - public static void shutdown() { - MockBukkit.unmock(); - } -} diff --git a/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java b/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java deleted file mode 100644 index bac0c45..0000000 --- a/src/test/java/xyz/ineanto/nicko/test/i18n/TranslationTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package xyz.ineanto.nicko.test.i18n; - -import be.seeseemelk.mockbukkit.MockBukkit; -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.ineanto.nicko.Nicko; -import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.language.Language; -import xyz.ineanto.nicko.language.PlayerLanguage; -import xyz.ineanto.nicko.language.LanguageKey; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class TranslationTest { - @BeforeAll - public static void setup() { - final Configuration config = Configuration.DEFAULT; - MockBukkit.mock(); - MockBukkit.load(Nicko.class, config); - } - - @Test - @DisplayName("Translate Line With Replacement") - public void translateItemTranslationWithoutLore() { - final PlayerLanguage playerLanguage = new PlayerLanguage(Language.FRENCH); - final String translation = playerLanguage.translate(LanguageKey.Event.Settings.ERROR, false, "Test"); - assertEquals("§cImpossible de mettre à jour vos paramètres. §7§o(Test)", translation); - } - - @AfterAll - public static void shutdown() { - MockBukkit.unmock(); - } -} diff --git a/src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java b/src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java deleted file mode 100644 index 170f367..0000000 --- a/src/test/java/xyz/ineanto/nicko/test/migration/MigrationTest.java +++ /dev/null @@ -1,73 +0,0 @@ -package xyz.ineanto.nicko.test.migration; - -import be.seeseemelk.mockbukkit.MockBukkit; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import xyz.ineanto.nicko.Nicko; -import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.config.DefaultDataSources; -import xyz.ineanto.nicko.language.CustomLanguage; -import xyz.ineanto.nicko.migration.CustomLocaleMigrator; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class MigrationTest { - private static Nicko plugin; - - private static File folder; - private static File localeFile; - - @BeforeAll - public static void setup() throws IOException { - MockBukkit.mock(); - final Configuration configuration = new Configuration(Configuration.VERSION.toString(), - DefaultDataSources.SQL_EMPTY, - DefaultDataSources.REDIS_EMPTY, - true); - plugin = MockBukkit.load(Nicko.class, configuration); - folder = new File(plugin.getDataFolder(), "/locale/"); - localeFile = new File(folder, "locale.yml"); - folder.mkdirs(); - localeFile.createNewFile(); - } - - @Test - public void testLanguageFileMigration() throws IOException { - final String content = """ - # Nicko - Language File: - - # hello I'm the invalid version - version: "1.0.0" - """; - - BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(localeFile)); - outputStream.write(content.getBytes(StandardCharsets.UTF_8)); - outputStream.flush(); - - // Get wrong locale - final CustomLanguage customLanguageBeforeMigration = new CustomLanguage(); - assertEquals(customLanguageBeforeMigration.getVersion(), "1.0.0"); - - // Migrate the wrong locale to the correct one - final CustomLocaleMigrator localeMigrator = new CustomLocaleMigrator(plugin, customLanguageBeforeMigration); - localeMigrator.migrate(); - - // Get the migrated locale - final CustomLanguage customLanguageMigrated = new CustomLanguage(); - assertEquals(customLanguageMigrated.getVersion(), "1.1.0"); - } - - @AfterAll - public static void shutdown() { - MockBukkit.unmock(); - folder.delete(); - localeFile.delete(); - } -} diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/MapCacheTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/MapCacheTest.java deleted file mode 100644 index 2cc8ca7..0000000 --- a/src/test/java/xyz/ineanto/nicko/test/storage/MapCacheTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package xyz.ineanto.nicko.test.storage; - -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; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import xyz.ineanto.nicko.Nicko; -import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.profile.NickoProfile; - -import java.util.Optional; - -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class MapCacheTest { - private static Nicko plugin; - private static PlayerMock player; - - @BeforeAll - public static void setup() { - final Configuration config = Configuration.DEFAULT; - final ServerMock server = MockBukkit.mock(); - plugin = MockBukkit.load(Nicko.class, config); - player = server.addPlayer(); - } - - @Test - @DisplayName("Cache Player Data") - public void cachePlayerData() { - final Optional optionalProfile = plugin.getDataStore().getData(player.getUniqueId()); - assertTrue(optionalProfile.isPresent()); - assertTrue(plugin.getDataStore().getCache().isCached(player.getUniqueId())); - } - - @AfterAll - public static void shutdown() { - MockBukkit.unmock(); - } -} diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java deleted file mode 100644 index a5ce971..0000000 --- a/src/test/java/xyz/ineanto/nicko/test/storage/RedisCacheTest.java +++ /dev/null @@ -1,78 +0,0 @@ -package xyz.ineanto.nicko.test.storage; - -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import be.seeseemelk.mockbukkit.entity.PlayerMock; -import org.junit.jupiter.api.*; -import xyz.ineanto.nicko.Nicko; -import xyz.ineanto.nicko.appearance.ActionResult; -import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.config.DataSourceConfiguration; -import xyz.ineanto.nicko.config.DefaultDataSources; -import xyz.ineanto.nicko.profile.NickoProfile; -import xyz.ineanto.nicko.storage.PlayerDataStore; -import xyz.ineanto.nicko.storage.redis.RedisCacheProvider; - -import java.util.Optional; - -import static org.junit.jupiter.api.Assertions.*; - -@TestMethodOrder(MethodOrderer.OrderAnnotation.class) -public class RedisCacheTest { - private static Nicko plugin; - private static PlayerMock player; - - @BeforeAll - public static void setup() { - final Configuration config = new Configuration( - "", - DefaultDataSources.SQL_EMPTY, - new DataSourceConfiguration(true, "127.0.0.1", 6379, "", ""), - false); - final ServerMock server = MockBukkit.mock(); - plugin = MockBukkit.load(Nicko.class, config); - player = server.addPlayer(); - assertInstanceOf(RedisCacheProvider.class, plugin.getDataStore().getCache().getProvider()); - } - - @Test - @DisplayName("Cache Profile") - @Order(1) - public void cacheProfile() { - final Optional optionalProfile = plugin.getDataStore().getData(player.getUniqueId()); - assertTrue(optionalProfile.isPresent()); - assertTrue(plugin.getDataStore().getCache().isCached(player.getUniqueId())); - } - - @Test - @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(); - profile.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"); - } - - @Test - @DisplayName("Delete Cache Profile") - @Order(3) - public void deleteCache() { - final PlayerDataStore dataStore = plugin.getDataStore(); - final ActionResult cacheDelete = dataStore.getCache().delete(player.getUniqueId()); - assertFalse(cacheDelete.isError()); - } - - @AfterAll - public static void shutdown() { - MockBukkit.unmock(); - } -} diff --git a/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java b/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java deleted file mode 100644 index 0bd04ba..0000000 --- a/src/test/java/xyz/ineanto/nicko/test/storage/SQLStorageTest.java +++ /dev/null @@ -1,104 +0,0 @@ -package xyz.ineanto.nicko.test.storage; - -import be.seeseemelk.mockbukkit.MockBukkit; -import org.junit.jupiter.api.*; -import xyz.ineanto.nicko.Nicko; -import xyz.ineanto.nicko.appearance.ActionResult; -import xyz.ineanto.nicko.config.Configuration; -import xyz.ineanto.nicko.config.DefaultDataSources; -import xyz.ineanto.nicko.config.SQLDataSourceConfiguration; -import xyz.ineanto.nicko.language.Language; -import xyz.ineanto.nicko.profile.NickoProfile; -import xyz.ineanto.nicko.storage.PlayerDataStore; -import xyz.ineanto.nicko.storage.mariadb.MariaDBStorageProvider; - -import java.util.Optional; -import java.util.UUID; - -import static org.junit.jupiter.api.Assertions.*; - -@TestMethodOrder(MethodOrderer.OrderAnnotation.class) -public class SQLStorageTest { - private static PlayerDataStore dataStore; - private static UUID uuid; - - @BeforeAll - public static void setup() { - final Configuration config = new Configuration( - "", - new SQLDataSourceConfiguration(true, "127.0.0.1", 3306, "root", "12345", true), - DefaultDataSources.REDIS_EMPTY, - false); - - MockBukkit.mock(); - - final Nicko plugin = MockBukkit.load(Nicko.class, config); - dataStore = plugin.getDataStore(); - uuid = UUID.randomUUID(); - assertInstanceOf(MariaDBStorageProvider.class, dataStore.getStorage().getProvider()); - } - - @Test - @DisplayName("Create tables") - @Order(1) - public void createTables() { - assertFalse(dataStore.getStorage().isError()); - } - - @Test - @DisplayName("Store empty profile") - @Order(2) - public void storeEmptyProfile() { - final Optional optionalProfile = NickoProfile.get(uuid); - assertTrue(optionalProfile.isPresent()); - } - - @Test - @DisplayName("Update profile") - @Order(3) - public void updateProfile() { - final Optional optionalProfile = NickoProfile.get(uuid); - assertTrue(optionalProfile.isPresent()); - - final NickoProfile profile = optionalProfile.get(); - assertNull(profile.getName()); - assertNull(profile.getSkin()); - assertEquals(profile.getLocale(), Language.ENGLISH); - assertTrue(profile.isRandomSkin()); - - profile.setName("Notch"); - profile.setSkin("Notch"); - profile.setLocale(Language.FRENCH); - profile.setRandomSkin(false); - - final ActionResult result = dataStore.getStorage().store(uuid, profile); - assertFalse(result.isError()); - } - - @Test - @DisplayName("Get updated profile") - @Order(4) - public void hasProfileBeenUpdated() { - final Optional optionalProfile = NickoProfile.get(uuid); - assertTrue(optionalProfile.isPresent()); - - final NickoProfile updatedProfile = optionalProfile.get(); - assertEquals(updatedProfile.getName(), "Notch"); - assertEquals(updatedProfile.getSkin(), "Notch"); - assertEquals(updatedProfile.getLocale(), Language.FRENCH); - assertFalse(updatedProfile.isRandomSkin()); - } - - @Test - @DisplayName("Delete profile") - @Order(5) - public void deleteProfile() { - final ActionResult sqlDelete = dataStore.getStorage().delete(uuid); - assertFalse(sqlDelete.isError()); - } - - @AfterAll - public static void shutdown() { - MockBukkit.unmock(); - } -} \ No newline at end of file From 4f9e334544b91b27dc72ed08391fd73658dfaff3 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 20 Mar 2025 20:35:24 +0100 Subject: [PATCH 249/296] feat: make nicko work again partially --- .gitignore | 3 +- build.gradle.kts | 2 +- .../com/comphenix/protocol/utility/LICENSE | 13 + .../protocol/utility/MinecraftVersion.java | 468 +++++++++ .../protocol/utility/SnapshotVersion.java | 150 +++ .../java/net/wesjd/anvilgui/AnvilGUI.java | 889 ++++++++++++++++++ src/main/java/net/wesjd/anvilgui/LICENSE | 21 + .../anvilgui/version/PaperWrapper1_21_R4.java | 135 +++ .../anvilgui/version/VersionMatcher.java | 51 + .../anvilgui/version/VersionWrapper.java | 150 +++ src/main/java/xyz/ineanto/nicko/Nicko.java | 77 +- .../ineanto/nicko/command/NickoCommand.java | 37 +- .../nicko/loader/NickoPluginLoader.java | 6 +- .../{plugin.yml => paper-plugin.yml} | 14 +- 14 files changed, 1939 insertions(+), 77 deletions(-) create mode 100644 src/main/java/com/comphenix/protocol/utility/LICENSE create mode 100644 src/main/java/com/comphenix/protocol/utility/MinecraftVersion.java create mode 100644 src/main/java/com/comphenix/protocol/utility/SnapshotVersion.java create mode 100644 src/main/java/net/wesjd/anvilgui/AnvilGUI.java create mode 100644 src/main/java/net/wesjd/anvilgui/LICENSE create mode 100644 src/main/java/net/wesjd/anvilgui/version/PaperWrapper1_21_R4.java create mode 100644 src/main/java/net/wesjd/anvilgui/version/VersionMatcher.java create mode 100644 src/main/java/net/wesjd/anvilgui/version/VersionWrapper.java rename src/main/resources/{plugin.yml => paper-plugin.yml} (63%) diff --git a/.gitignore b/.gitignore index 077cc42..89b7f3d 100644 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,5 @@ bin/ run/ ### Private ### -TODO \ No newline at end of file +TODO +src/main/java/net/ \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index bf7009e..7f90f12 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -36,7 +36,7 @@ dependencies { compileOnly("me.clip:placeholderapi:2.11.5") compileOnly("net.kyori:adventure-api:4.17.0") compileOnly("xyz.xenondevs.invui:invui-core:$invuiVersion") - compileOnly("net.wesjd:anvilgui:1.10.4-SNAPSHOT") + //compileOnly("net.wesjd:anvilgui:1.10.4-SNAPSHOT") //implementation("xyz.xenondevs.invui:inventory-access-r22:$invuiVersion:remapped-mojang") diff --git a/src/main/java/com/comphenix/protocol/utility/LICENSE b/src/main/java/com/comphenix/protocol/utility/LICENSE new file mode 100644 index 0000000..2673e3f --- /dev/null +++ b/src/main/java/com/comphenix/protocol/utility/LICENSE @@ -0,0 +1,13 @@ +Copyright (C) 2012 Kristian S. Stangeland + +This program is free software; you can redistribute it and/or modify it under the terms of the +GNU General Public License as published by the Free Software Foundation; either version 2 of +the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; +if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA diff --git a/src/main/java/com/comphenix/protocol/utility/MinecraftVersion.java b/src/main/java/com/comphenix/protocol/utility/MinecraftVersion.java new file mode 100644 index 0000000..0f3cd7b --- /dev/null +++ b/src/main/java/com/comphenix/protocol/utility/MinecraftVersion.java @@ -0,0 +1,468 @@ +/* + * ProtocolLib - Bukkit server library that allows access to the Minecraft protocol. + * Copyright (C) 2012 Kristian S. Stangeland + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; + * if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + */ + +package com.comphenix.protocol.utility; + +import com.comphenix.protocol.ProtocolLibrary; +import com.google.common.collect.ComparisonChain; +import com.google.common.collect.Ordering; +import org.bukkit.Bukkit; +import org.bukkit.Server; + +import java.io.Serializable; +import java.text.SimpleDateFormat; +import java.util.Locale; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Determine the current Minecraft version. + * + * @author Kristian + */ +public final class MinecraftVersion implements Comparable, Serializable { + /** + * Version 1.21.4 - the garden awakens drop + */ + public static final MinecraftVersion v1_21_4 = new MinecraftVersion("1.21.4"); + + /** + * Version 1.21.2 - the bundles of bravery drop + */ + public static final MinecraftVersion v1_21_2 = new MinecraftVersion("1.21.2"); + + /** + * Version 1.21.0 - the tricky trials update + */ + public static final MinecraftVersion v1_21_0 = new MinecraftVersion("1.21.0"); + + /** + * Version 1.20.5 - the cookie and transfer packet update + */ + public static final MinecraftVersion v1_20_5 = new MinecraftVersion("1.20.5"); + + /** + * Version 1.20.4 - the decorated pot update + */ + public static final MinecraftVersion v1_20_4 = new MinecraftVersion("1.20.4"); + + /** + * Version 1.20.2 - the update that added the configuration protocol phase. + */ + public static final MinecraftVersion CONFIG_PHASE_PROTOCOL_UPDATE = new MinecraftVersion("1.20.2"); + /** + * Version 1.20 - the trails and tails update + */ + public static final MinecraftVersion TRAILS_AND_TAILS = new MinecraftVersion("1.20"); + + /** + * Version 1.19.4 - the rest of the feature preview + */ + public static final MinecraftVersion FEATURE_PREVIEW_2 = new MinecraftVersion("1.19.4"); + + /** + * Version 1.19.3 - introducing feature preview + */ + public static final MinecraftVersion FEATURE_PREVIEW_UPDATE = new MinecraftVersion("1.19.3"); + /** + * Version 1.19 - the wild update + */ + public static final MinecraftVersion WILD_UPDATE = new MinecraftVersion("1.19"); + /** + * Version 1.18 - caves and cliffs part 2 + */ + public static final MinecraftVersion CAVES_CLIFFS_2 = new MinecraftVersion("1.18"); + /** + * Version 1.17 - caves and cliffs part 1 + */ + public static final MinecraftVersion CAVES_CLIFFS_1 = new MinecraftVersion("1.17"); + /** + * Version 1.16.4 + */ + public static final MinecraftVersion NETHER_UPDATE_4 = new MinecraftVersion("1.16.4"); + /** + * Version 1.16.2 - breaking change to the nether update + */ + public static final MinecraftVersion NETHER_UPDATE_2 = new MinecraftVersion("1.16.2"); + /** + * Version 1.16.0 - the nether update + */ + public static final MinecraftVersion NETHER_UPDATE = new MinecraftVersion("1.16"); + /** + * Version 1.15 - the bee update + */ + public static final MinecraftVersion BEE_UPDATE = new MinecraftVersion("1.15"); + /** + * Version 1.14 - village and pillage update. + */ + public static final MinecraftVersion VILLAGE_UPDATE = new MinecraftVersion("1.14"); + /** + * Version 1.13 - update aquatic. + */ + public static final MinecraftVersion AQUATIC_UPDATE = new MinecraftVersion("1.13"); + /** + * Version 1.12 - the world of color update. + */ + public static final MinecraftVersion COLOR_UPDATE = new MinecraftVersion("1.12"); + /** + * Version 1.11 - the exploration update. + */ + public static final MinecraftVersion EXPLORATION_UPDATE = new MinecraftVersion("1.11"); + /** + * Version 1.10 - the frostburn update. + */ + public static final MinecraftVersion FROSTBURN_UPDATE = new MinecraftVersion("1.10"); + /** + * Version 1.9 - the combat update. + */ + public static final MinecraftVersion COMBAT_UPDATE = new MinecraftVersion("1.9"); + /** + * Version 1.8 - the "bountiful" update. + */ + public static final MinecraftVersion BOUNTIFUL_UPDATE = new MinecraftVersion("1.8"); + /** + * Version 1.7.8 - the update that changed the skin format (and distribution - R.I.P. player disguise) + */ + public static final MinecraftVersion SKIN_UPDATE = new MinecraftVersion("1.7.8"); + /** + * Version 1.7.2 - the update that changed the world. + */ + public static final MinecraftVersion WORLD_UPDATE = new MinecraftVersion("1.7.2"); + /** + * Version 1.6.1 - the horse update. + */ + public static final MinecraftVersion HORSE_UPDATE = new MinecraftVersion("1.6.1"); + /** + * Version 1.5.0 - the redstone update. + */ + public static final MinecraftVersion REDSTONE_UPDATE = new MinecraftVersion("1.5.0"); + /** + * Version 1.4.2 - the scary update (Wither Boss). + */ + public static final MinecraftVersion SCARY_UPDATE = new MinecraftVersion("1.4.2"); + + /** + * The latest release version of minecraft. + */ + public static final MinecraftVersion LATEST = v1_21_4; + + // used when serializing + private static final long serialVersionUID = -8695133558996459770L; + + /** + * Regular expression used to parse version strings. + */ + private static final Pattern VERSION_PATTERN = Pattern.compile(".*\\(.*MC.\\s*([a-zA-z0-9\\-.]+).*"); + + /** + * The current version of minecraft, lazy initialized by MinecraftVersion.currentVersion() + */ + private static MinecraftVersion currentVersion; + + private final int major; + private final int minor; + private final int build; + // The development stage + private final String development; + + // Snapshot? + private final SnapshotVersion snapshot; + private volatile Boolean atCurrentOrAbove; + + /** + * Determine the current Minecraft version. + * + * @param server - the Bukkit server that will be used to examine the MC version. + */ + public MinecraftVersion(Server server) { + this(extractVersion(server.getVersion())); + } + + /** + * Construct a version object from the format major.minor.build, or the snapshot format. + * + * @param versionOnly - the version in text form. + */ + public MinecraftVersion(String versionOnly) { + this(versionOnly, true); + } + + /** + * Construct a version format from the standard release version or the snapshot verison. + * + * @param versionOnly - the version. + * @param parseSnapshot - TRUE to parse the snapshot, FALSE otherwise. + */ + private MinecraftVersion(String versionOnly, boolean parseSnapshot) { + String[] section = versionOnly.split("-"); + SnapshotVersion snapshot = null; + int[] numbers = new int[3]; + + try { + numbers = this.parseVersion(section[0]); + } catch (NumberFormatException cause) { + // Skip snapshot parsing + if (!parseSnapshot) { + throw cause; + } + + try { + // Determine if the snapshot is newer than the current release version + snapshot = new SnapshotVersion(section[0]); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.US); + + MinecraftVersion latest = new MinecraftVersion(ProtocolLibrary.MAXIMUM_MINECRAFT_VERSION, false); + boolean newer = snapshot.getSnapshotDate().compareTo( + format.parse(ProtocolLibrary.MINECRAFT_LAST_RELEASE_DATE)) > 0; + + numbers[0] = latest.getMajor(); + numbers[1] = latest.getMinor() + (newer ? 1 : -1); + } catch (Exception e) { + throw new IllegalStateException("Cannot parse " + section[0], e); + } + } + + this.major = numbers[0]; + this.minor = numbers[1]; + this.build = numbers[2]; + this.development = section.length > 1 ? section[1] : (snapshot != null ? "snapshot" : null); + this.snapshot = snapshot; + } + + /** + * Construct a version object directly. + * + * @param major - major version number. + * @param minor - minor version number. + * @param build - build version number. + */ + public MinecraftVersion(int major, int minor, int build) { + this(major, minor, build, null); + } + + /** + * Construct a version object directly. + * + * @param major - major version number. + * @param minor - minor version number. + * @param build - build version number. + * @param development - development stage. + */ + public MinecraftVersion(int major, int minor, int build, String development) { + this.major = major; + this.minor = minor; + this.build = build; + this.development = development; + this.snapshot = null; + } + + /** + * Extract the Minecraft version from CraftBukkit itself. + * + * @param text - the server version in text form. + * @return The underlying MC version. + * @throws IllegalStateException If we could not parse the version string. + */ + public static String extractVersion(String text) { + Matcher version = VERSION_PATTERN.matcher(text); + + if (version.matches() && version.group(1) != null) { + return version.group(1); + } else { + throw new IllegalStateException("Cannot parse version String '" + text + "'"); + } + } + + /** + * Parse the given server version into a Minecraft version. + * + * @param serverVersion - the server version. + * @return The resulting Minecraft version. + */ + public static MinecraftVersion fromServerVersion(String serverVersion) { + return new MinecraftVersion(extractVersion(serverVersion)); + } + + public static MinecraftVersion getCurrentVersion() { + if (currentVersion == null) { + currentVersion = fromServerVersion(Bukkit.getVersion()); + } + + return currentVersion; + } + + public static void setCurrentVersion(MinecraftVersion version) { + currentVersion = version; + } + + private static boolean atOrAbove(MinecraftVersion version) { + return getCurrentVersion().isAtLeast(version); + } + + private int[] parseVersion(String version) { + String[] elements = version.split("\\."); + int[] numbers = new int[3]; + + // Make sure it's even a valid version + if (elements.length < 1) { + throw new IllegalStateException("Corrupt MC version: " + version); + } + + // The String 1 or 1.2 is interpreted as 1.0.0 and 1.2.0 respectively. + for (int i = 0; i < Math.min(numbers.length, elements.length); i++) { + numbers[i] = Integer.parseInt(elements[i].trim()); + } + return numbers; + } + + /** + * Major version number + * + * @return Current major version number. + */ + public int getMajor() { + return this.major; + } + + /** + * Minor version number + * + * @return Current minor version number. + */ + public int getMinor() { + return this.minor; + } + + /** + * Build version number + * + * @return Current build version number. + */ + public int getBuild() { + return this.build; + } + + /** + * Retrieve the development stage. + * + * @return Development stage, or NULL if this is a release. + */ + public String getDevelopmentStage() { + return this.development; + } + + /** + * Retrieve the snapshot version, or NULL if this is a release. + * + * @return The snapshot version. + */ + public SnapshotVersion getSnapshot() { + return this.snapshot; + } + + /** + * Determine if this version is a snapshot. + * + * @return The snapshot version. + */ + public boolean isSnapshot() { + return this.snapshot != null; + } + + /** + * Checks if this version is at or above the current version the server is running. + * + * @return true if this version is equal or newer than the server version, false otherwise. + */ + public boolean atOrAbove() { + if (this.atCurrentOrAbove == null) { + this.atCurrentOrAbove = atOrAbove(this); + } + + return this.atCurrentOrAbove; + } + + /** + * Retrieve the version String (major.minor.build) only. + * + * @return A normal version string. + */ + public String getVersion() { + if (this.getDevelopmentStage() == null) { + return String.format("%s.%s.%s", this.getMajor(), this.getMinor(), this.getBuild()); + } else { + return String.format("%s.%s.%s-%s%s", this.getMajor(), this.getMinor(), this.getBuild(), + this.getDevelopmentStage(), this.isSnapshot() ? this.snapshot : ""); + } + } + + @Override + public int compareTo(MinecraftVersion o) { + if (o == null) { + return 1; + } + + return ComparisonChain.start() + .compare(this.getMajor(), o.getMajor()) + .compare(this.getMinor(), o.getMinor()) + .compare(this.getBuild(), o.getBuild()) + .compare(this.getDevelopmentStage(), o.getDevelopmentStage(), Ordering.natural().nullsLast()) + .compare(this.getSnapshot(), o.getSnapshot(), Ordering.natural().nullsFirst()) + .result(); + } + + public boolean isAtLeast(MinecraftVersion other) { + if (other == null) { + return false; + } + + return this.compareTo(other) >= 0; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + + if (obj instanceof MinecraftVersion) { + MinecraftVersion other = (MinecraftVersion) obj; + + return this.getMajor() == other.getMajor() && + this.getMinor() == other.getMinor() && + this.getBuild() == other.getBuild() && + Objects.equals(this.getDevelopmentStage(), other.getDevelopmentStage()); + } + + return false; + } + + @Override + public int hashCode() { + return Objects.hash(this.getMajor(), this.getMinor(), this.getBuild()); + } + + @Override + public String toString() { + // Convert to a String that we can parse back again + return String.format("(MC: %s)", this.getVersion()); + } +} diff --git a/src/main/java/com/comphenix/protocol/utility/SnapshotVersion.java b/src/main/java/com/comphenix/protocol/utility/SnapshotVersion.java new file mode 100644 index 0000000..dc4cdfd --- /dev/null +++ b/src/main/java/com/comphenix/protocol/utility/SnapshotVersion.java @@ -0,0 +1,150 @@ +/* + * ProtocolLib - Bukkit server library that allows access to the Minecraft protocol. + * Copyright (C) 2012 Kristian S. Stangeland + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program; + * if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + */ + +package com.comphenix.protocol.utility; + +import com.google.common.collect.ComparisonChain; + +import java.io.Serial; +import java.io.Serializable; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Used to parse a snapshot version. + * + * @author Kristian + */ +public class SnapshotVersion implements Comparable, Serializable { + + @Serial + private static final long serialVersionUID = 2778655372579322310L; + private static final Pattern SNAPSHOT_PATTERN = Pattern.compile("(\\d{2}w\\d{2})([a-z])"); + + private final Date snapshotDate; + private final int snapshotWeekVersion; + + private transient String rawString; + + public SnapshotVersion(String version) { + Matcher matcher = SNAPSHOT_PATTERN.matcher(version.trim()); + + if (matcher.matches()) { + try { + this.snapshotDate = getDateFormat().parse(matcher.group(1)); + this.snapshotWeekVersion = matcher.group(2).charAt(0) - 'a'; + this.rawString = version; + } catch (ParseException e) { + throw new IllegalArgumentException("Date implied by snapshot version is invalid.", e); + } + } else { + throw new IllegalArgumentException("Cannot parse " + version + " as a snapshot version."); + } + } + + /** + * Retrieve the snapshot date parser. + *

+ * We have to create a new instance of SimpleDateFormat every time as it is not thread safe. + * + * @return The date formatter. + */ + private static SimpleDateFormat getDateFormat() { + SimpleDateFormat format = new SimpleDateFormat("yy'w'ww", Locale.US); + format.setLenient(false); + return format; + } + + /** + * Retrieve the snapshot version within a week, starting at zero. + * + * @return The weekly version + */ + public int getSnapshotWeekVersion() { + return this.snapshotWeekVersion; + } + + /** + * Retrieve the week this snapshot was released. + * + * @return The week. + */ + public Date getSnapshotDate() { + return this.snapshotDate; + } + + /** + * Retrieve the raw snapshot string (yy'w'ww[a-z]). + * + * @return The snapshot string. + */ + public String getSnapshotString() { + if (this.rawString == null) { + // It's essential that we use the same locale + Calendar current = Calendar.getInstance(Locale.US); + current.setTime(this.snapshotDate); + this.rawString = String.format("%02dw%02d%s", + current.get(Calendar.YEAR) % 100, + current.get(Calendar.WEEK_OF_YEAR), + (char) ('a' + this.snapshotWeekVersion)); + } + return this.rawString; + } + + @Override + public int compareTo(SnapshotVersion o) { + if (o == null) { + return 1; + } + + return ComparisonChain.start() + .compare(this.snapshotDate, o.getSnapshotDate()) + .compare(this.snapshotWeekVersion, o.getSnapshotWeekVersion()) + .result(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + + if (obj instanceof SnapshotVersion) { + SnapshotVersion other = (SnapshotVersion) obj; + return Objects.equals(this.snapshotDate, other.getSnapshotDate()) + && this.snapshotWeekVersion == other.getSnapshotWeekVersion(); + } + + return false; + } + + @Override + public int hashCode() { + return Objects.hash(this.snapshotDate, this.snapshotWeekVersion); + } + + @Override + public String toString() { + return this.getSnapshotString(); + } +} diff --git a/src/main/java/net/wesjd/anvilgui/AnvilGUI.java b/src/main/java/net/wesjd/anvilgui/AnvilGUI.java new file mode 100644 index 0000000..6beaacc --- /dev/null +++ b/src/main/java/net/wesjd/anvilgui/AnvilGUI.java @@ -0,0 +1,889 @@ +package net.wesjd.anvilgui; + +import net.md_5.bungee.api.chat.BaseComponent; +import net.wesjd.anvilgui.version.VersionWrapper; +import net.wesjd.anvilgui.version.VersionMatcher; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.*; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.plugin.Plugin; + +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.logging.Level; + +/** + * An anvil gui, used for gathering a user's input + * + * @author Wesley Smith + * @since 1.0 + */ +public class AnvilGUI { + + /** + * The local {@link VersionWrapper} object for the server's version + */ + private static final VersionWrapper WRAPPER = new VersionMatcher().match(); + + /** + * The variable containing an item with air. Used when the item would be null. + * To keep the heap clean, this object only gets iniziaised once + */ + private static final ItemStack AIR = new ItemStack(Material.AIR); + /** + * If the given ItemStack is null, return an air ItemStack, otherwise return the given ItemStack + * + * @param stack The ItemStack to check + * @return air or the given ItemStack + */ + private static ItemStack itemNotNull(ItemStack stack) { + return stack == null ? AIR : stack; + } + + /** + * The {@link Plugin} that this anvil GUI is associated with + */ + private final Plugin plugin; + /** + * The player who has the GUI open + */ + private final Player player; + /** + * An {@link Executor} that executes tasks on the main server thread + */ + private final Executor mainThreadExecutor; + /** + * The title of the anvil inventory + */ + private final Object titleComponent; + /** + * The initial contents of the inventory + */ + private final ItemStack[] initialContents; + /** + * A state that decides where the anvil GUI is able to get closed by the user + */ + private final boolean preventClose; + /** + * A state that decides whether compatibility with Geyser software is enabled + */ + private final boolean geyserCompatibility; + /** + * A set of slot numbers that are permitted to be interacted with by the user. An interactable + * slot is one that is able to be minipulated by the player, i.e. clicking and picking up an item, + * placing in a new one, etc. + */ + private final Set interactableSlots; + + /** An {@link Consumer} that is called when the anvil GUI is close */ + private final Consumer closeListener; + /** A flag that decides whether the async click handler can be run concurrently */ + private final boolean concurrentClickHandlerExecution; + /** An {@link BiFunction} that is called when a slot is clicked */ + private final ClickHandler clickHandler; + + /** + * The container id of the inventory, used for NMS methods + */ + private int containerId; + + /** + * The inventory that is used on the Bukkit side of things + */ + private Inventory inventory; + /** + * The listener holder class + */ + private final ListenUp listener = new ListenUp(); + + /** + * Represents the state of the inventory being open + */ + private boolean open; + + /** + * The actual container backing the Anvil GUI + */ + private VersionWrapper.AnvilContainerWrapper container; + + /** + * Create an AnvilGUI + * + * @param plugin A {@link org.bukkit.plugin.java.JavaPlugin} instance + * @param player The {@link Player} to open the inventory for + * @param mainThreadExecutor An {@link Executor} that executes on the main server thread + * @param titleComponent What to have the text already set to + * @param initialContents The initial contents of the inventory + * @param preventClose Whether to prevent the inventory from closing + * @param geyserCompatibility Whether to enable compatibility with Geyser software + * @param closeListener A {@link Consumer} when the inventory closes + * @param concurrentClickHandlerExecution Flag to allow concurrent execution of the click handler + * @param clickHandler A {@link ClickHandler} that is called when the player clicks a slot + */ + private AnvilGUI( + Plugin plugin, + Player player, + Executor mainThreadExecutor, + Object titleComponent, + ItemStack[] initialContents, + boolean preventClose, + boolean geyserCompatibility, + Set interactableSlots, + Consumer closeListener, + boolean concurrentClickHandlerExecution, + ClickHandler clickHandler) { + this.plugin = plugin; + this.player = player; + this.mainThreadExecutor = mainThreadExecutor; + this.titleComponent = titleComponent; + this.initialContents = initialContents; + this.preventClose = preventClose; + this.geyserCompatibility = geyserCompatibility; + this.interactableSlots = Collections.unmodifiableSet(interactableSlots); + this.closeListener = closeListener; + this.concurrentClickHandlerExecution = concurrentClickHandlerExecution; + this.clickHandler = clickHandler; + } + + /** + * Opens the anvil GUI + */ + private void openInventory() { + Bukkit.getPluginManager().registerEvents(listener, plugin); + + container = WRAPPER.newContainerAnvil(player, titleComponent); + + inventory = container.getBukkitInventory(); + // We need to use setItem instead of setContents because a Minecraft ContainerAnvil + // contains two separate inventories: the result inventory and the ingredients inventory. + // The setContents method only updates the ingredients inventory unfortunately, + // but setItem handles the index going into the result inventory. + for (int i = 0; i < initialContents.length; i++) { + inventory.setItem(i, initialContents[i]); + } + + containerId = WRAPPER.getNextContainerId(player, container); + WRAPPER.handleInventoryCloseEvent(player); + WRAPPER.sendPacketOpenWindow(player, containerId, titleComponent); + WRAPPER.setActiveContainer(player, container); + WRAPPER.setActiveContainerId(container, containerId); + WRAPPER.addActiveContainerSlotListener(container, player); + + open = true; + } + + /** + * Closes the inventory if it's open. + */ + public void closeInventory() { + closeInventory(true); + } + + /** + * Closes the inventory if it's open, only sending the close inventory packets if the arg is true + * + * @param sendClosePacket Whether to send the close inventory event, packet, etc + */ + private void closeInventory(boolean sendClosePacket) { + if (!open) { + return; + } + + open = false; + + HandlerList.unregisterAll(listener); + + if (sendClosePacket) { + WRAPPER.handleInventoryCloseEvent(player); + WRAPPER.setActiveContainerDefault(player); + WRAPPER.sendPacketCloseWindow(player, containerId); + } + + if (closeListener != null) { + closeListener.accept(StateSnapshot.fromAnvilGUI(this)); + } + } + + /** + * Updates the title of the AnvilGUI to the new one. + * + * @param literalTitle The title to use as literal text + * @param preserveRenameText Whether to preserve the entered rename text + * @throws IllegalArgumentException when literalTitle is null + * @see Builder#title(String) + */ + public void setTitle(String literalTitle, boolean preserveRenameText) { + Validate.notNull(literalTitle, "literalTitle cannot be null"); + setTitle(WRAPPER.literalChatComponent(literalTitle), preserveRenameText); + } + + /** + * Updates the title of the AnvilGUI to the new one. + * + * @param json The json used to parse into a rich chat component + * @param preserveRenameText Whether to preserve the entered rename text + * @throws IllegalArgumentException when json is null + * @see Builder#jsonTitle(String) + */ + public void setJsonTitle(String json, boolean preserveRenameText) { + Validate.notNull(json, "json cannot be null"); + setTitle(WRAPPER.jsonChatComponent(json), preserveRenameText); + } + + /** + * Updates the title of the AnvilGUI to the new one. + * + * @param title The title as a NMS ChatComponent + * @param preserveRenameText Whether to preserve the entered rename text + */ + private void setTitle(Object title, boolean preserveRenameText) { + if (!WRAPPER.isCustomTitleSupported()) { + return; + } + String renameText = container.getRenameText(); + WRAPPER.sendPacketOpenWindow(player, containerId, title); + if (preserveRenameText) { + // The renameText field is marked as @Nullable in newer versions + container.setRenameText(renameText == null ? "" : renameText); + } + } + + /** + * Returns the Bukkit inventory for this anvil gui + * + * @return the {@link Inventory} for this anvil gui + */ + public Inventory getInventory() { + return inventory; + } + + /** + * Simply holds the listeners for the GUI + */ + private class ListenUp implements Listener { + + /** + * Boolean storing the running status of the latest click handler to prevent double execution. + * All accesses to this boolean will be from the main server thread, except for the rare event + * that the plugin is disabled and the mainThreadExecutor throws an exception + */ + private boolean clickHandlerRunning = false; + + @EventHandler + public void onInventoryClick(InventoryClickEvent event) { + if (!event.getInventory().equals(inventory)) { + return; + } + + final int rawSlot = event.getRawSlot(); + // ignore items dropped outside the window + if (rawSlot == -999) return; + + final Player clicker = (Player) event.getWhoClicked(); + final Inventory clickedInventory = event.getClickedInventory(); + + if (clickedInventory != null) { + if (clickedInventory.equals(clicker.getInventory())) { + // prevent players from merging items from the anvil inventory + if (event.getClick().equals(ClickType.DOUBLE_CLICK)) { + event.setCancelled(true); + return; + } + // prevent shift moving items from players inv to the anvil inventory + if (event.isShiftClick()) { + event.setCancelled(true); + return; + } + } + // prevent players from swapping items in the anvil gui + if ((event.getCursor() != null && event.getCursor().getType() != Material.AIR) + && !interactableSlots.contains(rawSlot) + && event.getClickedInventory().equals(inventory)) { + event.setCancelled(true); + return; + } + } + + if (rawSlot < 3 && rawSlot >= 0 || event.getAction().equals(InventoryAction.MOVE_TO_OTHER_INVENTORY)) { + event.setCancelled(!interactableSlots.contains(rawSlot)); + if (clickHandlerRunning && !concurrentClickHandlerExecution) { + // A click handler is running, don't launch another one + return; + } + + final CompletableFuture> actionsFuture = + clickHandler.apply(rawSlot, StateSnapshot.fromAnvilGUI(AnvilGUI.this)); + + final Consumer> actionsConsumer = actions -> { + for (final ResponseAction action : actions) { + action.accept(AnvilGUI.this, clicker); + } + }; + + if (actionsFuture.isDone()) { + // Fast-path without scheduling if clickHandler is performed in sync + // Because the future is already completed, .join() will not block the server thread + actionsFuture.thenAccept(actionsConsumer).join(); + } else { + clickHandlerRunning = true; + // If the plugin is disabled and the Executor throws an exception, the exception will be passed to + // the .handle method + actionsFuture + .thenAcceptAsync(actionsConsumer, mainThreadExecutor) + .handle((results, exception) -> { + if (exception != null) { + plugin.getLogger() + .log( + Level.SEVERE, + "An exception occurred in the AnvilGUI clickHandler", + exception); + } + // Whether an exception occurred or not, set running to false + clickHandlerRunning = false; + return null; + }); + } + } + } + + @EventHandler + public void onInventoryDrag(InventoryDragEvent event) { + if (event.getInventory().equals(inventory)) { + for (int slot : Slot.values()) { + if (event.getRawSlots().contains(slot)) { + event.setCancelled(!interactableSlots.contains(slot)); + break; + } + } + } + } + + @EventHandler + public void onInventoryClose(InventoryCloseEvent event) { + if (open && event.getInventory().equals(inventory)) { + closeInventory(false); + if (preventClose) { + mainThreadExecutor.execute(AnvilGUI.this::openInventory); + } + } + } + } + + /** A builder class for an {@link AnvilGUI} object */ + public static class Builder { + + /** An {@link Executor} that executes tasks on the main server thread */ + private Executor mainThreadExecutor; + /** An {@link Consumer} that is called when the anvil GUI is close */ + private Consumer closeListener; + /** A flag that decides whether the async click handler can be run concurrently */ + private boolean concurrentClickHandlerExecution = false; + /** An {@link Function} that is called when a slot in the inventory has been clicked */ + private ClickHandler clickHandler; + /** A state that decides where the anvil GUI is able to be closed by the user */ + private boolean preventClose = false; + /** A state that determines whether support for Geyser software is enabled */ + private boolean geyserCompatibility = true; + /** A set of integers containing the slot numbers that should be modifiable by the user. */ + private Set interactableSlots = Collections.emptySet(); + /** The {@link Plugin} that this anvil GUI is associated with */ + private Plugin plugin; + /** The text that will be displayed to the user */ + private Object titleComponent = WRAPPER.literalChatComponent("Repair & Name"); + /** The starting text on the item */ + private String itemText; + /** An {@link ItemStack} to be put in the left input slot */ + private ItemStack itemLeft; + /** An {@link ItemStack} to be put in the right input slot */ + private ItemStack itemRight; + /** An {@link ItemStack} to be placed in the output slot */ + private ItemStack itemOutput; + + /** + * Set a custom main server thread executor. Useful for plugins targeting Folia. + * + * @param executor The executor to run tasks on + * @return The {@link Builder} instance + * @throws IllegalArgumentException when the executor is null + */ + public Builder mainThreadExecutor(Executor executor) { + Validate.notNull(executor, "Executor cannot be null"); + this.mainThreadExecutor = executor; + return this; + } + + /** + * Prevents the closing of the anvil GUI by the user + * + * @return The {@link Builder} instance + */ + public Builder preventClose() { + preventClose = true; + return this; + } + + /** + * Disables compatibility with Geyser software + */ + public Builder disableGeyserCompat() { + geyserCompatibility = false; + return this; + } + + /** + * Permit the user to modify (take items in and out) the slot numbers provided. + * + * @param slots A varags param for the slot numbers. You can avoid relying on magic constants by using + * the {@link AnvilGUI.Slot} class. + * @return The {@link Builder} instance + */ + public Builder interactableSlots(int... slots) { + final Set newValue = new HashSet<>(); + for (int slot : slots) { + newValue.add(slot); + } + interactableSlots = newValue; + return this; + } + + /** + * Listens for when the inventory is closed + * + * @param closeListener An {@link Consumer} that is called when the anvil GUI is closed + * @return The {@link Builder} instance + * @throws IllegalArgumentException when the closeListener is null + */ + public Builder onClose(Consumer closeListener) { + Validate.notNull(closeListener, "closeListener cannot be null"); + this.closeListener = closeListener; + return this; + } + + /** + * Do an action when a slot is clicked in the inventory + *

+ * The ClickHandler is only called when the previous execution of the ClickHandler has finished. + * To alter this behaviour use {@link #allowConcurrentClickHandlerExecution()} + * + * @param clickHandler A {@link ClickHandler} that is called when the user clicks a slot. The + * {@link Integer} is the slot number corresponding to {@link Slot}, the + * {@link StateSnapshot} contains information about the current state of the anvil, + * and the response is a {@link CompletableFuture} that will eventually return a + * list of {@link ResponseAction} to execute in the order that they are supplied. + * @return The {@link Builder} instance + * @throws IllegalArgumentException when the function supplied is null + */ + public Builder onClickAsync(ClickHandler clickHandler) { + Validate.notNull(clickHandler, "click function cannot be null"); + this.clickHandler = clickHandler; + return this; + } + + /** + * By default, the {@link #onClickAsync(ClickHandler) async click handler} will not run concurrently + * and instead wait for the previous {@link CompletableFuture} to finish before executing it again. + *

+ * If this trait is desired, it can be enabled by calling this method but may lead to inconsistent + * behaviour if not handled properly. + * + * @return The {@link Builder} instance + */ + public Builder allowConcurrentClickHandlerExecution() { + this.concurrentClickHandlerExecution = true; + return this; + } + + /** + * Do an action when a slot is clicked in the inventory + * + * @param clickHandler A {@link BiFunction} that is called when the user clicks a slot. The + * {@link Integer} is the slot number corresponding to {@link Slot}, the + * {@link StateSnapshot} contains information about the current state of the anvil, + * and the response is a list of {@link ResponseAction} to execute in the order + * that they are supplied. + * @return The {@link Builder} instance + * @throws IllegalArgumentException when the function supplied is null + */ + public Builder onClick(BiFunction> clickHandler) { + Validate.notNull(clickHandler, "click function cannot be null"); + this.clickHandler = + (slot, stateSnapshot) -> CompletableFuture.completedFuture(clickHandler.apply(slot, stateSnapshot)); + return this; + } + + /** + * Sets the plugin for the {@link AnvilGUI} + * + * @param plugin The {@link Plugin} this anvil GUI is associated with + * @return The {@link Builder} instance + * @throws IllegalArgumentException if the plugin is null + */ + public Builder plugin(Plugin plugin) { + Validate.notNull(plugin, "Plugin cannot be null"); + this.plugin = plugin; + return this; + } + + /** + * Sets the initial item-text that is displayed to the user. + *

+ * If the usage of Adventure Components is desired, you must create an item, set the displayname of it + * and put it into the AnvilGUI via {@link #itemLeft(ItemStack)} manually. + * + * @param text The initial name of the item in the anvil + * @return The {@link Builder} instance + * @throws IllegalArgumentException if the text is null + */ + public Builder text(String text) { + Validate.notNull(text, "Text cannot be null"); + this.itemText = text; + return this; + } + + /** + * Sets the AnvilGUI title that is to be displayed to the user. + *
+ * The provided title will be treated as literal text. + * + * @param title The title that is to be displayed to the user + * @return The {@link Builder} instance + * @throws IllegalArgumentException if the title is null + */ + public Builder title(String title) { + Validate.notNull(title, "title cannot be null"); + this.titleComponent = WRAPPER.literalChatComponent(title); + return this; + } + + /** + * Sets the AnvilGUI title that is to be displayed to the user. + *
+ * The provided json will be parsed into rich chat components. + * + * @param json The title that is to be displayed to the user + * @return The {@link Builder} instance + * @throws IllegalArgumentException if the title is null + * @see net.md_5.bungee.chat.ComponentSerializer#toString(BaseComponent) + */ + public Builder jsonTitle(String json) { + Validate.notNull(json, "json cannot be null"); + this.titleComponent = WRAPPER.jsonChatComponent(json); + return this; + } + + /** + * Sets the {@link ItemStack} to be put in the first slot + * + * @param item The {@link ItemStack} to be put in the first slot + * @return The {@link Builder} instance + * @throws IllegalArgumentException if the {@link ItemStack} is null + */ + public Builder itemLeft(ItemStack item) { + Validate.notNull(item, "item cannot be null"); + this.itemLeft = item; + return this; + } + + /** + * Sets the {@link ItemStack} to be put in the second slot + * + * @param item The {@link ItemStack} to be put in the second slot + * @return The {@link Builder} instance + */ + public Builder itemRight(ItemStack item) { + this.itemRight = item; + return this; + } + + /** + * Sets the {@link ItemStack} to be put in the output slot + * + * @param item The {@link ItemStack} to be put in the output slot + * @return The {@link Builder} instance + */ + public Builder itemOutput(ItemStack item) { + this.itemOutput = item; + return this; + } + + /** + * Creates the anvil GUI and opens it for the player + * + * @param player The {@link Player} the anvil GUI should open for + * @return The {@link AnvilGUI} instance from this builder + * @throws IllegalArgumentException when the onClick function, plugin, or player is null + */ + public AnvilGUI open(Player player) { + Validate.notNull(plugin, "Plugin cannot be null"); + Validate.notNull(clickHandler, "click handler cannot be null"); + Validate.notNull(player, "Player cannot be null"); + + if (itemText != null) { + if (itemLeft == null) { + itemLeft = new ItemStack(Material.PAPER); + } + + ItemMeta paperMeta = itemLeft.getItemMeta(); + paperMeta.setDisplayName(itemText); + itemLeft.setItemMeta(paperMeta); + } + + // If no executor is specified, execute all tasks with the BukkitScheduler + if (mainThreadExecutor == null) { + mainThreadExecutor = task -> Bukkit.getScheduler().runTask(plugin, task); + } + + final AnvilGUI anvilGUI = new AnvilGUI( + plugin, + player, + mainThreadExecutor, + titleComponent, + new ItemStack[] {itemLeft, itemRight, itemOutput}, + preventClose, + geyserCompatibility, + interactableSlots, + closeListener, + concurrentClickHandlerExecution, + clickHandler); + anvilGUI.openInventory(); + return anvilGUI; + } + } + + /** + * A handler that is called when the user clicks a slot. The + * {@link Integer} is the slot number corresponding to {@link Slot}, the + * {@link StateSnapshot} contains information about the current state of the anvil, + * and the response is a {@link CompletableFuture} that will eventually return a + * list of {@link ResponseAction} to execute in the order that they are supplied. + */ + @FunctionalInterface + public interface ClickHandler extends BiFunction>> {} + + /** An action to run in response to a player clicking the output slot in the GUI. This interface is public + * and permits you, the developer, to add additional response features easily to your custom AnvilGUIs. */ + @FunctionalInterface + public interface ResponseAction extends BiConsumer { + + /** + * Replace the input text box value with the provided text value. + * + * Before using this method, it must be verified by the caller that items are either in + * {@link Slot#INPUT_LEFT} or {@link Slot#OUTPUT} present. + * + * @param text The text to write in the input box + * @return The {@link ResponseAction} to achieve the text replacement + * @throws IllegalArgumentException when the text is null + * @throws IllegalStateException when the slots {@link Slot#INPUT_LEFT} and {@link Slot#OUTPUT} are null + */ + static ResponseAction replaceInputText(String text) { + Validate.notNull(text, "text cannot be null"); + return (anvilgui, player) -> { + ItemStack item = anvilgui.getInventory().getItem(Slot.OUTPUT); + if (item == null) { + // Fallback on left input slot if player hasn't typed anything yet + item = anvilgui.getInventory().getItem(Slot.INPUT_LEFT); + } + if (item == null) { + throw new IllegalStateException( + "replaceInputText can only be used if slots OUTPUT or INPUT_LEFT are not empty"); + } + + final ItemStack cloned = item.clone(); + final ItemMeta meta = cloned.getItemMeta(); + meta.setDisplayName(text); + cloned.setItemMeta(meta); + anvilgui.getInventory().setItem(Slot.INPUT_LEFT, cloned); + }; + } + + /** + * Updates the title of the AnvilGUI to the new one. + * + * @param literalTitle The title to use as literal text + * @param preserveRenameText Whether to preserve the entered rename text + * @throws IllegalArgumentException when literalTitle is null + * @see Builder#title(String) + */ + static ResponseAction updateTitle(String literalTitle, boolean preserveRenameText) { + Validate.notNull(literalTitle, "literalTitle cannot be null"); + return (anvilGUI, player) -> anvilGUI.setTitle(literalTitle, preserveRenameText); + } + + /** + * Updates the title of the AnvilGUI to the new one. + * + * @param json The json used to parse into a rich chat component + * @param preserveRenameText Whether to preserve the entered rename text + * @throws IllegalArgumentException when json is null + * @see Builder#jsonTitle(String) + */ + static ResponseAction updateJsonTitle(String json, boolean preserveRenameText) { + Validate.notNull(json, "json cannot be null"); + return (anvilGUI, player) -> anvilGUI.setJsonTitle(json, preserveRenameText); + } + + /** + * Open another inventory + * @param otherInventory The inventory to open + * @return The {@link ResponseAction} to achieve the inventory open + * @throws IllegalArgumentException when the otherInventory is null + */ + static ResponseAction openInventory(Inventory otherInventory) { + Validate.notNull(otherInventory, "otherInventory cannot be null"); + return (anvilgui, player) -> player.openInventory(otherInventory); + } + + /** + * Close the AnvilGUI + * @return The {@link ResponseAction} to achieve closing the AnvilGUI + */ + static ResponseAction close() { + return (anvilgui, player) -> anvilgui.closeInventory(); + } + + /** + * Run the provided runnable + * @param runnable The runnable to run + * @return The {@link ResponseAction} to achieve running the runnable + * @throws IllegalArgumentException when the runnable is null + */ + static ResponseAction run(Runnable runnable) { + Validate.notNull(runnable, "runnable cannot be null"); + return (anvilgui, player) -> runnable.run(); + } + } + + /** + * Class wrapping the magic constants of slot numbers in an anvil GUI + */ + public static class Slot { + + private static final int[] values = new int[] {Slot.INPUT_LEFT, Slot.INPUT_RIGHT, Slot.OUTPUT}; + + /** + * The slot on the far left, where the first input is inserted. An {@link ItemStack} is always inserted + * here to be renamed + */ + public static final int INPUT_LEFT = 0; + /** + * Not used, but in a real anvil you are able to put the second item you want to combine here + */ + public static final int INPUT_RIGHT = 1; + /** + * The output slot, where an item is put when two items are combined from {@link #INPUT_LEFT} and + * {@link #INPUT_RIGHT} or {@link #INPUT_LEFT} is renamed + */ + public static final int OUTPUT = 2; + + /** + * Get all anvil slot values + * + * @return The array containing all possible anvil slots + */ + public static int[] values() { + return values; + } + } + + /** Represents a snapshot of the state of an AnvilGUI */ + public static final class StateSnapshot { + + /** + * Create an {@link StateSnapshot} from the current state of an {@link AnvilGUI} + * @param anvilGUI The instance to take the snapshot of + * @return The snapshot + */ + private static StateSnapshot fromAnvilGUI(AnvilGUI anvilGUI) { + final Inventory inventory = anvilGUI.getInventory(); + return new StateSnapshot( + itemNotNull(inventory.getItem(Slot.INPUT_LEFT)).clone(), + itemNotNull(inventory.getItem(Slot.INPUT_RIGHT)).clone(), + itemNotNull(inventory.getItem(Slot.OUTPUT)).clone(), + anvilGUI.player); + } + + /** + * The {@link ItemStack} in the anvilGui slots + */ + private final ItemStack leftItem, rightItem, outputItem; + + /** + * The {@link Player} that clicked the output slot + */ + private final Player player; + + /** + * The event parameter constructor + * @param leftItem The left item in the combine slot of the anvilGUI + * @param rightItem The right item in the combine slot of the anvilGUI + * @param outputItem The item that would have been outputted, when the items would have been combined + * @param player The player that clicked the output slot + */ + public StateSnapshot(ItemStack leftItem, ItemStack rightItem, ItemStack outputItem, Player player) { + this.leftItem = leftItem; + this.rightItem = rightItem; + this.outputItem = outputItem; + this.player = player; + } + + /** + * It returns the item in the left combine slot of the gui + * + * @return The leftItem + */ + public ItemStack getLeftItem() { + return leftItem; + } + + /** + * It returns the item in the right combine slot of the gui + * + * @return The rightItem + */ + public ItemStack getRightItem() { + return rightItem; + } + + /** + * It returns the output item that would have been the result + * by combining the left and right one + * + * @return The outputItem + */ + public ItemStack getOutputItem() { + return outputItem; + } + + /** + * It returns the player that clicked onto the output slot + * + * @return The player + */ + public Player getPlayer() { + return player; + } + + /** + * It returns the text the player typed into the rename field + * + * @return The text of the rename field + */ + public String getText() { + return outputItem.hasItemMeta() ? outputItem.getItemMeta().getDisplayName() : ""; + } + } +} diff --git a/src/main/java/net/wesjd/anvilgui/LICENSE b/src/main/java/net/wesjd/anvilgui/LICENSE new file mode 100644 index 0000000..c735359 --- /dev/null +++ b/src/main/java/net/wesjd/anvilgui/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Wesley Smith + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/src/main/java/net/wesjd/anvilgui/version/PaperWrapper1_21_R4.java b/src/main/java/net/wesjd/anvilgui/version/PaperWrapper1_21_R4.java new file mode 100644 index 0000000..11bc655 --- /dev/null +++ b/src/main/java/net/wesjd/anvilgui/version/PaperWrapper1_21_R4.java @@ -0,0 +1,135 @@ +package net.wesjd.anvilgui.version; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.RegistryAccess; +import net.minecraft.core.component.DataComponentPatch; +import net.minecraft.core.component.DataComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundContainerClosePacket; +import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; +import net.minecraft.network.protocol.game.ClientboundSetExperiencePacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.inventory.*; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.NotNull; + +public final class PaperWrapper1_21_R4 implements VersionWrapper { + private int getRealNextContainerId(Player player) { + return toNMS(player).nextContainerCounter(); + } + + + private ServerPlayer toNMS(Player player) { + return ((CraftPlayer) player).getHandle(); + } + + @Override + public int getNextContainerId(Player player, AnvilContainerWrapper container) { + return ((AnvilContainer) container).containerId; + } + + @Override + public void handleInventoryCloseEvent(Player player) { + //CraftEventFactory.handleInventoryCloseEvent(toNMS(player)); + toNMS(player).doCloseContainer(); // q -> doCloseContainer + } + + @Override + public void sendPacketOpenWindow(Player player, int containerId, Object inventoryTitle) { + toNMS(player).connection.send(new ClientboundOpenScreenPacket(containerId, MenuType.ANVIL, Component.literal(inventoryTitle.toString()))); + } + + @Override + public void sendPacketCloseWindow(Player player, int containerId) { + toNMS(player).connection.send(new ClientboundContainerClosePacket(containerId)); + } + + @Override + public void sendPacketExperienceChange(Player player, int experienceLevel) { + toNMS(player).connection.send(new ClientboundSetExperiencePacket(0f, 0, experienceLevel)); + } + + @Override + public void setActiveContainerDefault(Player player) { + toNMS(player).containerMenu = toNMS(player).inventoryMenu; // cd -> containerMenu, cc -> inventoryMenu + } + + @Override + public void setActiveContainer(Player player, AnvilContainerWrapper container) { + toNMS(player).containerMenu = (AbstractContainerMenu) container; + } + + @Override + public void setActiveContainerId(AnvilContainerWrapper container, int containerId) { } + + @Override + public void addActiveContainerSlotListener(AnvilContainerWrapper container, Player player) { + toNMS(player).initMenu((AbstractContainerMenu) container); + } + + @Override + public AnvilContainerWrapper newContainerAnvil(Player player, Object title) { + return new AnvilContainer(player, getRealNextContainerId(player), Component.literal(title.toString())); + } + + @Override + public Object literalChatComponent(String content) { + return Component.literal(content); // IChatBaseComponent.b -> Component.literal + } + + @Override + public Object jsonChatComponent(String json) { + return Component.Serializer.toJson(Component.literal(json), RegistryAccess.EMPTY); + } + + private static class AnvilContainer extends AnvilMenu implements AnvilContainerWrapper { + public AnvilContainer(Player player, int containerId, Component guiTitle) { + super( + containerId, + ((CraftPlayer) player).getHandle().getInventory(), + ContainerLevelAccess.create(((CraftPlayer) player).getHandle().level(), BlockPos.ZERO) + ); + this.checkReachable = false; + setTitle(guiTitle); + } + + @Override + public void createResult() { + // If the output is empty, copy the left input into the output + Slot output = getSlot(2); // b -> getSlot + if (!output.hasItem()) { // h -> hasItem + output.set(getSlot(0).getItem().copy()); // f -> set, g -> getItem, v -> copy + } + + this.cost.set(0); // y -> cost, a -> set + + // Sync to the client + this.sendAllDataToRemote(); // b -> sendAllDataToRemote + this.broadcastChanges(); // d -> broadcastChanges + } + + @Override + public boolean setItemName(@NotNull String itemName) { + Slot inputLeft = getSlot(0); + if (inputLeft.hasItem()) { + inputLeft + .getItem() + .applyComponents(DataComponentPatch + .builder() + .set(DataComponents.CUSTOM_NAME, Component.literal(itemName)) + .build() + ); + return true; + } + + return false; + } + + @Override + public Inventory getBukkitInventory() { + return this.getBukkitView().getTopInventory(); + } + } +} diff --git a/src/main/java/net/wesjd/anvilgui/version/VersionMatcher.java b/src/main/java/net/wesjd/anvilgui/version/VersionMatcher.java new file mode 100644 index 0000000..c4f1bcc --- /dev/null +++ b/src/main/java/net/wesjd/anvilgui/version/VersionMatcher.java @@ -0,0 +1,51 @@ +package net.wesjd.anvilgui.version; + +import org.bukkit.Bukkit; + +import java.util.HashMap; +import java.util.Map; + +/** + * Matches the server's NMS version to its {@link VersionWrapper} + * + * @author Wesley Smith + * @since 1.2.1 + */ +public class VersionMatcher { + /** Maps a Minecraft version string to the corresponding revision string */ + private static final Map VERSION_TO_REVISION = new HashMap() { + { + this.put("1.21.4", "1_21_R4"); + } + }; + /* This needs to be updated to reflect the newest available version wrapper */ + private static final String FALLBACK_REVISION = "1_21_R4"; + + /** + * Matches the server version to it's {@link VersionWrapper} + * + * @return The {@link VersionWrapper} for this server + * @throws IllegalStateException If the version wrapper failed to be instantiated or is unable to be found + */ + public VersionWrapper match() { + String craftBukkitPackage = Bukkit.getServer().getClass().getPackage().getName(); + + String rVersion; + if (!craftBukkitPackage.contains(".v")) { // cb package not relocated (i.e. paper 1.20.5+) + final String version = Bukkit.getBukkitVersion().split("-")[0]; + rVersion = VERSION_TO_REVISION.getOrDefault(version, FALLBACK_REVISION); + } else { + rVersion = craftBukkitPackage.split("\\.")[3].substring(1); + } + + try { + return (VersionWrapper) Class.forName(getClass().getPackage().getName() + ".PaperWrapper" + rVersion) + .getDeclaredConstructor() + .newInstance(); + } catch (ClassNotFoundException exception) { + throw new IllegalStateException("AnvilGUI does not support server version \"" + rVersion + "\"", exception); + } catch (ReflectiveOperationException exception) { + throw new IllegalStateException("Failed to instantiate version wrapper for version " + rVersion, exception); + } + } +} diff --git a/src/main/java/net/wesjd/anvilgui/version/VersionWrapper.java b/src/main/java/net/wesjd/anvilgui/version/VersionWrapper.java new file mode 100644 index 0000000..5efe2c5 --- /dev/null +++ b/src/main/java/net/wesjd/anvilgui/version/VersionWrapper.java @@ -0,0 +1,150 @@ +package net.wesjd.anvilgui.version; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; + +/** + * Wraps versions to be able to easily use different NMS server versions + * + * @author Wesley Smith + * @since 1.0 + */ +public interface VersionWrapper { + + /** + * Gets the next available NMS container id for the player + * + * @param player The player to get the next container id of + * @param container The container that a new id is being generated for + * @return The next available NMS container id + */ + int getNextContainerId(Player player, AnvilContainerWrapper container); + + /** + * Closes the current inventory for the player + * + * @param player The player that needs their current inventory closed + */ + void handleInventoryCloseEvent(Player player); + + /** + * Sends PacketPlayOutOpenWindow to the player with the container id and window title + * + * @param player The player to send the packet to + * @param containerId The container id to open + * @param inventoryTitle The title of the inventory to be opened (only works in Minecraft 1.14 and above) + */ + void sendPacketOpenWindow(Player player, int containerId, Object inventoryTitle); + + /** + * Sends PacketPlayOutCloseWindow to the player with the container id + * + * @param player The player to send the packet to + * @param containerId The container id to close + */ + void sendPacketCloseWindow(Player player, int containerId); + + /** + * Sends PacketPlayOutExperience to the player with the experience level + * + * @param player The player to send the packet to + * @param experienceLevel The experience level to set + */ + void sendPacketExperienceChange(Player player, int experienceLevel); + + /** + * Sets the NMS player's active container to the default one + * + * @param player The player to set the active container of + */ + void setActiveContainerDefault(Player player); + + /** + * Sets the NMS player's active container to the one supplied + * + * @param player The player to set the active container of + * @param container The container to set as active + */ + void setActiveContainer(Player player, AnvilContainerWrapper container); + + /** + * Sets the supplied windowId of the supplied Container + * + * @param container The container to set the windowId of + * @param containerId The new windowId + */ + void setActiveContainerId(AnvilContainerWrapper container, int containerId); + + /** + * Adds a slot listener to the supplied container for the player + * + * @param container The container to add the slot listener to + * @param player The player to have as a listener + */ + void addActiveContainerSlotListener(AnvilContainerWrapper container, Player player); + + /** + * Creates a new ContainerAnvil + * + * @param player The player to get the container of + * @param title The title of the anvil inventory + * @return The Container instance + */ + AnvilContainerWrapper newContainerAnvil(Player player, Object title); + + /** + * Checks if the current Minecraft version actually supports custom titles + * + * @return The current supported state + */ + default boolean isCustomTitleSupported() { + return true; + } + + /** + * Creates a new chat component that does not handle the content in any special way + * + * @param content The content to display + * @return Version-specific ChatComponent instance + */ + Object literalChatComponent(String content); + + /** + * Creates a new rich chat component from the provided json + * + * @param json The component to parse + * @return Version-specific ChatComponent instance + */ + Object jsonChatComponent(String json); + + /** + * Interface implemented by the custom NMS AnvilContainer used to interact with it directly + */ + interface AnvilContainerWrapper { + + /** + * Retrieves the raw text that has been entered into the Anvil at the moment + *

+ * This field is marked as public in the Minecraft AnvilContainer only from Minecraft 1.11 and upwards + * + * @return The raw text in the rename field + */ + default String getRenameText() { + return null; + } + + /** + * Sets the provided text as the literal hovername of the item in the left input slot + * + * @param text The text to set + */ + default void setRenameText(String text) {} + + /** + * Gets the {@link Inventory} wrapper of the NMS container + * + * @return The inventory of the NMS container + */ + Inventory getBukkitInventory(); + } +} diff --git a/src/main/java/xyz/ineanto/nicko/Nicko.java b/src/main/java/xyz/ineanto/nicko/Nicko.java index fcd8a3c..83ec229 100644 --- a/src/main/java/xyz/ineanto/nicko/Nicko.java +++ b/src/main/java/xyz/ineanto/nicko/Nicko.java @@ -3,7 +3,6 @@ package xyz.ineanto.nicko; import com.comphenix.protocol.utility.MinecraftVersion; import org.bukkit.Bukkit; import org.bukkit.Material; -import org.bukkit.command.PluginCommand; import org.bukkit.plugin.java.JavaPlugin; import xyz.ineanto.nicko.appearance.random.RandomNameFetcher; import xyz.ineanto.nicko.command.NickoCommand; @@ -21,6 +20,7 @@ import xyz.ineanto.nicko.storage.PlayerDataStore; import xyz.ineanto.nicko.storage.json.JSONStorage; import xyz.ineanto.nicko.storage.map.MapCache; import xyz.ineanto.nicko.storage.name.PlayerNameStore; +import xyz.xenondevs.invui.InvUI; import xyz.xenondevs.invui.gui.structure.Structure; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SimpleItem; @@ -30,8 +30,6 @@ import java.io.IOException; public class Nicko extends JavaPlugin { private static Nicko plugin; - private final boolean unitTesting; - private MojangAPI mojangAPI; private PlayerDataStore dataStore; private ConfigurationManager configurationManager; @@ -40,19 +38,6 @@ public class Nicko extends JavaPlugin { private PlayerNameStore nameStore; private RandomNameFetcher nameFetcher; - public Nicko() { - this.unitTesting = false; - } - - /** - * Used by MockBukkit - */ - protected Nicko(Configuration configuration) { - this.unitTesting = true; - this.configuration = configuration; - getLogger().info("Unit Testing Mode enabled."); - } - @Override public void onEnable() { plugin = this; @@ -96,41 +81,37 @@ public class Nicko extends JavaPlugin { dataStore.setCache(cache); } - if (!unitTesting) { - nameStore = new PlayerNameStore(); - mojangAPI = new MojangAPI(); - nameFetcher = new RandomNameFetcher(this); + nameStore = new PlayerNameStore(); + mojangAPI = new MojangAPI(); + nameFetcher = new RandomNameFetcher(this); - new ConfigurationMigrator(this).migrate(); + new ConfigurationMigrator(this).migrate(); + InvUI.getInstance().setPlugin(this); - if (configuration.isCustomLocale()) { - try { - CustomLanguage.dumpIntoFile(Language.ENGLISH); - customLanguage = new CustomLanguage(); - new CustomLocaleMigrator(this, customLanguage).migrate(); - getLogger().info("Successfully loaded the custom locale."); - } catch (IOException e) { - getLogger().severe("Failed to load the custom locale!"); - } + if (configuration.isCustomLocale()) { + try { + CustomLanguage.dumpIntoFile(Language.ENGLISH); + customLanguage = new CustomLanguage(); + new CustomLocaleMigrator(this, customLanguage).migrate(); + getLogger().info("Successfully loaded the custom locale."); + } catch (IOException e) { + getLogger().severe("Failed to load the custom locale!"); } - - final PluginCommand command = getCommand("nicko"); - if (command != null) { - command.setExecutor(new NickoCommand()); - } - - Structure.addGlobalIngredient('#', new SimpleItem(new ItemBuilder(Material.AIR))); - Structure.addGlobalIngredient('%', new SimpleItem(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setDisplayName(" "))); - - if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { - getLogger().info("Enabling PlaceHolderAPI support..."); - new NickoExpansion(this).register(); - } - - getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this); - getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this); } + registerCommand("nicko", new NickoCommand()); + + Structure.addGlobalIngredient('#', new SimpleItem(new ItemBuilder(Material.AIR))); + Structure.addGlobalIngredient('%', new SimpleItem(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setDisplayName(" "))); + + if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { + getLogger().info("Enabling PlaceHolderAPI support..."); + new NickoExpansion(this).register(); + } + + getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this); + getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this); + getLogger().info("Nicko has been enabled."); } @@ -145,9 +126,7 @@ public class Nicko extends JavaPlugin { } } - if (!unitTesting) { - nameStore.clearStoredNames(); - } + nameStore.clearStoredNames(); getLogger().info("Nicko (Bukkit) has been disabled."); } diff --git a/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java b/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java index 118696e..6665761 100644 --- a/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java +++ b/src/main/java/xyz/ineanto/nicko/command/NickoCommand.java @@ -1,28 +1,29 @@ package xyz.ineanto.nicko.command; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; +import io.papermc.paper.command.brigadier.BasicCommand; +import io.papermc.paper.command.brigadier.CommandSourceStack; import org.bukkit.command.CommandSender; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import xyz.ineanto.nicko.gui.HomeGUI; -import xyz.ineanto.nicko.language.PlayerLanguage; -import xyz.ineanto.nicko.language.LanguageKey; -public class NickoCommand implements CommandExecutor { +public class NickoCommand implements BasicCommand { @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { - if (sender instanceof Player player) { - if (player.isOp() || player.hasPermission("nicko.use") || player.hasPermission("nicko.*")) { - new HomeGUI(player).open(); - } else { - final PlayerLanguage playerLanguage = new PlayerLanguage(player); - player.sendMessage(playerLanguage.translate(LanguageKey.Error.PERMISSION, true)); - } - return false; - } + public void execute(CommandSourceStack stack, String[] strings) { + final Entity executor = stack.getExecutor(); + final Player player = (Player) executor; - sender.sendMessage("This plugin can only be used in-game. Sorry!"); - return false; + new HomeGUI(player).open(); + } + + @Override + public boolean canUse(CommandSender sender) { + return sender instanceof Player && sender.isOp() || sender.hasPermission(permission()); + } + + @Override + public @Nullable String permission() { + return "nicko.use"; } } diff --git a/src/main/java/xyz/ineanto/nicko/loader/NickoPluginLoader.java b/src/main/java/xyz/ineanto/nicko/loader/NickoPluginLoader.java index 1f0f511..eaac594 100644 --- a/src/main/java/xyz/ineanto/nicko/loader/NickoPluginLoader.java +++ b/src/main/java/xyz/ineanto/nicko/loader/NickoPluginLoader.java @@ -11,10 +11,12 @@ public class NickoPluginLoader implements PluginLoader { @Override public void classloader(PluginClasspathBuilder pluginClasspathBuilder) { final MavenLibraryResolver resolver = new MavenLibraryResolver(); + resolver.addRepository(new RemoteRepository.Builder("xenondevs", "default", "https://repo.xenondevs.xyz/releases/").build()); - resolver.addRepository(new RemoteRepository.Builder("wesjd", "default", "https://repo.codemc.io/repository/maven-snapshots/").build()); + resolver.addRepository(new RemoteRepository.Builder("codemc", "default", "https://repo.codemc.io/repository/maven-snapshots/").build()); resolver.addDependency(new Dependency(new DefaultArtifact("xyz.xenondevs.invui:invui:pom:1.44"), null)); - resolver.addDependency(new Dependency(new DefaultArtifact("net:wesjd:anvilgui:1.10.4-SNAPSHOT"), null)); + //resolver.addDependency(new Dependency(new DefaultArtifact("net.wesjd:anvilgui:1.10.4-SNAPSHOT"), null)); + pluginClasspathBuilder.addLibrary(resolver); } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/paper-plugin.yml similarity index 63% rename from src/main/resources/plugin.yml rename to src/main/resources/paper-plugin.yml index 08b70ce..048a12e 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/paper-plugin.yml @@ -1,17 +1,19 @@ name: Nicko main: xyz.ineanto.nicko.Nicko +loader: xyz.ineanto.nicko.loader.NickoPluginLoader version: ${version} author: Ineanto description: "The feature packed, next generation disguise plugin for Minecraft." -api-version: 1.21 +api-version: "1.21" softdepend: [ PlaceholderAPI ] depend: - ProtocolLib -load: POSTWORLD -commands: - nicko: - description: "Opens Nicko's GUI." - permission: nicko.use + +# Suppose we require ProtocolLib to be loaded for our plugin +AnvilGUI: + join-classpath: true + required: true + permissions: nicko.*: default: op From 3cc2b4415d4539fc2f31f1736922cc0a1a179aa9 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 20 Mar 2025 20:37:06 +0100 Subject: [PATCH 250/296] refactor: cleanup leftovers from before the paperweight switch --- .gitignore | 6 +----- build.gradle.kts | 7 ------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 89b7f3d..8a238de 100644 --- a/.gitignore +++ b/.gitignore @@ -26,8 +26,4 @@ bin/ !**/src/test/**/bin/ ### Server ### -run/ - -### Private ### -TODO -src/main/java/net/ \ No newline at end of file +run/ \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 7f90f12..67a9fe2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -36,9 +36,6 @@ dependencies { compileOnly("me.clip:placeholderapi:2.11.5") compileOnly("net.kyori:adventure-api:4.17.0") compileOnly("xyz.xenondevs.invui:invui-core:$invuiVersion") - //compileOnly("net.wesjd:anvilgui:1.10.4-SNAPSHOT") - - //implementation("xyz.xenondevs.invui:inventory-access-r22:$invuiVersion:remapped-mojang") implementation("com.github.jsixface:yamlconfig:1.2") implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.18.1") @@ -61,8 +58,6 @@ tasks { shadowJar { // RELOCATIONS - //relocate("xyz.xenondevs", "xyz.ineanto.nicko.libs.invui") - //relocate("net.wesjd", "xyz.ineanto.nicko.libs.anvilgui") relocate("com.github.jsixface", "xyz.ineanto.nicko.libs.yaml") relocate("me.clip", "xyz.ineanto.nicko.libs.placeholderapi") relocate("com.fasterxml.jackson", "xyz.ineanto.nicko.libs.jacksonpr") @@ -91,8 +86,6 @@ tasks { // MINIFY minimize { - //exclude(dependency("xyz.xenondevs.invui:.*")) - //exclude(dependency("net.wesjd:.*")) exclude(dependency("org.bstats:.*")) } From 11730d52345b8922cf59abe621388f1dce83019e Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 20 Mar 2025 20:37:34 +0100 Subject: [PATCH 251/296] fix: remove test language file --- src/test/resources/en.yml | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 src/test/resources/en.yml diff --git a/src/test/resources/en.yml b/src/test/resources/en.yml deleted file mode 100644 index 7b83c58..0000000 --- a/src/test/resources/en.yml +++ /dev/null @@ -1,4 +0,0 @@ -# Nicko ${version} - Language File: - -# hello I'm the good version -version: "1.1.0" \ No newline at end of file From 1a81c7c6578b0906cbd0facbd91e18b5e26f7e6b Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 26 Mar 2025 19:29:12 +0100 Subject: [PATCH 252/296] feat: split prompt from AnvilGUI dependency --- build.gradle.kts | 1 + .../xyz/ineanto/nicko/anvil/AnvilManager.java | 148 ------------------ .../nicko/appearance/AppearanceManager.java | 32 ++-- .../custom/PlayerResetDisguiseEvent.java | 36 +++++ .../admin/check/PlayerInformationItem.java | 2 +- .../gui/items/appearance/ChangeBothItem.java | 8 +- .../gui/items/appearance/ChangeNameItem.java | 13 +- .../gui/items/appearance/ChangeSkinItem.java | 9 +- .../nicko/gui/items/home/RandomSkinItem.java | 2 +- .../nicko/gui/items/home/ResetItem.java | 2 +- .../ineanto/nicko/gui/prompt/AnvilPrompt.java | 112 +++++++++++++ .../xyz/ineanto/nicko/gui/prompt/Prompt.java | 11 ++ .../nicko/gui/prompt/PromptManager.java | 79 ++++++++++ 13 files changed, 280 insertions(+), 175 deletions(-) delete mode 100644 src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java create mode 100644 src/main/java/xyz/ineanto/nicko/event/custom/PlayerResetDisguiseEvent.java create mode 100644 src/main/java/xyz/ineanto/nicko/gui/prompt/AnvilPrompt.java create mode 100644 src/main/java/xyz/ineanto/nicko/gui/prompt/Prompt.java create mode 100644 src/main/java/xyz/ineanto/nicko/gui/prompt/PromptManager.java diff --git a/build.gradle.kts b/build.gradle.kts index 67a9fe2..3ca7fbf 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -37,6 +37,7 @@ dependencies { compileOnly("net.kyori:adventure-api:4.17.0") compileOnly("xyz.xenondevs.invui:invui-core:$invuiVersion") + implementation("de.rapha149.signgui:signgui:2.5.0") implementation("com.github.jsixface:yamlconfig:1.2") implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.18.1") implementation("com.fasterxml.jackson.core:jackson-core:2.18.1") diff --git a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java b/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java deleted file mode 100644 index 5e326d6..0000000 --- a/src/main/java/xyz/ineanto/nicko/anvil/AnvilManager.java +++ /dev/null @@ -1,148 +0,0 @@ -package xyz.ineanto.nicko.anvil; - -import net.kyori.adventure.text.Component; -import net.wesjd.anvilgui.AnvilGUI; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import xyz.ineanto.nicko.Nicko; -import xyz.ineanto.nicko.appearance.ActionResult; -import xyz.ineanto.nicko.appearance.AppearanceManager; -import xyz.ineanto.nicko.event.custom.PlayerDisguiseEvent; -import xyz.ineanto.nicko.language.LanguageKey; -import xyz.ineanto.nicko.language.PlayerLanguage; -import xyz.ineanto.nicko.mojang.MojangUtils; -import xyz.ineanto.nicko.profile.NickoProfile; -import xyz.ineanto.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 = Nicko.getInstance().getDataStore(); - private final NickoProfile profile; - private final PlayerLanguage playerLanguage; - - public AnvilManager(Player player) { - this.player = player; - this.playerLanguage = new PlayerLanguage(player); - - final Optional optionalProfile = dataStore.getData(player.getUniqueId()); - this.profile = optionalProfile.orElse(NickoProfile.EMPTY_PROFILE.clone()); - this.appearanceManager = new AppearanceManager(player); - } - - public void openNameThenSkinAnvil() { - getNameThenSkinAnvil().open(player); - } - - public void openSkinAnvil() { - getSkinAnvil().open(player); - } - - public void openNameAnvil() { - getNameAnvil().open(player); - } - - private AnvilGUI.Builder getNameThenSkinAnvil() { - return new AnvilGUI.Builder() - .plugin(Nicko.getInstance()) - .itemLeft(getLeftItem(false)) - .interactableSlots(AnvilGUI.Slot.OUTPUT) - .onClick((slot, snapshot) -> { - if (slot == AnvilGUI.Slot.OUTPUT) { - if (MojangUtils.isUsernameInvalid(snapshot.getText())) { - return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); - } else { - profile.setName(snapshot.getText()); - openSkinAnvil(); - return Collections.singletonList(AnvilGUI.ResponseAction.close()); - } - } - return Collections.emptyList(); - }) - .text("New name..."); - } - - private AnvilGUI.Builder getNameAnvil() { - return new AnvilGUI.Builder() - .plugin(Nicko.getInstance()) - .itemLeft(getLeftItem(false)) - .interactableSlots(AnvilGUI.Slot.OUTPUT) - .onClick((slot, snapshot) -> { - if (slot == AnvilGUI.Slot.OUTPUT) { - if (MojangUtils.isUsernameInvalid(snapshot.getText())) { - return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); - } else { - profile.setName(snapshot.getText()); - dataStore.updateCache(player.getUniqueId(), profile); - return sendResultAndClose(false); - } - } - return Collections.emptyList(); - }) - .text("New name..."); - } - - private AnvilGUI.Builder getSkinAnvil() { - return new AnvilGUI.Builder() - .plugin(Nicko.getInstance()) - .itemLeft(getLeftItem(true)) - .interactableSlots(AnvilGUI.Slot.OUTPUT) - .onClick((slot, snapshot) -> { - if (slot == AnvilGUI.Slot.OUTPUT) { - if (MojangUtils.isUsernameInvalid(snapshot.getText())) { - return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); - } else { - profile.setSkin(snapshot.getText()); - dataStore.updateCache(player.getUniqueId(), profile); - return sendResultAndClose(true); - } - } - return Collections.emptyList(); - }) - .text("New skin..."); - } - - private List sendResultAndClose(boolean skinChange) { - final PlayerDisguiseEvent event = new PlayerDisguiseEvent(player, profile.getSkin(), player.getName()); - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) { return Collections.singletonList(AnvilGUI.ResponseAction.close()); } - - final ActionResult actionResult = appearanceManager.update(skinChange, false); - if (!actionResult.isError()) { - player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Appearance.Set.OK)); - player.playSound(player.getLocation(), Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1, 1f); - } else { - player.sendMessage( - playerLanguage.translateWithOops( - LanguageKey.Event.Appearance.Set.ERROR, - playerLanguage.translate(actionResult.getErrorKey(), false) - )); - player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_PLACE, 1f, 1f); - } - return Collections.singletonList(AnvilGUI.ResponseAction.close()); - } - - private ItemStack getLeftItem(boolean skin) { - final ItemStack item = new ItemStack(Material.PAPER); - final ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - if (skin) { - meta.displayName(Component.text(playerLanguage.translate(LanguageKey.GUI.NEW_SKIN, false))); - } else { - meta.displayName(Component.text(playerLanguage.translate(LanguageKey.GUI.NEW_NAME, false))); - } - } - - item.setItemMeta(meta); - return item; - } -} \ No newline at end of file diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index 465ccf7..ecc22ff 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -1,8 +1,11 @@ package xyz.ineanto.nicko.appearance; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerTeleportEvent; import xyz.ineanto.nicko.Nicko; +import xyz.ineanto.nicko.event.custom.PlayerDisguiseEvent; +import xyz.ineanto.nicko.event.custom.PlayerResetDisguiseEvent; import xyz.ineanto.nicko.packet.InternalPacketSender; import xyz.ineanto.nicko.packet.PacketSender; import xyz.ineanto.nicko.profile.NickoProfile; @@ -24,25 +27,24 @@ public class AppearanceManager { this.packetSender = new InternalPacketSender(player, getNickoProfile()); } - public ActionResult reset(boolean apply) { + public ActionResult reset() { final NickoProfile profile = getNickoProfile(); final String defaultName = nameStore.getStoredName(player); + // Call the event. + final PlayerResetDisguiseEvent event = new PlayerResetDisguiseEvent(player); + Bukkit.getPluginManager().callEvent(event); + profile.setName(defaultName); profile.setSkin(defaultName); + + final ActionResult result = update(true, true); + + profile.setName(null); + profile.setSkin(null); dataStore.getCache().cache(player.getUniqueId(), profile); - if (apply) { - final ActionResult result = update(true, true); - - profile.setName(null); - profile.setSkin(null); - dataStore.getCache().cache(player.getUniqueId(), profile); - - return result; - } - - return ActionResult.ok(); + return result; } public ActionResult update(boolean skinChange, boolean reset) { @@ -52,9 +54,13 @@ public class AppearanceManager { final ActionResult result = packetSender.sendGameProfileUpdate(displayName, skinChange, reset); if (result.isError()) { - return reset(false); + return reset(); } + // Call the event. + final PlayerDisguiseEvent event = new PlayerDisguiseEvent(player, profile.getSkin(), profile.getName()); + Bukkit.getPluginManager().callEvent(event); + packetSender.sendEntityMetadataUpdate(); packetSender.sendTabListUpdate(displayName); respawnPlayer(); diff --git a/src/main/java/xyz/ineanto/nicko/event/custom/PlayerResetDisguiseEvent.java b/src/main/java/xyz/ineanto/nicko/event/custom/PlayerResetDisguiseEvent.java new file mode 100644 index 0000000..cc9f1ec --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/event/custom/PlayerResetDisguiseEvent.java @@ -0,0 +1,36 @@ +package xyz.ineanto.nicko.event.custom; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +public class PlayerResetDisguiseEvent extends Event implements Cancellable { + private static final HandlerList HANDLERS_LIST = new HandlerList(); + private boolean isCancelled; + private final Player player; + + public PlayerResetDisguiseEvent(Player player) { + this.player = player; + } + + @Override + public boolean isCancelled() { + return isCancelled; + } + + @Override + public void setCancelled(boolean isCancelled) { + this.isCancelled = isCancelled; + } + + @Override + public @NotNull HandlerList getHandlers() { + return HANDLERS_LIST; + } + + public Player getPlayer() { + return player; + } +} diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java index bc01434..6e396a0 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/check/PlayerInformationItem.java @@ -78,7 +78,7 @@ public class PlayerInformationItem extends AsyncItem { @Override public void onConfirm() { final AppearanceManager appearanceManager = new AppearanceManager(target); - appearanceManager.reset(true); + appearanceManager.reset(); player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_TRADE, 1, 1f); player.sendMessage(playerLanguage.translate(LanguageKey.Event.Admin.Check.REMOVE_SKIN, true, target.getName())); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java index a076ab1..5a70c4f 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeBothItem.java @@ -3,9 +3,9 @@ package xyz.ineanto.nicko.gui.items.appearance; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; -import xyz.ineanto.nicko.anvil.AnvilManager; -import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.gui.prompt.PromptManager; import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.language.PlayerLanguage; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; @@ -24,8 +24,8 @@ public class ChangeBothItem { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { click.getEvent().getView().close(); - final AnvilManager manager = new AnvilManager(click.getPlayer()); - manager.openNameThenSkinAnvil(); + final PromptManager manager = new PromptManager(click.getPlayer()); + manager.displayNameThenSkinPrompt(); } return true; }); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java index 744851c..6f54bda 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java @@ -3,16 +3,21 @@ package xyz.ineanto.nicko.gui.items.appearance; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; -import xyz.ineanto.nicko.anvil.AnvilManager; -import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.appearance.AppearanceManager; +import xyz.ineanto.nicko.gui.prompt.PromptManager; import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.language.PlayerLanguage; import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; public class ChangeNameItem { + private final AppearanceManager appearanceManager; + private final Player player; private final PlayerLanguage playerLanguage; public ChangeNameItem(Player player) { + this.appearanceManager = new AppearanceManager(player); + this.player = player; this.playerLanguage = new PlayerLanguage(player); } @@ -24,8 +29,8 @@ public class ChangeNameItem { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { click.getEvent().getView().close(); - final AnvilManager manager = new AnvilManager(click.getPlayer()); - manager.openNameAnvil(); + final PromptManager manager = new PromptManager(click.getPlayer()); + manager.displayNamePromptThenUpdate(); } return true; }); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java index 8753fff..e6b841b 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java @@ -4,7 +4,8 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import xyz.ineanto.nicko.Nicko; -import xyz.ineanto.nicko.anvil.AnvilManager; +import xyz.ineanto.nicko.appearance.AppearanceManager; +import xyz.ineanto.nicko.gui.prompt.PromptManager; import xyz.ineanto.nicko.language.LanguageKey; import xyz.ineanto.nicko.language.PlayerLanguage; import xyz.ineanto.nicko.storage.name.PlayerNameStore; @@ -17,11 +18,13 @@ import xyz.xenondevs.invui.util.MojangApiUtils; import java.io.IOException; public class ChangeSkinItem { + private final AppearanceManager appearanceManager; private final PlayerLanguage playerLanguage; private final PlayerNameStore playerNameStore; private final Player player; public ChangeSkinItem(Player player) { + this.appearanceManager = new AppearanceManager(player); this.playerLanguage = new PlayerLanguage(player); this.playerNameStore = Nicko.getInstance().getNameStore(); this.player = player; @@ -42,8 +45,8 @@ public class ChangeSkinItem { final ClickType clickType = click.getClickType(); if (clickType.isLeftClick() || clickType.isRightClick()) { click.getEvent().getView().close(); - final AnvilManager manager = new AnvilManager(click.getPlayer()); - manager.openSkinAnvil(); + final PromptManager manager = new PromptManager(click.getPlayer()); + manager.displaySkinPromptThenUpdate(); } return true; }); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java index d15cee5..9f7b5e0 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java @@ -49,7 +49,7 @@ public class RandomSkinItem { playerLanguage.translate(result.getErrorKey(), false) ) ); - appearanceManager.reset(false); + appearanceManager.reset(); } }); return true; diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java index 2903caf..2e8fb1c 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java @@ -36,7 +36,7 @@ public class ResetItem { } final AppearanceManager appearanceManager = new AppearanceManager(player); - if (!appearanceManager.reset(true).isError()) { + if (!appearanceManager.reset().isError()) { player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Appearance.Remove.OK)); } else { player.sendMessage(playerLanguage.translateWithOops(LanguageKey.Event.Appearance.Remove.ERROR)); diff --git a/src/main/java/xyz/ineanto/nicko/gui/prompt/AnvilPrompt.java b/src/main/java/xyz/ineanto/nicko/gui/prompt/AnvilPrompt.java new file mode 100644 index 0000000..41a5f84 --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/gui/prompt/AnvilPrompt.java @@ -0,0 +1,112 @@ +package xyz.ineanto.nicko.gui.prompt; + +import net.kyori.adventure.text.Component; +import net.wesjd.anvilgui.AnvilGUI; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import xyz.ineanto.nicko.Nicko; +import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.mojang.MojangUtils; + +import java.util.Collections; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicReference; + +public class AnvilPrompt implements Prompt { + private final Player player; + private final PlayerLanguage playerLanguage; + + private final AtomicReference> name = new AtomicReference<>(); + private final AtomicReference> skin = new AtomicReference<>(); + + public AnvilPrompt(Player player, PlayerLanguage playerLanguage) { + this.player = player; + this.playerLanguage = playerLanguage; + } + + @Override + public Optional displayNameThenSkinPrompt() { + new AnvilGUI.Builder() + .plugin(Nicko.getInstance()) + .itemLeft(getLeftItem(false)) + .interactableSlots(AnvilGUI.Slot.OUTPUT) + .onClick((slot, snapshot) -> { + if (slot == AnvilGUI.Slot.OUTPUT) { + if (MojangUtils.isUsernameInvalid(snapshot.getText())) { + return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); + } else { + // Praying that it works. This is untested code! + name.set(Optional.of(snapshot.getText())); + + final Optional skinFromAnvil = displaySkinPrompt(); + skin.set(skinFromAnvil); + } + } + return Collections.emptyList(); + }) + .text("New name...").open(player); + + if (name.get().isEmpty() || skin.get().isEmpty()) { + return Optional.empty(); + } + + return Optional.of(new String[]{name.get().orElse(player.getName()), skin.get().orElse(player.getName())}); + } + + @Override + public Optional displaySkinPrompt() { + new AnvilGUI.Builder() + .plugin(Nicko.getInstance()) + .itemLeft(getLeftItem(true)) + .interactableSlots(AnvilGUI.Slot.OUTPUT) + .onClick((slot, snapshot) -> { + if (slot == AnvilGUI.Slot.OUTPUT) { + if (MojangUtils.isUsernameInvalid(snapshot.getText())) { + return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); + } else { + skin.set(Optional.of(snapshot.getText())); + return Collections.singletonList(AnvilGUI.ResponseAction.close()); + } + } + return Collections.emptyList(); + }) + .text("New skin...").open(player); + return skin.get(); + } + + @Override + public Optional displayNamePrompt() { + new AnvilGUI.Builder() + .plugin(Nicko.getInstance()) + .itemLeft(getLeftItem(false)) + .interactableSlots(AnvilGUI.Slot.OUTPUT) + .onClick((slot, snapshot) -> { + if (slot == AnvilGUI.Slot.OUTPUT) { + if (MojangUtils.isUsernameInvalid(snapshot.getText())) { + return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!")); + } else { + name.set(Optional.of(snapshot.getText())); + return Collections.singletonList(AnvilGUI.ResponseAction.close()); + } + } + return Collections.emptyList(); + }) + .text("New name...").open(player); + return name.get(); + } + + private ItemStack getLeftItem(boolean skin) { + final ItemStack item = new ItemStack(Material.PAPER); + final ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.displayName(Component.text(playerLanguage.translate(skin ? LanguageKey.GUI.NEW_SKIN : LanguageKey.GUI.NEW_NAME, false))); + } + + item.setItemMeta(meta); + return item; + } +} diff --git a/src/main/java/xyz/ineanto/nicko/gui/prompt/Prompt.java b/src/main/java/xyz/ineanto/nicko/gui/prompt/Prompt.java new file mode 100644 index 0000000..afe4603 --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/gui/prompt/Prompt.java @@ -0,0 +1,11 @@ +package xyz.ineanto.nicko.gui.prompt; + +import java.util.Optional; + +public interface Prompt { + Optional displayNameThenSkinPrompt(); + + Optional displaySkinPrompt(); + + Optional displayNamePrompt(); +} diff --git a/src/main/java/xyz/ineanto/nicko/gui/prompt/PromptManager.java b/src/main/java/xyz/ineanto/nicko/gui/prompt/PromptManager.java new file mode 100644 index 0000000..afd9a96 --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/gui/prompt/PromptManager.java @@ -0,0 +1,79 @@ +package xyz.ineanto.nicko.gui.prompt; + +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import xyz.ineanto.nicko.Nicko; +import xyz.ineanto.nicko.appearance.ActionResult; +import xyz.ineanto.nicko.appearance.AppearanceManager; +import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.language.PlayerLanguage; +import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.storage.PlayerDataStore; + +import java.util.Optional; + +public class PromptManager { + private final AppearanceManager appearanceManager; + private final NickoProfile profile; + private final Player player; + private final Prompt prompt; + private final PlayerDataStore dataStore = Nicko.getInstance().getDataStore(); + private final PlayerLanguage playerLanguage; + + public PromptManager(Player player) { + this.player = player; + this.playerLanguage = new PlayerLanguage(player); + + final Optional optionalProfile = dataStore.getData(player.getUniqueId()); + this.profile = optionalProfile.orElse(NickoProfile.EMPTY_PROFILE.clone()); + this.appearanceManager = new AppearanceManager(player); + this.prompt = new AnvilPrompt(player, playerLanguage); + } + + public void displayNameThenSkinPrompt() { + final Optional optionalValues = prompt.displayNameThenSkinPrompt(); + + if (optionalValues.isPresent()) { + final String[] values = optionalValues.get(); + profile.setName(values[0]); + profile.setSkin(values[1]); + dataStore.updateCache(player.getUniqueId(), profile); + update(true); + } + } + + public void displaySkinPromptThenUpdate() { + final Optional name = prompt.displaySkinPrompt(); + + if (name.isPresent()) { + profile.setName(name.get()); + dataStore.updateCache(player.getUniqueId(), profile); + update(false); + } + } + + public void displayNamePromptThenUpdate() { + final Optional name = prompt.displayNamePrompt(); + + if (name.isPresent()) { + profile.setName(name.get()); + dataStore.updateCache(player.getUniqueId(), profile); + update(false); + } + } + + private void update(boolean skinChange) { + final ActionResult actionResult = appearanceManager.update(skinChange, false); + if (!actionResult.isError()) { + player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Appearance.Set.OK)); + player.playSound(player.getLocation(), Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1, 1f); + } else { + player.sendMessage( + playerLanguage.translateWithOops( + LanguageKey.Event.Appearance.Set.ERROR, + playerLanguage.translate(actionResult.getErrorKey(), false) + )); + player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_PLACE, 1f, 1f); + } + } +} \ No newline at end of file From 1edfbb9123caeb2f01eac4a6d1462b1ebee3b6ae Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 26 Mar 2025 19:34:25 +0100 Subject: [PATCH 253/296] refactor: remove file dependencies --- build.gradle.kts | 3 + .../com/comphenix/protocol/utility/LICENSE | 13 - .../protocol/utility/MinecraftVersion.java | 468 --------- .../protocol/utility/SnapshotVersion.java | 150 --- .../java/net/wesjd/anvilgui/AnvilGUI.java | 889 ------------------ src/main/java/net/wesjd/anvilgui/LICENSE | 21 - .../anvilgui/version/PaperWrapper1_21_R4.java | 135 --- .../anvilgui/version/VersionMatcher.java | 51 - .../anvilgui/version/VersionWrapper.java | 150 --- .../ineanto/nicko/gui/prompt/AnvilPrompt.java | 4 + 10 files changed, 7 insertions(+), 1877 deletions(-) delete mode 100644 src/main/java/com/comphenix/protocol/utility/LICENSE delete mode 100644 src/main/java/com/comphenix/protocol/utility/MinecraftVersion.java delete mode 100644 src/main/java/com/comphenix/protocol/utility/SnapshotVersion.java delete mode 100644 src/main/java/net/wesjd/anvilgui/AnvilGUI.java delete mode 100644 src/main/java/net/wesjd/anvilgui/LICENSE delete mode 100644 src/main/java/net/wesjd/anvilgui/version/PaperWrapper1_21_R4.java delete mode 100644 src/main/java/net/wesjd/anvilgui/version/VersionMatcher.java delete mode 100644 src/main/java/net/wesjd/anvilgui/version/VersionWrapper.java diff --git a/build.gradle.kts b/build.gradle.kts index 3ca7fbf..9681564 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -36,6 +36,7 @@ dependencies { compileOnly("me.clip:placeholderapi:2.11.5") compileOnly("net.kyori:adventure-api:4.17.0") compileOnly("xyz.xenondevs.invui:invui-core:$invuiVersion") + compileOnly("net.wesjd:anvilgui:1.10.4-SNAPSHOT") implementation("de.rapha149.signgui:signgui:2.5.0") implementation("com.github.jsixface:yamlconfig:1.2") @@ -59,6 +60,7 @@ tasks { shadowJar { // RELOCATIONS + relocate("net.wesjd", "xyz.ineanto.nicko.libs.anvilgui") relocate("com.github.jsixface", "xyz.ineanto.nicko.libs.yaml") relocate("me.clip", "xyz.ineanto.nicko.libs.placeholderapi") relocate("com.fasterxml.jackson", "xyz.ineanto.nicko.libs.jacksonpr") @@ -87,6 +89,7 @@ tasks { // MINIFY minimize { + exclude(dependency("xyz.xenondevs.invui:.*")) exclude(dependency("org.bstats:.*")) } diff --git a/src/main/java/com/comphenix/protocol/utility/LICENSE b/src/main/java/com/comphenix/protocol/utility/LICENSE deleted file mode 100644 index 2673e3f..0000000 --- a/src/main/java/com/comphenix/protocol/utility/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright (C) 2012 Kristian S. Stangeland - -This program is free software; you can redistribute it and/or modify it under the terms of the -GNU General Public License as published by the Free Software Foundation; either version 2 of -the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with this program; -if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA diff --git a/src/main/java/com/comphenix/protocol/utility/MinecraftVersion.java b/src/main/java/com/comphenix/protocol/utility/MinecraftVersion.java deleted file mode 100644 index 0f3cd7b..0000000 --- a/src/main/java/com/comphenix/protocol/utility/MinecraftVersion.java +++ /dev/null @@ -1,468 +0,0 @@ -/* - * ProtocolLib - Bukkit server library that allows access to the Minecraft protocol. - * Copyright (C) 2012 Kristian S. Stangeland - * - * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -package com.comphenix.protocol.utility; - -import com.comphenix.protocol.ProtocolLibrary; -import com.google.common.collect.ComparisonChain; -import com.google.common.collect.Ordering; -import org.bukkit.Bukkit; -import org.bukkit.Server; - -import java.io.Serializable; -import java.text.SimpleDateFormat; -import java.util.Locale; -import java.util.Objects; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Determine the current Minecraft version. - * - * @author Kristian - */ -public final class MinecraftVersion implements Comparable, Serializable { - /** - * Version 1.21.4 - the garden awakens drop - */ - public static final MinecraftVersion v1_21_4 = new MinecraftVersion("1.21.4"); - - /** - * Version 1.21.2 - the bundles of bravery drop - */ - public static final MinecraftVersion v1_21_2 = new MinecraftVersion("1.21.2"); - - /** - * Version 1.21.0 - the tricky trials update - */ - public static final MinecraftVersion v1_21_0 = new MinecraftVersion("1.21.0"); - - /** - * Version 1.20.5 - the cookie and transfer packet update - */ - public static final MinecraftVersion v1_20_5 = new MinecraftVersion("1.20.5"); - - /** - * Version 1.20.4 - the decorated pot update - */ - public static final MinecraftVersion v1_20_4 = new MinecraftVersion("1.20.4"); - - /** - * Version 1.20.2 - the update that added the configuration protocol phase. - */ - public static final MinecraftVersion CONFIG_PHASE_PROTOCOL_UPDATE = new MinecraftVersion("1.20.2"); - /** - * Version 1.20 - the trails and tails update - */ - public static final MinecraftVersion TRAILS_AND_TAILS = new MinecraftVersion("1.20"); - - /** - * Version 1.19.4 - the rest of the feature preview - */ - public static final MinecraftVersion FEATURE_PREVIEW_2 = new MinecraftVersion("1.19.4"); - - /** - * Version 1.19.3 - introducing feature preview - */ - public static final MinecraftVersion FEATURE_PREVIEW_UPDATE = new MinecraftVersion("1.19.3"); - /** - * Version 1.19 - the wild update - */ - public static final MinecraftVersion WILD_UPDATE = new MinecraftVersion("1.19"); - /** - * Version 1.18 - caves and cliffs part 2 - */ - public static final MinecraftVersion CAVES_CLIFFS_2 = new MinecraftVersion("1.18"); - /** - * Version 1.17 - caves and cliffs part 1 - */ - public static final MinecraftVersion CAVES_CLIFFS_1 = new MinecraftVersion("1.17"); - /** - * Version 1.16.4 - */ - public static final MinecraftVersion NETHER_UPDATE_4 = new MinecraftVersion("1.16.4"); - /** - * Version 1.16.2 - breaking change to the nether update - */ - public static final MinecraftVersion NETHER_UPDATE_2 = new MinecraftVersion("1.16.2"); - /** - * Version 1.16.0 - the nether update - */ - public static final MinecraftVersion NETHER_UPDATE = new MinecraftVersion("1.16"); - /** - * Version 1.15 - the bee update - */ - public static final MinecraftVersion BEE_UPDATE = new MinecraftVersion("1.15"); - /** - * Version 1.14 - village and pillage update. - */ - public static final MinecraftVersion VILLAGE_UPDATE = new MinecraftVersion("1.14"); - /** - * Version 1.13 - update aquatic. - */ - public static final MinecraftVersion AQUATIC_UPDATE = new MinecraftVersion("1.13"); - /** - * Version 1.12 - the world of color update. - */ - public static final MinecraftVersion COLOR_UPDATE = new MinecraftVersion("1.12"); - /** - * Version 1.11 - the exploration update. - */ - public static final MinecraftVersion EXPLORATION_UPDATE = new MinecraftVersion("1.11"); - /** - * Version 1.10 - the frostburn update. - */ - public static final MinecraftVersion FROSTBURN_UPDATE = new MinecraftVersion("1.10"); - /** - * Version 1.9 - the combat update. - */ - public static final MinecraftVersion COMBAT_UPDATE = new MinecraftVersion("1.9"); - /** - * Version 1.8 - the "bountiful" update. - */ - public static final MinecraftVersion BOUNTIFUL_UPDATE = new MinecraftVersion("1.8"); - /** - * Version 1.7.8 - the update that changed the skin format (and distribution - R.I.P. player disguise) - */ - public static final MinecraftVersion SKIN_UPDATE = new MinecraftVersion("1.7.8"); - /** - * Version 1.7.2 - the update that changed the world. - */ - public static final MinecraftVersion WORLD_UPDATE = new MinecraftVersion("1.7.2"); - /** - * Version 1.6.1 - the horse update. - */ - public static final MinecraftVersion HORSE_UPDATE = new MinecraftVersion("1.6.1"); - /** - * Version 1.5.0 - the redstone update. - */ - public static final MinecraftVersion REDSTONE_UPDATE = new MinecraftVersion("1.5.0"); - /** - * Version 1.4.2 - the scary update (Wither Boss). - */ - public static final MinecraftVersion SCARY_UPDATE = new MinecraftVersion("1.4.2"); - - /** - * The latest release version of minecraft. - */ - public static final MinecraftVersion LATEST = v1_21_4; - - // used when serializing - private static final long serialVersionUID = -8695133558996459770L; - - /** - * Regular expression used to parse version strings. - */ - private static final Pattern VERSION_PATTERN = Pattern.compile(".*\\(.*MC.\\s*([a-zA-z0-9\\-.]+).*"); - - /** - * The current version of minecraft, lazy initialized by MinecraftVersion.currentVersion() - */ - private static MinecraftVersion currentVersion; - - private final int major; - private final int minor; - private final int build; - // The development stage - private final String development; - - // Snapshot? - private final SnapshotVersion snapshot; - private volatile Boolean atCurrentOrAbove; - - /** - * Determine the current Minecraft version. - * - * @param server - the Bukkit server that will be used to examine the MC version. - */ - public MinecraftVersion(Server server) { - this(extractVersion(server.getVersion())); - } - - /** - * Construct a version object from the format major.minor.build, or the snapshot format. - * - * @param versionOnly - the version in text form. - */ - public MinecraftVersion(String versionOnly) { - this(versionOnly, true); - } - - /** - * Construct a version format from the standard release version or the snapshot verison. - * - * @param versionOnly - the version. - * @param parseSnapshot - TRUE to parse the snapshot, FALSE otherwise. - */ - private MinecraftVersion(String versionOnly, boolean parseSnapshot) { - String[] section = versionOnly.split("-"); - SnapshotVersion snapshot = null; - int[] numbers = new int[3]; - - try { - numbers = this.parseVersion(section[0]); - } catch (NumberFormatException cause) { - // Skip snapshot parsing - if (!parseSnapshot) { - throw cause; - } - - try { - // Determine if the snapshot is newer than the current release version - snapshot = new SnapshotVersion(section[0]); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.US); - - MinecraftVersion latest = new MinecraftVersion(ProtocolLibrary.MAXIMUM_MINECRAFT_VERSION, false); - boolean newer = snapshot.getSnapshotDate().compareTo( - format.parse(ProtocolLibrary.MINECRAFT_LAST_RELEASE_DATE)) > 0; - - numbers[0] = latest.getMajor(); - numbers[1] = latest.getMinor() + (newer ? 1 : -1); - } catch (Exception e) { - throw new IllegalStateException("Cannot parse " + section[0], e); - } - } - - this.major = numbers[0]; - this.minor = numbers[1]; - this.build = numbers[2]; - this.development = section.length > 1 ? section[1] : (snapshot != null ? "snapshot" : null); - this.snapshot = snapshot; - } - - /** - * Construct a version object directly. - * - * @param major - major version number. - * @param minor - minor version number. - * @param build - build version number. - */ - public MinecraftVersion(int major, int minor, int build) { - this(major, minor, build, null); - } - - /** - * Construct a version object directly. - * - * @param major - major version number. - * @param minor - minor version number. - * @param build - build version number. - * @param development - development stage. - */ - public MinecraftVersion(int major, int minor, int build, String development) { - this.major = major; - this.minor = minor; - this.build = build; - this.development = development; - this.snapshot = null; - } - - /** - * Extract the Minecraft version from CraftBukkit itself. - * - * @param text - the server version in text form. - * @return The underlying MC version. - * @throws IllegalStateException If we could not parse the version string. - */ - public static String extractVersion(String text) { - Matcher version = VERSION_PATTERN.matcher(text); - - if (version.matches() && version.group(1) != null) { - return version.group(1); - } else { - throw new IllegalStateException("Cannot parse version String '" + text + "'"); - } - } - - /** - * Parse the given server version into a Minecraft version. - * - * @param serverVersion - the server version. - * @return The resulting Minecraft version. - */ - public static MinecraftVersion fromServerVersion(String serverVersion) { - return new MinecraftVersion(extractVersion(serverVersion)); - } - - public static MinecraftVersion getCurrentVersion() { - if (currentVersion == null) { - currentVersion = fromServerVersion(Bukkit.getVersion()); - } - - return currentVersion; - } - - public static void setCurrentVersion(MinecraftVersion version) { - currentVersion = version; - } - - private static boolean atOrAbove(MinecraftVersion version) { - return getCurrentVersion().isAtLeast(version); - } - - private int[] parseVersion(String version) { - String[] elements = version.split("\\."); - int[] numbers = new int[3]; - - // Make sure it's even a valid version - if (elements.length < 1) { - throw new IllegalStateException("Corrupt MC version: " + version); - } - - // The String 1 or 1.2 is interpreted as 1.0.0 and 1.2.0 respectively. - for (int i = 0; i < Math.min(numbers.length, elements.length); i++) { - numbers[i] = Integer.parseInt(elements[i].trim()); - } - return numbers; - } - - /** - * Major version number - * - * @return Current major version number. - */ - public int getMajor() { - return this.major; - } - - /** - * Minor version number - * - * @return Current minor version number. - */ - public int getMinor() { - return this.minor; - } - - /** - * Build version number - * - * @return Current build version number. - */ - public int getBuild() { - return this.build; - } - - /** - * Retrieve the development stage. - * - * @return Development stage, or NULL if this is a release. - */ - public String getDevelopmentStage() { - return this.development; - } - - /** - * Retrieve the snapshot version, or NULL if this is a release. - * - * @return The snapshot version. - */ - public SnapshotVersion getSnapshot() { - return this.snapshot; - } - - /** - * Determine if this version is a snapshot. - * - * @return The snapshot version. - */ - public boolean isSnapshot() { - return this.snapshot != null; - } - - /** - * Checks if this version is at or above the current version the server is running. - * - * @return true if this version is equal or newer than the server version, false otherwise. - */ - public boolean atOrAbove() { - if (this.atCurrentOrAbove == null) { - this.atCurrentOrAbove = atOrAbove(this); - } - - return this.atCurrentOrAbove; - } - - /** - * Retrieve the version String (major.minor.build) only. - * - * @return A normal version string. - */ - public String getVersion() { - if (this.getDevelopmentStage() == null) { - return String.format("%s.%s.%s", this.getMajor(), this.getMinor(), this.getBuild()); - } else { - return String.format("%s.%s.%s-%s%s", this.getMajor(), this.getMinor(), this.getBuild(), - this.getDevelopmentStage(), this.isSnapshot() ? this.snapshot : ""); - } - } - - @Override - public int compareTo(MinecraftVersion o) { - if (o == null) { - return 1; - } - - return ComparisonChain.start() - .compare(this.getMajor(), o.getMajor()) - .compare(this.getMinor(), o.getMinor()) - .compare(this.getBuild(), o.getBuild()) - .compare(this.getDevelopmentStage(), o.getDevelopmentStage(), Ordering.natural().nullsLast()) - .compare(this.getSnapshot(), o.getSnapshot(), Ordering.natural().nullsFirst()) - .result(); - } - - public boolean isAtLeast(MinecraftVersion other) { - if (other == null) { - return false; - } - - return this.compareTo(other) >= 0; - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (obj == this) { - return true; - } - - if (obj instanceof MinecraftVersion) { - MinecraftVersion other = (MinecraftVersion) obj; - - return this.getMajor() == other.getMajor() && - this.getMinor() == other.getMinor() && - this.getBuild() == other.getBuild() && - Objects.equals(this.getDevelopmentStage(), other.getDevelopmentStage()); - } - - return false; - } - - @Override - public int hashCode() { - return Objects.hash(this.getMajor(), this.getMinor(), this.getBuild()); - } - - @Override - public String toString() { - // Convert to a String that we can parse back again - return String.format("(MC: %s)", this.getVersion()); - } -} diff --git a/src/main/java/com/comphenix/protocol/utility/SnapshotVersion.java b/src/main/java/com/comphenix/protocol/utility/SnapshotVersion.java deleted file mode 100644 index dc4cdfd..0000000 --- a/src/main/java/com/comphenix/protocol/utility/SnapshotVersion.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * ProtocolLib - Bukkit server library that allows access to the Minecraft protocol. - * Copyright (C) 2012 Kristian S. Stangeland - * - * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with this program; - * if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -package com.comphenix.protocol.utility; - -import com.google.common.collect.ComparisonChain; - -import java.io.Serial; -import java.io.Serializable; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.Locale; -import java.util.Objects; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Used to parse a snapshot version. - * - * @author Kristian - */ -public class SnapshotVersion implements Comparable, Serializable { - - @Serial - private static final long serialVersionUID = 2778655372579322310L; - private static final Pattern SNAPSHOT_PATTERN = Pattern.compile("(\\d{2}w\\d{2})([a-z])"); - - private final Date snapshotDate; - private final int snapshotWeekVersion; - - private transient String rawString; - - public SnapshotVersion(String version) { - Matcher matcher = SNAPSHOT_PATTERN.matcher(version.trim()); - - if (matcher.matches()) { - try { - this.snapshotDate = getDateFormat().parse(matcher.group(1)); - this.snapshotWeekVersion = matcher.group(2).charAt(0) - 'a'; - this.rawString = version; - } catch (ParseException e) { - throw new IllegalArgumentException("Date implied by snapshot version is invalid.", e); - } - } else { - throw new IllegalArgumentException("Cannot parse " + version + " as a snapshot version."); - } - } - - /** - * Retrieve the snapshot date parser. - *

- * We have to create a new instance of SimpleDateFormat every time as it is not thread safe. - * - * @return The date formatter. - */ - private static SimpleDateFormat getDateFormat() { - SimpleDateFormat format = new SimpleDateFormat("yy'w'ww", Locale.US); - format.setLenient(false); - return format; - } - - /** - * Retrieve the snapshot version within a week, starting at zero. - * - * @return The weekly version - */ - public int getSnapshotWeekVersion() { - return this.snapshotWeekVersion; - } - - /** - * Retrieve the week this snapshot was released. - * - * @return The week. - */ - public Date getSnapshotDate() { - return this.snapshotDate; - } - - /** - * Retrieve the raw snapshot string (yy'w'ww[a-z]). - * - * @return The snapshot string. - */ - public String getSnapshotString() { - if (this.rawString == null) { - // It's essential that we use the same locale - Calendar current = Calendar.getInstance(Locale.US); - current.setTime(this.snapshotDate); - this.rawString = String.format("%02dw%02d%s", - current.get(Calendar.YEAR) % 100, - current.get(Calendar.WEEK_OF_YEAR), - (char) ('a' + this.snapshotWeekVersion)); - } - return this.rawString; - } - - @Override - public int compareTo(SnapshotVersion o) { - if (o == null) { - return 1; - } - - return ComparisonChain.start() - .compare(this.snapshotDate, o.getSnapshotDate()) - .compare(this.snapshotWeekVersion, o.getSnapshotWeekVersion()) - .result(); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - if (obj instanceof SnapshotVersion) { - SnapshotVersion other = (SnapshotVersion) obj; - return Objects.equals(this.snapshotDate, other.getSnapshotDate()) - && this.snapshotWeekVersion == other.getSnapshotWeekVersion(); - } - - return false; - } - - @Override - public int hashCode() { - return Objects.hash(this.snapshotDate, this.snapshotWeekVersion); - } - - @Override - public String toString() { - return this.getSnapshotString(); - } -} diff --git a/src/main/java/net/wesjd/anvilgui/AnvilGUI.java b/src/main/java/net/wesjd/anvilgui/AnvilGUI.java deleted file mode 100644 index 6beaacc..0000000 --- a/src/main/java/net/wesjd/anvilgui/AnvilGUI.java +++ /dev/null @@ -1,889 +0,0 @@ -package net.wesjd.anvilgui; - -import net.md_5.bungee.api.chat.BaseComponent; -import net.wesjd.anvilgui.version.VersionWrapper; -import net.wesjd.anvilgui.version.VersionMatcher; -import org.apache.commons.lang.Validate; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.HandlerList; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.*; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.plugin.Plugin; - -import java.util.*; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.logging.Level; - -/** - * An anvil gui, used for gathering a user's input - * - * @author Wesley Smith - * @since 1.0 - */ -public class AnvilGUI { - - /** - * The local {@link VersionWrapper} object for the server's version - */ - private static final VersionWrapper WRAPPER = new VersionMatcher().match(); - - /** - * The variable containing an item with air. Used when the item would be null. - * To keep the heap clean, this object only gets iniziaised once - */ - private static final ItemStack AIR = new ItemStack(Material.AIR); - /** - * If the given ItemStack is null, return an air ItemStack, otherwise return the given ItemStack - * - * @param stack The ItemStack to check - * @return air or the given ItemStack - */ - private static ItemStack itemNotNull(ItemStack stack) { - return stack == null ? AIR : stack; - } - - /** - * The {@link Plugin} that this anvil GUI is associated with - */ - private final Plugin plugin; - /** - * The player who has the GUI open - */ - private final Player player; - /** - * An {@link Executor} that executes tasks on the main server thread - */ - private final Executor mainThreadExecutor; - /** - * The title of the anvil inventory - */ - private final Object titleComponent; - /** - * The initial contents of the inventory - */ - private final ItemStack[] initialContents; - /** - * A state that decides where the anvil GUI is able to get closed by the user - */ - private final boolean preventClose; - /** - * A state that decides whether compatibility with Geyser software is enabled - */ - private final boolean geyserCompatibility; - /** - * A set of slot numbers that are permitted to be interacted with by the user. An interactable - * slot is one that is able to be minipulated by the player, i.e. clicking and picking up an item, - * placing in a new one, etc. - */ - private final Set interactableSlots; - - /** An {@link Consumer} that is called when the anvil GUI is close */ - private final Consumer closeListener; - /** A flag that decides whether the async click handler can be run concurrently */ - private final boolean concurrentClickHandlerExecution; - /** An {@link BiFunction} that is called when a slot is clicked */ - private final ClickHandler clickHandler; - - /** - * The container id of the inventory, used for NMS methods - */ - private int containerId; - - /** - * The inventory that is used on the Bukkit side of things - */ - private Inventory inventory; - /** - * The listener holder class - */ - private final ListenUp listener = new ListenUp(); - - /** - * Represents the state of the inventory being open - */ - private boolean open; - - /** - * The actual container backing the Anvil GUI - */ - private VersionWrapper.AnvilContainerWrapper container; - - /** - * Create an AnvilGUI - * - * @param plugin A {@link org.bukkit.plugin.java.JavaPlugin} instance - * @param player The {@link Player} to open the inventory for - * @param mainThreadExecutor An {@link Executor} that executes on the main server thread - * @param titleComponent What to have the text already set to - * @param initialContents The initial contents of the inventory - * @param preventClose Whether to prevent the inventory from closing - * @param geyserCompatibility Whether to enable compatibility with Geyser software - * @param closeListener A {@link Consumer} when the inventory closes - * @param concurrentClickHandlerExecution Flag to allow concurrent execution of the click handler - * @param clickHandler A {@link ClickHandler} that is called when the player clicks a slot - */ - private AnvilGUI( - Plugin plugin, - Player player, - Executor mainThreadExecutor, - Object titleComponent, - ItemStack[] initialContents, - boolean preventClose, - boolean geyserCompatibility, - Set interactableSlots, - Consumer closeListener, - boolean concurrentClickHandlerExecution, - ClickHandler clickHandler) { - this.plugin = plugin; - this.player = player; - this.mainThreadExecutor = mainThreadExecutor; - this.titleComponent = titleComponent; - this.initialContents = initialContents; - this.preventClose = preventClose; - this.geyserCompatibility = geyserCompatibility; - this.interactableSlots = Collections.unmodifiableSet(interactableSlots); - this.closeListener = closeListener; - this.concurrentClickHandlerExecution = concurrentClickHandlerExecution; - this.clickHandler = clickHandler; - } - - /** - * Opens the anvil GUI - */ - private void openInventory() { - Bukkit.getPluginManager().registerEvents(listener, plugin); - - container = WRAPPER.newContainerAnvil(player, titleComponent); - - inventory = container.getBukkitInventory(); - // We need to use setItem instead of setContents because a Minecraft ContainerAnvil - // contains two separate inventories: the result inventory and the ingredients inventory. - // The setContents method only updates the ingredients inventory unfortunately, - // but setItem handles the index going into the result inventory. - for (int i = 0; i < initialContents.length; i++) { - inventory.setItem(i, initialContents[i]); - } - - containerId = WRAPPER.getNextContainerId(player, container); - WRAPPER.handleInventoryCloseEvent(player); - WRAPPER.sendPacketOpenWindow(player, containerId, titleComponent); - WRAPPER.setActiveContainer(player, container); - WRAPPER.setActiveContainerId(container, containerId); - WRAPPER.addActiveContainerSlotListener(container, player); - - open = true; - } - - /** - * Closes the inventory if it's open. - */ - public void closeInventory() { - closeInventory(true); - } - - /** - * Closes the inventory if it's open, only sending the close inventory packets if the arg is true - * - * @param sendClosePacket Whether to send the close inventory event, packet, etc - */ - private void closeInventory(boolean sendClosePacket) { - if (!open) { - return; - } - - open = false; - - HandlerList.unregisterAll(listener); - - if (sendClosePacket) { - WRAPPER.handleInventoryCloseEvent(player); - WRAPPER.setActiveContainerDefault(player); - WRAPPER.sendPacketCloseWindow(player, containerId); - } - - if (closeListener != null) { - closeListener.accept(StateSnapshot.fromAnvilGUI(this)); - } - } - - /** - * Updates the title of the AnvilGUI to the new one. - * - * @param literalTitle The title to use as literal text - * @param preserveRenameText Whether to preserve the entered rename text - * @throws IllegalArgumentException when literalTitle is null - * @see Builder#title(String) - */ - public void setTitle(String literalTitle, boolean preserveRenameText) { - Validate.notNull(literalTitle, "literalTitle cannot be null"); - setTitle(WRAPPER.literalChatComponent(literalTitle), preserveRenameText); - } - - /** - * Updates the title of the AnvilGUI to the new one. - * - * @param json The json used to parse into a rich chat component - * @param preserveRenameText Whether to preserve the entered rename text - * @throws IllegalArgumentException when json is null - * @see Builder#jsonTitle(String) - */ - public void setJsonTitle(String json, boolean preserveRenameText) { - Validate.notNull(json, "json cannot be null"); - setTitle(WRAPPER.jsonChatComponent(json), preserveRenameText); - } - - /** - * Updates the title of the AnvilGUI to the new one. - * - * @param title The title as a NMS ChatComponent - * @param preserveRenameText Whether to preserve the entered rename text - */ - private void setTitle(Object title, boolean preserveRenameText) { - if (!WRAPPER.isCustomTitleSupported()) { - return; - } - String renameText = container.getRenameText(); - WRAPPER.sendPacketOpenWindow(player, containerId, title); - if (preserveRenameText) { - // The renameText field is marked as @Nullable in newer versions - container.setRenameText(renameText == null ? "" : renameText); - } - } - - /** - * Returns the Bukkit inventory for this anvil gui - * - * @return the {@link Inventory} for this anvil gui - */ - public Inventory getInventory() { - return inventory; - } - - /** - * Simply holds the listeners for the GUI - */ - private class ListenUp implements Listener { - - /** - * Boolean storing the running status of the latest click handler to prevent double execution. - * All accesses to this boolean will be from the main server thread, except for the rare event - * that the plugin is disabled and the mainThreadExecutor throws an exception - */ - private boolean clickHandlerRunning = false; - - @EventHandler - public void onInventoryClick(InventoryClickEvent event) { - if (!event.getInventory().equals(inventory)) { - return; - } - - final int rawSlot = event.getRawSlot(); - // ignore items dropped outside the window - if (rawSlot == -999) return; - - final Player clicker = (Player) event.getWhoClicked(); - final Inventory clickedInventory = event.getClickedInventory(); - - if (clickedInventory != null) { - if (clickedInventory.equals(clicker.getInventory())) { - // prevent players from merging items from the anvil inventory - if (event.getClick().equals(ClickType.DOUBLE_CLICK)) { - event.setCancelled(true); - return; - } - // prevent shift moving items from players inv to the anvil inventory - if (event.isShiftClick()) { - event.setCancelled(true); - return; - } - } - // prevent players from swapping items in the anvil gui - if ((event.getCursor() != null && event.getCursor().getType() != Material.AIR) - && !interactableSlots.contains(rawSlot) - && event.getClickedInventory().equals(inventory)) { - event.setCancelled(true); - return; - } - } - - if (rawSlot < 3 && rawSlot >= 0 || event.getAction().equals(InventoryAction.MOVE_TO_OTHER_INVENTORY)) { - event.setCancelled(!interactableSlots.contains(rawSlot)); - if (clickHandlerRunning && !concurrentClickHandlerExecution) { - // A click handler is running, don't launch another one - return; - } - - final CompletableFuture> actionsFuture = - clickHandler.apply(rawSlot, StateSnapshot.fromAnvilGUI(AnvilGUI.this)); - - final Consumer> actionsConsumer = actions -> { - for (final ResponseAction action : actions) { - action.accept(AnvilGUI.this, clicker); - } - }; - - if (actionsFuture.isDone()) { - // Fast-path without scheduling if clickHandler is performed in sync - // Because the future is already completed, .join() will not block the server thread - actionsFuture.thenAccept(actionsConsumer).join(); - } else { - clickHandlerRunning = true; - // If the plugin is disabled and the Executor throws an exception, the exception will be passed to - // the .handle method - actionsFuture - .thenAcceptAsync(actionsConsumer, mainThreadExecutor) - .handle((results, exception) -> { - if (exception != null) { - plugin.getLogger() - .log( - Level.SEVERE, - "An exception occurred in the AnvilGUI clickHandler", - exception); - } - // Whether an exception occurred or not, set running to false - clickHandlerRunning = false; - return null; - }); - } - } - } - - @EventHandler - public void onInventoryDrag(InventoryDragEvent event) { - if (event.getInventory().equals(inventory)) { - for (int slot : Slot.values()) { - if (event.getRawSlots().contains(slot)) { - event.setCancelled(!interactableSlots.contains(slot)); - break; - } - } - } - } - - @EventHandler - public void onInventoryClose(InventoryCloseEvent event) { - if (open && event.getInventory().equals(inventory)) { - closeInventory(false); - if (preventClose) { - mainThreadExecutor.execute(AnvilGUI.this::openInventory); - } - } - } - } - - /** A builder class for an {@link AnvilGUI} object */ - public static class Builder { - - /** An {@link Executor} that executes tasks on the main server thread */ - private Executor mainThreadExecutor; - /** An {@link Consumer} that is called when the anvil GUI is close */ - private Consumer closeListener; - /** A flag that decides whether the async click handler can be run concurrently */ - private boolean concurrentClickHandlerExecution = false; - /** An {@link Function} that is called when a slot in the inventory has been clicked */ - private ClickHandler clickHandler; - /** A state that decides where the anvil GUI is able to be closed by the user */ - private boolean preventClose = false; - /** A state that determines whether support for Geyser software is enabled */ - private boolean geyserCompatibility = true; - /** A set of integers containing the slot numbers that should be modifiable by the user. */ - private Set interactableSlots = Collections.emptySet(); - /** The {@link Plugin} that this anvil GUI is associated with */ - private Plugin plugin; - /** The text that will be displayed to the user */ - private Object titleComponent = WRAPPER.literalChatComponent("Repair & Name"); - /** The starting text on the item */ - private String itemText; - /** An {@link ItemStack} to be put in the left input slot */ - private ItemStack itemLeft; - /** An {@link ItemStack} to be put in the right input slot */ - private ItemStack itemRight; - /** An {@link ItemStack} to be placed in the output slot */ - private ItemStack itemOutput; - - /** - * Set a custom main server thread executor. Useful for plugins targeting Folia. - * - * @param executor The executor to run tasks on - * @return The {@link Builder} instance - * @throws IllegalArgumentException when the executor is null - */ - public Builder mainThreadExecutor(Executor executor) { - Validate.notNull(executor, "Executor cannot be null"); - this.mainThreadExecutor = executor; - return this; - } - - /** - * Prevents the closing of the anvil GUI by the user - * - * @return The {@link Builder} instance - */ - public Builder preventClose() { - preventClose = true; - return this; - } - - /** - * Disables compatibility with Geyser software - */ - public Builder disableGeyserCompat() { - geyserCompatibility = false; - return this; - } - - /** - * Permit the user to modify (take items in and out) the slot numbers provided. - * - * @param slots A varags param for the slot numbers. You can avoid relying on magic constants by using - * the {@link AnvilGUI.Slot} class. - * @return The {@link Builder} instance - */ - public Builder interactableSlots(int... slots) { - final Set newValue = new HashSet<>(); - for (int slot : slots) { - newValue.add(slot); - } - interactableSlots = newValue; - return this; - } - - /** - * Listens for when the inventory is closed - * - * @param closeListener An {@link Consumer} that is called when the anvil GUI is closed - * @return The {@link Builder} instance - * @throws IllegalArgumentException when the closeListener is null - */ - public Builder onClose(Consumer closeListener) { - Validate.notNull(closeListener, "closeListener cannot be null"); - this.closeListener = closeListener; - return this; - } - - /** - * Do an action when a slot is clicked in the inventory - *

- * The ClickHandler is only called when the previous execution of the ClickHandler has finished. - * To alter this behaviour use {@link #allowConcurrentClickHandlerExecution()} - * - * @param clickHandler A {@link ClickHandler} that is called when the user clicks a slot. The - * {@link Integer} is the slot number corresponding to {@link Slot}, the - * {@link StateSnapshot} contains information about the current state of the anvil, - * and the response is a {@link CompletableFuture} that will eventually return a - * list of {@link ResponseAction} to execute in the order that they are supplied. - * @return The {@link Builder} instance - * @throws IllegalArgumentException when the function supplied is null - */ - public Builder onClickAsync(ClickHandler clickHandler) { - Validate.notNull(clickHandler, "click function cannot be null"); - this.clickHandler = clickHandler; - return this; - } - - /** - * By default, the {@link #onClickAsync(ClickHandler) async click handler} will not run concurrently - * and instead wait for the previous {@link CompletableFuture} to finish before executing it again. - *

- * If this trait is desired, it can be enabled by calling this method but may lead to inconsistent - * behaviour if not handled properly. - * - * @return The {@link Builder} instance - */ - public Builder allowConcurrentClickHandlerExecution() { - this.concurrentClickHandlerExecution = true; - return this; - } - - /** - * Do an action when a slot is clicked in the inventory - * - * @param clickHandler A {@link BiFunction} that is called when the user clicks a slot. The - * {@link Integer} is the slot number corresponding to {@link Slot}, the - * {@link StateSnapshot} contains information about the current state of the anvil, - * and the response is a list of {@link ResponseAction} to execute in the order - * that they are supplied. - * @return The {@link Builder} instance - * @throws IllegalArgumentException when the function supplied is null - */ - public Builder onClick(BiFunction> clickHandler) { - Validate.notNull(clickHandler, "click function cannot be null"); - this.clickHandler = - (slot, stateSnapshot) -> CompletableFuture.completedFuture(clickHandler.apply(slot, stateSnapshot)); - return this; - } - - /** - * Sets the plugin for the {@link AnvilGUI} - * - * @param plugin The {@link Plugin} this anvil GUI is associated with - * @return The {@link Builder} instance - * @throws IllegalArgumentException if the plugin is null - */ - public Builder plugin(Plugin plugin) { - Validate.notNull(plugin, "Plugin cannot be null"); - this.plugin = plugin; - return this; - } - - /** - * Sets the initial item-text that is displayed to the user. - *

- * If the usage of Adventure Components is desired, you must create an item, set the displayname of it - * and put it into the AnvilGUI via {@link #itemLeft(ItemStack)} manually. - * - * @param text The initial name of the item in the anvil - * @return The {@link Builder} instance - * @throws IllegalArgumentException if the text is null - */ - public Builder text(String text) { - Validate.notNull(text, "Text cannot be null"); - this.itemText = text; - return this; - } - - /** - * Sets the AnvilGUI title that is to be displayed to the user. - *
- * The provided title will be treated as literal text. - * - * @param title The title that is to be displayed to the user - * @return The {@link Builder} instance - * @throws IllegalArgumentException if the title is null - */ - public Builder title(String title) { - Validate.notNull(title, "title cannot be null"); - this.titleComponent = WRAPPER.literalChatComponent(title); - return this; - } - - /** - * Sets the AnvilGUI title that is to be displayed to the user. - *
- * The provided json will be parsed into rich chat components. - * - * @param json The title that is to be displayed to the user - * @return The {@link Builder} instance - * @throws IllegalArgumentException if the title is null - * @see net.md_5.bungee.chat.ComponentSerializer#toString(BaseComponent) - */ - public Builder jsonTitle(String json) { - Validate.notNull(json, "json cannot be null"); - this.titleComponent = WRAPPER.jsonChatComponent(json); - return this; - } - - /** - * Sets the {@link ItemStack} to be put in the first slot - * - * @param item The {@link ItemStack} to be put in the first slot - * @return The {@link Builder} instance - * @throws IllegalArgumentException if the {@link ItemStack} is null - */ - public Builder itemLeft(ItemStack item) { - Validate.notNull(item, "item cannot be null"); - this.itemLeft = item; - return this; - } - - /** - * Sets the {@link ItemStack} to be put in the second slot - * - * @param item The {@link ItemStack} to be put in the second slot - * @return The {@link Builder} instance - */ - public Builder itemRight(ItemStack item) { - this.itemRight = item; - return this; - } - - /** - * Sets the {@link ItemStack} to be put in the output slot - * - * @param item The {@link ItemStack} to be put in the output slot - * @return The {@link Builder} instance - */ - public Builder itemOutput(ItemStack item) { - this.itemOutput = item; - return this; - } - - /** - * Creates the anvil GUI and opens it for the player - * - * @param player The {@link Player} the anvil GUI should open for - * @return The {@link AnvilGUI} instance from this builder - * @throws IllegalArgumentException when the onClick function, plugin, or player is null - */ - public AnvilGUI open(Player player) { - Validate.notNull(plugin, "Plugin cannot be null"); - Validate.notNull(clickHandler, "click handler cannot be null"); - Validate.notNull(player, "Player cannot be null"); - - if (itemText != null) { - if (itemLeft == null) { - itemLeft = new ItemStack(Material.PAPER); - } - - ItemMeta paperMeta = itemLeft.getItemMeta(); - paperMeta.setDisplayName(itemText); - itemLeft.setItemMeta(paperMeta); - } - - // If no executor is specified, execute all tasks with the BukkitScheduler - if (mainThreadExecutor == null) { - mainThreadExecutor = task -> Bukkit.getScheduler().runTask(plugin, task); - } - - final AnvilGUI anvilGUI = new AnvilGUI( - plugin, - player, - mainThreadExecutor, - titleComponent, - new ItemStack[] {itemLeft, itemRight, itemOutput}, - preventClose, - geyserCompatibility, - interactableSlots, - closeListener, - concurrentClickHandlerExecution, - clickHandler); - anvilGUI.openInventory(); - return anvilGUI; - } - } - - /** - * A handler that is called when the user clicks a slot. The - * {@link Integer} is the slot number corresponding to {@link Slot}, the - * {@link StateSnapshot} contains information about the current state of the anvil, - * and the response is a {@link CompletableFuture} that will eventually return a - * list of {@link ResponseAction} to execute in the order that they are supplied. - */ - @FunctionalInterface - public interface ClickHandler extends BiFunction>> {} - - /** An action to run in response to a player clicking the output slot in the GUI. This interface is public - * and permits you, the developer, to add additional response features easily to your custom AnvilGUIs. */ - @FunctionalInterface - public interface ResponseAction extends BiConsumer { - - /** - * Replace the input text box value with the provided text value. - * - * Before using this method, it must be verified by the caller that items are either in - * {@link Slot#INPUT_LEFT} or {@link Slot#OUTPUT} present. - * - * @param text The text to write in the input box - * @return The {@link ResponseAction} to achieve the text replacement - * @throws IllegalArgumentException when the text is null - * @throws IllegalStateException when the slots {@link Slot#INPUT_LEFT} and {@link Slot#OUTPUT} are null - */ - static ResponseAction replaceInputText(String text) { - Validate.notNull(text, "text cannot be null"); - return (anvilgui, player) -> { - ItemStack item = anvilgui.getInventory().getItem(Slot.OUTPUT); - if (item == null) { - // Fallback on left input slot if player hasn't typed anything yet - item = anvilgui.getInventory().getItem(Slot.INPUT_LEFT); - } - if (item == null) { - throw new IllegalStateException( - "replaceInputText can only be used if slots OUTPUT or INPUT_LEFT are not empty"); - } - - final ItemStack cloned = item.clone(); - final ItemMeta meta = cloned.getItemMeta(); - meta.setDisplayName(text); - cloned.setItemMeta(meta); - anvilgui.getInventory().setItem(Slot.INPUT_LEFT, cloned); - }; - } - - /** - * Updates the title of the AnvilGUI to the new one. - * - * @param literalTitle The title to use as literal text - * @param preserveRenameText Whether to preserve the entered rename text - * @throws IllegalArgumentException when literalTitle is null - * @see Builder#title(String) - */ - static ResponseAction updateTitle(String literalTitle, boolean preserveRenameText) { - Validate.notNull(literalTitle, "literalTitle cannot be null"); - return (anvilGUI, player) -> anvilGUI.setTitle(literalTitle, preserveRenameText); - } - - /** - * Updates the title of the AnvilGUI to the new one. - * - * @param json The json used to parse into a rich chat component - * @param preserveRenameText Whether to preserve the entered rename text - * @throws IllegalArgumentException when json is null - * @see Builder#jsonTitle(String) - */ - static ResponseAction updateJsonTitle(String json, boolean preserveRenameText) { - Validate.notNull(json, "json cannot be null"); - return (anvilGUI, player) -> anvilGUI.setJsonTitle(json, preserveRenameText); - } - - /** - * Open another inventory - * @param otherInventory The inventory to open - * @return The {@link ResponseAction} to achieve the inventory open - * @throws IllegalArgumentException when the otherInventory is null - */ - static ResponseAction openInventory(Inventory otherInventory) { - Validate.notNull(otherInventory, "otherInventory cannot be null"); - return (anvilgui, player) -> player.openInventory(otherInventory); - } - - /** - * Close the AnvilGUI - * @return The {@link ResponseAction} to achieve closing the AnvilGUI - */ - static ResponseAction close() { - return (anvilgui, player) -> anvilgui.closeInventory(); - } - - /** - * Run the provided runnable - * @param runnable The runnable to run - * @return The {@link ResponseAction} to achieve running the runnable - * @throws IllegalArgumentException when the runnable is null - */ - static ResponseAction run(Runnable runnable) { - Validate.notNull(runnable, "runnable cannot be null"); - return (anvilgui, player) -> runnable.run(); - } - } - - /** - * Class wrapping the magic constants of slot numbers in an anvil GUI - */ - public static class Slot { - - private static final int[] values = new int[] {Slot.INPUT_LEFT, Slot.INPUT_RIGHT, Slot.OUTPUT}; - - /** - * The slot on the far left, where the first input is inserted. An {@link ItemStack} is always inserted - * here to be renamed - */ - public static final int INPUT_LEFT = 0; - /** - * Not used, but in a real anvil you are able to put the second item you want to combine here - */ - public static final int INPUT_RIGHT = 1; - /** - * The output slot, where an item is put when two items are combined from {@link #INPUT_LEFT} and - * {@link #INPUT_RIGHT} or {@link #INPUT_LEFT} is renamed - */ - public static final int OUTPUT = 2; - - /** - * Get all anvil slot values - * - * @return The array containing all possible anvil slots - */ - public static int[] values() { - return values; - } - } - - /** Represents a snapshot of the state of an AnvilGUI */ - public static final class StateSnapshot { - - /** - * Create an {@link StateSnapshot} from the current state of an {@link AnvilGUI} - * @param anvilGUI The instance to take the snapshot of - * @return The snapshot - */ - private static StateSnapshot fromAnvilGUI(AnvilGUI anvilGUI) { - final Inventory inventory = anvilGUI.getInventory(); - return new StateSnapshot( - itemNotNull(inventory.getItem(Slot.INPUT_LEFT)).clone(), - itemNotNull(inventory.getItem(Slot.INPUT_RIGHT)).clone(), - itemNotNull(inventory.getItem(Slot.OUTPUT)).clone(), - anvilGUI.player); - } - - /** - * The {@link ItemStack} in the anvilGui slots - */ - private final ItemStack leftItem, rightItem, outputItem; - - /** - * The {@link Player} that clicked the output slot - */ - private final Player player; - - /** - * The event parameter constructor - * @param leftItem The left item in the combine slot of the anvilGUI - * @param rightItem The right item in the combine slot of the anvilGUI - * @param outputItem The item that would have been outputted, when the items would have been combined - * @param player The player that clicked the output slot - */ - public StateSnapshot(ItemStack leftItem, ItemStack rightItem, ItemStack outputItem, Player player) { - this.leftItem = leftItem; - this.rightItem = rightItem; - this.outputItem = outputItem; - this.player = player; - } - - /** - * It returns the item in the left combine slot of the gui - * - * @return The leftItem - */ - public ItemStack getLeftItem() { - return leftItem; - } - - /** - * It returns the item in the right combine slot of the gui - * - * @return The rightItem - */ - public ItemStack getRightItem() { - return rightItem; - } - - /** - * It returns the output item that would have been the result - * by combining the left and right one - * - * @return The outputItem - */ - public ItemStack getOutputItem() { - return outputItem; - } - - /** - * It returns the player that clicked onto the output slot - * - * @return The player - */ - public Player getPlayer() { - return player; - } - - /** - * It returns the text the player typed into the rename field - * - * @return The text of the rename field - */ - public String getText() { - return outputItem.hasItemMeta() ? outputItem.getItemMeta().getDisplayName() : ""; - } - } -} diff --git a/src/main/java/net/wesjd/anvilgui/LICENSE b/src/main/java/net/wesjd/anvilgui/LICENSE deleted file mode 100644 index c735359..0000000 --- a/src/main/java/net/wesjd/anvilgui/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 Wesley Smith - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/src/main/java/net/wesjd/anvilgui/version/PaperWrapper1_21_R4.java b/src/main/java/net/wesjd/anvilgui/version/PaperWrapper1_21_R4.java deleted file mode 100644 index 11bc655..0000000 --- a/src/main/java/net/wesjd/anvilgui/version/PaperWrapper1_21_R4.java +++ /dev/null @@ -1,135 +0,0 @@ -package net.wesjd.anvilgui.version; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.RegistryAccess; -import net.minecraft.core.component.DataComponentPatch; -import net.minecraft.core.component.DataComponents; -import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.game.ClientboundContainerClosePacket; -import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; -import net.minecraft.network.protocol.game.ClientboundSetExperiencePacket; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.inventory.*; -import org.bukkit.craftbukkit.entity.CraftPlayer; -import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.jetbrains.annotations.NotNull; - -public final class PaperWrapper1_21_R4 implements VersionWrapper { - private int getRealNextContainerId(Player player) { - return toNMS(player).nextContainerCounter(); - } - - - private ServerPlayer toNMS(Player player) { - return ((CraftPlayer) player).getHandle(); - } - - @Override - public int getNextContainerId(Player player, AnvilContainerWrapper container) { - return ((AnvilContainer) container).containerId; - } - - @Override - public void handleInventoryCloseEvent(Player player) { - //CraftEventFactory.handleInventoryCloseEvent(toNMS(player)); - toNMS(player).doCloseContainer(); // q -> doCloseContainer - } - - @Override - public void sendPacketOpenWindow(Player player, int containerId, Object inventoryTitle) { - toNMS(player).connection.send(new ClientboundOpenScreenPacket(containerId, MenuType.ANVIL, Component.literal(inventoryTitle.toString()))); - } - - @Override - public void sendPacketCloseWindow(Player player, int containerId) { - toNMS(player).connection.send(new ClientboundContainerClosePacket(containerId)); - } - - @Override - public void sendPacketExperienceChange(Player player, int experienceLevel) { - toNMS(player).connection.send(new ClientboundSetExperiencePacket(0f, 0, experienceLevel)); - } - - @Override - public void setActiveContainerDefault(Player player) { - toNMS(player).containerMenu = toNMS(player).inventoryMenu; // cd -> containerMenu, cc -> inventoryMenu - } - - @Override - public void setActiveContainer(Player player, AnvilContainerWrapper container) { - toNMS(player).containerMenu = (AbstractContainerMenu) container; - } - - @Override - public void setActiveContainerId(AnvilContainerWrapper container, int containerId) { } - - @Override - public void addActiveContainerSlotListener(AnvilContainerWrapper container, Player player) { - toNMS(player).initMenu((AbstractContainerMenu) container); - } - - @Override - public AnvilContainerWrapper newContainerAnvil(Player player, Object title) { - return new AnvilContainer(player, getRealNextContainerId(player), Component.literal(title.toString())); - } - - @Override - public Object literalChatComponent(String content) { - return Component.literal(content); // IChatBaseComponent.b -> Component.literal - } - - @Override - public Object jsonChatComponent(String json) { - return Component.Serializer.toJson(Component.literal(json), RegistryAccess.EMPTY); - } - - private static class AnvilContainer extends AnvilMenu implements AnvilContainerWrapper { - public AnvilContainer(Player player, int containerId, Component guiTitle) { - super( - containerId, - ((CraftPlayer) player).getHandle().getInventory(), - ContainerLevelAccess.create(((CraftPlayer) player).getHandle().level(), BlockPos.ZERO) - ); - this.checkReachable = false; - setTitle(guiTitle); - } - - @Override - public void createResult() { - // If the output is empty, copy the left input into the output - Slot output = getSlot(2); // b -> getSlot - if (!output.hasItem()) { // h -> hasItem - output.set(getSlot(0).getItem().copy()); // f -> set, g -> getItem, v -> copy - } - - this.cost.set(0); // y -> cost, a -> set - - // Sync to the client - this.sendAllDataToRemote(); // b -> sendAllDataToRemote - this.broadcastChanges(); // d -> broadcastChanges - } - - @Override - public boolean setItemName(@NotNull String itemName) { - Slot inputLeft = getSlot(0); - if (inputLeft.hasItem()) { - inputLeft - .getItem() - .applyComponents(DataComponentPatch - .builder() - .set(DataComponents.CUSTOM_NAME, Component.literal(itemName)) - .build() - ); - return true; - } - - return false; - } - - @Override - public Inventory getBukkitInventory() { - return this.getBukkitView().getTopInventory(); - } - } -} diff --git a/src/main/java/net/wesjd/anvilgui/version/VersionMatcher.java b/src/main/java/net/wesjd/anvilgui/version/VersionMatcher.java deleted file mode 100644 index c4f1bcc..0000000 --- a/src/main/java/net/wesjd/anvilgui/version/VersionMatcher.java +++ /dev/null @@ -1,51 +0,0 @@ -package net.wesjd.anvilgui.version; - -import org.bukkit.Bukkit; - -import java.util.HashMap; -import java.util.Map; - -/** - * Matches the server's NMS version to its {@link VersionWrapper} - * - * @author Wesley Smith - * @since 1.2.1 - */ -public class VersionMatcher { - /** Maps a Minecraft version string to the corresponding revision string */ - private static final Map VERSION_TO_REVISION = new HashMap() { - { - this.put("1.21.4", "1_21_R4"); - } - }; - /* This needs to be updated to reflect the newest available version wrapper */ - private static final String FALLBACK_REVISION = "1_21_R4"; - - /** - * Matches the server version to it's {@link VersionWrapper} - * - * @return The {@link VersionWrapper} for this server - * @throws IllegalStateException If the version wrapper failed to be instantiated or is unable to be found - */ - public VersionWrapper match() { - String craftBukkitPackage = Bukkit.getServer().getClass().getPackage().getName(); - - String rVersion; - if (!craftBukkitPackage.contains(".v")) { // cb package not relocated (i.e. paper 1.20.5+) - final String version = Bukkit.getBukkitVersion().split("-")[0]; - rVersion = VERSION_TO_REVISION.getOrDefault(version, FALLBACK_REVISION); - } else { - rVersion = craftBukkitPackage.split("\\.")[3].substring(1); - } - - try { - return (VersionWrapper) Class.forName(getClass().getPackage().getName() + ".PaperWrapper" + rVersion) - .getDeclaredConstructor() - .newInstance(); - } catch (ClassNotFoundException exception) { - throw new IllegalStateException("AnvilGUI does not support server version \"" + rVersion + "\"", exception); - } catch (ReflectiveOperationException exception) { - throw new IllegalStateException("Failed to instantiate version wrapper for version " + rVersion, exception); - } - } -} diff --git a/src/main/java/net/wesjd/anvilgui/version/VersionWrapper.java b/src/main/java/net/wesjd/anvilgui/version/VersionWrapper.java deleted file mode 100644 index 5efe2c5..0000000 --- a/src/main/java/net/wesjd/anvilgui/version/VersionWrapper.java +++ /dev/null @@ -1,150 +0,0 @@ -package net.wesjd.anvilgui.version; - -import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; - -/** - * Wraps versions to be able to easily use different NMS server versions - * - * @author Wesley Smith - * @since 1.0 - */ -public interface VersionWrapper { - - /** - * Gets the next available NMS container id for the player - * - * @param player The player to get the next container id of - * @param container The container that a new id is being generated for - * @return The next available NMS container id - */ - int getNextContainerId(Player player, AnvilContainerWrapper container); - - /** - * Closes the current inventory for the player - * - * @param player The player that needs their current inventory closed - */ - void handleInventoryCloseEvent(Player player); - - /** - * Sends PacketPlayOutOpenWindow to the player with the container id and window title - * - * @param player The player to send the packet to - * @param containerId The container id to open - * @param inventoryTitle The title of the inventory to be opened (only works in Minecraft 1.14 and above) - */ - void sendPacketOpenWindow(Player player, int containerId, Object inventoryTitle); - - /** - * Sends PacketPlayOutCloseWindow to the player with the container id - * - * @param player The player to send the packet to - * @param containerId The container id to close - */ - void sendPacketCloseWindow(Player player, int containerId); - - /** - * Sends PacketPlayOutExperience to the player with the experience level - * - * @param player The player to send the packet to - * @param experienceLevel The experience level to set - */ - void sendPacketExperienceChange(Player player, int experienceLevel); - - /** - * Sets the NMS player's active container to the default one - * - * @param player The player to set the active container of - */ - void setActiveContainerDefault(Player player); - - /** - * Sets the NMS player's active container to the one supplied - * - * @param player The player to set the active container of - * @param container The container to set as active - */ - void setActiveContainer(Player player, AnvilContainerWrapper container); - - /** - * Sets the supplied windowId of the supplied Container - * - * @param container The container to set the windowId of - * @param containerId The new windowId - */ - void setActiveContainerId(AnvilContainerWrapper container, int containerId); - - /** - * Adds a slot listener to the supplied container for the player - * - * @param container The container to add the slot listener to - * @param player The player to have as a listener - */ - void addActiveContainerSlotListener(AnvilContainerWrapper container, Player player); - - /** - * Creates a new ContainerAnvil - * - * @param player The player to get the container of - * @param title The title of the anvil inventory - * @return The Container instance - */ - AnvilContainerWrapper newContainerAnvil(Player player, Object title); - - /** - * Checks if the current Minecraft version actually supports custom titles - * - * @return The current supported state - */ - default boolean isCustomTitleSupported() { - return true; - } - - /** - * Creates a new chat component that does not handle the content in any special way - * - * @param content The content to display - * @return Version-specific ChatComponent instance - */ - Object literalChatComponent(String content); - - /** - * Creates a new rich chat component from the provided json - * - * @param json The component to parse - * @return Version-specific ChatComponent instance - */ - Object jsonChatComponent(String json); - - /** - * Interface implemented by the custom NMS AnvilContainer used to interact with it directly - */ - interface AnvilContainerWrapper { - - /** - * Retrieves the raw text that has been entered into the Anvil at the moment - *

- * This field is marked as public in the Minecraft AnvilContainer only from Minecraft 1.11 and upwards - * - * @return The raw text in the rename field - */ - default String getRenameText() { - return null; - } - - /** - * Sets the provided text as the literal hovername of the item in the left input slot - * - * @param text The text to set - */ - default void setRenameText(String text) {} - - /** - * Gets the {@link Inventory} wrapper of the NMS container - * - * @return The inventory of the NMS container - */ - Inventory getBukkitInventory(); - } -} diff --git a/src/main/java/xyz/ineanto/nicko/gui/prompt/AnvilPrompt.java b/src/main/java/xyz/ineanto/nicko/gui/prompt/AnvilPrompt.java index 41a5f84..8238faa 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/prompt/AnvilPrompt.java +++ b/src/main/java/xyz/ineanto/nicko/gui/prompt/AnvilPrompt.java @@ -15,6 +15,10 @@ import java.util.Collections; import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; +/** + * This is currently unused, I'm waiting for AnvilGUI + * to be updated to compile with Paper mappings. + */ public class AnvilPrompt implements Prompt { private final Player player; private final PlayerLanguage playerLanguage; From c74532ce66a8b198101dcfb3574270581d4410b7 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 28 Mar 2025 09:46:26 +0100 Subject: [PATCH 254/296] feat: add sign prompt --- .../ineanto/nicko/gui/prompt/SignPrompt.java | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 src/main/java/xyz/ineanto/nicko/gui/prompt/SignPrompt.java diff --git a/src/main/java/xyz/ineanto/nicko/gui/prompt/SignPrompt.java b/src/main/java/xyz/ineanto/nicko/gui/prompt/SignPrompt.java new file mode 100644 index 0000000..7d1e986 --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/gui/prompt/SignPrompt.java @@ -0,0 +1,95 @@ +package xyz.ineanto.nicko.gui.prompt; + +import de.rapha149.signgui.SignGUI; +import de.rapha149.signgui.SignGUIAction; +import de.rapha149.signgui.exception.SignGUIVersionException; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.language.PlayerLanguage; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicReference; + +public class SignPrompt implements Prompt { + private final Player player; + private final PlayerLanguage playerLanguage; + + private List lines = List.of( + "VVVVVVVVVVVVVVV", + null, + null, + "ΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛ" + ); + + private final AtomicReference> name = new AtomicReference<>(); + private final AtomicReference> skin = new AtomicReference<>(); + + public SignPrompt(Player player) { + this.player = player; + this.playerLanguage = new PlayerLanguage(player); + } + + @Override + public Optional displayNameThenSkinPrompt() { + try { + final SignGUI gui = SignGUI.builder() + .setLines(lines.toArray(new String[0])) + .setType(Material.OAK_SIGN) + .setHandler((_, result) -> { + String internalLine2 = result.getLineWithoutColor(2); + + if (internalLine2.isEmpty()) { + return List.of(SignGUIAction.displayNewLines(lines.toArray(new String[0]))); + } + + name.set(Optional.of(internalLine2)); + return Collections.emptyList(); + }) + .build(); + + gui.open(player); + return Optional.of(new String[]{name.get().orElse(player.getName()), skin.get().orElse(player.getName())}); + } catch (SignGUIVersionException exception) { + return Optional.empty(); + } + } + + @Override + public Optional displaySkinPrompt() { + this.lines.set(1, playerLanguage.translate(LanguageKey.GUI.NEW_SKIN, false)); + return displaySign(skin); + } + + @Override + public Optional displayNamePrompt() { + this.lines.set(1, playerLanguage.translate(LanguageKey.GUI.NEW_NAME, false)); + return displaySign(name); + } + + private Optional displaySign(AtomicReference> reference) { + try { + final SignGUI gui = SignGUI.builder() + .setLines(lines.toArray(new String[0])) + .setType(Material.OAK_SIGN) + .setHandler((_, result) -> { + final String internalLine2 = result.getLineWithoutColor(2); + + if (internalLine2.isEmpty()) { + return List.of(SignGUIAction.displayNewLines(lines.toArray(new String[0]))); + } + + reference.set(Optional.of(internalLine2)); + return Collections.emptyList(); + }) + .build(); + + gui.open(player); + return reference.get(); + } catch (SignGUIVersionException exception) { + return Optional.empty(); + } + } +} From 9adf5f34f56642d11949b34deef30096d3004442 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 28 Mar 2025 10:09:47 +0100 Subject: [PATCH 255/296] refactor: update displayed latest minecraft version --- build.gradle.kts | 5 ----- src/main/java/xyz/ineanto/nicko/Nicko.java | 2 +- .../java/xyz/ineanto/nicko/gui/prompt/PromptManager.java | 2 +- src/main/java/xyz/ineanto/nicko/gui/prompt/SignPrompt.java | 4 ++-- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9681564..ca19101 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -22,7 +22,6 @@ repositories { mavenCentral() mavenLocal() - maven { url = uri("https://jitpack.io") } maven { url = uri("https://repo.xenondevs.xyz/releases") } maven { url = uri("https://repo.papermc.io/repository/maven-public/") } maven { url = uri("https://repo.codemc.io/repository/maven-snapshots/") } @@ -92,10 +91,6 @@ tasks { exclude(dependency("xyz.xenondevs.invui:.*")) exclude(dependency("org.bstats:.*")) } - - manifest { - attributes["paperweight-mappings-namespace"] = "mojang" - } } runServer { diff --git a/src/main/java/xyz/ineanto/nicko/Nicko.java b/src/main/java/xyz/ineanto/nicko/Nicko.java index 83ec229..6899229 100644 --- a/src/main/java/xyz/ineanto/nicko/Nicko.java +++ b/src/main/java/xyz/ineanto/nicko/Nicko.java @@ -49,7 +49,7 @@ public class Nicko extends JavaPlugin { if (!MinecraftVersion.TRAILS_AND_TAILS.atOrAbove()) { getLogger().severe("This version (" + MinecraftVersion.getCurrentVersion().getVersion() + ") is not supported by Nicko!"); - getLogger().severe("As of version 1.2.0, Nicko only supports the latest Minecraft version. (Currently 1.21.3)"); + getLogger().severe("As of version 1.2.0, Nicko only supports the latest Minecraft version. (Currently 1.21.4)"); dataStore.getStorage().setError(true); Bukkit.getPluginManager().disablePlugin(this); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/prompt/PromptManager.java b/src/main/java/xyz/ineanto/nicko/gui/prompt/PromptManager.java index afd9a96..6cccbb0 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/prompt/PromptManager.java +++ b/src/main/java/xyz/ineanto/nicko/gui/prompt/PromptManager.java @@ -27,7 +27,7 @@ public class PromptManager { final Optional optionalProfile = dataStore.getData(player.getUniqueId()); this.profile = optionalProfile.orElse(NickoProfile.EMPTY_PROFILE.clone()); this.appearanceManager = new AppearanceManager(player); - this.prompt = new AnvilPrompt(player, playerLanguage); + this.prompt = new SignPrompt(player, playerLanguage); } public void displayNameThenSkinPrompt() { diff --git a/src/main/java/xyz/ineanto/nicko/gui/prompt/SignPrompt.java b/src/main/java/xyz/ineanto/nicko/gui/prompt/SignPrompt.java index 7d1e986..3f16d9a 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/prompt/SignPrompt.java +++ b/src/main/java/xyz/ineanto/nicko/gui/prompt/SignPrompt.java @@ -27,9 +27,9 @@ public class SignPrompt implements Prompt { private final AtomicReference> name = new AtomicReference<>(); private final AtomicReference> skin = new AtomicReference<>(); - public SignPrompt(Player player) { + public SignPrompt(Player player, PlayerLanguage playerLanguage) { this.player = player; - this.playerLanguage = new PlayerLanguage(player); + this.playerLanguage = playerLanguage; } @Override From 875a04a8504425500395dcc9e7e2040cc55697a4 Mon Sep 17 00:00:00 2001 From: ineanto Date: Wed, 2 Apr 2025 18:23:19 +0200 Subject: [PATCH 256/296] feat: update paper plugin sender, fix protocollib classpath access --- build.gradle.kts | 10 +- img/LOGO.png | Bin 8524 -> 0 bytes .../nicko/appearance/AppearanceManager.java | 18 ++- .../ineanto/nicko/gui/prompt/SignPrompt.java | 16 +- .../xyz/ineanto/nicko/language/Language.java | 2 +- .../ineanto/nicko/language/LanguageKey.java | 3 +- .../nicko/loader/NickoPluginLoader.java | 3 +- .../xyz/ineanto/nicko/mojang/MojangSkin.java | 8 + .../ineanto/nicko/packet/PacketSender.java | 4 +- ...cketSender.java => PaperPacketSender.java} | 72 +++++---- .../nicko/packet/WrapperPacketSender.java | 139 ------------------ src/main/resources/en.yml | 5 +- src/main/resources/fr.yml | 5 +- src/main/resources/paper-plugin.yml | 9 +- 14 files changed, 84 insertions(+), 210 deletions(-) delete mode 100644 img/LOGO.png rename src/main/java/xyz/ineanto/nicko/packet/{InternalPacketSender.java => PaperPacketSender.java} (72%) delete mode 100644 src/main/java/xyz/ineanto/nicko/packet/WrapperPacketSender.java diff --git a/build.gradle.kts b/build.gradle.kts index ca19101..868f042 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,7 @@ plugins { id("java") id("com.gradleup.shadow") version "8.3.2" - id("xyz.jpenilla.run-paper") version "2.3.0" + id("xyz.jpenilla.run-paper") version "2.3.1" id("io.papermc.paperweight.userdev") version "2.0.0-beta.10" } @@ -31,11 +31,11 @@ repositories { dependencies { paperweight.paperDevBundle("1.21.4-R0.1-SNAPSHOT") - compileOnly("com.comphenix.protocol:ProtocolLib:5.4.0-SNAPSHOT") compileOnly("me.clip:placeholderapi:2.11.5") compileOnly("net.kyori:adventure-api:4.17.0") compileOnly("xyz.xenondevs.invui:invui-core:$invuiVersion") compileOnly("net.wesjd:anvilgui:1.10.4-SNAPSHOT") + compileOnly("com.comphenix.protocol:ProtocolLib:5.4.0-SNAPSHOT") implementation("de.rapha149.signgui:signgui:2.5.0") implementation("com.github.jsixface:yamlconfig:1.2") @@ -62,7 +62,7 @@ tasks { relocate("net.wesjd", "xyz.ineanto.nicko.libs.anvilgui") relocate("com.github.jsixface", "xyz.ineanto.nicko.libs.yaml") relocate("me.clip", "xyz.ineanto.nicko.libs.placeholderapi") - relocate("com.fasterxml.jackson", "xyz.ineanto.nicko.libs.jacksonpr") + relocate("com.fasterxml.jackson", "xyz.ineanto.nicko.libs.jackson") relocate("com.mysql", "xyz.ineanto.nicko.libs.mysql") relocate("org.mariadb.jdbc", "xyz.ineanto.nicko.libs.mariadb") relocate("redis.clients", "xyz.ineanto.nicko.libs.redis") @@ -95,10 +95,10 @@ tasks { runServer { downloadPlugins { - url("https://download.luckperms.net/1568/bukkit/loader/LuckPerms-Bukkit-5.4.151.jar") + url("https://download.luckperms.net/1575/bukkit/loader/LuckPerms-Bukkit-5.4.158.jar") // 1.20.5 - latest testing - url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar") + //url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar") } minecraftVersion("1.21.4") diff --git a/img/LOGO.png b/img/LOGO.png deleted file mode 100644 index 747222945b1fa5dde3bebadb04535a33b0d1db01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8524 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 lines = List.of( - "VVVVVVVVVVVVVVV", - null, - null, - "ΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛ" + private final ArrayList lines = new ArrayList<>( + List.of( + "VVVVVVVVVVVVVVV", + "", + "", + "ΛΛΛΛΛΛΛΛΛΛΛΛΛΛΛ" + ) ); private final AtomicReference> name = new AtomicReference<>(); @@ -73,6 +75,7 @@ public class SignPrompt implements Prompt { try { final SignGUI gui = SignGUI.builder() .setLines(lines.toArray(new String[0])) + .setLine(2, null) .setType(Material.OAK_SIGN) .setHandler((_, result) -> { final String internalLine2 = result.getLineWithoutColor(2); @@ -89,6 +92,7 @@ public class SignPrompt implements Prompt { gui.open(player); return reference.get(); } catch (SignGUIVersionException exception) { + exception.printStackTrace(); return Optional.empty(); } } diff --git a/src/main/java/xyz/ineanto/nicko/language/Language.java b/src/main/java/xyz/ineanto/nicko/language/Language.java index 049039c..d916301 100644 --- a/src/main/java/xyz/ineanto/nicko/language/Language.java +++ b/src/main/java/xyz/ineanto/nicko/language/Language.java @@ -9,7 +9,7 @@ public enum Language implements Serializable { FRENCH("fr", "Français"), CUSTOM("cm", "Server Custom"); - public static final Version VERSION = new Version(1, 2, 0); + public static final Version VERSION = new Version(1, 3, 0); private final String code; private transient final String name; diff --git a/src/main/java/xyz/ineanto/nicko/language/LanguageKey.java b/src/main/java/xyz/ineanto/nicko/language/LanguageKey.java index 0dea8af..7e8fb29 100644 --- a/src/main/java/xyz/ineanto/nicko/language/LanguageKey.java +++ b/src/main/java/xyz/ineanto/nicko/language/LanguageKey.java @@ -10,8 +10,7 @@ public class LanguageKey { 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"; + public static final String MOJANG = ERROR_KEY + "mojang"; } public static class Event { diff --git a/src/main/java/xyz/ineanto/nicko/loader/NickoPluginLoader.java b/src/main/java/xyz/ineanto/nicko/loader/NickoPluginLoader.java index eaac594..096e9c7 100644 --- a/src/main/java/xyz/ineanto/nicko/loader/NickoPluginLoader.java +++ b/src/main/java/xyz/ineanto/nicko/loader/NickoPluginLoader.java @@ -3,8 +3,8 @@ package xyz.ineanto.nicko.loader; import io.papermc.paper.plugin.loader.PluginClasspathBuilder; import io.papermc.paper.plugin.loader.PluginLoader; import io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver; -import org.eclipse.aether.graph.Dependency; import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.graph.Dependency; import org.eclipse.aether.repository.RemoteRepository; public class NickoPluginLoader implements PluginLoader { @@ -15,7 +15,6 @@ public class NickoPluginLoader implements PluginLoader { resolver.addRepository(new RemoteRepository.Builder("xenondevs", "default", "https://repo.xenondevs.xyz/releases/").build()); resolver.addRepository(new RemoteRepository.Builder("codemc", "default", "https://repo.codemc.io/repository/maven-snapshots/").build()); resolver.addDependency(new Dependency(new DefaultArtifact("xyz.xenondevs.invui:invui:pom:1.44"), null)); - //resolver.addDependency(new Dependency(new DefaultArtifact("net.wesjd:anvilgui:1.10.4-SNAPSHOT"), null)); pluginClasspathBuilder.addLibrary(resolver); } diff --git a/src/main/java/xyz/ineanto/nicko/mojang/MojangSkin.java b/src/main/java/xyz/ineanto/nicko/mojang/MojangSkin.java index 3e50105..0b22223 100644 --- a/src/main/java/xyz/ineanto/nicko/mojang/MojangSkin.java +++ b/src/main/java/xyz/ineanto/nicko/mojang/MojangSkin.java @@ -1,7 +1,11 @@ package xyz.ineanto.nicko.mojang; +import com.destroystokyo.paper.profile.ProfileProperty; import com.google.gson.JsonObject; +import java.util.Collection; +import java.util.Collections; + public record MojangSkin(String value, String signature) { public static MojangSkin buildFromJson(JsonObject object) { final JsonObject properties = object.get("properties").getAsJsonArray().get(0).getAsJsonObject(); @@ -9,4 +13,8 @@ public record MojangSkin(String value, String signature) { final String signature = properties.get("signature").getAsString(); return new MojangSkin(value, signature); } + + public Collection asProfileProperties() { + return Collections.singleton(new ProfileProperty("textures", value, signature)); + } } diff --git a/src/main/java/xyz/ineanto/nicko/packet/PacketSender.java b/src/main/java/xyz/ineanto/nicko/packet/PacketSender.java index ef93153..28bb695 100644 --- a/src/main/java/xyz/ineanto/nicko/packet/PacketSender.java +++ b/src/main/java/xyz/ineanto/nicko/packet/PacketSender.java @@ -5,7 +5,9 @@ import xyz.ineanto.nicko.appearance.ActionResult; public interface PacketSender { void sendEntityRespawn(); - ActionResult sendGameProfileUpdate(String name, boolean skinChange, boolean reset); + ActionResult updatePlayerProfile(String name); + + ActionResult updatePlayerProfileProperties(); void sendEntityMetadataUpdate(); diff --git a/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java b/src/main/java/xyz/ineanto/nicko/packet/PaperPacketSender.java similarity index 72% rename from src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java rename to src/main/java/xyz/ineanto/nicko/packet/PaperPacketSender.java index d1796cb..ded8f5e 100644 --- a/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java +++ b/src/main/java/xyz/ineanto/nicko/packet/PaperPacketSender.java @@ -1,8 +1,7 @@ package xyz.ineanto.nicko.packet; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import com.mojang.authlib.properties.PropertyMap; +import com.destroystokyo.paper.profile.CraftPlayerProfile; +import com.destroystokyo.paper.profile.PlayerProfile; import it.unimi.dsi.fastutil.ints.IntList; import net.minecraft.Optionull; import net.minecraft.network.chat.MutableComponent; @@ -39,11 +38,11 @@ import java.util.concurrent.ExecutionException; * I want you to really stare at this code. * You made me do this. */ -public class InternalPacketSender implements PacketSender { +public class PaperPacketSender implements PacketSender { private final Player player; private final NickoProfile profile; - public InternalPacketSender(Player player, NickoProfile profile) { + public PaperPacketSender(Player player, NickoProfile profile) { this.player = player; this.profile = profile; } @@ -74,41 +73,40 @@ public class InternalPacketSender implements PacketSender { } @Override - public ActionResult sendGameProfileUpdate(String name, boolean skinChange, boolean reset) { - final GameProfile gameProfile = new GameProfile(player.getUniqueId(), name); - - // TODO (Ineanto, 31/10/2024): Could this be refactored to get rid of the boolean? - if (skinChange) { - Optional skin; - try { - final MojangAPI mojangAPI = Nicko.getInstance().getMojangAPI(); - final Optional uuid = mojangAPI.getUUID(profile.getSkin()); - if (uuid.isPresent()) { - skin = reset ? mojangAPI.getSkinWithoutCaching(uuid.get()) : mojangAPI.getSkin(uuid.get()); - if (skin.isPresent()) { - final MojangSkin skinResult = skin.get(); - final PropertyMap properties = gameProfile.getProperties(); - properties.get("textures").clear(); - properties.put("textures", new Property("textures", skinResult.value(), skinResult.signature())); - ((CraftPlayer) player).getHandle().gameProfile = gameProfile; - } else { - return ActionResult.error(LanguageKey.Error.MOJANG_SKIN); - } - } else { - return ActionResult.error(LanguageKey.Error.MOJANG_NAME); - } - return ActionResult.ok(); - } catch (ExecutionException e) { - return ActionResult.error(LanguageKey.Error.CACHE); - } catch (IOException e) { - return ActionResult.error(LanguageKey.Error.MOJANG_NAME); - } catch (InterruptedException e) { - return ActionResult.error("Unknown error"); - } - } + public ActionResult updatePlayerProfile(String name) { + final PlayerProfile playerProfile = new CraftPlayerProfile(player.getUniqueId(), name); + // Copy previous properties to preserve skin + playerProfile.setProperties(playerProfile.getProperties()); + player.setPlayerProfile(playerProfile); return ActionResult.ok(); } + @Override + public ActionResult updatePlayerProfileProperties() { + final PlayerProfile playerProfile = new CraftPlayerProfile(player.getUniqueId(), profile.getName() == null ? player.getName() : profile.getName()); + + try { + final MojangAPI mojangAPI = Nicko.getInstance().getMojangAPI(); + + final Optional uuid = mojangAPI.getUUID(profile.getSkin()); + if (uuid.isEmpty()) { + return ActionResult.error(LanguageKey.Error.MOJANG); + } + + final Optional skin = mojangAPI.getSkin(uuid.get()); + if (skin.isEmpty()) { + return ActionResult.error(LanguageKey.Error.MOJANG); + } + + final MojangSkin skinResult = skin.get(); + playerProfile.setProperties(skinResult.asProfileProperties()); + player.setPlayerProfile(playerProfile); + return ActionResult.ok(); + } catch (ExecutionException | IOException e) { + return ActionResult.error(LanguageKey.Error.CACHE); + } + } + @Override public void sendEntityMetadataUpdate() { final SynchedEntityData.DataValue dataValueComponent = diff --git a/src/main/java/xyz/ineanto/nicko/packet/WrapperPacketSender.java b/src/main/java/xyz/ineanto/nicko/packet/WrapperPacketSender.java deleted file mode 100644 index fc2b140..0000000 --- a/src/main/java/xyz/ineanto/nicko/packet/WrapperPacketSender.java +++ /dev/null @@ -1,139 +0,0 @@ -package xyz.ineanto.nicko.packet; - -import com.comphenix.protocol.wrappers.*; -import com.google.common.collect.Multimap; -import it.unimi.dsi.fastutil.ints.IntList; -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.entity.Player; -import xyz.ineanto.nicko.Nicko; -import xyz.ineanto.nicko.appearance.ActionResult; -import xyz.ineanto.nicko.language.LanguageKey; -import xyz.ineanto.nicko.mojang.MojangAPI; -import xyz.ineanto.nicko.mojang.MojangSkin; -import xyz.ineanto.nicko.packet.wrapper.*; -import xyz.ineanto.nicko.profile.NickoProfile; - -import java.io.IOException; -import java.util.EnumSet; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.ExecutionException; - -public class WrapperPacketSender implements PacketSender { - private final Player player; - private final NickoProfile profile; - - private WrappedGameProfile gameProfile; - - public WrapperPacketSender(Player player, NickoProfile profile) { - this.player = player; - this.profile = profile; - } - - @Override - public void sendEntityRespawn() { - if (!profile.hasData()) return; - - final WrapperPlayServerEntityDestroy destroy = new WrapperPlayServerEntityDestroy(); - final WrapperPlayServerSpawnEntity spawn = new WrapperPlayServerSpawnEntity(); - destroy.setEntityIds(IntList.of(player.getEntityId())); - spawn.setEntityId(player.getEntityId()); - spawn.setLocation(player.getLocation()); - spawn.setPlayerId(player.getUniqueId()); - Bukkit.getOnlinePlayers().stream().filter(receiver -> receiver.getUniqueId() != player.getUniqueId()).forEach(receiver -> { - destroy.sendPacket(receiver); - spawn.sendPacket(receiver); - }); - } - - @Override - public ActionResult sendGameProfileUpdate(String name, boolean skinChange, boolean reset) { - this.gameProfile = WrappedGameProfile.fromPlayer(player).withName(name); - - // TODO (Ineanto, 31/10/2024): Could get refactored to omit this boolean? - if (skinChange) { - Optional skin; - try { - final MojangAPI mojangAPI = Nicko.getInstance().getMojangAPI(); - final Optional uuid = mojangAPI.getUUID(profile.getSkin()); - if (uuid.isPresent()) { - skin = reset ? mojangAPI.getSkinWithoutCaching(uuid.get()) : mojangAPI.getSkin(uuid.get()); - if (skin.isPresent()) { - final MojangSkin skinResult = skin.get(); - final Multimap properties = gameProfile.getProperties(); - properties.get("textures").clear(); - properties.put("textures", new WrappedSignedProperty("textures", skinResult.value(), skinResult.signature())); - } else { - return ActionResult.error(LanguageKey.Error.MOJANG_SKIN); - } - } else { - return ActionResult.error(LanguageKey.Error.MOJANG_NAME); - } - return ActionResult.ok(); - } catch (ExecutionException e) { - return ActionResult.error(LanguageKey.Error.CACHE); - } catch (IOException e) { - return ActionResult.error(LanguageKey.Error.MOJANG_NAME); - } catch (InterruptedException e) { - return ActionResult.error("Unknown error"); - } - } - return ActionResult.ok(); - } - - - @Override - public void sendEntityMetadataUpdate() { - final WrappedDataWatcher entityWatcher = WrappedDataWatcher.getEntityWatcher(player); - entityWatcher.setObject(17, (byte) 0x7f, true); - } - - @Override - public void sendPlayerRespawn() { - final World world = player.getWorld(); - - final WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(); - respawn.setDimension(world); - respawn.setSeed(world.getSeed()); - respawn.setGameMode(player.getGameMode()); - respawn.setPreviousGameMode(player.getGameMode()); - respawn.setCopyMetadata(true); - respawn.sendPacket(player); - } - - @Override - public void sendTabListUpdate(String displayName) { - if (gameProfile == null) { - Nicko.getInstance().getLogger().warning("Hello. I sincerely hope you're doing great out there."); - Nicko.getInstance().getLogger().warning("If you see this message, I've failed at my task and I'm a terrible programmer."); - Nicko.getInstance().getLogger().warning("Report this issue on https://git.ineanto.xyz/ineanto/nicko, thank you!"); - return; - } - - final WrapperPlayerServerPlayerInfo add = new WrapperPlayerServerPlayerInfo(); - final WrapperPlayerServerPlayerInfoRemove remove = new WrapperPlayerServerPlayerInfoRemove(); - final EnumSet actions = EnumSet.of( - EnumWrappers.PlayerInfoAction.ADD_PLAYER, - EnumWrappers.PlayerInfoAction.INITIALIZE_CHAT, - EnumWrappers.PlayerInfoAction.UPDATE_LISTED, - EnumWrappers.PlayerInfoAction.UPDATE_DISPLAY_NAME, - EnumWrappers.PlayerInfoAction.UPDATE_GAME_MODE, - EnumWrappers.PlayerInfoAction.UPDATE_LATENCY); - remove.setUUIDs(List.of(player.getUniqueId())); - remove.broadcastPacket(); - add.setActions(actions); - - add.setData(List.of(new PlayerInfoData( - player.getUniqueId(), - player.getPing(), - true, - EnumWrappers.NativeGameMode.fromBukkit(player.getGameMode()), - gameProfile, - WrappedChatComponent.fromText(displayName), - WrappedRemoteChatSessionData.fromPlayer(player) - ))); - - add.broadcastPacket(); - } -} diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 887ebce..888ff59 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -1,7 +1,7 @@ # Nicko ${version} - Language File: # Specifies the configuration version, don't change. -version: "1.2.0" +version: "1.3.0" prefix: "NICKO" whoosh: "WHOOSH!" @@ -10,8 +10,7 @@ oops: "OOPS!" error: permission: "You're missing the permission to do that." invalid_username: "This is an invalid Minecraft username." - mojang_name: "There's is not Minecraft account with this username." - mojang_skin: "This Minecraft account has no skin." + mojang: "Something went wrong while fetching data from Mojang." cache: "Unable to get data from the cache." event: diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index eb92b7b..68df92e 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -1,7 +1,7 @@ # Nicko ${version} - Fichier de langue: # Précise la version de la configuration, ne pas changer. -version: "1.2.0" +version: "1.3.0" prefix: "NICKO" whoosh: "WHOOSH!" @@ -10,8 +10,7 @@ oops: "OOPS!" error: permission: "Vous n'avez pas la permission de faire cela." invalid_username: "Nom d'utilisateur Minecraft invalide." - mojang_name: "Aucun compte Minecraft associé à ce nom d'utilisateur." - mojang_skin: "Ce compte Minecraft n'a pas de skin." + mojang: "Une erreur est surevenue en récupérant les information depuis Mojang." cache: "Impossible de récupérer les données depuis le cache." event: diff --git a/src/main/resources/paper-plugin.yml b/src/main/resources/paper-plugin.yml index 048a12e..f515c80 100644 --- a/src/main/resources/paper-plugin.yml +++ b/src/main/resources/paper-plugin.yml @@ -9,10 +9,11 @@ softdepend: [ PlaceholderAPI ] depend: - ProtocolLib -# Suppose we require ProtocolLib to be loaded for our plugin -AnvilGUI: - join-classpath: true - required: true +dependencies: + server: + ProtocolLib: + load: BEFORE + join-classpath: true permissions: nicko.*: From 1ce7fbe3f05bddb7a8cf30fc70b962e631e42597 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 3 Apr 2025 09:33:17 +0200 Subject: [PATCH 257/296] feat: update function signature across codebase --- build.gradle.kts | 4 ++-- .../nicko/appearance/AppearanceManager.java | 4 ++-- .../nicko/event/PlayerJoinListener.java | 22 +++---------------- .../nicko/event/PlayerQuitListener.java | 3 ++- .../nicko/gui/items/home/RandomSkinItem.java | 2 +- .../nicko/gui/prompt/PromptManager.java | 2 +- .../nicko/loader/NickoPluginLoader.java | 1 - 7 files changed, 11 insertions(+), 27 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 868f042..33cddee 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,7 @@ plugins { id("java") id("com.gradleup.shadow") version "8.3.2" - id("xyz.jpenilla.run-paper") version "2.3.1" + id("xyz.jpenilla.run-paper") version "2.3.0" id("io.papermc.paperweight.userdev") version "2.0.0-beta.10" } @@ -98,7 +98,7 @@ tasks { url("https://download.luckperms.net/1575/bukkit/loader/LuckPerms-Bukkit-5.4.158.jar") // 1.20.5 - latest testing - //url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar") + url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar") } minecraftVersion("1.21.4") diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index 23bd447..3ef26ad 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -38,7 +38,7 @@ public class AppearanceManager { profile.setName(defaultName); profile.setSkin(defaultName); - final ActionResult result = update(true, true); + final ActionResult result = update(true); profile.setName(null); profile.setSkin(null); @@ -47,7 +47,7 @@ public class AppearanceManager { return result; } - public ActionResult update(boolean skinChange, boolean reset) { + public ActionResult update(boolean skinChange) { final NickoProfile profile = getNickoProfile(); final String displayName = profile.getName() == null ? player.getName() : profile.getName(); diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java index 28171f5..cdb2cd4 100644 --- a/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerJoinListener.java @@ -11,8 +11,8 @@ import xyz.ineanto.nicko.appearance.ActionResult; import xyz.ineanto.nicko.appearance.AppearanceManager; import xyz.ineanto.nicko.gui.PlayerCheckGUI; import xyz.ineanto.nicko.gui.PlayerCheckGUIData; -import xyz.ineanto.nicko.language.PlayerLanguage; import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.language.PlayerLanguage; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.PlayerDataStore; import xyz.ineanto.nicko.storage.name.PlayerNameStore; @@ -22,12 +22,9 @@ import xyz.xenondevs.invui.window.WindowManager; import java.util.ArrayList; import java.util.Optional; import java.util.UUID; -import java.util.logging.Logger; public class PlayerJoinListener implements Listener { - private final Logger logger = Logger.getLogger("PlayerJoinListener"); - - @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) + @EventHandler(priority = EventPriority.LOWEST) public void onPlayerJoin(PlayerJoinEvent event) { final Player player = event.getPlayer(); final Nicko instance = Nicko.getInstance(); @@ -50,7 +47,7 @@ public class PlayerJoinListener implements Listener { if (profile.hasData()) { final AppearanceManager appearanceManager = new AppearanceManager(player); final boolean needsASkinChange = profile.getSkin() != null && !profile.getSkin().equals(player.getName()); - final ActionResult actionResult = appearanceManager.update(needsASkinChange, false); + final ActionResult actionResult = appearanceManager.update(needsASkinChange); if (!actionResult.isError()) { player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Appearance.Restore.OK)); } else { @@ -62,19 +59,6 @@ public class PlayerJoinListener implements Listener { } }, () -> instance.getLogger().warning("Failed to load data for " + player.getName())); - for (Player online : Bukkit.getOnlinePlayers().stream().filter(op -> op.getUniqueId() != player.getUniqueId()).toList()) { - final Optional optionalOnlinePlayerProfile = dataStore.getData(online.getUniqueId()); - - optionalOnlinePlayerProfile.ifPresent(profile -> { - final AppearanceManager appearanceManager = new AppearanceManager(online); - final boolean needsASkinChange = profile.getSkin() != null && !profile.getSkin().equals(online.getName()); - final ActionResult actionResult = appearanceManager.update(needsASkinChange, false); - if (actionResult.isError()) { - logger.warning("Something wrong happened while updating players to joining player (" + actionResult.getErrorKey() + ")"); - } - }); - } - @SuppressWarnings("unchecked") final ArrayList viewers = (ArrayList) PlayerCheckGUIData.VIEWERS.clone(); viewers.forEach(uuid -> { final Player windowWatcher = Bukkit.getPlayer(uuid); diff --git a/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java b/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java index 10160a4..020790b 100644 --- a/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java +++ b/src/main/java/xyz/ineanto/nicko/event/PlayerQuitListener.java @@ -3,6 +3,7 @@ package xyz.ineanto.nicko.event; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; import xyz.ineanto.nicko.Nicko; @@ -18,7 +19,7 @@ import java.util.UUID; import java.util.stream.Collectors; public class PlayerQuitListener implements Listener { - @EventHandler + @EventHandler(priority = EventPriority.LOWEST) public void onPlayerQuit(PlayerQuitEvent event) { final Player player = event.getPlayer(); final ActionResult result = Nicko.getInstance().getDataStore().saveData(player); diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java index 9f7b5e0..8f88b7c 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java @@ -40,7 +40,7 @@ public class RandomSkinItem { instance.getDataStore().updateCache(player.getUniqueId(), profile); final AppearanceManager appearanceManager = new AppearanceManager(player); - final ActionResult result = appearanceManager.update(true, false); + final ActionResult result = appearanceManager.update(true); if (!result.isError()) { player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Appearance.Set.OK)); } else { diff --git a/src/main/java/xyz/ineanto/nicko/gui/prompt/PromptManager.java b/src/main/java/xyz/ineanto/nicko/gui/prompt/PromptManager.java index 6cccbb0..651b740 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/prompt/PromptManager.java +++ b/src/main/java/xyz/ineanto/nicko/gui/prompt/PromptManager.java @@ -63,7 +63,7 @@ public class PromptManager { } private void update(boolean skinChange) { - final ActionResult actionResult = appearanceManager.update(skinChange, false); + final ActionResult actionResult = appearanceManager.update(skinChange); if (!actionResult.isError()) { player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Appearance.Set.OK)); player.playSound(player.getLocation(), Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1, 1f); diff --git a/src/main/java/xyz/ineanto/nicko/loader/NickoPluginLoader.java b/src/main/java/xyz/ineanto/nicko/loader/NickoPluginLoader.java index 096e9c7..647c1ca 100644 --- a/src/main/java/xyz/ineanto/nicko/loader/NickoPluginLoader.java +++ b/src/main/java/xyz/ineanto/nicko/loader/NickoPluginLoader.java @@ -13,7 +13,6 @@ public class NickoPluginLoader implements PluginLoader { final MavenLibraryResolver resolver = new MavenLibraryResolver(); resolver.addRepository(new RemoteRepository.Builder("xenondevs", "default", "https://repo.xenondevs.xyz/releases/").build()); - resolver.addRepository(new RemoteRepository.Builder("codemc", "default", "https://repo.codemc.io/repository/maven-snapshots/").build()); resolver.addDependency(new Dependency(new DefaultArtifact("xyz.xenondevs.invui:invui:pom:1.44"), null)); pluginClasspathBuilder.addLibrary(resolver); From 76c8f734e7df9ad416cbe425877a94afa0a2328d Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 3 Apr 2025 09:34:04 +0200 Subject: [PATCH 258/296] refactor(appearance): remove old code --- .../nicko/appearance/AppearanceManager.java | 21 +------------------ 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index 3ef26ad..b0b3d24 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -2,12 +2,11 @@ package xyz.ineanto.nicko.appearance; import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerTeleportEvent; import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.event.custom.PlayerDisguiseEvent; import xyz.ineanto.nicko.event.custom.PlayerResetDisguiseEvent; -import xyz.ineanto.nicko.packet.PaperPacketSender; import xyz.ineanto.nicko.packet.PacketSender; +import xyz.ineanto.nicko.packet.PaperPacketSender; import xyz.ineanto.nicko.profile.NickoProfile; import xyz.ineanto.nicko.storage.PlayerDataStore; import xyz.ineanto.nicko.storage.name.PlayerNameStore; @@ -67,27 +66,9 @@ public class AppearanceManager { packetSender.sendEntityMetadataUpdate(); packetSender.sendTabListUpdate(displayName); - //respawnPlayer(); - //packetSender.sendEntityRespawn(); - return result; } - private void respawnPlayer() { - final boolean wasFlying = player.isFlying(); - final boolean wasAllowedToFly = player.getAllowFlight(); - final int foodLevel = player.getFoodLevel(); - - packetSender.sendPlayerRespawn(); - - player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); - player.setAllowFlight(wasAllowedToFly); - player.setFlying(wasFlying); - player.updateInventory(); - player.sendHealthUpdate(); - player.setFoodLevel(foodLevel); - } - private NickoProfile getNickoProfile() { final Optional optionalProfile = dataStore.getData(player.getUniqueId()); return optionalProfile.orElse(NickoProfile.EMPTY_PROFILE.clone()); From a709a9195f18227d6d71df2a78c1108350218279 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 3 Apr 2025 09:47:48 +0200 Subject: [PATCH 259/296] feat: update changelog --- CHANGELOG.log | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.log b/CHANGELOG.log index 3cd81a6..ca76781 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,4 +1,4 @@ -1.2.0: Update n°13 (XX/XX/24) +1.3.0: Update n°14 (XX/XX/25) [FEATURES] - Players are now able to mark disguises as favorites. - Modernized the messages and added various sound effects upon interacting with the plugin. @@ -11,6 +11,20 @@ [LANGUAGE] - Moved the prefix to the language file. +1.2.0: Update n°13 (XX/XX/25) + [FEATURES] + - Updated to support up to Minecraft 1.21.4. + - Modernized the messages and added various sound effects upon interacting with the plugin. + - Made GUIs names cleaner. + + [FIXES] + - Cleaned up the codebase to prepare for future updates. + - Fixed an oversight preventing the configuration from properly being migrated. + - Fixed the placeholder item in the skin cache invalidation not being translated. + + [LANGUAGE] + - Moved the prefix to the language file. + 1.1.8: Update n°12 (XX/XX/24) [FEATURES] From dc36a0148e5fef77f079c337fe9dbe747151f0c0 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 3 Apr 2025 09:49:12 +0200 Subject: [PATCH 260/296] refactor: fixed changelog --- CHANGELOG.log | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.log b/CHANGELOG.log index ca76781..b18742a 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,4 +1,4 @@ -1.3.0: Update n°14 (XX/XX/25) +1.3.0-RC1: Update n°13 (XX/XX/25) [FEATURES] - Players are now able to mark disguises as favorites. - Modernized the messages and added various sound effects upon interacting with the plugin. @@ -11,7 +11,7 @@ [LANGUAGE] - Moved the prefix to the language file. -1.2.0: Update n°13 (XX/XX/25) +1.2.0-RC1: Update n°12 (XX/XX/25) [FEATURES] - Updated to support up to Minecraft 1.21.4. - Modernized the messages and added various sound effects upon interacting with the plugin. @@ -25,12 +25,6 @@ [LANGUAGE] - Moved the prefix to the language file. -1.1.8: Update n°12 (XX/XX/24) - [FEATURES] - - [OTHER] - - Dropped the release candidate status as Nicko is now considered stable. - 1.1.7-RC1: Hotfix n°5 (04/05/24) [OTHER] - Restored download link again on spigotmc.org From 197f4f32591be8dd2281ac4465b35cca54d42ca8 Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 3 Apr 2025 21:17:59 +0200 Subject: [PATCH 261/296] feat(prompt): sign not working properly due to synchronization issues --- build.gradle.kts | 3 +- .../ineanto/nicko/gui/prompt/SignPrompt.java | 67 +++++++++---------- 2 files changed, 34 insertions(+), 36 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 33cddee..d67ef76 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -68,7 +68,6 @@ tasks { relocate("redis.clients", "xyz.ineanto.nicko.libs.redis") relocate("com.google.gson", "xyz.ineanto.nicko.libs.gson") relocate("org.apache.commons.pool2", "xyz.ineanto.nicko.libs.pool2") - relocate("org.bstats", "xyz.ineanto.nicko.libs.bstats") // EXCLUSIONS exclude("colors.bin") @@ -89,7 +88,7 @@ tasks { // MINIFY minimize { exclude(dependency("xyz.xenondevs.invui:.*")) - exclude(dependency("org.bstats:.*")) + exclude(dependency("de.rapha149.signgui:.*")) } } diff --git a/src/main/java/xyz/ineanto/nicko/gui/prompt/SignPrompt.java b/src/main/java/xyz/ineanto/nicko/gui/prompt/SignPrompt.java index f31fbb8..0ca6182 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/prompt/SignPrompt.java +++ b/src/main/java/xyz/ineanto/nicko/gui/prompt/SignPrompt.java @@ -5,6 +5,7 @@ import de.rapha149.signgui.SignGUIAction; import de.rapha149.signgui.exception.SignGUIVersionException; import org.bukkit.Material; import org.bukkit.entity.Player; +import xyz.ineanto.nicko.Nicko; import xyz.ineanto.nicko.language.LanguageKey; import xyz.ineanto.nicko.language.PlayerLanguage; @@ -12,7 +13,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.concurrent.atomic.AtomicReference; public class SignPrompt implements Prompt { private final Player player; @@ -26,8 +26,8 @@ public class SignPrompt implements Prompt { ) ); - private final AtomicReference> name = new AtomicReference<>(); - private final AtomicReference> skin = new AtomicReference<>(); + private String name = null; + private String skin = null; public SignPrompt(Player player, PlayerLanguage playerLanguage) { this.player = player; @@ -36,64 +36,63 @@ public class SignPrompt implements Prompt { @Override public Optional displayNameThenSkinPrompt() { - try { - final SignGUI gui = SignGUI.builder() - .setLines(lines.toArray(new String[0])) - .setType(Material.OAK_SIGN) - .setHandler((_, result) -> { - String internalLine2 = result.getLineWithoutColor(2); + displayNamePrompt(); + displaySkinPrompt(); - if (internalLine2.isEmpty()) { - return List.of(SignGUIAction.displayNewLines(lines.toArray(new String[0]))); - } - - name.set(Optional.of(internalLine2)); - return Collections.emptyList(); - }) - .build(); - - gui.open(player); - return Optional.of(new String[]{name.get().orElse(player.getName()), skin.get().orElse(player.getName())}); - } catch (SignGUIVersionException exception) { + if (skin == null || name == null) { return Optional.empty(); } + + return Optional.of(new String[]{name, skin}); } @Override public Optional displaySkinPrompt() { this.lines.set(1, playerLanguage.translate(LanguageKey.GUI.NEW_SKIN, false)); - return displaySign(skin); + displaySign(true); + + if (skin == null) { + return Optional.empty(); + } + + return Optional.of(skin); } @Override public Optional displayNamePrompt() { this.lines.set(1, playerLanguage.translate(LanguageKey.GUI.NEW_NAME, false)); - return displaySign(name); + displaySign(false); + + if (name == null) { + return Optional.empty(); + } + + return Optional.of(skin); } - private Optional displaySign(AtomicReference> reference) { + private void displaySign(boolean isSkin) { try { final SignGUI gui = SignGUI.builder() .setLines(lines.toArray(new String[0])) - .setLine(2, null) .setType(Material.OAK_SIGN) + .callHandlerSynchronously(Nicko.getInstance()) .setHandler((_, result) -> { - final String internalLine2 = result.getLineWithoutColor(2); + final String internalLine1 = result.getLineWithoutColor(1); - if (internalLine2.isEmpty()) { + if (internalLine1.isEmpty()) { return List.of(SignGUIAction.displayNewLines(lines.toArray(new String[0]))); } - reference.set(Optional.of(internalLine2)); + if (isSkin) { + skin = internalLine1; + } else { + name = internalLine1; + } + return Collections.emptyList(); }) .build(); - gui.open(player); - return reference.get(); - } catch (SignGUIVersionException exception) { - exception.printStackTrace(); - return Optional.empty(); - } + } catch (SignGUIVersionException _) { } } } From 1a792112cc80a29440ea256b87df49cb00a0c801 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 4 Apr 2025 09:27:57 +0200 Subject: [PATCH 262/296] refactor: remove unused code --- .../ineanto/nicko/gui/items/appearance/ChangeNameItem.java | 5 ----- .../ineanto/nicko/gui/items/appearance/ChangeSkinItem.java | 3 --- 2 files changed, 8 deletions(-) diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java index 6f54bda..e18643a 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeNameItem.java @@ -3,7 +3,6 @@ package xyz.ineanto.nicko.gui.items.appearance; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; -import xyz.ineanto.nicko.appearance.AppearanceManager; import xyz.ineanto.nicko.gui.prompt.PromptManager; import xyz.ineanto.nicko.language.LanguageKey; import xyz.ineanto.nicko.language.PlayerLanguage; @@ -11,13 +10,9 @@ import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.impl.SuppliedItem; public class ChangeNameItem { - private final AppearanceManager appearanceManager; - private final Player player; private final PlayerLanguage playerLanguage; public ChangeNameItem(Player player) { - this.appearanceManager = new AppearanceManager(player); - this.player = player; this.playerLanguage = new PlayerLanguage(player); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java index e6b841b..1d97610 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/appearance/ChangeSkinItem.java @@ -4,7 +4,6 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import xyz.ineanto.nicko.Nicko; -import xyz.ineanto.nicko.appearance.AppearanceManager; import xyz.ineanto.nicko.gui.prompt.PromptManager; import xyz.ineanto.nicko.language.LanguageKey; import xyz.ineanto.nicko.language.PlayerLanguage; @@ -18,13 +17,11 @@ import xyz.xenondevs.invui.util.MojangApiUtils; import java.io.IOException; public class ChangeSkinItem { - private final AppearanceManager appearanceManager; private final PlayerLanguage playerLanguage; private final PlayerNameStore playerNameStore; private final Player player; public ChangeSkinItem(Player player) { - this.appearanceManager = new AppearanceManager(player); this.playerLanguage = new PlayerLanguage(player); this.playerNameStore = Nicko.getInstance().getNameStore(); this.player = player; From d30f43352758a035c37f21056f0803829ab553d2 Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 4 Apr 2025 10:32:39 +0200 Subject: [PATCH 263/296] feat: add chat prompt because nothing reliably works --- CHANGELOG.log | 9 --- .../ineanto/nicko/gui/prompt/ChatPrompt.java | 70 +++++++++++++++++++ .../ineanto/nicko/gui/prompt/SignPrompt.java | 22 ++++++ 3 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 src/main/java/xyz/ineanto/nicko/gui/prompt/ChatPrompt.java diff --git a/CHANGELOG.log b/CHANGELOG.log index b18742a..6056af3 100644 --- a/CHANGELOG.log +++ b/CHANGELOG.log @@ -1,15 +1,6 @@ 1.3.0-RC1: Update n°13 (XX/XX/25) [FEATURES] - Players are now able to mark disguises as favorites. - - Modernized the messages and added various sound effects upon interacting with the plugin. - - Made GUIs names cleaner. - - [FIXES] - - Fixed an oversight preventing the configuration from properly being migrated. - - Fixed the placeholder item in the skin cache invalidation not being translated. - - [LANGUAGE] - - Moved the prefix to the language file. 1.2.0-RC1: Update n°12 (XX/XX/25) [FEATURES] diff --git a/src/main/java/xyz/ineanto/nicko/gui/prompt/ChatPrompt.java b/src/main/java/xyz/ineanto/nicko/gui/prompt/ChatPrompt.java new file mode 100644 index 0000000..4cf1cb4 --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/gui/prompt/ChatPrompt.java @@ -0,0 +1,70 @@ +package xyz.ineanto.nicko.gui.prompt; + +import io.papermc.paper.event.player.AsyncChatEvent; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import xyz.ineanto.nicko.Nicko; +import xyz.ineanto.nicko.language.LanguageKey; +import xyz.ineanto.nicko.language.PlayerLanguage; + +import java.util.Optional; + +public class ChatPrompt implements Prompt { + private final Player player; + private final PlayerLanguage playerLanguage; + + private String name = null; + private String skin = null; + + public ChatPrompt(Player player, PlayerLanguage playerLanguage) { + this.player = player; + this.playerLanguage = playerLanguage; + } + + @Override + public Optional displayNameThenSkinPrompt() { + displayNamePrompt(); + displaySkinPrompt(); + + if (skin == null || name == null) { + return Optional.empty(); + } + + return Optional.of(new String[]{name, skin}); + } + + @Override + public Optional displaySkinPrompt() { + promptInChat(true); + return Optional.empty(); + } + + @Override + public Optional displayNamePrompt() { + promptInChat(false); + return Optional.empty(); + } + + private void promptInChat(boolean isSkin) { + player.sendMessage(playerLanguage.translate(isSkin ? LanguageKey.GUI.NEW_SKIN : LanguageKey.GUI.NEW_NAME, false)); + //player.sendMessage(playerLanguage.translate(LanguageKey.GUI.ENTER_IN_CHAT, false)); + + Nicko.getInstance().getServer().getPluginManager().registerEvents(new Listener() { + @EventHandler + public void onPlayerChat(AsyncChatEvent event) { + if (event.getPlayer().equals(player)) { + event.setCancelled(true); + final String plain = PlainTextComponentSerializer.plainText().serialize(event.originalMessage()); + + if (isSkin) { + skin = plain; + } else { + name = plain; + } + } + } + }, Nicko.getInstance()); + } +} diff --git a/src/main/java/xyz/ineanto/nicko/gui/prompt/SignPrompt.java b/src/main/java/xyz/ineanto/nicko/gui/prompt/SignPrompt.java index 0ca6182..67a9cea 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/prompt/SignPrompt.java +++ b/src/main/java/xyz/ineanto/nicko/gui/prompt/SignPrompt.java @@ -13,8 +13,12 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; public class SignPrompt implements Prompt { + private final CompletableFuture future = new CompletableFuture<>(); + private final Player player; private final PlayerLanguage playerLanguage; private final ArrayList lines = new ArrayList<>( @@ -51,6 +55,14 @@ public class SignPrompt implements Prompt { this.lines.set(1, playerLanguage.translate(LanguageKey.GUI.NEW_SKIN, false)); displaySign(true); + synchronized (future) { + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + if (skin == null) { return Optional.empty(); } @@ -63,6 +75,14 @@ public class SignPrompt implements Prompt { this.lines.set(1, playerLanguage.translate(LanguageKey.GUI.NEW_NAME, false)); displaySign(false); + synchronized (future) { + try { + future.get(); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + } + if (name == null) { return Optional.empty(); } @@ -89,9 +109,11 @@ public class SignPrompt implements Prompt { name = internalLine1; } + future.complete(null); return Collections.emptyList(); }) .build(); + gui.open(player); } catch (SignGUIVersionException _) { } } From 63f2e7f699ae16c87f02704e65a8d21c378322b1 Mon Sep 17 00:00:00 2001 From: ineanto Date: Mon, 12 May 2025 18:41:50 +0200 Subject: [PATCH 264/296] feat: trying to circumvent AnvilGUI --- .idea/gradle.xml | 1 - .idea/misc.xml | 2 +- build.gradle.kts | 4 +- src/main/java/xyz/ineanto/nicko/Nicko.java | 2 + .../nicko/event/PromptCloseListener.java | 16 +++++ .../nicko/event/custom/PromptCloseEvent.java | 52 ++++++++++++++++ .../ineanto/nicko/gui/prompt/ChatPrompt.java | 62 ++++++++++++++----- .../nicko/gui/prompt/PromptManager.java | 2 +- .../ineanto/nicko/language/LanguageKey.java | 2 + .../nicko/loader/NickoPluginLoader.java | 2 +- src/main/resources/en.yml | 1 + 11 files changed, 125 insertions(+), 21 deletions(-) create mode 100644 src/main/java/xyz/ineanto/nicko/event/PromptCloseListener.java create mode 100644 src/main/java/xyz/ineanto/nicko/event/custom/PromptCloseEvent.java diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 1b86f21..89022a7 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -5,7 +5,6 @@