diff --git a/build.gradle b/build.gradle index 0b4da38d2..65ffa4912 100644 --- a/build.gradle +++ b/build.gradle @@ -136,6 +136,9 @@ dependencies { // Cloth Config相关 implementation "me.shedaniel.cloth:cloth-config-neoforge:15.0.140" +// implementation "curse.maven:cupboard-326652:6078150" +// implementation "curse.maven:connectivity-470193:6229173" + // // 测试用mod // implementation fg.deobf("curse.maven:oculus-581495:6020952") // implementation fg.deobf("curse.maven:embeddium-908741:5681725") diff --git a/src/main/java/com/atsuishio/superbwarfare/capability/player/PlayerVariable.java b/src/main/java/com/atsuishio/superbwarfare/capability/player/PlayerVariable.java index 5bdbb8d07..d34dafb32 100644 --- a/src/main/java/com/atsuishio/superbwarfare/capability/player/PlayerVariable.java +++ b/src/main/java/com/atsuishio/superbwarfare/capability/player/PlayerVariable.java @@ -37,7 +37,7 @@ public class PlayerVariable implements INBTSerializable { if (old != null && old.equals(newVariable)) return; if (entity instanceof ServerPlayer serverPlayer) { - PacketDistributor.sendToPlayer(serverPlayer, new PlayerVariablesSyncMessage(entity.getId(), newVariable.writeToNBT())); + PacketDistributor.sendToPlayer(serverPlayer, new PlayerVariablesSyncMessage(entity.getId(), compareAndUpdate())); } } @@ -45,7 +45,7 @@ public class PlayerVariable implements INBTSerializable { public static void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) { if (!(event.getEntity() instanceof ServerPlayer player)) return; - PacketDistributor.sendToPlayer(player, new PlayerVariablesSyncMessage(player.getId(), player.getData(ModAttachments.PLAYER_VARIABLE).writeToNBT())); + PacketDistributor.sendToPlayer(player, new PlayerVariablesSyncMessage(player.getId(), player.getData(ModAttachments.PLAYER_VARIABLE).compareAndUpdate())); } public PlayerVariable watch() { @@ -53,6 +53,29 @@ public class PlayerVariable implements INBTSerializable { return this; } + public Map compareAndUpdate() { + var map = new HashMap(); + var old = this.old == null ? new PlayerVariable() : this.old; + + for (var type : Ammo.values()) { + var oldCount = old.ammo.getOrDefault(type, 0); + var newCount = type.get(this); + + if (oldCount != newCount) { + map.put((byte) type.ordinal(), newCount); + } + } + + if (old.tacticalSprint != this.tacticalSprint) { + map.put((byte) -1, this.tacticalSprint ? 1 : 0); + } + if (old.edit != this.edit) { + map.put((byte) -2, this.edit ? 1 : 0); + } + + return map; + } + /** * 编辑并同步玩家变量 */ diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/receive/PlayerVariablesSyncMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/receive/PlayerVariablesSyncMessage.java index 6fd924fa4..de3457290 100644 --- a/src/main/java/com/atsuishio/superbwarfare/network/message/receive/PlayerVariablesSyncMessage.java +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/receive/PlayerVariablesSyncMessage.java @@ -1,37 +1,61 @@ package com.atsuishio.superbwarfare.network.message.receive; import com.atsuishio.superbwarfare.Mod; -import com.atsuishio.superbwarfare.capability.player.PlayerVariable; import com.atsuishio.superbwarfare.init.ModAttachments; +import com.atsuishio.superbwarfare.tools.Ammo; import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.neoforged.neoforge.network.handling.IPayloadContext; import org.jetbrains.annotations.NotNull; -public record PlayerVariablesSyncMessage(int target, CompoundTag data) implements CustomPacketPayload { +import java.util.HashMap; +import java.util.Map; + +public record PlayerVariablesSyncMessage(int target, Map data) implements CustomPacketPayload { public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(Mod.loc("player_variable_sync")); public static final StreamCodec STREAM_CODEC = StreamCodec.composite( ByteBufCodecs.INT, PlayerVariablesSyncMessage::target, - ByteBufCodecs.COMPOUND_TAG, + ByteBufCodecs.map( + HashMap::new, + ByteBufCodecs.BYTE, + ByteBufCodecs.VAR_INT, + 256 + ), PlayerVariablesSyncMessage::data, PlayerVariablesSyncMessage::new ); public static void handler(final PlayerVariablesSyncMessage message, final IPayloadContext context) { - var data = new PlayerVariable().readFromNBT(message.data()); - if (Minecraft.getInstance().player == null) return; + var entity = Minecraft.getInstance().player.level().getEntity(message.target()); if (entity == null) return; - entity.setData(ModAttachments.PLAYER_VARIABLE, data); + var variable = entity.getData(ModAttachments.PLAYER_VARIABLE); + var map = message.data(); + + for (var entry : map.entrySet()) { + var type = entry.getKey(); + switch (type) { + case -1 -> variable.tacticalSprint = entry.getValue() == 1; + case -2 -> variable.edit = entry.getValue() == 1; + default -> { + var ammoTypes = Ammo.values(); + if (type < ammoTypes.length) { + var ammo = ammoTypes[type]; + variable.ammo.put(ammo, entry.getValue()); + } + } + } + } + + entity.setData(ModAttachments.PLAYER_VARIABLE, variable); } @Override