Skip to content

Commit

Permalink
Fix: *actually* resync attributes when switching games
Browse files Browse the repository at this point in the history
  • Loading branch information
Gegy committed Nov 14, 2024
1 parent 7ee4364 commit 607e1d5
Showing 1 changed file with 16 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import com.mojang.serialization.Dynamic;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.Tag;
import net.minecraft.network.protocol.game.ClientboundChangeDifficultyPacket;
Expand All @@ -21,8 +20,9 @@
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.players.PlayerList;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import net.minecraft.world.entity.ai.attributes.AttributeMap;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.dimension.DimensionType;
Expand Down Expand Up @@ -152,8 +152,7 @@ private ServerPlayer reloadPlayer(final ServerPlayer oldPlayer, final Consumer<S
newPlayer.setHealth(newPlayer.getHealth());
newPlayer.connection.send(new ClientboundSetHealthPacket(newPlayer.getHealth(), newPlayer.getFoodData().getFoodLevel(), newPlayer.getFoodData().getSaturationLevel()));
// It's not possible to specify to the client to drop its base attributes anymore - so just resync everything
newPlayer.connection.send(new ClientboundUpdateAttributesPacket(newPlayer.getId(), newPlayer.getAttributes().getSyncableAttributes()));
newPlayer.getAttributes().getAttributesToSync().clear();
resyncAttributes(oldPlayer, newPlayer);

((PlayerListAccess) playerList).ltminigames$add(newPlayer);

Expand All @@ -171,6 +170,19 @@ private ServerPlayer reloadPlayer(final ServerPlayer oldPlayer, final Consumer<S
return newPlayer;
}

private static void resyncAttributes(ServerPlayer oldPlayer, ServerPlayer newPlayer) {
AttributeMap oldAttributes = oldPlayer.getAttributes();
AttributeMap newAttributes = newPlayer.getAttributes();

// We need to initialize the attributes before we can synchronize them
for (AttributeInstance instance : oldAttributes.getSyncableAttributes()) {
newAttributes.getInstance(instance.getAttribute());
}

newPlayer.connection.send(new ClientboundUpdateAttributesPacket(newPlayer.getId(), newAttributes.getSyncableAttributes()));
newAttributes.getAttributesToSync().clear();
}

private static ServerPlayer recreatePlayer(final ServerPlayer oldPlayer) {
final ServerPlayer newPlayer = new ServerPlayer(oldPlayer.server, oldPlayer.serverLevel(), oldPlayer.getGameProfile(), oldPlayer.clientInformation());
newPlayer.connection = oldPlayer.connection;
Expand Down

0 comments on commit 607e1d5

Please sign in to comment.