From 4948610860a19dbe22d9360563ec476565b24ddf Mon Sep 17 00:00:00 2001 From: ineanto Date: Thu, 12 Dec 2024 19:22:11 +0100 Subject: [PATCH] feat: spigot branch --- .idea/gradle.xml | 3 + build.gradle.kts | 63 ++------ common/build.gradle.kts | 14 ++ .../ineanto/nicko/action}/ActionResult.java | 2 +- .../xyz/ineanto/nicko/mojang/MojangAPI.java | 0 .../xyz/ineanto/nicko/mojang/MojangSkin.java | 0 .../xyz/ineanto/nicko/mojang/MojangUtils.java | 0 mappings/build.gradle.kts | 10 ++ .../ineanto/nicko/packet/PacketSender.java | 26 ++++ mappings/v1_21_R1/build.gradle.kts | 21 +++ .../nicko/mappings/Mapping1_21_R1.java | 73 ++++----- settings.gradle.kts | 4 +- src/main/java/xyz/ineanto/nicko/Nicko.java | 2 +- .../nicko/appearance/AppearanceManager.java | 1 + .../nicko/loader/NickoLibraryLoader.java | 19 +++ .../ineanto/nicko/packet/PacketSender.java | 15 -- .../nicko/packet/WrapperPacketSender.java | 139 ------------------ .../packet/debug/RespawnPacketListener.java | 82 ----------- .../nicko/packet/wrapper/AbstractPacket.java | 73 --------- .../WrapperPlayServerEntityDestroy.java | 32 ---- .../wrapper/WrapperPlayServerRespawn.java | 115 --------------- .../wrapper/WrapperPlayServerSpawnEntity.java | 103 ------------- .../WrapperPlayerServerPlayerInfo.java | 37 ----- .../WrapperPlayerServerPlayerInfoRemove.java | 27 ---- .../{plugin.yml => paper-plugin.yml} | 16 +- .../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 ------------- 35 files changed, 144 insertions(+), 1291 deletions(-) create mode 100644 common/build.gradle.kts rename {src/main/java/xyz/ineanto/nicko/appearance => common/src/main/java/xyz/ineanto/nicko/action}/ActionResult.java (94%) rename {src => common/src}/main/java/xyz/ineanto/nicko/mojang/MojangAPI.java (100%) rename {src => common/src}/main/java/xyz/ineanto/nicko/mojang/MojangSkin.java (100%) rename {src => common/src}/main/java/xyz/ineanto/nicko/mojang/MojangUtils.java (100%) create mode 100644 mappings/build.gradle.kts create mode 100644 mappings/src/main/java/xyz/ineanto/nicko/packet/PacketSender.java create mode 100644 mappings/v1_21_R1/build.gradle.kts rename src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java => mappings/v1_21_R1/src/main/java/xyz/ineanto/nicko/mappings/Mapping1_21_R1.java (70%) create mode 100644 src/main/java/xyz/ineanto/nicko/loader/NickoLibraryLoader.java delete mode 100644 src/main/java/xyz/ineanto/nicko/packet/PacketSender.java delete mode 100644 src/main/java/xyz/ineanto/nicko/packet/WrapperPacketSender.java delete mode 100644 src/main/java/xyz/ineanto/nicko/packet/debug/RespawnPacketListener.java delete mode 100644 src/main/java/xyz/ineanto/nicko/packet/wrapper/AbstractPacket.java delete mode 100644 src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerEntityDestroy.java delete mode 100644 src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerRespawn.java delete mode 100644 src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerSpawnEntity.java delete mode 100644 src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayerServerPlayerInfo.java delete mode 100644 src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayerServerPlayerInfoRemove.java rename src/main/resources/{plugin.yml => paper-plugin.yml} (56%) 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/.idea/gradle.xml b/.idea/gradle.xml index 89022a7..ff75118 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -8,6 +8,9 @@ diff --git a/build.gradle.kts b/build.gradle.kts index 9d58da8..a966679 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,12 +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" id("xyz.jpenilla.run-paper") version "2.3.0" - id("io.papermc.paperweight.userdev") version "1.7.4" } group = "xyz.ineanto" @@ -23,34 +18,24 @@ java { repositories { mavenCentral() mavenLocal() + maven { url = uri("https://jitpack.io") } - 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/") - } + maven { url = uri("https://repo.codemc.io/repository/maven-snapshots/") } + maven { url = uri("https://repo.xenondevs.xyz/releases") } + maven { url = uri("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") } + maven { url = uri("https://repo.extendedclip.com/content/repositories/placeholderapi/") } } dependencies { - paperweight.paperDevBundle("1.21.3-R0.1-SNAPSHOT") + compileOnly("org.spigotmc:spigot-api:1.21.3-R0.1-SNAPSHOT") - compileOnly("com.github.dmulloy2:ProtocolLib:5.3.0") + compileOnly("com.github.dmulloy2:ProtocolLib:6845acd89d") compileOnly("me.clip:placeholderapi:2.11.5") compileOnly("net.kyori:adventure-api:4.17.0") + compileOnly("xyz.xenondevs.invui:invui:1.41") - implementation("xyz.xenondevs.invui:invui-core:1.41") - implementation("xyz.xenondevs.invui:inventory-access-r21:1.41") + implementation(project(":common")) + implementation(project(":mappings")) implementation("net.wesjd:anvilgui:1.10.3-SNAPSHOT") implementation("com.github.jsixface:yamlconfig:1.2") @@ -60,15 +45,6 @@ dependencies { 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") - - 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") -} - -paperweight { - reobfArtifactConfiguration = ReobfArtifactConfiguration.REOBF_PRODUCTION } tasks { @@ -83,7 +59,6 @@ tasks { shadowJar { // 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") @@ -93,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") @@ -113,20 +87,11 @@ tasks { // MINIFY minimize { - exclude(dependency("xyz.xenondevs.invui:.*")) exclude(dependency("net.wesjd:.*")) - exclude(dependency("org.bstats:.*")) - } - - manifest { - attributes["paperweight-mappings-namespace"] = "spigot" } } runServer { - dependsOn(reobfJar) - - /** * https://github.com/jpenilla/run-task/issues/56 * @@ -140,7 +105,7 @@ tasks { * 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()}") + //args("-add-plugin=${reobfJar.get().outputJar.path.toAbsolutePath()}") downloadPlugins { url("https://download.luckperms.net/1554/bukkit/loader/LuckPerms-Bukkit-5.4.139.jar") @@ -152,10 +117,6 @@ tasks { url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar") } - minecraftVersion("1.21.3") + minecraftVersion("1.20.6") } -} - -extensions.configure { - disablePluginJarDetection() } \ No newline at end of file diff --git a/common/build.gradle.kts b/common/build.gradle.kts new file mode 100644 index 0000000..6a87b94 --- /dev/null +++ b/common/build.gradle.kts @@ -0,0 +1,14 @@ +plugins { + id("java") +} + +group = "xyz.ineanto.nicko" +version = project.version + +repositories { + mavenCentral() +} + +dependencies { + compileOnly("org.spigotmc:spigot-api:1.23.3-R0.1-SNAPSHOT") +} \ No newline at end of file diff --git a/src/main/java/xyz/ineanto/nicko/appearance/ActionResult.java b/common/src/main/java/xyz/ineanto/nicko/action/ActionResult.java similarity index 94% rename from src/main/java/xyz/ineanto/nicko/appearance/ActionResult.java rename to common/src/main/java/xyz/ineanto/nicko/action/ActionResult.java index b7cd505..e868893 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/ActionResult.java +++ b/common/src/main/java/xyz/ineanto/nicko/action/ActionResult.java @@ -1,4 +1,4 @@ -package xyz.ineanto.nicko.appearance; +package xyz.ineanto.nicko.action; public class ActionResult { private final String errorKey; diff --git a/src/main/java/xyz/ineanto/nicko/mojang/MojangAPI.java b/common/src/main/java/xyz/ineanto/nicko/mojang/MojangAPI.java similarity index 100% rename from src/main/java/xyz/ineanto/nicko/mojang/MojangAPI.java rename to common/src/main/java/xyz/ineanto/nicko/mojang/MojangAPI.java diff --git a/src/main/java/xyz/ineanto/nicko/mojang/MojangSkin.java b/common/src/main/java/xyz/ineanto/nicko/mojang/MojangSkin.java similarity index 100% rename from src/main/java/xyz/ineanto/nicko/mojang/MojangSkin.java rename to common/src/main/java/xyz/ineanto/nicko/mojang/MojangSkin.java diff --git a/src/main/java/xyz/ineanto/nicko/mojang/MojangUtils.java b/common/src/main/java/xyz/ineanto/nicko/mojang/MojangUtils.java similarity index 100% rename from src/main/java/xyz/ineanto/nicko/mojang/MojangUtils.java rename to common/src/main/java/xyz/ineanto/nicko/mojang/MojangUtils.java diff --git a/mappings/build.gradle.kts b/mappings/build.gradle.kts new file mode 100644 index 0000000..1ffe60f --- /dev/null +++ b/mappings/build.gradle.kts @@ -0,0 +1,10 @@ +plugins { + id("java") +} + +group = "xyz.ineanto.nicko.mappings" +version = project.version + +repositories { + mavenCentral() +} \ No newline at end of file diff --git a/mappings/src/main/java/xyz/ineanto/nicko/packet/PacketSender.java b/mappings/src/main/java/xyz/ineanto/nicko/packet/PacketSender.java new file mode 100644 index 0000000..c4bfac3 --- /dev/null +++ b/mappings/src/main/java/xyz/ineanto/nicko/packet/PacketSender.java @@ -0,0 +1,26 @@ +package xyz.ineanto.nicko.packet; + +import org.bukkit.entity.Player; +import xyz.ineanto.nicko.action.ActionResult; + +public abstract class PacketSender { + protected final Player player; + protected final String name; + protected final String skin; + + public PacketSender(Player player, String name, String skin) { + this.player = player; + this.name = name; + this.skin = skin; + } + + public abstract void sendEntityRespawn(); + + public abstract ActionResult sendGameProfileUpdate(String name, boolean skinChange, boolean reset); + + public abstract void sendEntityMetadataUpdate(); + + public abstract void sendPlayerRespawn(); + + public abstract void sendTabListUpdate(String displayName); +} diff --git a/mappings/v1_21_R1/build.gradle.kts b/mappings/v1_21_R1/build.gradle.kts new file mode 100644 index 0000000..e3f9b80 --- /dev/null +++ b/mappings/v1_21_R1/build.gradle.kts @@ -0,0 +1,21 @@ +plugins { + id("java") +} + +group = "xyz.ineanto.nicko.mappings" +version = project.version + +// maybe see +// https://github.com/tagavari/nms-remap?tab=readme-ov-file + + +repositories { + mavenCentral() + mavenLocal() +} + +dependencies { + compileOnly(project(":mappings")) + compileOnly(project(":common")) + compileOnly("org.spigotmc:spigot:1.21.3-R0.1-SNAPSHOT") +} \ No newline at end of file diff --git a/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java b/mappings/v1_21_R1/src/main/java/xyz/ineanto/nicko/mappings/Mapping1_21_R1.java similarity index 70% rename from src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java rename to mappings/v1_21_R1/src/main/java/xyz/ineanto/nicko/mappings/Mapping1_21_R1.java index bbb41a3..276f88a 100644 --- a/src/main/java/xyz/ineanto/nicko/packet/InternalPacketSender.java +++ b/mappings/v1_21_R1/src/main/java/xyz/ineanto/nicko/mappings/Mapping1_21_R1.java @@ -1,31 +1,21 @@ -package xyz.ineanto.nicko.packet; +package xyz.ineanto.nicko.mappings; 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.*; -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.EntityType; -import net.minecraft.world.phys.Vec3; +import net.minecraft.network.protocol.game.PacketPlayOutEntityDestroy; +import net.minecraft.network.protocol.game.PacketPlayOutSpawnEntity; +import net.minecraft.world.entity.EntityTypes; +import net.minecraft.world.phys.Vec3D; import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_21_R2.entity.CraftPlayer; 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.action.ActionResult; import xyz.ineanto.nicko.mojang.MojangAPI; import xyz.ineanto.nicko.mojang.MojangSkin; -import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.ineanto.nicko.packet.PacketSender; import java.io.IOException; import java.util.EnumSet; @@ -34,37 +24,29 @@ import java.util.Optional; import java.util.Random; 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 class Mapping1_21_R1 extends PacketSender { - public InternalPacketSender(Player player, NickoProfile profile) { - this.player = player; - this.profile = profile; + public Mapping1_21_R1(Player player, String name, String skin) { + super(player, name, skin); } @Override public void sendEntityRespawn() { - if (!profile.hasData()) return; + if (name == null || name.isEmpty() || skin == null || skin.isEmpty()) return; - final ClientboundRemoveEntitiesPacket destroy = new ClientboundRemoveEntitiesPacket(IntList.of(player.getEntityId())); - final ClientboundAddEntityPacket add = new ClientboundAddEntityPacket( + final PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(IntList.of(player.getEntityId())); + final PacketPlayOutSpawnEntity add = new PacketPlayOutSpawnEntity( new Random().nextInt(9999), player.getUniqueId(), - player.getX(), - player.getY(), - player.getZ(), - player.getPitch(), - player.getYaw(), - EntityType.PLAYER, + player.getLocation().getX(), + player.getLocation().getY(), + player.getLocation().getZ(), + player.getLocation().getPitch(), + player.getLocation().getYaw(), + EntityTypes.bS, 0, - Vec3.ZERO, - player.getBodyYaw() + Vec3D.c, + player.getEyeLocation().getYaw() ); Bukkit.getOnlinePlayers().stream().filter(receiver -> receiver.getUniqueId() != player.getUniqueId()).forEach(receiver -> { @@ -81,10 +63,10 @@ public class InternalPacketSender implements PacketSender { if (skinChange) { Optional skin; try { - final MojangAPI mojangAPI = Nicko.getInstance().getMojangAPI(); - final Optional uuid = mojangAPI.getUUID(profile.getSkin()); + final MojangAPI mojang = new MojangAPI(); + final Optional uuid = mojang.getUUID(skin); if (uuid.isPresent()) { - skin = reset ? mojangAPI.getSkinWithoutCaching(uuid.get()) : mojangAPI.getSkin(uuid.get()); + skin = reset ? mojang.getSkinWithoutCaching(uuid.get()) : mojang.getSkin(uuid.get()); if (skin.isPresent()) { final MojangSkin skinResult = skin.get(); final PropertyMap properties = gameProfile.getProperties(); @@ -149,7 +131,6 @@ public class InternalPacketSender implements PacketSender { serverPlayer.connection.latency(), serverPlayer.gameMode.getGameModeForPlayer(), MutableComponent.create(new PlainTextContents.LiteralContents(displayName)), - serverPlayer.getTabListOrder(), Optionull.map(serverPlayer.getChatSession(), RemoteChatSession::asData) )); @@ -163,6 +144,6 @@ public class InternalPacketSender implements PacketSender { } private void sendPacket(Packet packet, Player player) { - (((CraftPlayer) player).getHandle()).connection.send(packet); + (((CraftPlayer) player).getHandle()).f.a(packet); } -} +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 4549581..78072f2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,2 +1,4 @@ rootProject.name = "nicko" - +include("mappings") +include("mappings:v1_21_R1") +include("common") diff --git a/src/main/java/xyz/ineanto/nicko/Nicko.java b/src/main/java/xyz/ineanto/nicko/Nicko.java index fcd8a3c..5079670 100644 --- a/src/main/java/xyz/ineanto/nicko/Nicko.java +++ b/src/main/java/xyz/ineanto/nicko/Nicko.java @@ -64,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 version. (Currently 1.21.3)"); + getLogger().severe("As of version 1.2.0, Nicko only supports the latest two majors Minecraft versions. (Currently 1.20.6-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 465ccf7..71ad2f6 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -3,6 +3,7 @@ package xyz.ineanto.nicko.appearance; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerTeleportEvent; import xyz.ineanto.nicko.Nicko; +import xyz.ineanto.nicko.action.ActionResult; import xyz.ineanto.nicko.packet.InternalPacketSender; import xyz.ineanto.nicko.packet.PacketSender; import xyz.ineanto.nicko.profile.NickoProfile; diff --git a/src/main/java/xyz/ineanto/nicko/loader/NickoLibraryLoader.java b/src/main/java/xyz/ineanto/nicko/loader/NickoLibraryLoader.java new file mode 100644 index 0000000..8980cde --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/loader/NickoLibraryLoader.java @@ -0,0 +1,19 @@ +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.artifact.DefaultArtifact; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.repository.RemoteRepository; +import org.jetbrains.annotations.NotNull; + +public class NickoLibraryLoader implements PluginLoader { + @Override + public void classloader(@NotNull PluginClasspathBuilder pluginClasspathBuilder) { + MavenLibraryResolver resolver = new MavenLibraryResolver(); + resolver.addRepository(new RemoteRepository.Builder("xenondevs", "default", "https://repo.xenondevs.xyz/releases/").build()); + resolver.addDependency(new Dependency(new DefaultArtifact("xyz.xenondevs.invui", "invui", "pom", "1.41"), null)); + pluginClasspathBuilder.addLibrary(resolver); + } +} diff --git a/src/main/java/xyz/ineanto/nicko/packet/PacketSender.java b/src/main/java/xyz/ineanto/nicko/packet/PacketSender.java deleted file mode 100644 index ef93153..0000000 --- a/src/main/java/xyz/ineanto/nicko/packet/PacketSender.java +++ /dev/null @@ -1,15 +0,0 @@ -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 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/java/xyz/ineanto/nicko/packet/debug/RespawnPacketListener.java b/src/main/java/xyz/ineanto/nicko/packet/debug/RespawnPacketListener.java deleted file mode 100644 index 5222dd0..0000000 --- a/src/main/java/xyz/ineanto/nicko/packet/debug/RespawnPacketListener.java +++ /dev/null @@ -1,82 +0,0 @@ -package xyz.ineanto.nicko.packet.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.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 { - // 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()); - component.getAccessor().setAccessible(false); - } - ); - - // get the key of the level the player is joining. Second field in the object. First of type ResourceKey - final MinecraftKey key = MinecraftKey.fromHandle(commonSpawnData.getClass().getRecordComponents()[1]); - 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/packet/wrapper/AbstractPacket.java b/src/main/java/xyz/ineanto/nicko/packet/wrapper/AbstractPacket.java deleted file mode 100644 index 42e138b..0000000 --- a/src/main/java/xyz/ineanto/nicko/packet/wrapper/AbstractPacket.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * 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 xyz.ineanto.nicko.packet.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()); - } -} \ No newline at end of file diff --git a/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerEntityDestroy.java b/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerEntityDestroy.java deleted file mode 100644 index a23f1a6..0000000 --- a/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerEntityDestroy.java +++ /dev/null @@ -1,32 +0,0 @@ -package xyz.ineanto.nicko.packet.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(); - } - - /** - * 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)).writeSafely(0, value); - } - -} \ 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 deleted file mode 100644 index dc71b1f..0000000 --- a/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerRespawn.java +++ /dev/null @@ -1,115 +0,0 @@ -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.StructureModifier; -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) - *

- * 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 InternalStructure spawnInfoStructure = null; - - public WrapperPlayServerRespawn() { - super(new PacketContainer(TYPE), TYPE); - handle.getModifier().writeDefaults(); - if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { - spawnInfoStructure = handle.getStructures().read(0); - } - } - - public void setDimension(World value) { - final MinecraftVersion v1_20_5 = new MinecraftVersion(1, 20, 5); - - if (!MinecraftVersion.getCurrentVersion().isAtLeast(v1_20_5)) { - // 1.20 - 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")); - structureModifier.writeSafely(0, dimensionType); - worldStructureModifier.writeSafely(0, value); - } 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 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(); - } - } - } - - public void setGameMode(GameMode value) { - if (!MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { - // 1.20 to 1.20.1 - handle.getGameModes().writeSafely(0, EnumWrappers.NativeGameMode.fromBukkit(value)); - return; - } - - spawnInfoStructure.getGameModes().writeSafely(0, EnumWrappers.NativeGameMode.fromBukkit(value)); - } - - public void setPreviousGameMode(GameMode value) { - if (!MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { - // 1.20 to 1.20.1 - handle.getGameModes().writeSafely(1, EnumWrappers.NativeGameMode.fromBukkit(value)); - return; - } - - spawnInfoStructure.getGameModes().writeSafely(1, EnumWrappers.NativeGameMode.fromBukkit(value)); - } - - public void setCopyMetadata(boolean 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.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { - // 1.20 to 1.20.1 - handle.getLongs().writeSafely(0, Hashing.sha256().hashLong(value).asLong()); - } - } -} diff --git a/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerSpawnEntity.java b/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerSpawnEntity.java deleted file mode 100644 index 0512717..0000000 --- a/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayServerSpawnEntity.java +++ /dev/null @@ -1,103 +0,0 @@ -package xyz.ineanto.nicko.packet.wrapper; - -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.events.PacketContainer; -import org.bukkit.Location; -import org.bukkit.entity.EntityType; - -import javax.annotation.Nonnull; -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 WrapperPlayServerSpawnEntity extends AbstractPacket { - /** - * The packet type that is wrapped by this wrapper. - */ - public static final PacketType TYPE = PacketType.Play.Server.SPAWN_ENTITY; - - /** - * Constructors a new wrapper for the specified packet - */ - public WrapperPlayServerSpawnEntity() { - super(new PacketContainer(TYPE), TYPE); - handle.getModifier().writeDefaults(); - } - - /** - * Sets the entity id of the player - * - * @param value New value for field 'entityId' - */ - public void setEntityId(int value) { - this.handle.getIntegers().writeSafely(0, value); - this.handle.getEntityTypeModifier().writeSafely(0, EntityType.PLAYER); - } - - /** - * Sets the unique id of the player - * - * @param value New value for field 'playerId' - */ - public void setPlayerId(UUID value) { - this.handle.getUUIDs().writeSafely(0, value); - } - - /** - * Sets the value of field 'x' - * - * @param value New value for field 'x' - */ - public void setX(double value) { - this.handle.getDoubles().writeSafely(0, value); - } - - /** - * Sets the value of field 'y' - * - * @param value New value for field 'y' - */ - public void setY(double value) { - this.handle.getDoubles().writeSafely(1, value); - } - - /** - * Sets the value of field 'z' - * - * @param value New value for field 'z' - */ - public void setZ(double value) { - this.handle.getDoubles().write(2, value); - } - - /** - * Sets the discrete rotation around the y-axis (yaw) - * - * @param value New value for field 'yRot' - */ - public void setYRotRaw(byte value) { - this.handle.getBytes().writeSafely(0, value); - } - - /** - * Sets the discrete rotation around the x-axis (pitch) - * - * @param value New value for field 'xRot' - */ - public void setXRotRaw(byte value) { - this.handle.getBytes().writeSafely(1, value); - } - - public void setLocation(@Nonnull Location location) { - setX(location.getX()); - setY(location.getY()); - setZ(location.getZ()); - setYRotRaw(degreesToAngle(location.getYaw())); - setXRotRaw(degreesToAngle(location.getPitch())); - } - - private byte degreesToAngle(float degree) { - return (byte)((int)(degree * 256.0F / 360.0F)); - } -} \ No newline at end of file diff --git a/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayerServerPlayerInfo.java b/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayerServerPlayerInfo.java deleted file mode 100644 index ca37dc0..0000000 --- a/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayerServerPlayerInfo.java +++ /dev/null @@ -1,37 +0,0 @@ -package xyz.ineanto.nicko.packet.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; - -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 void setActions(Set value) { - if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) { - handle.getPlayerInfoActions().writeSafely(0, value); - } else { - handle.getPlayerInfoAction().writeSafely(0, value.stream().iterator().next()); // Get the first Value. - } - } - - public void setData(List value) { - handle.getPlayerInfoDataLists().writeSafely(1, value); - } -} diff --git a/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayerServerPlayerInfoRemove.java b/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayerServerPlayerInfoRemove.java deleted file mode 100644 index 2273c48..0000000 --- a/src/main/java/xyz/ineanto/nicko/packet/wrapper/WrapperPlayerServerPlayerInfoRemove.java +++ /dev/null @@ -1,27 +0,0 @@ -package xyz.ineanto.nicko.packet.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 void setUUIDs(List value) { - handle.getUUIDLists().writeSafely(0, value); - } -} diff --git a/src/main/resources/plugin.yml b/src/main/resources/paper-plugin.yml similarity index 56% rename from src/main/resources/plugin.yml rename to src/main/resources/paper-plugin.yml index 08b70ce..89bfa52 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/paper-plugin.yml @@ -1,17 +1,13 @@ name: Nicko main: xyz.ineanto.nicko.Nicko +loader: xyz.ineanto.nicko.loader.NickoLibraryLoader version: ${version} -author: Ineanto +authors: [ Ineanto ] description: "The feature packed, next generation disguise plugin for Minecraft." -api-version: 1.21 -softdepend: [ PlaceholderAPI ] -depend: - - ProtocolLib -load: POSTWORLD -commands: - nicko: - description: "Opens Nicko's GUI." - permission: nicko.use +api-version: "1.20" +dependencies: + server: + { "ProtocolLib" } permissions: nicko.*: default: op 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