From c7154510de24713ec4c43745289db02f7ac36939 Mon Sep 17 00:00:00 2001 From: aro Date: Sat, 21 Jan 2023 12:38:20 +0100 Subject: [PATCH] feat: reflection here so save the day --- nicko-core/pom.xml | 10 -- .../nicko/impl/InternalsProvider.java | 5 - .../net/artelnatif/nicko/impl/v1_19_R2.java | 50 +++--- .../net/artelnatif/nicko/impl/v1_19_R2_P.java | 147 ------------------ 4 files changed, 28 insertions(+), 184 deletions(-) delete mode 100644 v1_19_R2/src/main/java/net/artelnatif/nicko/impl/v1_19_R2_P.java diff --git a/nicko-core/pom.xml b/nicko-core/pom.xml index 52570d0..0917b60 100644 --- a/nicko-core/pom.xml +++ b/nicko-core/pom.xml @@ -36,10 +36,6 @@ spigot-repo https://hub.spigotmc.org/nexus/content/groups/public/ - - dmulloy2-repo - https://repo.dmulloy2.net/repository/public/ - codemc-snapshots https://repo.codemc.io/repository/maven-snapshots/ @@ -115,12 +111,6 @@ yamlconfig 1.1.1 - - - com.comphenix.protocol - ProtocolLib - 5.0.0-SNAPSHOT - diff --git a/nicko-core/src/main/java/net/artelnatif/nicko/impl/InternalsProvider.java b/nicko-core/src/main/java/net/artelnatif/nicko/impl/InternalsProvider.java index 8b6a1b0..38e576b 100644 --- a/nicko-core/src/main/java/net/artelnatif/nicko/impl/InternalsProvider.java +++ b/nicko-core/src/main/java/net/artelnatif/nicko/impl/InternalsProvider.java @@ -6,17 +6,12 @@ import java.lang.reflect.InvocationTargetException; public class InternalsProvider { private static Internals internals; - private static boolean protocolLib = true; static { try { final String packageName = Internals.class.getPackage().getName(); final String bukkitVersion = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; String fullClassName = packageName + "." + bukkitVersion; - if (protocolLib) { - System.out.println("USING PROTOCOLLIB HACK"); - fullClassName += "_P"; - } internals = (Internals) Class.forName(fullClassName).getConstructors()[0].newInstance(); } catch (InvocationTargetException | ClassNotFoundException | InstantiationException | IllegalAccessException | ClassCastException exception) { 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 index c6669de..ea6bf4d 100644 --- 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 @@ -9,6 +9,7 @@ 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.minecraft.network.chat.Component; import net.minecraft.network.protocol.game.*; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; @@ -24,6 +25,9 @@ import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerTeleportEvent; import java.io.IOException; +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.EnumSet; import java.util.List; import java.util.Optional; import java.util.concurrent.ExecutionException; @@ -95,7 +99,7 @@ public class v1_19_R2 implements Internals { final ClientboundPlayerInfoRemovePacket remove = new ClientboundPlayerInfoRemovePacket(List.of(player.getUniqueId())); // TODO: 1/20/23 Sets Gamemode to Survival but keeps the flying? Visual effect only? - final ClientboundPlayerInfoUpdatePacket init = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(serverPlayer)); + //final ClientboundPlayerInfoUpdatePacket init = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(serverPlayer)); if (skinChange || changeOnlyName) { try { @@ -121,29 +125,31 @@ public class v1_19_R2 implements Internals { } } - /* - Tried this solution, doesn't work either: + final ClientboundPlayerInfoUpdatePacket init = new ClientboundPlayerInfoUpdatePacket( + EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, + ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY, + ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED), + Collections.singletonList(serverPlayer)); - final FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.buffer()); - final EnumSet actions = EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER); - byteBuf.writeEnumSet(actions, ClientboundPlayerInfoUpdatePacket.Action.class); - byteBuf.writeCollection(List.of(new ClientboundPlayerInfoUpdatePacket.Entry( - player.getUniqueId(), - newGameProfile, - true, - serverPlayer.latency, - serverPlayer.gameMode.getGameModeForPlayer(), - Component.literal(profileName), - serverPlayer.getChatSession().asData() - )), (bb, entry) -> { - bb.writeUUID(entry.profileId()); - Iterator iterator = actions.iterator(); + Field field; + try { + field = init.getClass().getDeclaredField("b"); + field.setAccessible(true); + field.set(init, List.of(new ClientboundPlayerInfoUpdatePacket.Entry( + player.getUniqueId(), + newGameProfile, + true, + serverPlayer.latency, + serverPlayer.gameMode.getGameModeForPlayer(), + Component.literal(profileName), + serverPlayer.getChatSession().asData() + ))); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException(e); + } - while (iterator.hasNext()) { - bb.writeUtf(entry.profile().getName(), 16); - bb.writeGameProfileProperties(newGameProfile.getProperties()); - } - });*/ + System.out.println("======= AFTER "); + System.out.println("init.entries().toString() = " + init.entries().toString()); serverPlayer.connection.send(remove); serverPlayer.connection.send(init); diff --git a/v1_19_R2/src/main/java/net/artelnatif/nicko/impl/v1_19_R2_P.java b/v1_19_R2/src/main/java/net/artelnatif/nicko/impl/v1_19_R2_P.java deleted file mode 100644 index 810c8f2..0000000 --- a/v1_19_R2/src/main/java/net/artelnatif/nicko/impl/v1_19_R2_P.java +++ /dev/null @@ -1,147 +0,0 @@ -package net.artelnatif.nicko.impl; - -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.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.resources.ResourceKey; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.level.Level; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_19_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerTeleportEvent; - -import java.io.IOException; -import java.util.Collections; -import java.util.EnumSet; -import java.util.Optional; -import java.util.concurrent.ExecutionException; - -public class v1_19_R2_P implements InternalsProtocolLib { - @Override - public void updateSelf(Player player) { - final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); - final ServerLevel level = serverPlayer.getLevel(); - final ResourceKey levelResourceKey = serverPlayer.getLevel().dimension(); - final CraftWorld world = level.getWorld(); - // last boolean is: "has death location" attribute, if true, the optional contains the death dimension and position. - // with the boolean being false, we don't need to provide a value, and thus we return an empty optional. - final ClientboundRespawnPacket respawn = new ClientboundRespawnPacket(serverPlayer.level.dimensionTypeId(), - levelResourceKey, world.getSeed(), - serverPlayer.gameMode.getPreviousGameModeForPlayer(), serverPlayer.gameMode.getGameModeForPlayer(), - 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); - - /* - BIT MASKS: - 0x01 Cape enabled - 0x02 Jacket enabled - 0x04 Left sleeve enabled - 0x08 Right sleeve enabled - 0x10 Left pants leg enabled - 0x20 Right pants leg enabled - 0x40 Hat enabled - */ - final SynchedEntityData entityData = serverPlayer.getEntityData(); - final EntityDataAccessor skinPartAccessor = new EntityDataAccessor<>(17, EntityDataSerializers.BYTE); - entityData.set(skinPartAccessor, (byte) 0x7f); // 127, all masks combined - final ClientboundSetEntityDataPacket entityMetadata = new ClientboundSetEntityDataPacket(serverPlayer.getBukkitEntity().getEntityId(), entityData.getNonDefaultValues()); - - Bukkit.getOnlinePlayers().forEach(online -> { - 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(); - Optional skin; - - final WrappedGameProfile gameProfile = WrappedGameProfile.fromPlayer(player).withName(profileName); - if (skinChange || changeOnlyName) { - 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())); - if (skin.isPresent()) { - final Multimap properties = gameProfile.getProperties(); - properties.removeAll("textures"); - properties.put("textures", new WrappedSignedProperty("textures", skin.get().value(), skin.get().signature())); - updateSelf(player); - } else { - return new ActionResult(I18NDict.Error.SKIN_FAIL_MOJANG); - } - } else { - 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); - } - } - - // Letting ProtocolLib handle the reflection here. - final PacketContainer remove = getProtocolLib().createPacket(PacketType.Play.Server.PLAYER_INFO_REMOVE); - remove.getUUIDLists().write(0, Collections.singletonList(player.getUniqueId())); - - final EnumSet actions = EnumSet.of( - EnumWrappers.PlayerInfoAction.ADD_PLAYER, - EnumWrappers.PlayerInfoAction.UPDATE_LATENCY, - EnumWrappers.PlayerInfoAction.UPDATE_LISTED); - final PacketContainer add = getProtocolLib().createPacket(PacketType.Play.Server.PLAYER_INFO); - - add.getPlayerInfoActions().write(0, actions); - add.getPlayerInfoDataLists().write(1, Collections.singletonList(new PlayerInfoData( - gameProfile, - player.getPing(), - EnumWrappers.NativeGameMode.fromBukkit(player.getGameMode()), - WrappedChatComponent.fromText(profileName) - ))); - - Bukkit.getOnlinePlayers().forEach(online -> { - getProtocolLib().sendServerPacket(online, remove); - getProtocolLib().sendServerPacket(online, add); - }); - updateOthers(player); - return new ActionResult(); - } -} \ No newline at end of file