From 3dd235226783e13c61f45c2e580fa298ac925e4b Mon Sep 17 00:00:00 2001 From: Light_Quanta Date: Thu, 29 May 2025 16:29:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=9D=E8=AF=95=E8=BF=9B=E4=B8=80=E6=AD=A5?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=BD=BD=E5=85=B7=E5=92=8C=E6=9E=AA=E6=A2=B0?= =?UTF-8?q?=E7=9A=84=E6=95=B0=E6=8D=AE=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/gun/DefaultGunData.java | 3 ++ .../message/receive/GunsDataMessage.java | 48 ++++++++--------- .../message/receive/VehiclesDataMessage.java | 1 + .../superbwarfare/tools/BufferSerializer.java | 51 ++----------------- .../superbwarfare/tools/GunsTool.java | 1 + 5 files changed, 35 insertions(+), 69 deletions(-) diff --git a/src/main/java/com/atsuishio/superbwarfare/data/gun/DefaultGunData.java b/src/main/java/com/atsuishio/superbwarfare/data/gun/DefaultGunData.java index 60bd99d21..f976ede9c 100644 --- a/src/main/java/com/atsuishio/superbwarfare/data/gun/DefaultGunData.java +++ b/src/main/java/com/atsuishio/superbwarfare/data/gun/DefaultGunData.java @@ -1,5 +1,6 @@ package com.atsuishio.superbwarfare.data.gun; +import com.atsuishio.superbwarfare.annotation.ServerOnly; import com.google.gson.annotations.SerializedName; import java.util.List; @@ -39,6 +40,7 @@ public class DefaultGunData { @SerializedName("MeleeDamageTime") public int meleeDamageTime = 6; + @ServerOnly @SerializedName("Projectile") public ProjectileInfo projectile = new ProjectileInfo(); @@ -124,6 +126,7 @@ public class DefaultGunData { "!superbwarfare:cupid_arrow" ); + @ServerOnly @SerializedName("DamageReduce") public DamageReduce damageReduce = new DamageReduce(); } diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/receive/GunsDataMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/receive/GunsDataMessage.java index fa0ed964a..aaa79d196 100644 --- a/src/main/java/com/atsuishio/superbwarfare/network/message/receive/GunsDataMessage.java +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/receive/GunsDataMessage.java @@ -2,46 +2,48 @@ package com.atsuishio.superbwarfare.network.message.receive; import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.data.gun.DefaultGunData; +import com.atsuishio.superbwarfare.tools.BufferSerializer; import com.atsuishio.superbwarfare.tools.GunsTool; -import com.google.gson.Gson; -import io.netty.buffer.ByteBuf; -import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.FriendlyByteBuf; 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; -import java.util.HashMap; -import java.util.Map; +import java.util.ArrayList; +import java.util.List; -public record GunsDataMessage(Map gunsData) implements CustomPacketPayload { +public record GunsDataMessage(List data) implements CustomPacketPayload { public static final Type TYPE = new Type<>(Mod.loc("set_guns_data")); - public static final StreamCodec STREAM_CODEC = StreamCodec.composite( - ByteBufCodecs.map( - HashMap::new, - ByteBufCodecs.STRING_UTF8, - ByteBufCodecs.STRING_UTF8 - ), - GunsDataMessage::gunsData, - GunsDataMessage::new + public static final StreamCodec STREAM_CODEC = StreamCodec.ofMember( + (obj, buf) -> { + buf.writeVarInt(obj.data.size()); + for (var data : obj.data) { + buf.writeBytes(BufferSerializer.serialize(data).copy()); + } + }, + (buf) -> { + var size = buf.readVarInt(); + var list = new ArrayList(); + for (var i = 0; i < size; i++) { + list.add(BufferSerializer.deserialize(buf, new DefaultGunData())); + } + return new GunsDataMessage(list); + } ); - private static final Gson GSON = new Gson(); - public static GunsDataMessage create() { - var map = new HashMap(); - for (var entry : GunsTool.gunsData.entrySet()) { - map.put(entry.getKey(), GSON.toJson(entry.getValue())); - } - return new GunsDataMessage(map); + return new GunsDataMessage(GunsTool.gunsData.values().stream().toList()); } public static void handler(final GunsDataMessage message, final IPayloadContext context) { GunsTool.gunsData.clear(); - for (var entry : message.gunsData.entrySet()) { - GunsTool.gunsData.put(entry.getKey(), GSON.fromJson(entry.getValue(), DefaultGunData.class)); + + for (var entry : message.data) { + if (GunsTool.gunsData.containsKey(entry.id)) continue; + GunsTool.gunsData.put(entry.id, entry); } } diff --git a/src/main/java/com/atsuishio/superbwarfare/network/message/receive/VehiclesDataMessage.java b/src/main/java/com/atsuishio/superbwarfare/network/message/receive/VehiclesDataMessage.java index f9bd70525..3c9bbb7a0 100644 --- a/src/main/java/com/atsuishio/superbwarfare/network/message/receive/VehiclesDataMessage.java +++ b/src/main/java/com/atsuishio/superbwarfare/network/message/receive/VehiclesDataMessage.java @@ -41,6 +41,7 @@ public record VehiclesDataMessage(List data) implements Cust VehicleDataTool.vehicleData.clear(); for (var entry : message.data) { + if (VehicleDataTool.vehicleData.containsKey(entry.id)) continue; VehicleDataTool.vehicleData.put(entry.id, entry); } } diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/BufferSerializer.java b/src/main/java/com/atsuishio/superbwarfare/tools/BufferSerializer.java index 61c4eb105..e5e83e420 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/BufferSerializer.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/BufferSerializer.java @@ -2,6 +2,7 @@ package com.atsuishio.superbwarfare.tools; import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.annotation.ServerOnly; +import com.google.gson.Gson; import io.netty.buffer.Unpooled; import net.minecraft.network.FriendlyByteBuf; @@ -12,9 +13,6 @@ import java.util.Arrays; import java.util.Comparator; import java.util.List; - -// 屎 -// TODO 优化这一坨(至少得支持数组和嵌套对象序列化) public class BufferSerializer { public static List sortedFields(Class clazz) { return Arrays.stream(clazz.getDeclaredFields()) @@ -42,6 +40,8 @@ public class BufferSerializer { return fields; } + private static final Gson gson = new Gson(); + public static FriendlyByteBuf serialize(Object object) { var buffer = new FriendlyByteBuf(Unpooled.buffer()); var fields = fieldValuesList(object); @@ -55,12 +55,8 @@ public class BufferSerializer { case Double d -> buffer.writeDouble(d); case String s -> buffer.writeUtf(s); case Boolean b -> buffer.writeBoolean(b); -// case List l -> { -// buffer.writeVarInt(l.size()); -// l.forEach(o -> serialize(o, buffer)); -// } - default -> serialize(value); + default -> buffer.writeUtf(gson.toJson(value)); } }); @@ -83,51 +79,14 @@ public class BufferSerializer { setField(object, field, buffer.readUtf()); } else if (field.getType().isAssignableFrom(Boolean.class) || field.getType().getName().equals("boolean")) { setField(object, field, buffer.readBoolean()); -// } else if (field.getType().isAssignableFrom(List.class)) { -// var size = buffer.readVarInt(); -// var list = new ArrayList<>(); -// for (int i = 0; i < size; i++) { -// list.add(readFieldByClass(object, field.getGenericType().getClass(), buffer)); -// } -// setField(object, field, list); } else { - throw new IllegalArgumentException("Non-primary Object not supported"); -// setField(object, field, deserialize(buffer, getField(object, field))); + setField(object, field, gson.fromJson(buffer.readUtf(), field.getType())); } }); return object; } - public static Object readFieldByClass(Object object, Class clazz, FriendlyByteBuf buffer) { - if (clazz.isAssignableFrom(Byte.class) || clazz.getName().equals("byte")) { - return buffer.readByte(); - } else if (clazz.isAssignableFrom(Integer.class) || clazz.getName().equals("int")) { - return buffer.readVarInt(); - } else if (clazz.isAssignableFrom(Long.class) || clazz.getName().equals("long")) { - return buffer.readLong(); - } else if (clazz.isAssignableFrom(Float.class) || clazz.getName().equals("float")) { - return buffer.readFloat(); - } else if (clazz.isAssignableFrom(Double.class) || clazz.getName().equals("double")) { - return buffer.readDouble(); - } else if (clazz.isAssignableFrom(String.class)) { - return buffer.readUtf(); - } else if (clazz.isAssignableFrom(Boolean.class) || clazz.getName().equals("boolean")) { - return buffer.readByte(); -// } else if (clazz.isAssignableFrom(List.class)) { -// var size = buffer.readVarInt(); -// var list = new ArrayList<>(); -// for (int i = 0; i < size; i++) { -// clazz.getDeclaredConstructors()[0].newInstance() -// list.add(deserialize(field)); -// } -// setField(object, field, list); - } else { - throw new IllegalArgumentException("Non-primary Object not supported"); -// deserialize(buffer, getField(object, field)); - } - } - public static void setField(Object object, Field field, Object value) { try { field.setAccessible(true); diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/GunsTool.java b/src/main/java/com/atsuishio/superbwarfare/tools/GunsTool.java index f713a2bd1..a9fff3874 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/GunsTool.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/GunsTool.java @@ -48,6 +48,7 @@ public class GunsTool { var path = entry.getKey().getPath(); id = Mod.MODID + ":" + path.substring(GUN_DATA_FOLDER.length() + 1, path.length() - GUN_DATA_FOLDER.length() - 1); Mod.LOGGER.warn("Gun ID for {} is empty, try using {} as id", path, id); + data.id = id; } if (!gunsData.containsKey(id)) {