From c934cb9694e84b97acd2fdd40261b78a1149210d Mon Sep 17 00:00:00 2001 From: johni0702 Date: Sun, 13 Nov 2016 17:07:34 +0100 Subject: [PATCH] Fix spawn player packet being sent twice The vanilla server sends the player list packet with ADD action twice to the joining player, however we must only send the spawn player packet once. This also fixes semi-dead player entities in replays that just existed at spawn but never did anything. --- .../mixin/MixinNetHandlerPlayClient.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/replaymod/recording/mixin/MixinNetHandlerPlayClient.java b/src/main/java/com/replaymod/recording/mixin/MixinNetHandlerPlayClient.java index baf316ed..bd5d4a99 100644 --- a/src/main/java/com/replaymod/recording/mixin/MixinNetHandlerPlayClient.java +++ b/src/main/java/com/replaymod/recording/mixin/MixinNetHandlerPlayClient.java @@ -3,6 +3,7 @@ package com.replaymod.recording.mixin; import com.replaymod.recording.handler.RecordingEventHandler; import net.minecraft.client.Minecraft; import net.minecraft.client.network.NetHandlerPlayClient; +import net.minecraft.client.network.NetworkPlayerInfo; import net.minecraft.network.play.server.S07PacketRespawn; import net.minecraft.network.play.server.S38PacketPlayerListItem; import org.spongepowered.asm.mixin.Mixin; @@ -12,6 +13,8 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.List; +import java.util.Map; +import java.util.UUID; @Mixin(NetHandlerPlayClient.class) public abstract class MixinNetHandlerPlayClient { @@ -19,6 +22,9 @@ public abstract class MixinNetHandlerPlayClient { @Shadow private Minecraft gameController; + @Shadow + private Map playerInfoMap; + public RecordingEventHandler getRecordingEventHandler() { return ((RecordingEventHandler.RecordingEventSender) gameController.renderGlobal).getRecordingEventHandler(); } @@ -30,14 +36,19 @@ public abstract class MixinNetHandlerPlayClient { * @param packet The packet * @param ci Callback info */ - @Inject(method = "handlePlayerListItem", at=@At("RETURN")) + @Inject(method = "handlePlayerListItem", at=@At("HEAD")) public void recordOwnJoin(S38PacketPlayerListItem packet, CallbackInfo ci) { + if (gameController.thePlayer == null) return; + RecordingEventHandler handler = getRecordingEventHandler(); if (handler != null && packet.func_179768_b() == S38PacketPlayerListItem.Action.ADD_PLAYER) { @SuppressWarnings("unchecked") List dataList = packet.func_179767_a(); for (S38PacketPlayerListItem.AddPlayerData data : dataList) { - if (data.func_179962_a().getId().equals(Minecraft.getMinecraft().thePlayer.getGameProfile().getId())) { + if (data.func_179962_a() == null || data.func_179962_a().getId() == null) continue; + // Only add spawn packet for our own player and only if he isn't known yet + if (data.func_179962_a().getId().equals(Minecraft.getMinecraft().thePlayer.getGameProfile().getId()) + && !playerInfoMap.containsKey(data.func_179962_a().getId())) { handler.onPlayerJoin(); } }