From 82dfe13223c1780c86ef27e605e085201045427d Mon Sep 17 00:00:00 2001 From: Suiranoil Date: Sat, 30 Sep 2023 06:55:26 +0300 Subject: [PATCH] update to 1.20.2 --- gradle.properties | 6 +- .../lionarius/skinrestorer/SkinRestorer.java | 100 +++++++++++------- .../mixin/PlayerManagerMixin.java | 3 +- .../mixin/ServerLoginNetworkHandlerMixin.java | 13 +-- 4 files changed, 68 insertions(+), 54 deletions(-) diff --git a/gradle.properties b/gradle.properties index 8e2a900..e7dd551 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,9 +2,9 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/versions.html -minecraft_version=1.20 -yarn_mappings=1.20+build.1 -loader_version=0.14.21 +minecraft_version=1.20.2 +yarn_mappings=1.20.2+build.1 +loader_version=0.14.22 # Mod Properties mod_version=1.2.3 maven_group=net.lionarius diff --git a/src/main/java/net/lionarius/skinrestorer/SkinRestorer.java b/src/main/java/net/lionarius/skinrestorer/SkinRestorer.java index 1ebce87..595b8a1 100644 --- a/src/main/java/net/lionarius/skinrestorer/SkinRestorer.java +++ b/src/main/java/net/lionarius/skinrestorer/SkinRestorer.java @@ -1,5 +1,6 @@ package net.lionarius.skinrestorer; +import com.google.common.collect.Lists; import com.google.gson.Gson; import com.google.gson.JsonObject; import com.mojang.authlib.GameProfile; @@ -7,8 +8,11 @@ import com.mojang.authlib.properties.Property; import it.unimi.dsi.fastutil.Pair; import net.fabricmc.api.DedicatedServerModInitializer; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; import net.minecraft.network.packet.s2c.play.*; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayerEntity; @@ -38,11 +42,57 @@ public class SkinRestorer implements DedicatedServerModInitializer { skinStorage = new SkinStorage(new SkinIO(FabricLoader.getInstance().getConfigDir().resolve("skinrestorer"))); } + public static void refreshPlayer(ServerPlayerEntity player) { + List> equipment = Lists.newArrayList(); + for (EquipmentSlot slot : EquipmentSlot.values()) { + ItemStack itemStack = player.getEquippedStack(slot); + if (!itemStack.isEmpty()) { + equipment.add(com.mojang.datafixers.util.Pair.of(slot, itemStack.copy())); + } + } + + for (ServerPlayerEntity observer : player.server.getPlayerManager().getPlayerList()) { + observer.networkHandler.sendPacket(new PlayerRemoveS2CPacket(List.of(player.getUuid()))); + observer.networkHandler.sendPacket(PlayerListS2CPacket.entryFromPlayer(Collections.singleton(player))); + + if (observer == player) + continue; + + observer.networkHandler.sendPacket(new EntitiesDestroyS2CPacket(player.getId())); + observer.networkHandler.sendPacket(new EntitySpawnS2CPacket(player)); + observer.networkHandler.sendPacket(new EntityPositionS2CPacket(player)); + observer.networkHandler.sendPacket(new EntityTrackerUpdateS2CPacket(player.getId(), player.getDataTracker().getChangedEntries())); + + if (!equipment.isEmpty()) + observer.networkHandler.sendPacket(new EntityEquipmentUpdateS2CPacket(player.getId(), equipment)); + + if (player.hasVehicle()) + observer.networkHandler.sendPacket(new EntityPassengersSetS2CPacket(player.getVehicle())); + } + + player.networkHandler.sendPacket(new PlayerRespawnS2CPacket(player.createCommonPlayerSpawnInfo(player.getServerWorld()), (byte) 2)); + player.networkHandler.requestTeleport(player.getX(), player.getY(), player.getZ(), player.getYaw(), player.getPitch()); + player.networkHandler.sendPacket(new UpdateSelectedSlotS2CPacket(player.getInventory().selectedSlot)); + player.networkHandler.sendPacket(new EntityTrackerUpdateS2CPacket(player.getId(), player.getDataTracker().getChangedEntries())); + + player.sendAbilitiesUpdate(); + player.playerScreenHandler.updateToClient(); + + player.networkHandler.sendPacket(new ExperienceBarUpdateS2CPacket(player.experienceProgress, player.totalExperience, player.experienceLevel)); + player.networkHandler.sendPacket(new HealthUpdateS2CPacket(player.getHealth(), player.getHungerManager().getFoodLevel(), player.getHungerManager().getSaturationLevel())); + + for (StatusEffectInstance instance : player.getStatusEffects()) + player.networkHandler.sendPacket(new EntityStatusEffectS2CPacket(player.getId(), instance)); + + if (player.hasVehicle()) + player.networkHandler.sendPacket(new EntityPassengersSetS2CPacket(player.getVehicle())); + } + public static CompletableFuture, Collection>> setSkinAsync(MinecraftServer server, Collection targets, Supplier skinSupplier) { return CompletableFuture.>>supplyAsync(() -> { HashSet acceptedProfiles = new HashSet<>(); Property skin = skinSupplier.get(); - if (skin == null) { + if (Objects.isNull(skin)) { SkinRestorer.LOGGER.error("Cannot get the skin for {}", targets.stream().findFirst().orElseThrow()); return Pair.of(null, Collections.emptySet()); } @@ -55,12 +105,12 @@ public class SkinRestorer implements DedicatedServerModInitializer { return Pair.of(skin, acceptedProfiles); })., Collection>>thenApplyAsync(pair -> { Property skin = pair.left(); - if (skin == null) + if (Objects.isNull(skin)) return Pair.of(Collections.emptySet(), Collections.emptySet()); Collection acceptedProfiles = pair.right(); HashSet acceptedPlayers = new HashSet<>(); - JsonObject newSkinJson = gson.fromJson(new String(Base64.getDecoder().decode(skin.getValue()), StandardCharsets.UTF_8), JsonObject.class); + JsonObject newSkinJson = gson.fromJson(new String(Base64.getDecoder().decode(skin.value()), StandardCharsets.UTF_8), JsonObject.class); newSkinJson.remove("timestamp"); for (GameProfile profile : acceptedProfiles) { ServerPlayerEntity player = server.getPlayerManager().getPlayer(profile.getId()); @@ -68,49 +118,17 @@ public class SkinRestorer implements DedicatedServerModInitializer { if (player == null || arePropertiesEquals(newSkinJson, player.getGameProfile())) continue; - applyRestoredSkin(player, skin); - for (PlayerEntity observer : player.getWorld().getPlayers()) { - ServerPlayerEntity observer1 = (ServerPlayerEntity) observer; - observer1.networkHandler.sendPacket(new PlayerRemoveS2CPacket(Collections.singletonList(player.getUuid()))); - observer1.networkHandler.sendPacket(new PlayerListS2CPacket(PlayerListS2CPacket.Action.ADD_PLAYER, player)); // refresh the player information - if (player != observer1 && observer1.canSee(player)) { - observer1.networkHandler.sendPacket(new EntitiesDestroyS2CPacket(player.getId())); - observer1.networkHandler.sendPacket(new PlayerSpawnS2CPacket(player)); - observer1.networkHandler.sendPacket(new EntityPositionS2CPacket(player)); - observer1.networkHandler.sendPacket(new EntityTrackerUpdateS2CPacket(player.getId(), player.getDataTracker().getChangedEntries())); - } else if (player == observer1) { - observer1.networkHandler.sendPacket(new PlayerRespawnS2CPacket( - observer1.getWorld().getDimensionKey(), - observer1.getWorld().getRegistryKey(), - BiomeAccess.hashSeed(observer1.getServerWorld().getSeed()), - observer1.interactionManager.getGameMode(), - observer1.interactionManager.getPreviousGameMode(), - observer1.getWorld().isDebugWorld(), - observer1.getServerWorld().isFlat(), - (byte)2, - Optional.empty(), - observer1.getPortalCooldown() - )); - observer1.networkHandler.sendPacket(new UpdateSelectedSlotS2CPacket(observer1.getInventory().selectedSlot)); - observer1.sendAbilitiesUpdate(); - observer1.playerScreenHandler.updateToClient(); - for (StatusEffectInstance instance : observer1.getStatusEffects()) { - observer1.networkHandler.sendPacket(new EntityStatusEffectS2CPacket(observer1.getId(), instance)); - } - observer1.networkHandler.requestTeleport(observer1.getX(), observer1.getY(), observer1.getZ(), observer1.getYaw(), observer1.getPitch()); - observer1.networkHandler.sendPacket(new EntityTrackerUpdateS2CPacket(player.getId(), player.getDataTracker().getChangedEntries())); - observer1.networkHandler.sendPacket(new ExperienceBarUpdateS2CPacket(player.experienceProgress, player.totalExperience, player.experienceLevel)); - } - } + applyRestoredSkin(player.getGameProfile(), skin); + refreshPlayer(player); acceptedPlayers.add(player); } return Pair.of(acceptedPlayers, acceptedProfiles); }, server).orTimeout(10, TimeUnit.SECONDS).exceptionally(e -> Pair.of(Collections.emptySet(), Collections.emptySet())); } - private static void applyRestoredSkin(ServerPlayerEntity playerEntity, Property skin) { - playerEntity.getGameProfile().getProperties().removeAll("textures"); - playerEntity.getGameProfile().getProperties().put("textures", skin); + public static void applyRestoredSkin(GameProfile profile, Property skin) { + profile.getProperties().removeAll("textures"); + profile.getProperties().put("textures", skin); } private static final Gson gson = new Gson(); @@ -121,7 +139,7 @@ public class SkinRestorer implements DedicatedServerModInitializer { return false; try { - JsonObject jy = gson.fromJson(new String(Base64.getDecoder().decode(py.getValue()), StandardCharsets.UTF_8), JsonObject.class); + JsonObject jy = gson.fromJson(new String(Base64.getDecoder().decode(py.value()), StandardCharsets.UTF_8), JsonObject.class); jy.remove("timestamp"); return x.equals(jy); } catch (Exception ex) { diff --git a/src/main/java/net/lionarius/skinrestorer/mixin/PlayerManagerMixin.java b/src/main/java/net/lionarius/skinrestorer/mixin/PlayerManagerMixin.java index d5a85d0..7c6b97d 100644 --- a/src/main/java/net/lionarius/skinrestorer/mixin/PlayerManagerMixin.java +++ b/src/main/java/net/lionarius/skinrestorer/mixin/PlayerManagerMixin.java @@ -4,6 +4,7 @@ import net.lionarius.skinrestorer.SkinRestorer; import net.minecraft.network.ClientConnection; import net.minecraft.server.MinecraftServer; import net.minecraft.server.PlayerManager; +import net.minecraft.server.network.ConnectedClientData; import net.minecraft.server.network.ServerPlayerEntity; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -36,7 +37,7 @@ public abstract class PlayerManagerMixin { } @Inject(method = "onPlayerConnect", at = @At("HEAD")) - private void onPlayerConnected(ClientConnection connection, ServerPlayerEntity player, CallbackInfo ci) { + private void onPlayerConnected(ClientConnection connection, ServerPlayerEntity player, ConnectedClientData clientData, CallbackInfo ci) { if (player.getClass() != ServerPlayerEntity.class) // if the player isn't a server player entity, it must be someone's fake player SkinRestorer.setSkinAsync(server, Collections.singleton(player.getGameProfile()), () -> SkinRestorer.getSkinStorage().getSkin(player.getUuid())); } diff --git a/src/main/java/net/lionarius/skinrestorer/mixin/ServerLoginNetworkHandlerMixin.java b/src/main/java/net/lionarius/skinrestorer/mixin/ServerLoginNetworkHandlerMixin.java index 033fc11..07fdf27 100644 --- a/src/main/java/net/lionarius/skinrestorer/mixin/ServerLoginNetworkHandlerMixin.java +++ b/src/main/java/net/lionarius/skinrestorer/mixin/ServerLoginNetworkHandlerMixin.java @@ -27,7 +27,7 @@ public abstract class ServerLoginNetworkHandlerMixin { static Logger LOGGER; private CompletableFuture skinrestorer_pendingSkin; - @Inject(method = "acceptPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/PlayerManager;checkCanJoin(Ljava/net/SocketAddress;Lcom/mojang/authlib/GameProfile;)Lnet/minecraft/text/Text;"), cancellable = true) + @Inject(method = "tickVerify", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/PlayerManager;checkCanJoin(Ljava/net/SocketAddress;Lcom/mojang/authlib/GameProfile;)Lnet/minecraft/text/Text;"), cancellable = true) public void waitForSkin(CallbackInfo ci) { if (skinrestorer_pendingSkin == null) { skinrestorer_pendingSkin = CompletableFuture.supplyAsync(() -> { @@ -44,14 +44,9 @@ public abstract class ServerLoginNetworkHandlerMixin { } } - private static void applyRestoredSkin(ServerPlayerEntity playerEntity, Property skin) { - playerEntity.getGameProfile().getProperties().removeAll("textures"); - playerEntity.getGameProfile().getProperties().put("textures", skin); - } - - @Inject(method = "addToServer", at = @At("HEAD")) - public void applyRestoredSkinHook(ServerPlayerEntity player, CallbackInfo ci) { + @Inject(method = "sendSuccessPacket", at = @At("HEAD")) + public void applyRestoredSkinHook(GameProfile profile, CallbackInfo ci) { if (skinrestorer_pendingSkin != null) - applyRestoredSkin(player, skinrestorer_pendingSkin.getNow(SkinStorage.DEFAULT_SKIN)); + SkinRestorer.applyRestoredSkin(profile, skinrestorer_pendingSkin.getNow(SkinStorage.DEFAULT_SKIN)); } }