diff --git a/src/main/java/xiamomc/morph/backends/server/renderer/network/PacketFactory.java b/src/main/java/xiamomc/morph/backends/server/renderer/network/PacketFactory.java index 3b159eef..5e0077b2 100644 --- a/src/main/java/xiamomc/morph/backends/server/renderer/network/PacketFactory.java +++ b/src/main/java/xiamomc/morph/backends/server/renderer/network/PacketFactory.java @@ -97,7 +97,7 @@ public List buildSpawnPackets(Player player, DisplayParameters var watcher = parameters.getWatcher(); watcher.sync(); - packets.add(buildMetaPacket(player, watcher)); + packets.add(buildFullMetaPacket(player, watcher)); for (PacketContainer packet : packets) { @@ -107,7 +107,41 @@ public List buildSpawnPackets(Player player, DisplayParameters return packets; } - public PacketContainer buildMetaPacket(Player player, SingleWatcher watcher) + public PacketContainer buildDiffMetaPacket(Player player, SingleWatcher watcher) + { + var metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); + metaPacket.getIntegers().write(0, player.getEntityId()); + + var modifier = metaPacket.getDataValueCollectionModifier(); + + List wrappedDataValues = new ObjectArrayList<>(); + Map, Object> valuesToSent = watcher.getDirty(); + + valuesToSent.forEach((single, v) -> + { + WrappedDataWatcher.Serializer serializer; + + try + { + serializer = ProtocolRegistryUtils.getSerializer(single.defaultValue()); + } + catch (Throwable t) + { + logger.warn("Error occurred while generating meta packet with id '%s': %s".formatted(single.index(), t.getMessage())); + return; + } + + var value = new WrappedDataValue(single.index(), serializer, v); + wrappedDataValues.add(value); + }); + + modifier.write(0, wrappedDataValues); + metaPacket.setMeta(MORPH_PACKET_METAKEY, true); + + return metaPacket; + } + + public PacketContainer buildFullMetaPacket(Player player, SingleWatcher watcher) { var metaPacket = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); metaPacket.getIntegers().write(0, player.getEntityId()); diff --git a/src/main/java/xiamomc/morph/backends/server/renderer/network/datawatcher/watchers/SingleWatcher.java b/src/main/java/xiamomc/morph/backends/server/renderer/network/datawatcher/watchers/SingleWatcher.java index 66ed5ea6..30b6f0b3 100644 --- a/src/main/java/xiamomc/morph/backends/server/renderer/network/datawatcher/watchers/SingleWatcher.java +++ b/src/main/java/xiamomc/morph/backends/server/renderer/network/datawatcher/watchers/SingleWatcher.java @@ -3,24 +3,16 @@ import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketContainer; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectLists; -import net.minecraft.server.packs.repository.Pack; import net.minecraft.world.level.GameType; import org.bukkit.Bukkit; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; -import org.bukkit.inventory.EntityEquipment; import org.jetbrains.annotations.Nullable; -import xiamomc.morph.MorphPlugin; import xiamomc.morph.MorphPluginObject; import xiamomc.morph.backends.server.renderer.network.PacketFactory; import xiamomc.morph.backends.server.renderer.network.datawatcher.values.AbstractValues; import xiamomc.morph.backends.server.renderer.network.datawatcher.values.SingleValue; -import xiamomc.morph.backends.server.renderer.network.queue.PacketQueue; -import xiamomc.morph.backends.server.renderer.network.queue.QueueEntry; -import xiamomc.morph.backends.server.renderer.network.registries.EntryIndex; import xiamomc.morph.backends.server.renderer.network.registries.RegistryKey; -import xiamomc.morph.misc.DisguiseEquipment; import xiamomc.morph.misc.NmsRecord; import xiamomc.pluginbase.Annotations.Resolved; import xiamomc.pluginbase.Exceptions.NullDependencyException; @@ -165,7 +157,7 @@ public void write(int index, Object value) dirtySingles.put(single, value); onTrackerWrite(index, prev, value); - sendPacketToAffectedPlayers(packetFactory.buildMetaPacket(getBindingPlayer(), this)); + sendPacketToAffectedPlayers(packetFactory.buildDiffMetaPacket(getBindingPlayer(), this)); } @Resolved(shouldSolveImmediately = true) diff --git a/src/main/java/xiamomc/morph/backends/server/renderer/network/listeners/MetaPacketListener.java b/src/main/java/xiamomc/morph/backends/server/renderer/network/listeners/MetaPacketListener.java index 642266cf..76cce52f 100644 --- a/src/main/java/xiamomc/morph/backends/server/renderer/network/listeners/MetaPacketListener.java +++ b/src/main/java/xiamomc/morph/backends/server/renderer/network/listeners/MetaPacketListener.java @@ -3,7 +3,6 @@ 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.injector.GamePhase; import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; import org.bukkit.entity.Player; @@ -53,7 +52,7 @@ private void onMetaPacket(ClientboundSetEntityDataPacket packet, PacketEvent pac //取得来源玩家的伪装后的Meta,发送给目标玩家 watcher.sync(); - packetEvent.setPacket(getFactory().buildMetaPacket(sourcePlayer, watcher)); + packetEvent.setPacket(getFactory().buildFullMetaPacket(sourcePlayer, watcher)); } @Override diff --git a/src/main/java/xiamomc/morph/backends/server/renderer/network/listeners/SpawnPacketHandler.java b/src/main/java/xiamomc/morph/backends/server/renderer/network/listeners/SpawnPacketHandler.java index 0ceb3051..38067bea 100644 --- a/src/main/java/xiamomc/morph/backends/server/renderer/network/listeners/SpawnPacketHandler.java +++ b/src/main/java/xiamomc/morph/backends/server/renderer/network/listeners/SpawnPacketHandler.java @@ -5,7 +5,6 @@ import com.comphenix.protocol.events.ListeningWhitelist; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketEvent; -import com.comphenix.protocol.events.PacketListener; import com.comphenix.protocol.injector.GamePhase; import com.mojang.authlib.GameProfile; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -14,7 +13,6 @@ import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; -import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.GameType; import org.bukkit.Bukkit; @@ -26,7 +24,6 @@ import xiamomc.morph.MorphPlugin; import xiamomc.morph.backends.server.renderer.network.DisplayParameters; import xiamomc.morph.backends.server.renderer.network.PacketFactory; -import xiamomc.morph.backends.server.renderer.network.ProtocolEquipment; import xiamomc.morph.backends.server.renderer.network.datawatcher.watchers.types.PlayerWatcher; import xiamomc.morph.backends.server.renderer.network.registries.EntryIndex; import xiamomc.morph.backends.server.renderer.network.registries.RenderRegistry; @@ -104,7 +101,7 @@ private void unDisguiseForPlayer(@Nullable Player player) var watcher = new PlayerWatcher(player); packets.add(getFactory().getEquipmentPacket(player, watcher)); - packets.add(getFactory().buildMetaPacket(player, watcher)); + packets.add(getFactory().buildFullMetaPacket(player, watcher)); affectedPlayers.forEach(p -> {