Send tracked data in smaller packets to avoid large buffer allocation warnings being printed

This commit is contained in:
Sollace 2024-05-25 14:38:17 +01:00
parent 79d97adf0b
commit 1e3560fc04
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
14 changed files with 99 additions and 123 deletions

View file

@ -64,7 +64,6 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility {
} }
player.calculateDimensions(); player.calculateDimensions();
iplayer.setDirty();
return true; return true;
} }

View file

@ -65,7 +65,6 @@ public class ToggleFlightAbility implements Ability<Hit> {
} else { } else {
player.getPhysics().cancelFlight(true); player.getPhysics().cancelFlight(true);
} }
player.setDirty();
player.setAnimation(Animation.SPREAD_WINGS, Animation.Recipient.ANYONE); player.setAnimation(Animation.SPREAD_WINGS, Animation.Recipient.ANYONE);
return true; return true;
} }

View file

@ -48,7 +48,6 @@ class GravityCommand {
static int set(ServerCommandSource source, Collection<? extends Entity> targets, float gravity, boolean isSelf) { static int set(ServerCommandSource source, Collection<? extends Entity> targets, float gravity, boolean isSelf) {
List<Entity> affected = targets.stream().map(Living::living).filter(Objects::nonNull).map(l -> { List<Entity> affected = targets.stream().map(Living::living).filter(Objects::nonNull).map(l -> {
l.getPhysics().setBaseGravityModifier(gravity); l.getPhysics().setBaseGravityModifier(gravity);
l.setDirty();
if (l.asEntity() instanceof PlayerEntity player) { if (l.asEntity() instanceof PlayerEntity player) {
if (source.getEntity() == player) { if (source.getEntity() == player) {
player.sendMessage(Text.translatable("commands.gravity.set.self", gravity)); player.sendMessage(Text.translatable("commands.gravity.set.self", gravity));

View file

@ -31,7 +31,6 @@ import com.minelittlepony.unicopia.input.Interactable;
import com.minelittlepony.unicopia.item.GlassesItem; import com.minelittlepony.unicopia.item.GlassesItem;
import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.item.UItems;
import com.minelittlepony.unicopia.item.enchantment.UEnchantments; import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
import com.minelittlepony.unicopia.network.datasync.Transmittable;
import com.minelittlepony.unicopia.network.track.DataTracker; import com.minelittlepony.unicopia.network.track.DataTracker;
import com.minelittlepony.unicopia.network.track.DataTrackerManager; import com.minelittlepony.unicopia.network.track.DataTrackerManager;
import com.minelittlepony.unicopia.network.track.Trackable; import com.minelittlepony.unicopia.network.track.Trackable;
@ -74,7 +73,7 @@ import net.minecraft.util.math.Direction;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
public abstract class Living<T extends LivingEntity> implements Equine<T>, Caster<T>, Transmittable { public abstract class Living<T extends LivingEntity> implements Equine<T>, Caster<T> {
protected final T entity; protected final T entity;
private final SpellInventory spells; private final SpellInventory spells;
@ -479,9 +478,6 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
return MathHelper.clamp(level / (float)maxLevel, 0, 1); return MathHelper.clamp(level / (float)maxLevel, 0, 1);
} }
@Override
public void setDirty() {}
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound) {
enchants.toNBT(compound); enchants.toNBT(compound);
@ -498,12 +494,10 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
fromSynchronizedNbt(compound); fromSynchronizedNbt(compound);
} }
@Override
public void toSyncronisedNbt(NbtCompound compound) { public void toSyncronisedNbt(NbtCompound compound) {
compound.put("armour", armour.toNBT()); compound.put("armour", armour.toNBT());
} }
@Override
public void fromSynchronizedNbt(NbtCompound compound) { public void fromSynchronizedNbt(NbtCompound compound) {
armour.fromNBT(compound.getCompound("armour")); armour.fromNBT(compound.getCompound("armour"));
} }

View file

@ -232,10 +232,8 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
entity.calculateDimensions(); entity.calculateDimensions();
} }
if (!pony.isClient()) {
pony.setDirty(); pony.setDirty();
} }
}
public double getHorizontalMotion() { public double getHorizontalMotion() {
return getClientVelocity().horizontalLengthSquared(); return getClientVelocity().horizontalLengthSquared();
@ -621,6 +619,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
thrustScale = 0; thrustScale = 0;
descentRate = 0; descentRate = 0;
entity.calculateDimensions(); entity.calculateDimensions();
pony.setDirty();
if (entity.isOnGround() || !force) { if (entity.isOnGround() || !force) {
//BlockState steppingState = pony.asEntity().getSteppingBlockState(); //BlockState steppingState = pony.asEntity().getSteppingBlockState();

View file

@ -175,6 +175,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
animation.animation().getSound().ifPresent(sound -> { animation.animation().getSound().ifPresent(sound -> {
playSound(sound, sound == USounds.ENTITY_PLAYER_WOLOLO ? 0.1F : 0.9F, 1); playSound(sound, sound == USounds.ENTITY_PLAYER_WOLOLO ? 0.1F : 0.9F, 1);
}); });
setDirty();
} }
} }
@ -314,7 +315,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
return getSpecies().getAffinity(); return getSpecies().getAffinity();
} }
@Override @Deprecated
public void setDirty() { public void setDirty() {
dirty = true; dirty = true;
} }

View file

@ -1,17 +1,12 @@
package com.minelittlepony.unicopia.network; package com.minelittlepony.unicopia.network;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.util.serialization.PacketCodec;
import com.sollace.fabwork.api.packets.HandledPacket; import com.sollace.fabwork.api.packets.HandledPacket;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtIo;
/** /**
* Sent to the client to update various data pertaining to a particular player. * Sent to the client to update various data pertaining to a particular player.
@ -26,11 +21,7 @@ public class MsgPlayerCapabilities implements HandledPacket<PlayerEntity> {
MsgPlayerCapabilities(PacketByteBuf buffer) { MsgPlayerCapabilities(PacketByteBuf buffer) {
playerId = buffer.readInt(); playerId = buffer.readInt();
try (InputStream in = new ByteBufInputStream(buffer)) { compoundTag = PacketCodec.COMPRESSED_NBT.read(buffer);
compoundTag = NbtIo.readCompressed(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
} }
public MsgPlayerCapabilities(Pony player) { public MsgPlayerCapabilities(Pony player) {
@ -42,10 +33,7 @@ public class MsgPlayerCapabilities implements HandledPacket<PlayerEntity> {
@Override @Override
public void toBuffer(PacketByteBuf buffer) { public void toBuffer(PacketByteBuf buffer) {
buffer.writeInt(playerId); buffer.writeInt(playerId);
try (OutputStream out = new ByteBufOutputStream(buffer)) { PacketCodec.COMPRESSED_NBT.write(buffer, compoundTag);
NbtIo.writeCompressed(compoundTag, out);
} catch (IOException e) {
}
} }
@Override @Override

View file

@ -1,11 +0,0 @@
package com.minelittlepony.unicopia.network.datasync;
import net.minecraft.nbt.NbtCompound;
public interface Transmittable {
void setDirty();
void toSyncronisedNbt(NbtCompound compound);
void fromSynchronizedNbt(NbtCompound compound);
}

View file

@ -3,7 +3,7 @@ package com.minelittlepony.unicopia.network.track;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import org.jetbrains.annotations.Nullable; import java.util.Optional;
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;
@ -75,30 +75,31 @@ public class DataTracker {
} }
} }
synchronized void getInitialPairs(List<MsgTrackedValues.TrackerEntries> output) { synchronized Optional<MsgTrackedValues.TrackerEntries> getInitialPairs() {
updateTrackables();
output.add(new MsgTrackedValues.TrackerEntries(id, true, codecs));
}
@Nullable
synchronized void getDirtyPairs(List<MsgTrackedValues.TrackerEntries> output) {
if (initial) {
initial = false; initial = false;
dirtyIndices = new IntOpenHashSet(); dirtyIndices = new IntOpenHashSet();
getInitialPairs(output); updateTrackables();
} else { return Optional.of(new MsgTrackedValues.TrackerEntries(id, true, codecs));
}
synchronized Optional<MsgTrackedValues.TrackerEntries> getDirtyPairs() {
if (initial) {
return getInitialPairs();
}
updateTrackables(); updateTrackables();
if (!dirtyIndices.isEmpty()) { if (dirtyIndices.isEmpty()) {
return Optional.empty();
}
IntSet toSend = dirtyIndices; IntSet toSend = dirtyIndices;
dirtyIndices = new IntOpenHashSet(); dirtyIndices = new IntOpenHashSet();
List<Pair<?>> pairs = new ArrayList<>(); List<Pair<?>> pairs = new ArrayList<>();
for (int i : toSend) { for (int i : toSend) {
pairs.add(codecs.get(i)); pairs.add(codecs.get(i));
} }
output.add(new MsgTrackedValues.TrackerEntries(id, false, pairs)); return Optional.of(new MsgTrackedValues.TrackerEntries(id, false, pairs));
}
}
} }
synchronized void load(MsgTrackedValues.TrackerEntries values) { synchronized void load(MsgTrackedValues.TrackerEntries values) {

View file

@ -1,7 +1,7 @@
package com.minelittlepony.unicopia.network.track; package com.minelittlepony.unicopia.network.track;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -19,7 +19,6 @@ public class DataTrackerManager {
final boolean isClient; final boolean isClient;
private final List<DataTracker> trackers = new ObjectArrayList<>(); private final List<DataTracker> trackers = new ObjectArrayList<>();
private final List<ObjectTracker<?>> objectTrackers = new ObjectArrayList<>(); private final List<ObjectTracker<?>> objectTrackers = new ObjectArrayList<>();
private final List<PacketEmitter> packetEmitters = new ObjectArrayList<>(); private final List<PacketEmitter> packetEmitters = new ObjectArrayList<>();
@Nullable @Nullable
@ -44,12 +43,32 @@ public class DataTrackerManager {
public synchronized DataTracker checkoutTracker() { public synchronized DataTracker checkoutTracker() {
DataTracker tracker = new DataTracker(this, trackers.size()); DataTracker tracker = new DataTracker(this, trackers.size());
trackers.add(tracker); trackers.add(tracker);
packetEmitters.add((sender, initial) -> {
var update = initial ? tracker.getInitialPairs() : tracker.getDirtyPairs();
if (update.isPresent()) {
sender.accept(Channel.SERVER_TRACKED_ENTITY_DATA.toPacket(new MsgTrackedValues(
entity.getId(),
Optional.empty(),
update
)));
}
});
return tracker; return tracker;
} }
public synchronized <T extends TrackableObject> ObjectTracker<T> checkoutTracker(Supplier<T> objFunction) { public synchronized <T extends TrackableObject> ObjectTracker<T> checkoutTracker(Supplier<T> objFunction) {
ObjectTracker<T> tracker = new ObjectTracker<>(objectTrackers.size(), objFunction); ObjectTracker<T> tracker = new ObjectTracker<>(objectTrackers.size(), objFunction);
objectTrackers.add(tracker); objectTrackers.add(tracker);
packetEmitters.add((sender, initial) -> {
var update = initial ? tracker.getInitialPairs() : tracker.getDirtyPairs();
if (update.isPresent()) {
sender.accept(Channel.SERVER_TRACKED_ENTITY_DATA.toPacket(new MsgTrackedValues(
entity.getId(),
update,
Optional.empty()
)));
}
});
return tracker; return tracker;
} }
@ -58,25 +77,6 @@ public class DataTrackerManager {
for (var emitter : packetEmitters) { for (var emitter : packetEmitters) {
emitter.sendPackets(sender, false); emitter.sendPackets(sender, false);
} }
if (trackers.isEmpty() && objectTrackers.isEmpty()) {
return;
}
List<MsgTrackedValues.TrackerEntries> toTransmit = new ArrayList<>();
List<MsgTrackedValues.TrackerObjects> objToTransmit = new ArrayList<>();
for (var entry : trackers) entry.getDirtyPairs(toTransmit);
for (var entry : objectTrackers) entry.getDirtyPairs(objToTransmit);
if (!toTransmit.isEmpty() || !objToTransmit.isEmpty()) {
MsgTrackedValues packet = new MsgTrackedValues(
entity.getId(),
objToTransmit,
toTransmit
);
sender.accept(Channel.SERVER_TRACKED_ENTITY_DATA.toPacket(packet));
}
} }
} }
@ -86,41 +86,22 @@ public class DataTrackerManager {
for (var emitter : packetEmitters) { for (var emitter : packetEmitters) {
emitter.sendPackets((Consumer)sender, true); emitter.sendPackets((Consumer)sender, true);
} }
if (trackers.isEmpty() && objectTrackers.isEmpty()) {
return;
}
List<MsgTrackedValues.TrackerEntries> toTransmit = new ArrayList<>();
List<MsgTrackedValues.TrackerObjects> objToTransmit = new ArrayList<>();
for (var entry : trackers) entry.getInitialPairs(toTransmit);
for (var entry : objectTrackers) entry.getInitialPairs(objToTransmit);
if (!toTransmit.isEmpty() || !objToTransmit.isEmpty()) {
MsgTrackedValues packet = new MsgTrackedValues(
entity.getId(),
objToTransmit,
toTransmit
);
sender.accept(Channel.SERVER_TRACKED_ENTITY_DATA.toPacket(packet));
}
} }
} }
synchronized void load(MsgTrackedValues packet) { synchronized void load(MsgTrackedValues packet) {
for (var update : packet.updatedTrackers()) { packet.updatedTrackers().ifPresent(update -> {
DataTracker tracker = trackers.get(update.id()); DataTracker tracker = trackers.get(update.id());
if (tracker != null) { if (tracker != null) {
tracker.load(update); tracker.load(update);
} }
} });
for (var update : packet.updatedObjects()) { packet.updatedObjects().ifPresent(update -> {
ObjectTracker<?> tracker = objectTrackers.get(update.id()); ObjectTracker<?> tracker = objectTrackers.get(update.id());
if (tracker != null) { if (tracker != null) {
tracker.load(update); tracker.load(update);
} }
} });
} }
public interface PacketEmitter { public interface PacketEmitter {

View file

@ -5,9 +5,11 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import com.minelittlepony.unicopia.util.serialization.PacketCodec;
import com.sollace.fabwork.api.packets.HandledPacket; import com.sollace.fabwork.api.packets.HandledPacket;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
@ -17,22 +19,22 @@ import net.minecraft.network.PacketByteBuf;
public record MsgTrackedValues( public record MsgTrackedValues(
int owner, int owner,
List<TrackerObjects> updatedObjects, Optional<TrackerObjects> updatedObjects,
List<TrackerEntries> updatedTrackers Optional<TrackerEntries> updatedTrackers
) implements HandledPacket<PlayerEntity> { ) implements HandledPacket<PlayerEntity> {
public MsgTrackedValues(PacketByteBuf buffer) { public MsgTrackedValues(PacketByteBuf buffer) {
this( this(
buffer.readInt(), buffer.readInt(),
buffer.readCollection(ArrayList::new, TrackerObjects::new), buffer.readOptional(TrackerObjects::new),
buffer.readCollection(ArrayList::new, TrackerEntries::new) buffer.readOptional(TrackerEntries::new)
); );
} }
@Override @Override
public void toBuffer(PacketByteBuf buffer) { public void toBuffer(PacketByteBuf buffer) {
buffer.writeInt(owner); buffer.writeInt(owner);
buffer.writeCollection(updatedObjects, (buf, obj) -> obj.write(buf)); buffer.writeOptional(updatedObjects, (buf, obj) -> obj.write(buf));
buffer.writeCollection(updatedTrackers, (buf, tracker) -> tracker.write(buf)); buffer.writeOptional(updatedTrackers, (buf, tracker) -> tracker.write(buf));
} }
@Override @Override
@ -48,14 +50,15 @@ public record MsgTrackedValues(
this( this(
buffer.readInt(), buffer.readInt(),
buffer.readCollection(HashSet::new, PacketByteBuf::readUuid), buffer.readCollection(HashSet::new, PacketByteBuf::readUuid),
buffer.readMap(HashMap::new, PacketByteBuf::readUuid, PacketByteBuf::readNbt) buffer.readMap(HashMap::new, PacketByteBuf::readUuid, PacketCodec.NBT::read)
); );
} }
public void write(PacketByteBuf buffer) { public void write(PacketByteBuf buffer) {
buffer.writeInt(id); buffer.writeInt(id);
buffer.writeCollection(removedValues, PacketByteBuf::writeUuid); buffer.writeCollection(removedValues, PacketByteBuf::writeUuid);
buffer.writeMap(values, PacketByteBuf::writeUuid, PacketByteBuf::writeNbt); buffer.writeMap(values, PacketByteBuf::writeUuid, PacketCodec.NBT::write);
} }
} }

View file

@ -3,8 +3,8 @@ package com.minelittlepony.unicopia.network.track;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -73,18 +73,20 @@ public class ObjectTracker<T extends TrackableObject> implements NbtSerialisable
quickAccess = Map.copyOf(trackedObjects); quickAccess = Map.copyOf(trackedObjects);
} }
synchronized void getInitialPairs(List<MsgTrackedValues.TrackerObjects> output) { synchronized Optional<MsgTrackedValues.TrackerObjects> getInitialPairs() {
if (!trackedObjects.isEmpty()) { if (trackedObjects.isEmpty()) {
return Optional.empty();
}
Map<UUID, NbtCompound> trackableCompounds = new HashMap<>(); Map<UUID, NbtCompound> trackableCompounds = new HashMap<>();
quickAccess.entrySet().forEach(object -> { quickAccess.entrySet().forEach(object -> {
trackableCompounds.put(object.getKey(), object.getValue().toTrackedNbt()); trackableCompounds.put(object.getKey(), object.getValue().toTrackedNbt());
}); });
output.add(new MsgTrackedValues.TrackerObjects(id, Set.of(), trackableCompounds)); return Optional.of(new MsgTrackedValues.TrackerObjects(id, Set.of(), trackableCompounds));
}
} }
synchronized void getDirtyPairs(List<MsgTrackedValues.TrackerObjects> output) { synchronized Optional<MsgTrackedValues.TrackerObjects> getDirtyPairs() {
if (!trackedObjects.isEmpty()) { if (!trackedObjects.isEmpty()) {
Map<UUID, NbtCompound> trackableCompounds = new HashMap<>(); Map<UUID, NbtCompound> trackableCompounds = new HashMap<>();
Set<UUID> removedTrackableObjects = new HashSet<>(); Set<UUID> removedTrackableObjects = new HashSet<>();
@ -100,9 +102,11 @@ public class ObjectTracker<T extends TrackableObject> implements NbtSerialisable
quickAccess = Map.copyOf(trackedObjects); quickAccess = Map.copyOf(trackedObjects);
if (!trackableCompounds.isEmpty() || !removedTrackableObjects.isEmpty()) { if (!trackableCompounds.isEmpty() || !removedTrackableObjects.isEmpty()) {
output.add(new MsgTrackedValues.TrackerObjects(id, removedTrackableObjects, trackableCompounds)); return Optional.of(new MsgTrackedValues.TrackerObjects(id, removedTrackableObjects, trackableCompounds));
} }
} }
return Optional.empty();
} }
synchronized void load(MsgTrackedValues.TrackerObjects objects) { synchronized void load(MsgTrackedValues.TrackerObjects objects) {

View file

@ -22,6 +22,7 @@ public record TrackableDataType<T>(int id, PacketCodec<T> codec) {
public static final TrackableDataType<Boolean> BOOLEAN = of(new Identifier("boolean"), PacketCodec.BOOLEAN); public static final TrackableDataType<Boolean> BOOLEAN = of(new Identifier("boolean"), PacketCodec.BOOLEAN);
public static final TrackableDataType<UUID> UUID = of(new Identifier("uuid"), PacketCodec.UUID); public static final TrackableDataType<UUID> UUID = of(new Identifier("uuid"), PacketCodec.UUID);
public static final TrackableDataType<NbtCompound> NBT = of(new Identifier("nbt"), PacketCodec.NBT); public static final TrackableDataType<NbtCompound> NBT = of(new Identifier("nbt"), PacketCodec.NBT);
public static final TrackableDataType<NbtCompound> COMPRESSED_NBT = of(new Identifier("compressed_nbt"), PacketCodec.COMPRESSED_NBT);
public static final TrackableDataType<Optional<BlockPos>> OPTIONAL_POS = of(new Identifier("optional_pos"), PacketCodec.OPTIONAL_POS); public static final TrackableDataType<Optional<BlockPos>> OPTIONAL_POS = of(new Identifier("optional_pos"), PacketCodec.OPTIONAL_POS);
public static final TrackableDataType<Race> RACE = TrackableDataType.of(Unicopia.id("race"), PacketCodec.ofRegistry(Race.REGISTRY)); public static final TrackableDataType<Race> RACE = TrackableDataType.of(Unicopia.id("race"), PacketCodec.ofRegistry(Race.REGISTRY));

View file

@ -1,5 +1,8 @@
package com.minelittlepony.unicopia.util.serialization; package com.minelittlepony.unicopia.util.serialization;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
@ -7,7 +10,10 @@ import java.util.function.BiFunction;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtIo;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.registry.Registry; import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@ -27,6 +33,18 @@ public record PacketCodec<T>(PacketByteBuf.PacketReader<T> reader, PacketByteBuf
public static final PacketCodec<Identifier> IDENTIFIER = STRING.xMap(Identifier::new, Identifier::toString); public static final PacketCodec<Identifier> IDENTIFIER = STRING.xMap(Identifier::new, Identifier::toString);
public static final PacketCodec<NbtCompound> NBT = new PacketCodec<>(PacketByteBuf::readNbt, PacketByteBuf::writeNbt); public static final PacketCodec<NbtCompound> NBT = new PacketCodec<>(PacketByteBuf::readNbt, PacketByteBuf::writeNbt);
public static final PacketCodec<NbtCompound> COMPRESSED_NBT = new PacketCodec<>(buffer -> {
try (InputStream in = new ByteBufInputStream(buffer)) {
return NbtIo.readCompressed(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
}, (buffer, nbt) -> {
try (OutputStream out = new ByteBufOutputStream(buffer)) {
NbtIo.writeCompressed(nbt, out);
} catch (IOException e) {
}
});
public static final PacketCodec<BlockPos> POS = new PacketCodec<>(PacketByteBuf::readBlockPos, PacketByteBuf::writeBlockPos); public static final PacketCodec<BlockPos> POS = new PacketCodec<>(PacketByteBuf::readBlockPos, PacketByteBuf::writeBlockPos);
public static final PacketCodec<Optional<BlockPos>> OPTIONAL_POS = POS.asOptional(); public static final PacketCodec<Optional<BlockPos>> OPTIONAL_POS = POS.asOptional();