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

View file

@ -1,5 +1,6 @@
package com.minelittlepony.unicopia.network.track;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@ -24,7 +25,7 @@ public record MsgTrackedValues(
int owner,
Optional<TrackerObjects> updatedObjects,
Optional<TrackerEntries> updatedTrackers
) implements Handled<PlayerEntity> {
) implements Handled<PlayerEntity>, AutoCloseable {
public static final PacketCodec<RegistryByteBuf, MsgTrackedValues> PACKET_CODEC = PacketCodec.tuple(
PacketCodecs.INTEGER, MsgTrackedValues::owner,
PacketCodecs.optional(TrackerObjects.PACKET_CODEC), MsgTrackedValues::updatedObjects,
@ -34,22 +35,33 @@ public record MsgTrackedValues(
@Override
public void handle(PlayerEntity sender) {
Entity entity = sender.getWorld().getEntityById(owner);
if (entity instanceof Trackable trackable) {
trackable.getDataTrackers().load(this);
try (this) {
Entity entity = sender.getWorld().getEntityById(owner);
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(
PacketCodecs.INTEGER, TrackerObjects::id,
Uuids.PACKET_CODEC.collect(PacketCodecs.toCollection(HashSet::new)), TrackerObjects::removedValues,
PacketCodecs.map(HashMap::new, Uuids.PACKET_CODEC, PacketCodecUtils.REGISTRY_BUFFER), TrackerObjects::values,
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(
PacketCodecs.INTEGER, TrackerEntries::id,
PacketCodecs.BOOL, TrackerEntries::wipe,
@ -57,5 +69,20 @@ public record MsgTrackedValues(
PacketCodecs.map(HashMap::new, PacketCodecs.INTEGER, PacketCodecUtils.REGISTRY_BUFFER), TrackerEntries::objects,
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.Int2ObjectOpenHashMap;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
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<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<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<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 io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
@ -20,17 +21,16 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
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) -> {
buffer.writeInt(bytes.writerIndex());
buffer.writeBytes(bytes);
}, buffer -> new RegistryByteBuf(buffer.readBytes(buffer.readInt()), buffer.getRegistryManager()));
PacketCodec<RegistryByteBuf, Optional<ByteBuf>> OPTIONAL_REGISTRY_BUFFER = PacketCodecs.optional(REGISTRY_BUFFER);
int length = bytes.readableBytes();
buffer.writeInt(length);
if (length > 0) {
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(
Identifier.PACKET_CODEC, RegistryKey::getRegistry,