1.12.2 Error trying to change skin with 1.12 & 1.14 packets

Discussion in 'Spigot Plugin Development' started by Cris_96, Mar 7, 2020.

  1. Hello, I'm trying to change skin and everything works alone but when I enable (removing comment block) part of code the server throws me a ClassNotFoundExeption error. The code should automatically check which server version is and use the right code for packets but it doesn't work.
    Code (Java):
    public class SkinHelper {
     
        private static void sendPacket(Player player, Packet<?> packet) {
            ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
        }
     
        private static void sendPacket(Packet<?> packet) {
            for (Player all : Bukkit.getServer().getOnlinePlayers()) {
                ((CraftPlayer) all).getHandle().playerConnection.sendPacket(packet);
            }
        }
     
        private static void sendPacket112(Player player, net.minecraft.server.v1_12_R1.Packet<?> packet) {
            ((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
        }
     
        private static void sendPacket112(net.minecraft.server.v1_12_R1.Packet<?> packet) {
            for (Player all : Bukkit.getServer().getOnlinePlayers()) {
                ((org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) all).getHandle().playerConnection.sendPacket(packet);
            }
        }
     
        public void changeSkin(Player p, String name) {
            if (Main.instance.MinecraftVersion().equals("1.12.x")) {
                org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer cp12 =
                        (org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer) p;
                Location location = p.getLocation().clone();
                boolean isFlying = p.isFlying();
                int levels = p.getLevel();
                float xp = p.getExp();
                double health = p.getHealth();
                int food = p.getFoodLevel();
                float saturation = p.getSaturation();
                ItemStack[] inventory = p.getInventory().getContents().clone();
                ItemStack[] armor = p.getInventory().getArmorContents().clone();
                GameProfile skingp = null;
                try {
                    skingp = GameProfileBuilder.fetch(UUIDFetcher.getUUID(name));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (skingp != null) {
                    Collection<Property> props = skingp.getProperties().get("textures");
                    cp12.getProfile().getProperties().removeAll("textures");
                    cp12.getProfile().getProperties().putAll("textures", props);
                    sendPacket112(new net.minecraft.server.v1_12_R1.PacketPlayOutEntityDestroy(cp12.getEntityId()));
                    sendPacket112(new net.minecraft.server.v1_12_R1.PacketPlayOutPlayerInfo(net.minecraft.server.v1_12_R1.PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, cp12.getHandle()));
                    net.minecraft.server.v1_12_R1.EntityPlayer ep12 = cp12.getHandle();
                    sendPacket112(new net.minecraft.server.v1_12_R1.PacketPlayOutNamedEntitySpawn(cp12.getHandle()));
                    sendPacket112(new net.minecraft.server.v1_12_R1.PacketPlayOutPlayerInfo(
                            net.minecraft.server.v1_12_R1.PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, cp12.getHandle()));
                    net.minecraft.server.v1_12_R1.PacketPlayOutRespawn packet =
                            new net.minecraft.server.v1_12_R1.PacketPlayOutRespawn(cp12.getHandle().dimension,
                                    cp12.getHandle().getWorld().getDifficulty(),
                                    cp12.getHandle().getWorld().getWorldData().getType(),
                                    cp12.getHandle().playerInteractManager.getGameMode());
                    sendPacket112(p, packet);
                    for (Player all : Bukkit.getOnlinePlayers()) {
                        all.hidePlayer(Main.instance, p);
                        all.showPlayer(Main.instance, p);
                    }
                    new BukkitRunnable() {
                        public void run() {
                            p.teleport(location);
                            p.setFlying(isFlying);
                            p.setLevel(levels);
                            p.setExp(xp);
                            p.setHealth(health);
                            p.setFoodLevel(food);
                            p.setSaturation(saturation);
                            p.getInventory().setContents(inventory);
                            p.getInventory().setArmorContents(armor);
                            p.updateInventory();
                        }
                    }.runTaskLater(Main.instance, 1);
                } else {
                    p.sendMessage("Error");
                }
            }
            if (Main.instance.MinecraftVersion().equals("1.14.x")) {
                CraftPlayer cp = (CraftPlayer) p;
                Location location = p.getLocation().clone();
                boolean isFlying = p.isFlying();
                int levels = p.getLevel();
                float xp = p.getExp();
                double health = p.getHealth();
                int food = p.getFoodLevel();
                float saturation = p.getSaturation();
                ItemStack[] inventory = p.getInventory().getContents().clone();
                ItemStack[] armor = p.getInventory().getArmorContents().clone();
                GameProfile skingp = null;
                try {
                    skingp = GameProfileBuilder.fetch(UUIDFetcher.getUUID(name));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (skingp != null) {
                    Collection<Property> props = skingp.getProperties().get("textures");
                    cp.getProfile().getProperties().removeAll("textures");
                    cp.getProfile().getProperties().putAll("textures", props);
                    sendPacket(new PacketPlayOutEntityDestroy(cp.getEntityId()));
                    sendPacket(new PacketPlayOutPlayerInfo(
                            PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, cp.getHandle()));
                    EntityPlayer ep = ((CraftPlayer) p).getHandle();
                    sendPacket(new PacketPlayOutNamedEntitySpawn(cp.getHandle()));
                    sendPacket(new PacketPlayOutPlayerInfo(
                            PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, cp.getHandle()));
                    PacketPlayOutRespawn packet =
                            new PacketPlayOutRespawn(DimensionManager.a(((CraftPlayer) p).getWorld().getEnvironment().getId()),
                                    net.minecraft.server.v1_14_R1.WorldType.getType(((CraftPlayer) p).getWorld().getWorldType().getName()),
                                    EnumGamemode.getById(p.getGameMode().getValue()));
                    sendPacket(p, packet);
                    for (Player all : Bukkit.getOnlinePlayers()) {
                        all.hidePlayer(Main.instance, p);
                        all.showPlayer(Main.instance, p);
                    }
                    new BukkitRunnable() {
                        public void run() {
                            p.teleport(location);
                            p.setFlying(isFlying);
                            p.setLevel(levels);
                            p.setExp(xp);
                            p.setHealth(health);
                            p.setFoodLevel(food);
                            p.setSaturation(saturation);
                            p.getInventory().setContents(inventory);
                            p.getInventory().setArmorContents(armor);
                            p.updateInventory();
                        }
                    }.runTaskLater(Main.instance, 1);
                } else {
                    p.sendMessage("Error");
                }
            }
        }
     
        public boolean isPremiumName(String name) {
            return UUIDFetcher.getUUID(name) != null;
        }
    Edit: I know the console reports the /skin command as error but as I said if I comment the code with the 1.14 packets the error doesn't exist

    Code (Text):
    [15:18:33 INFO]: Cris issued server command: /skin alex
    [15:18:33 ERROR]: null
    org.bukkit.command.CommandException: Unhandled exception executing command 'skin' in plugin Core v1.2-b7
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) ~[spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) ~[spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
        at org.bukkit.craftbukkit.v1_12_R1.CraftServer.dispatchCommand(CraftServer.java:648) ~[spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
        at net.minecraft.server.v1_12_R1.PlayerConnection.handleCommand(PlayerConnection.java:1401) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
        at net.minecraft.server.v1_12_R1.PlayerConnection.a(PlayerConnection.java:1236) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
        at net.minecraft.server.v1_12_R1.PacketPlayInChat.a(PacketPlayInChat.java:45) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
        at net.minecraft.server.v1_12_R1.PacketPlayInChat.a(PacketPlayInChat.java:1) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
        at net.minecraft.server.v1_12_R1.PlayerConnectionUtils$1.run(SourceFile:13) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_242]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_242]
        at net.minecraft.server.v1_12_R1.SystemUtils.a(SourceFile:46) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
        at net.minecraft.server.v1_12_R1.MinecraftServer.D(MinecraftServer.java:748) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
        at net.minecraft.server.v1_12_R1.DedicatedServer.D(DedicatedServer.java:406) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
        at net.minecraft.server.v1_12_R1.MinecraftServer.C(MinecraftServer.java:679) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
        at net.minecraft.server.v1_12_R1.MinecraftServer.run(MinecraftServer.java:577) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
        at java.lang.Thread.run(Thread.java:748) [?:1.8.0_242]
    Caused by: java.lang.NoClassDefFoundError: net/minecraft/server/v1_14_R1/Packet
        at com.core.commands.Skin.onCommand(Skin.java:55) ~[?:?]
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
        ... 15 more
    Caused by: java.lang.ClassNotFoundException: net.minecraft.server.v1_14_R1.Packet
        at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:105) ~[spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
        at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:100) ~[spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
        at java.lang.ClassLoader.loadClass(ClassLoader.java:419) ~[?:1.8.0_242]
        at java.lang.ClassLoader.loadClass(ClassLoader.java:352) ~[?:1.8.0_242]
        at com.core.commands.Skin.onCommand(Skin.java:55) ~[?:?]
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
        ... 15 more
     
    Reading the code I realized I can send the packets based on the version instead of use the whole block again (reducing the whole code size) and I will do it. I still need help
     
    #1 Cris_96, Mar 7, 2020
    Last edited: Mar 7, 2020
  2. Hmm says it cant find nms 1.14 do you have the api for 1.14 imported as well?
     
  3. 1.12 and 1.14
     
  4. thats not how that works.

    @op
    you cannot directly reference an an object that does not exist. what this means is you cannot have one class with several different methods for several different versions, as once that class is instantiated, it will load all classes for all versions too. but only 1 version will exist at runtime (the versioln the server will be running on). you need to use abstraction to avoid this issue, and have 1 class for each version you wish to support, and then instantiate the correct one for the current server version.
     
  5. Solved! Thanks. Let's fix the next problem \(*-*)/