尝试进一步优化载具和枪械的数据同步

This commit is contained in:
Light_Quanta 2025-05-29 16:29:48 +08:00
parent 3cb6940ec8
commit 3dd2352267
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
5 changed files with 35 additions and 69 deletions

View file

@ -1,5 +1,6 @@
package com.atsuishio.superbwarfare.data.gun; package com.atsuishio.superbwarfare.data.gun;
import com.atsuishio.superbwarfare.annotation.ServerOnly;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import java.util.List; import java.util.List;
@ -39,6 +40,7 @@ public class DefaultGunData {
@SerializedName("MeleeDamageTime") @SerializedName("MeleeDamageTime")
public int meleeDamageTime = 6; public int meleeDamageTime = 6;
@ServerOnly
@SerializedName("Projectile") @SerializedName("Projectile")
public ProjectileInfo projectile = new ProjectileInfo(); public ProjectileInfo projectile = new ProjectileInfo();
@ -124,6 +126,7 @@ public class DefaultGunData {
"!superbwarfare:cupid_arrow" "!superbwarfare:cupid_arrow"
); );
@ServerOnly
@SerializedName("DamageReduce") @SerializedName("DamageReduce")
public DamageReduce damageReduce = new DamageReduce(); public DamageReduce damageReduce = new DamageReduce();
} }

View file

@ -2,46 +2,48 @@ package com.atsuishio.superbwarfare.network.message.receive;
import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.data.gun.DefaultGunData; import com.atsuishio.superbwarfare.data.gun.DefaultGunData;
import com.atsuishio.superbwarfare.tools.BufferSerializer;
import com.atsuishio.superbwarfare.tools.GunsTool; import com.atsuishio.superbwarfare.tools.GunsTool;
import com.google.gson.Gson; import net.minecraft.network.FriendlyByteBuf;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.neoforged.neoforge.network.handling.IPayloadContext; import net.neoforged.neoforge.network.handling.IPayloadContext;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.ArrayList;
import java.util.Map; import java.util.List;
public record GunsDataMessage(Map<String, String> gunsData) implements CustomPacketPayload { public record GunsDataMessage(List<DefaultGunData> data) implements CustomPacketPayload {
public static final Type<GunsDataMessage> TYPE = new Type<>(Mod.loc("set_guns_data")); public static final Type<GunsDataMessage> TYPE = new Type<>(Mod.loc("set_guns_data"));
public static final StreamCodec<ByteBuf, GunsDataMessage> STREAM_CODEC = StreamCodec.composite( public static final StreamCodec<FriendlyByteBuf, GunsDataMessage> STREAM_CODEC = StreamCodec.ofMember(
ByteBufCodecs.map( (obj, buf) -> {
HashMap::new, buf.writeVarInt(obj.data.size());
ByteBufCodecs.STRING_UTF8, for (var data : obj.data) {
ByteBufCodecs.STRING_UTF8 buf.writeBytes(BufferSerializer.serialize(data).copy());
), }
GunsDataMessage::gunsData, },
GunsDataMessage::new (buf) -> {
var size = buf.readVarInt();
var list = new ArrayList<DefaultGunData>();
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() { public static GunsDataMessage create() {
var map = new HashMap<String, String>(); return new GunsDataMessage(GunsTool.gunsData.values().stream().toList());
for (var entry : GunsTool.gunsData.entrySet()) {
map.put(entry.getKey(), GSON.toJson(entry.getValue()));
}
return new GunsDataMessage(map);
} }
public static void handler(final GunsDataMessage message, final IPayloadContext context) { public static void handler(final GunsDataMessage message, final IPayloadContext context) {
GunsTool.gunsData.clear(); 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);
} }
} }

View file

@ -41,6 +41,7 @@ public record VehiclesDataMessage(List<DefaultVehicleData> data) implements Cust
VehicleDataTool.vehicleData.clear(); VehicleDataTool.vehicleData.clear();
for (var entry : message.data) { for (var entry : message.data) {
if (VehicleDataTool.vehicleData.containsKey(entry.id)) continue;
VehicleDataTool.vehicleData.put(entry.id, entry); VehicleDataTool.vehicleData.put(entry.id, entry);
} }
} }

View file

@ -2,6 +2,7 @@ package com.atsuishio.superbwarfare.tools;
import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.annotation.ServerOnly; import com.atsuishio.superbwarfare.annotation.ServerOnly;
import com.google.gson.Gson;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
@ -12,9 +13,6 @@ import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
//
// TODO 优化这一坨至少得支持数组和嵌套对象序列化
public class BufferSerializer { public class BufferSerializer {
public static List<Field> sortedFields(Class<?> clazz) { public static List<Field> sortedFields(Class<?> clazz) {
return Arrays.stream(clazz.getDeclaredFields()) return Arrays.stream(clazz.getDeclaredFields())
@ -42,6 +40,8 @@ public class BufferSerializer {
return fields; return fields;
} }
private static final Gson gson = new Gson();
public static FriendlyByteBuf serialize(Object object) { public static FriendlyByteBuf serialize(Object object) {
var buffer = new FriendlyByteBuf(Unpooled.buffer()); var buffer = new FriendlyByteBuf(Unpooled.buffer());
var fields = fieldValuesList(object); var fields = fieldValuesList(object);
@ -55,12 +55,8 @@ public class BufferSerializer {
case Double d -> buffer.writeDouble(d); case Double d -> buffer.writeDouble(d);
case String s -> buffer.writeUtf(s); case String s -> buffer.writeUtf(s);
case Boolean b -> buffer.writeBoolean(b); 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()); setField(object, field, buffer.readUtf());
} else if (field.getType().isAssignableFrom(Boolean.class) || field.getType().getName().equals("boolean")) { } else if (field.getType().isAssignableFrom(Boolean.class) || field.getType().getName().equals("boolean")) {
setField(object, field, buffer.readBoolean()); 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 { } else {
throw new IllegalArgumentException("Non-primary Object not supported"); setField(object, field, gson.fromJson(buffer.readUtf(), field.getType()));
// setField(object, field, deserialize(buffer, getField(object, field)));
} }
}); });
return object; 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) { public static void setField(Object object, Field field, Object value) {
try { try {
field.setAccessible(true); field.setAccessible(true);

View file

@ -48,6 +48,7 @@ public class GunsTool {
var path = entry.getKey().getPath(); var path = entry.getKey().getPath();
id = Mod.MODID + ":" + path.substring(GUN_DATA_FOLDER.length() + 1, path.length() - GUN_DATA_FOLDER.length() - 1); 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); Mod.LOGGER.warn("Gun ID for {} is empty, try using {} as id", path, id);
data.id = id;
} }
if (!gunsData.containsKey(id)) { if (!gunsData.containsKey(id)) {