Skip to content

Commit

Permalink
fix(Sponge): Fixed Sponge_SkinHandler for all versions.
Browse files Browse the repository at this point in the history
Added remove and add player packets in order to update the player skin for all players online.
  • Loading branch information
GeorgeV220 committed Jan 18, 2023
1 parent 9fe3541 commit 01acad4
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,31 @@

import com.georgev22.library.exceptions.ReflectionException;
import com.georgev22.library.minecraft.SpongeMinecraftUtils;
import com.georgev22.library.scheduler.SchedulerManager;
import com.georgev22.library.utilities.Utils;
import com.georgev22.library.yaml.file.FileConfiguration;
import com.georgev22.skinoverlay.SkinOverlay;
import com.georgev22.skinoverlay.SkinOverlaySponge;
import com.georgev22.skinoverlay.handler.SkinHandler.SkinHandler_;
import com.georgev22.skinoverlay.utilities.player.PlayerObject;
import com.georgev22.skinoverlay.utilities.player.UserData;
import com.google.common.collect.ImmutableList;
import com.google.common.hash.Hashing;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import lombok.SneakyThrows;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.api.data.Keys;
import org.spongepowered.api.effect.VanishState;
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
import org.spongepowered.api.entity.living.player.tab.TabListEntry;
import org.spongepowered.api.profile.property.ProfileProperty;
import org.spongepowered.api.world.server.ServerLocation;
import org.spongepowered.math.vector.Vector3d;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashSet;
import java.util.*;
import java.util.concurrent.ExecutionException;

import static com.georgev22.library.utilities.Utils.Reflection.*;
Expand All @@ -41,6 +42,8 @@ public class SkinHandler_Sponge extends SkinHandler_ {
private final Class<?> entityDataSerializersClass;
private final Class<?> entityDataAccessorClass;

private final Class<?> addPlayerPacketClass;
private final Class<?> removePlayerPacketClass;
private final Class<?> packet;

public SkinHandler_Sponge() {
Expand All @@ -51,6 +54,13 @@ public SkinHandler_Sponge() {
entityDataPacketClass = Utils.Reflection.getClass("net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket", classLoader);
entityDataSerializersClass = Utils.Reflection.getClass("net.minecraft.network.syncher.EntityDataSerializers", classLoader);
entityDataAccessorClass = Utils.Reflection.getClass("net.minecraft.network.syncher.EntityDataAccessor", classLoader);
if (SpongeMinecraftUtils.MinecraftVersion.getCurrentVersion().equals(SpongeMinecraftUtils.MinecraftVersion.V1_19_R2)) {
removePlayerPacketClass = Utils.Reflection.getClass("net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket", classLoader);
addPlayerPacketClass = Utils.Reflection.getClass("net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket", classLoader);
} else {
removePlayerPacketClass = Utils.Reflection.getClass("net.minecraft.network.protocol.game.ClientboundPlayerInfoPacket", classLoader);
addPlayerPacketClass = Utils.Reflection.getClass("net.minecraft.network.protocol.game.ClientboundPlayerInfoPacket", classLoader);
}
packet = Utils.Reflection.getClass("net.minecraft.network.protocol.Packet", classLoader);
}

Expand Down Expand Up @@ -93,6 +103,27 @@ public void updateSkin(@NotNull FileConfiguration fileConfiguration, @NotNull Pl
previousGameModeForPlayer = gameModeForPlayer;
}

Object addPlayer;
Object removePlayer;
//Add remove player packet
if (SpongeMinecraftUtils.MinecraftVersion.getCurrentVersion().equals(SpongeMinecraftUtils.MinecraftVersion.V1_19_R2)) {
removePlayer = invokeConstructor(removePlayerPacketClass, List.of(receiver.uniqueId()));
addPlayer = fetchMethodAndInvoke(addPlayerPacketClass, "createPlayerInitializing", null,
new Object[]{List.of(serverPlayer)},
new Class[]{Collection.class}
);

} else {
removePlayer = invokeConstructor(removePlayerPacketClass,
getEnum(Utils.Reflection.getClass(removePlayerPacketClass.getName() + "$Action", classLoader), "REMOVE_PLAYER"),
ImmutableList.of(serverPlayer));
addPlayer = invokeConstructor(addPlayerPacketClass,
getEnum(Utils.Reflection.getClass(addPlayerPacketClass.getName() + "$Action", classLoader), "ADD_PLAYER"),
ImmutableList.of(serverPlayer));
}

SkinOverlay.getInstance().getLogger().info(removePlayer + "\n" + addPlayer);

Object respawnPacket;
//Respawn packet
try {
Expand Down Expand Up @@ -191,26 +222,14 @@ public void updateSkin(@NotNull FileConfiguration fileConfiguration, @NotNull Pl
entityDataPacket = invokeConstructor(entityDataPacketClass,
fetchMethodAndInvoke(serverPlayerClass, "getId", serverPlayer, new Object[]{}, new Class[]{}),
synchedEntityData,
false
true
);
}

receiver.tabList().removeEntry(receiver.uniqueId());
receiver.tabList().addEntry(TabListEntry.builder()
.displayName(receiver.displayName().get())
.latency(receiver.connection().latency())
.list(receiver.tabList())
.gameMode(receiver.gameMode().get())
.profile(receiver.profile())
.build());

ServerLocation serverLocation = receiver.serverLocation();
Vector3d rotation = receiver.rotation();

Object playerConnection = getFieldByType(serverPlayer, "ServerGamePacketListenerImpl");
sendPacket(playerConnection, respawnPacket);
SkinOverlay.getInstance().getLogger().info("EntityDataPacket: " + Arrays.toString(entityDataPacket.getClass().getConstructors()) + "\n" + "Accessor: " + entityDataAccessor);
sendPacket(playerConnection, entityDataPacket);

Object playerPositionPacket;
Object playerCarriedItemPacket;
Expand Down Expand Up @@ -260,11 +279,25 @@ public void updateSkin(@NotNull FileConfiguration fileConfiguration, @NotNull Pl
return;
}

/*receiver.offer(Keys.VANISH_STATE, VanishState.vanished());
SchedulerManager.getScheduler().runTaskLater(skinOverlay.getClass(), () -> receiver.offer(Keys.VANISH_STATE, VanishState.unvanished()), 1L);*/
sendPacketToAll(removePlayer);
sendPacketToAll(addPlayer);

sendPacket(playerConnection, respawnPacket);
sendPacket(playerConnection, entityDataPacket);
receiver.offer(Keys.VANISH_STATE, VanishState.vanished());
SchedulerManager.getScheduler().runTaskLater(skinOverlay.getClass(), () -> receiver.offer(Keys.VANISH_STATE, VanishState.unvanished()), 1L);
fetchMethodAndInvoke(serverPlayerClass, "onUpdateAbilities", serverPlayer, new Object[]{}, new Class[]{});
sendPacket(playerConnection, playerPositionPacket);
sendPacket(playerConnection, playerCarriedItemPacket);

if (SpongeMinecraftUtils.MinecraftVersion.getCurrentVersion().isAboveOrEqual(SpongeMinecraftUtils.MinecraftVersion.V1_17_R1)) {
Object container = fetchDeclaredField(serverPlayerClass.getSuperclass(), serverPlayer, "containerMenu");
fetchMethodAndInvoke(container.getClass(), "sendAllDataToRemote", container, new Object[]{}, new Class[]{});
} else {
Object container = fetchDeclaredField(serverPlayerClass.getSuperclass(), serverPlayer, "activeContainer");
fetchMethodAndInvoke(serverPlayerClass, "updateInventory", serverPlayer, new Object[]{container}, new Class[]{container.getClass()});
}

fetchMethodAndInvoke(serverPlayerClass, "resetSentInfo", serverPlayer, new Object[]{}, new Class[]{});
}

Expand All @@ -286,6 +319,19 @@ private void sendPacket(Object playerConnection, Object packet) throws Reflectio
fetchMethodAndInvoke(playerConnection.getClass(), "send", playerConnection, new Object[]{packet}, new Class<?>[]{this.packet});
}

private void sendPacketToAll(Object packet) {
SkinOverlay.getInstance().onlinePlayers().forEach(playerObject -> {
ServerPlayer spongeServerPlayer = (ServerPlayer) playerObject.getPlayer();
Object serverPlayer = serverPlayerClass.cast(spongeServerPlayer);
Object playerConnection = getFieldByType(serverPlayer, "ServerGamePacketListenerImpl");
try {
sendPacket(playerConnection, packet);
} catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
throw new RuntimeException(e);
}
});
}

private void markDirty(@NotNull Object obj, @NotNull Object dataWatcherObject) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException, NoSuchFieldException {
Object getItem = fetchDeclaredMethodAndInvoke(obj.getClass(), "getItem", obj, new Object[]{dataWatcherObject}, new Class[]{entityDataAccessorClass});
fetchMethodAndInvoke(getItem.getClass(), "setDirty", getItem, new Object[]{true}, new Class[]{boolean.class});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import com.georgev22.library.maps.HashObjectMap;
import com.georgev22.library.maps.ObjectMap;
import com.georgev22.library.minecraft.SpongeMinecraftUtils;
import com.georgev22.library.scheduler.SchedulerManager;
import com.georgev22.skinoverlay.SkinOverlay;
import com.georgev22.skinoverlay.utilities.OptionsUtil;
import com.georgev22.skinoverlay.utilities.player.PlayerObject;
import com.georgev22.skinoverlay.utilities.player.PlayerObjectWrapper;
import com.google.common.collect.Lists;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.network.ServerSideConnectionEvent;

Expand Down Expand Up @@ -59,7 +59,7 @@ public void onLogin(ServerSideConnectionEvent.Join loginEvent) {
.append("%author%", String.join(", ", skinOverlay.getDescription().authors()))
.append("%main%", skinOverlay.getDescription().main())
.append("%javaversion%", System.getProperty("java.version"))
.append("%serverversion%", Sponge.platform().type().name())
.append("%serverversion%", SpongeMinecraftUtils.MinecraftVersion.getCurrentVersionName())
.append("%experimental%", String.valueOf(OptionsUtil.EXPERIMENTAL_FEATURES.getBooleanValue())), true);
}, 200L);
}
Expand Down

0 comments on commit 01acad4

Please sign in to comment.