Fixed packet errors in multiplayer and close a memory leak

This commit is contained in:
Sollace 2024-10-28 15:47:55 +00:00
parent e67954f370
commit 06e4a1c8be
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
4 changed files with 51 additions and 22 deletions

View file

@ -44,11 +44,13 @@ public class DataTrackerManager {
packetEmitters.add((sender, initial) -> { packetEmitters.add((sender, initial) -> {
var update = initial ? tracker.getInitialPairs(lookup) : tracker.getDirtyPairs(lookup); var update = initial ? tracker.getInitialPairs(lookup) : tracker.getDirtyPairs(lookup);
if (update.isPresent()) { if (update.isPresent()) {
sender.accept(Channel.SERVER_TRACKED_ENTITY_DATA.toPacket(new MsgTrackedValues( try (var payload = new MsgTrackedValues(
entity.getId(), entity.getId(),
Optional.empty(), Optional.empty(),
update update
))); )) {
sender.accept(Channel.SERVER_TRACKED_ENTITY_DATA.toPacket(payload));
}
} }
}); });
return tracker; return tracker;
@ -60,11 +62,13 @@ public class DataTrackerManager {
packetEmitters.add((sender, initial) -> { packetEmitters.add((sender, initial) -> {
var update = initial ? tracker.getInitialPairs(lookup) : tracker.getDirtyPairs(lookup); var update = initial ? tracker.getInitialPairs(lookup) : tracker.getDirtyPairs(lookup);
if (update.isPresent()) { if (update.isPresent()) {
sender.accept(Channel.SERVER_TRACKED_ENTITY_DATA.toPacket(new MsgTrackedValues( try (var payload = new MsgTrackedValues(
entity.getId(), entity.getId(),
update, update,
Optional.empty() Optional.empty()
))); )) {
sender.accept(Channel.SERVER_TRACKED_ENTITY_DATA.toPacket(payload));
}
} }
}); });
return tracker; return tracker;

View file

@ -1,5 +1,6 @@
package com.minelittlepony.unicopia.network.track; package com.minelittlepony.unicopia.network.track;
import java.io.Closeable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -24,7 +25,7 @@ public record MsgTrackedValues(
int owner, int owner,
Optional<TrackerObjects> updatedObjects, Optional<TrackerObjects> updatedObjects,
Optional<TrackerEntries> updatedTrackers Optional<TrackerEntries> updatedTrackers
) implements Handled<PlayerEntity> { ) implements Handled<PlayerEntity>, AutoCloseable {
public static final PacketCodec<RegistryByteBuf, MsgTrackedValues> PACKET_CODEC = PacketCodec.tuple( public static final PacketCodec<RegistryByteBuf, MsgTrackedValues> PACKET_CODEC = PacketCodec.tuple(
PacketCodecs.INTEGER, MsgTrackedValues::owner, PacketCodecs.INTEGER, MsgTrackedValues::owner,
PacketCodecs.optional(TrackerObjects.PACKET_CODEC), MsgTrackedValues::updatedObjects, PacketCodecs.optional(TrackerObjects.PACKET_CODEC), MsgTrackedValues::updatedObjects,
@ -34,22 +35,33 @@ public record MsgTrackedValues(
@Override @Override
public void handle(PlayerEntity sender) { public void handle(PlayerEntity sender) {
Entity entity = sender.getWorld().getEntityById(owner); try (this) {
if (entity instanceof Trackable trackable) { Entity entity = sender.getWorld().getEntityById(owner);
trackable.getDataTrackers().load(this); if (entity instanceof Trackable trackable) {
trackable.getDataTrackers().load(this);
}
} }
} }
public record TrackerObjects(int id, Set<UUID> removedValues, Map<UUID, ByteBuf> values) { public record TrackerObjects(int id, Set<UUID> removedValues, Map<UUID, ByteBuf> values) implements Closeable {
public static final PacketCodec<RegistryByteBuf, TrackerObjects> PACKET_CODEC = PacketCodec.tuple( public static final PacketCodec<RegistryByteBuf, TrackerObjects> PACKET_CODEC = PacketCodec.tuple(
PacketCodecs.INTEGER, TrackerObjects::id, PacketCodecs.INTEGER, TrackerObjects::id,
Uuids.PACKET_CODEC.collect(PacketCodecs.toCollection(HashSet::new)), TrackerObjects::removedValues, Uuids.PACKET_CODEC.collect(PacketCodecs.toCollection(HashSet::new)), TrackerObjects::removedValues,
PacketCodecs.map(HashMap::new, Uuids.PACKET_CODEC, PacketCodecUtils.REGISTRY_BUFFER), TrackerObjects::values, PacketCodecs.map(HashMap::new, Uuids.PACKET_CODEC, PacketCodecUtils.REGISTRY_BUFFER), TrackerObjects::values,
TrackerObjects::new TrackerObjects::new
); );
@Override
public void close() {
values.values().forEach(buf -> {
if (buf.refCnt() > 0) {
buf.release();
}
});
}
} }
public record TrackerEntries(int id, boolean wipe, List<DataTracker.Pair<?>> values, Map<Integer, ByteBuf> objects) { public record TrackerEntries(int id, boolean wipe, List<DataTracker.Pair<?>> values, Map<Integer, ByteBuf> objects) implements Closeable {
public static final PacketCodec<RegistryByteBuf, TrackerEntries> PACKET_CODEC = PacketCodec.tuple( public static final PacketCodec<RegistryByteBuf, TrackerEntries> PACKET_CODEC = PacketCodec.tuple(
PacketCodecs.INTEGER, TrackerEntries::id, PacketCodecs.INTEGER, TrackerEntries::id,
PacketCodecs.BOOL, TrackerEntries::wipe, PacketCodecs.BOOL, TrackerEntries::wipe,
@ -57,5 +69,20 @@ public record MsgTrackedValues(
PacketCodecs.map(HashMap::new, PacketCodecs.INTEGER, PacketCodecUtils.REGISTRY_BUFFER), TrackerEntries::objects, PacketCodecs.map(HashMap::new, PacketCodecs.INTEGER, PacketCodecUtils.REGISTRY_BUFFER), TrackerEntries::objects,
TrackerEntries::new TrackerEntries::new
); );
@Override
public void close() {
objects.values().forEach(buf -> {
if (buf.refCnt() > 0) {
buf.release();
}
});
}
}
@Override
public void close() {
updatedObjects.ifPresent(TrackerObjects::close);
updatedObjects.ifPresent(TrackerObjects::close);
} }
} }

View file

@ -13,7 +13,6 @@ import java.util.concurrent.atomic.AtomicReference;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.RegistryByteBuf; import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec; import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.codec.PacketCodecs; import net.minecraft.network.codec.PacketCodecs;
@ -36,7 +35,6 @@ public record TrackableDataType<T>(int id, PacketCodec<RegistryByteBuf, TypedVal
public static final TrackableDataType<UUID> UUID = of(Identifier.of("uuid"), Uuids.PACKET_CODEC); public static final TrackableDataType<UUID> UUID = of(Identifier.of("uuid"), Uuids.PACKET_CODEC);
public static final TrackableDataType<NbtCompound> NBT = of(Identifier.of("nbt"), PacketCodecs.NBT_COMPOUND); public static final TrackableDataType<NbtCompound> NBT = of(Identifier.of("nbt"), PacketCodecs.NBT_COMPOUND);
public static final TrackableDataType<NbtCompound> COMPRESSED_NBT = of(Identifier.of("compressed_nbt"), PacketCodecs.NBT_COMPOUND); public static final TrackableDataType<NbtCompound> COMPRESSED_NBT = of(Identifier.of("compressed_nbt"), PacketCodecs.NBT_COMPOUND);
public static final TrackableDataType<Optional<PacketByteBuf>> RAW_BYTES = of(Identifier.of("raw_bytes"), PacketCodecUtils.OPTIONAL_BUFFER);
public static final TrackableDataType<Optional<BlockPos>> OPTIONAL_POS = of(Identifier.of("optional_pos"), PacketCodecUtils.OPTIONAL_POS); public static final TrackableDataType<Optional<BlockPos>> OPTIONAL_POS = of(Identifier.of("optional_pos"), PacketCodecUtils.OPTIONAL_POS);
public static final TrackableDataType<Optional<Vec3d>> OPTIONAL_VECTOR = of(Identifier.of("optional_vector"), PacketCodecUtils.OPTIONAL_VECTOR); public static final TrackableDataType<Optional<Vec3d>> OPTIONAL_VECTOR = of(Identifier.of("optional_vector"), PacketCodecUtils.OPTIONAL_VECTOR);

View file

@ -9,6 +9,7 @@ import java.util.function.Function;
import java.util.function.IntFunction; import java.util.function.IntFunction;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.RegistryByteBuf; import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec; import net.minecraft.network.codec.PacketCodec;
@ -20,17 +21,16 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
public interface PacketCodecUtils { public interface PacketCodecUtils {
PacketCodec<PacketByteBuf, PacketByteBuf> BUFFER = PacketCodec.of((bytes, buffer) -> {
buffer.writeInt(bytes.writerIndex());
buffer.writeBytes(bytes);
}, buffer -> new PacketByteBuf(buffer.readBytes(buffer.readInt())));
PacketCodec<PacketByteBuf, Optional<PacketByteBuf>> OPTIONAL_BUFFER = PacketCodecs.optional(BUFFER);
PacketCodec<RegistryByteBuf, ByteBuf> REGISTRY_BUFFER = PacketCodec.of((bytes, buffer) -> { PacketCodec<RegistryByteBuf, ByteBuf> REGISTRY_BUFFER = PacketCodec.of((bytes, buffer) -> {
buffer.writeInt(bytes.writerIndex()); int length = bytes.readableBytes();
buffer.writeBytes(bytes); buffer.writeInt(length);
}, buffer -> new RegistryByteBuf(buffer.readBytes(buffer.readInt()), buffer.getRegistryManager())); if (length > 0) {
PacketCodec<RegistryByteBuf, Optional<ByteBuf>> OPTIONAL_REGISTRY_BUFFER = PacketCodecs.optional(REGISTRY_BUFFER); buffer.writeBytes(bytes, 0, length);
}
}, buffer -> {
int length = buffer.readInt();
return new RegistryByteBuf(length > 0 ? buffer.readBytes(length) : Unpooled.EMPTY_BUFFER, buffer.getRegistryManager());
});
PacketCodec<PacketByteBuf, RegistryKey<?>> REGISTRY_KEY = PacketCodec.tuple( PacketCodec<PacketByteBuf, RegistryKey<?>> REGISTRY_KEY = PacketCodec.tuple(
Identifier.PACKET_CODEC, RegistryKey::getRegistry, Identifier.PACKET_CODEC, RegistryKey::getRegistry,