mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Fix some packet serializing issues
This commit is contained in:
parent
b2f0a846de
commit
0e2b0bcc34
11 changed files with 89 additions and 83 deletions
|
@ -10,7 +10,6 @@ import com.google.common.base.Strings;
|
|||
import com.minelittlepony.unicopia.ability.Abilities;
|
||||
import com.minelittlepony.unicopia.ability.Ability;
|
||||
import com.minelittlepony.unicopia.ability.magic.Affine;
|
||||
import com.minelittlepony.unicopia.network.track.TrackableDataType;
|
||||
import com.minelittlepony.unicopia.util.RegistryUtils;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
|
@ -45,7 +44,6 @@ public record Race (
|
|||
public static final String DEFAULT_ID = "unicopia:unset";
|
||||
public static final Registry<Race> REGISTRY = RegistryUtils.createDefaulted(Unicopia.id("race"), DEFAULT_ID);
|
||||
public static final Registry<Race> COMMAND_REGISTRY = RegistryUtils.createDefaulted(Unicopia.id("race/grantable"), DEFAULT_ID);
|
||||
public static final TrackableDataType<Race> TRACKABLE_TYPE = TrackableDataType.RACE;
|
||||
public static final RegistryKey<? extends Registry<Race>> REGISTRY_KEY = REGISTRY.getKey();
|
||||
private static final DynamicCommandExceptionType UNKNOWN_RACE_EXCEPTION = new DynamicCommandExceptionType(id -> Text.translatable("commands.race.fail", id));
|
||||
private static final Function<Race, Composite> COMPOSITES = Util.memoize(race -> new Composite(race, null, null));
|
||||
|
|
|
@ -17,9 +17,10 @@ import com.minelittlepony.unicopia.network.track.TrackableObject;
|
|||
import com.minelittlepony.unicopia.network.track.MsgTrackedValues.TrackerEntries;
|
||||
import com.minelittlepony.unicopia.util.serialization.NbtSerialisable;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.network.RegistryByteBuf;
|
||||
import net.minecraft.network.codec.PacketCodecs;
|
||||
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
|
||||
|
||||
|
@ -147,22 +148,24 @@ class MultiSpellSlot implements SpellSlots, NbtSerialisable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void read(PacketByteBuf buffer, WrapperLookup lookup) {
|
||||
public void read(ByteBuf buffer, WrapperLookup lookup) {
|
||||
byte contentType = buffer.readByte();
|
||||
if (contentType == 1) {
|
||||
readTrackedNbt(PacketCodecs.NBT_COMPOUND.decode(buffer), lookup);
|
||||
} else {
|
||||
T spell = this.spell.get();
|
||||
if (spell != null) {
|
||||
spell.getDataTracker().load(MsgTrackedValues.TrackerEntries.PACKET_CODEC.decode(buffer), lookup);
|
||||
spell.getDataTracker().load(MsgTrackedValues.TrackerEntries.PACKET_CODEC.decode(
|
||||
buffer instanceof RegistryByteBuf r ? r : new RegistryByteBuf(buffer, owner.asEntity().getRegistryManager())
|
||||
), lookup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<PacketByteBuf> write(Status status, WrapperLookup lookup) {
|
||||
public Optional<? extends ByteBuf> write(Status status, WrapperLookup lookup) {
|
||||
if (status != Status.DEFAULT) {
|
||||
PacketByteBuf buffer = new PacketByteBuf(Unpooled.buffer());
|
||||
ByteBuf buffer = Unpooled.buffer();
|
||||
buffer.writeByte(1);
|
||||
PacketCodecs.NBT_COMPOUND.encode(buffer, spell.toNBT(lookup));
|
||||
return Optional.of(buffer);
|
||||
|
@ -172,7 +175,7 @@ class MultiSpellSlot implements SpellSlots, NbtSerialisable {
|
|||
return Optional.empty();
|
||||
}
|
||||
return spell.getDataTracker().getDirtyPairs(lookup).map(entries -> {
|
||||
PacketByteBuf buffer = new PacketByteBuf(Unpooled.buffer());
|
||||
RegistryByteBuf buffer = new RegistryByteBuf(Unpooled.buffer(), owner.asEntity().getRegistryManager());
|
||||
buffer.writeByte(0);
|
||||
TrackerEntries.PACKET_CODEC.encode(buffer, entries);
|
||||
return buffer;
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
|||
import com.minelittlepony.unicopia.network.track.DataTracker;
|
||||
import com.minelittlepony.unicopia.network.track.DataTrackerManager;
|
||||
import com.minelittlepony.unicopia.network.track.Trackable;
|
||||
import com.minelittlepony.unicopia.network.track.TrackableDataType;
|
||||
import com.minelittlepony.unicopia.particle.FollowingParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||
import com.minelittlepony.unicopia.particle.UParticles;
|
||||
|
@ -39,7 +40,7 @@ public class ItemImpl implements Equine<ItemEntity> {
|
|||
this.tracker = trackers.getPrimaryTracker();
|
||||
this.physics = new ItemPhysics(owner);
|
||||
|
||||
race = tracker.startTracking(Race.TRACKABLE_TYPE, Race.HUMAN);
|
||||
race = tracker.startTracking(TrackableDataType.RACE, Race.HUMAN);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -37,6 +37,7 @@ import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
|||
import com.minelittlepony.unicopia.util.*;
|
||||
import com.minelittlepony.unicopia.network.*;
|
||||
import com.minelittlepony.unicopia.network.track.DataTracker;
|
||||
import com.minelittlepony.unicopia.network.track.TrackableDataType;
|
||||
import com.minelittlepony.unicopia.server.world.UGameRules;
|
||||
import com.minelittlepony.common.util.animation.LinearInterpolator;
|
||||
import com.google.common.collect.Streams;
|
||||
|
@ -121,8 +122,8 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
}
|
||||
});
|
||||
|
||||
race = this.tracker.startTracking(Race.TRACKABLE_TYPE, Race.UNSET);
|
||||
suppressedRace = this.tracker.startTracking(Race.TRACKABLE_TYPE, Race.UNSET);
|
||||
race = this.tracker.startTracking(TrackableDataType.RACE, Race.UNSET);
|
||||
suppressedRace = this.tracker.startTracking(TrackableDataType.RACE, Race.UNSET);
|
||||
this.levels = new PlayerLevelStore(this, tracker, true, USounds.Vanilla.ENTITY_PLAYER_LEVELUP);
|
||||
this.corruption = new PlayerLevelStore(this, tracker, false, USounds.ENTITY_PLAYER_CORRUPTION);
|
||||
this.mana = addTicker(new ManaContainer(this, tracker));
|
||||
|
|
|
@ -7,11 +7,15 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.minelittlepony.unicopia.util.Untyped;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.network.RegistryByteBuf;
|
||||
import net.minecraft.network.codec.PacketCodec;
|
||||
import net.minecraft.network.codec.PacketCodecs;
|
||||
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
|
||||
|
||||
public class DataTracker {
|
||||
|
@ -44,14 +48,14 @@ public class DataTracker {
|
|||
}
|
||||
|
||||
private <T> T get(Entry<T> entry) {
|
||||
return getPair(entry).value;
|
||||
return getPair(entry).value.value;
|
||||
}
|
||||
|
||||
private <T> void set(Entry<T> entry, T value) {
|
||||
Pair<T> pair = getPair(entry);
|
||||
if (!Objects.equals(pair.value, value)) {
|
||||
synchronized (this) {
|
||||
pair.value = value;
|
||||
pair.value.value = value;
|
||||
dirtyIndices.add(entry.id());
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +64,7 @@ public class DataTracker {
|
|||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
synchronized void copyTo(DataTracker destination) {
|
||||
for (int i = 0; i < codecs.size(); i++) {
|
||||
((Pair<Object>)destination.codecs.get(i)).value = codecs.get(i).value;
|
||||
((Pair<Object>)destination.codecs.get(i)).value.value = codecs.get(i).value.value;
|
||||
if (i < persistentObjects.size() && i < destination.persistentObjects.size()) {
|
||||
TrackableObject<?> a = persistentObjects.get(i);
|
||||
TrackableObject<?> b = destination.persistentObjects.get(i);
|
||||
|
@ -74,7 +78,7 @@ public class DataTracker {
|
|||
synchronized Optional<MsgTrackedValues.TrackerEntries> getInitialPairs(WrapperLookup lookup) {
|
||||
initial = false;
|
||||
dirtyIndices = new IntOpenHashSet();
|
||||
return Optional.of(new MsgTrackedValues.TrackerEntries(id, true, codecs, writePersistentObjects(lookup, true)));
|
||||
return Optional.of(new MsgTrackedValues.TrackerEntries(id, true, codecs, Untyped.cast(writePersistentObjects(lookup, true))));
|
||||
}
|
||||
|
||||
public synchronized Optional<MsgTrackedValues.TrackerEntries> getDirtyPairs(WrapperLookup lookup) {
|
||||
|
@ -82,7 +86,7 @@ public class DataTracker {
|
|||
return getInitialPairs(lookup);
|
||||
}
|
||||
|
||||
Map<Integer, PacketByteBuf> updates = writePersistentObjects(lookup, false);
|
||||
Map<Integer, ByteBuf> updates = writePersistentObjects(lookup, false);
|
||||
|
||||
if (dirtyIndices.isEmpty() && updates.isEmpty()) {
|
||||
return Optional.empty();
|
||||
|
@ -94,11 +98,11 @@ public class DataTracker {
|
|||
for (int i : toSend) {
|
||||
pairs.add(codecs.get(i));
|
||||
}
|
||||
return Optional.of(new MsgTrackedValues.TrackerEntries(id, false, pairs, updates));
|
||||
return Optional.of(new MsgTrackedValues.TrackerEntries(id, false, pairs, Untyped.cast(updates)));
|
||||
}
|
||||
|
||||
private Map<Integer, PacketByteBuf> writePersistentObjects(WrapperLookup lookup, boolean initial) {
|
||||
Map<Integer, PacketByteBuf> updates = new HashMap<>();
|
||||
private Map<Integer, ByteBuf> writePersistentObjects(WrapperLookup lookup, boolean initial) {
|
||||
Map<Integer, ByteBuf> updates = new HashMap<>();
|
||||
for (int i = 0; i < persistentObjects.size(); i++) {
|
||||
TrackableObject<?> o = persistentObjects.get(i);
|
||||
TrackableObject.Status status = initial ? TrackableObject.Status.NEW : o.getStatus();
|
||||
|
@ -115,7 +119,7 @@ public class DataTracker {
|
|||
} else {
|
||||
for (var value : values.values()) {
|
||||
if (value.id >= 0 && value.id < codecs.size()) {
|
||||
if (codecs.get(value.id).type == value.type) {
|
||||
if (codecs.get(value.id).value.type == value.value.type) {
|
||||
codecs.set(value.id, value);
|
||||
}
|
||||
}
|
||||
|
@ -140,28 +144,16 @@ public class DataTracker {
|
|||
}
|
||||
}
|
||||
|
||||
static class Pair<T> {
|
||||
public static final PacketCodec<PacketByteBuf, Pair<?>> PACKET_CODEC = PacketCodec.ofStatic((buffer, pair) -> pair.write(buffer), Pair::new);
|
||||
|
||||
private final TrackableDataType<T> type;
|
||||
public final int id;
|
||||
public T value;
|
||||
record Pair<T> (int id, TrackableDataType.TypedValue<T> value) {
|
||||
@SuppressWarnings("unchecked")
|
||||
public static final PacketCodec<RegistryByteBuf, Pair<?>> PACKET_CODEC = PacketCodec.tuple(
|
||||
PacketCodecs.INTEGER, Pair::id,
|
||||
TrackableDataType.PACKET_CODEC, Pair::value,
|
||||
Pair::new
|
||||
);
|
||||
|
||||
public Pair(int id, TrackableDataType<T> type, T value) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private Pair(PacketByteBuf buffer) {
|
||||
this.id = buffer.readInt();
|
||||
this.type = TrackableDataType.of(buffer);
|
||||
this.value = type.read(buffer);
|
||||
}
|
||||
|
||||
private void write(PacketByteBuf buffer) {
|
||||
buffer.writeInt(id);
|
||||
type.write(buffer, value);
|
||||
this(id, new TrackableDataType.TypedValue<>(type, value));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@ import java.util.Optional;
|
|||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.network.Channel;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.entity.Entity;
|
||||
|
@ -23,13 +21,13 @@ public class DataTrackerManager {
|
|||
private final List<ObjectTracker<?>> objectTrackers = new ObjectArrayList<>();
|
||||
private final List<PacketEmitter> packetEmitters = new ObjectArrayList<>();
|
||||
|
||||
@Nullable
|
||||
private DataTracker primaryTracker;
|
||||
|
||||
public DataTrackerManager(Entity entity) {
|
||||
this.entity = entity;
|
||||
this.lookup = entity.getWorld().getRegistryManager();
|
||||
this.isClient = entity.getWorld().isClient;
|
||||
this.primaryTracker = checkoutTracker();
|
||||
}
|
||||
|
||||
public synchronized void addPacketEmitter(PacketEmitter packetEmitter) {
|
||||
|
@ -37,9 +35,6 @@ public class DataTrackerManager {
|
|||
}
|
||||
|
||||
public DataTracker getPrimaryTracker() {
|
||||
if (primaryTracker == null) {
|
||||
primaryTracker = checkoutTracker();
|
||||
}
|
||||
return primaryTracker;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,9 +11,11 @@ import java.util.UUID;
|
|||
|
||||
import com.minelittlepony.unicopia.util.serialization.PacketCodecUtils;
|
||||
import com.sollace.fabwork.api.packets.Handled;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.network.RegistryByteBuf;
|
||||
import net.minecraft.network.codec.PacketCodec;
|
||||
import net.minecraft.network.codec.PacketCodecs;
|
||||
import net.minecraft.util.Uuids;
|
||||
|
@ -23,7 +25,7 @@ public record MsgTrackedValues(
|
|||
Optional<TrackerObjects> updatedObjects,
|
||||
Optional<TrackerEntries> updatedTrackers
|
||||
) implements Handled<PlayerEntity> {
|
||||
public static final PacketCodec<PacketByteBuf, MsgTrackedValues> PACKET_CODEC = PacketCodec.tuple(
|
||||
public static final PacketCodec<RegistryByteBuf, MsgTrackedValues> PACKET_CODEC = PacketCodec.tuple(
|
||||
PacketCodecs.INTEGER, MsgTrackedValues::owner,
|
||||
PacketCodecs.optional(TrackerObjects.PACKET_CODEC), MsgTrackedValues::updatedObjects,
|
||||
PacketCodecs.optional(TrackerEntries.PACKET_CODEC), MsgTrackedValues::updatedTrackers,
|
||||
|
@ -38,21 +40,21 @@ public record MsgTrackedValues(
|
|||
}
|
||||
}
|
||||
|
||||
public record TrackerObjects(int id, Set<UUID> removedValues, Map<UUID, PacketByteBuf> values) {
|
||||
public static final PacketCodec<PacketByteBuf, TrackerObjects> PACKET_CODEC = PacketCodec.tuple(
|
||||
public record TrackerObjects(int id, Set<UUID> removedValues, Map<UUID, ByteBuf> values) {
|
||||
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.BUFFER), TrackerObjects::values,
|
||||
PacketCodecs.map(HashMap::new, Uuids.PACKET_CODEC, PacketCodecUtils.REGISTRY_BUFFER), TrackerObjects::values,
|
||||
TrackerObjects::new
|
||||
);
|
||||
}
|
||||
|
||||
public record TrackerEntries(int id, boolean wipe, List<DataTracker.Pair<?>> values, Map<Integer, PacketByteBuf> objects) {
|
||||
public static final PacketCodec<PacketByteBuf, TrackerEntries> PACKET_CODEC = PacketCodec.tuple(
|
||||
public record TrackerEntries(int id, boolean wipe, List<DataTracker.Pair<?>> values, Map<Integer, ByteBuf> objects) {
|
||||
public static final PacketCodec<RegistryByteBuf, TrackerEntries> PACKET_CODEC = PacketCodec.tuple(
|
||||
PacketCodecs.INTEGER, TrackerEntries::id,
|
||||
PacketCodecs.BOOL, TrackerEntries::wipe,
|
||||
DataTracker.Pair.PACKET_CODEC.collect(PacketCodecs.toCollection(ArrayList::new)), TrackerEntries::values,
|
||||
PacketCodecs.map(HashMap::new, PacketCodecs.INTEGER, PacketCodecUtils.BUFFER), TrackerEntries::objects,
|
||||
PacketCodecs.map(HashMap::new, PacketCodecs.INTEGER, PacketCodecUtils.REGISTRY_BUFFER), TrackerEntries::objects,
|
||||
TrackerEntries::new
|
||||
);
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@ import java.util.function.Supplier;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.network.track.TrackableObject.Status;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
|
||||
|
||||
public class ObjectTracker<T extends TrackableObject<T>> {
|
||||
|
@ -89,7 +89,7 @@ public class ObjectTracker<T extends TrackableObject<T>> {
|
|||
return Optional.empty();
|
||||
}
|
||||
|
||||
Map<UUID, PacketByteBuf> updates = new HashMap<>();
|
||||
Map<UUID, ByteBuf> updates = new HashMap<>();
|
||||
quickAccess.entrySet().forEach(object -> {
|
||||
object.getValue().write(Status.NEW, lookup).ifPresent(data -> {
|
||||
updates.put(object.getKey(), data);
|
||||
|
@ -101,7 +101,7 @@ public class ObjectTracker<T extends TrackableObject<T>> {
|
|||
|
||||
synchronized Optional<MsgTrackedValues.TrackerObjects> getDirtyPairs(WrapperLookup lookup) {
|
||||
if (!trackedObjects.isEmpty()) {
|
||||
Map<UUID, PacketByteBuf> updates = new HashMap<>();
|
||||
Map<UUID, ByteBuf> updates = new HashMap<>();
|
||||
Set<UUID> removedTrackableObjects = new HashSet<>();
|
||||
trackedObjects.entrySet().removeIf(object -> {
|
||||
TrackableObject.Status status = object.getValue().getStatus();
|
||||
|
|
|
@ -2,17 +2,19 @@ package com.minelittlepony.unicopia.network.track;
|
|||
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.util.Untyped;
|
||||
import com.minelittlepony.unicopia.util.serialization.PacketCodecUtils;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
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;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
|
@ -21,8 +23,12 @@ import net.minecraft.util.Uuids;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public record TrackableDataType<T>(int id, PacketCodec<PacketByteBuf, T> codec) {
|
||||
public record TrackableDataType<T>(int id, PacketCodec<RegistryByteBuf, TypedValue<T>> codec) {
|
||||
private static final Int2ObjectMap<TrackableDataType<?>> REGISTRY = new Int2ObjectOpenHashMap<>();
|
||||
public static final PacketCodec<RegistryByteBuf, TypedValue<?>> PACKET_CODEC = PacketCodecs.INTEGER.<RegistryByteBuf>cast().xmap(
|
||||
id -> Objects.requireNonNull(REGISTRY.get(id.intValue()), "Unknown trackable data type id: " + id),
|
||||
type -> type.id()
|
||||
).dispatch(value -> Untyped.cast(value.type), TrackableDataType::codec);
|
||||
|
||||
public static final TrackableDataType<Integer> INT = of(Identifier.of("integer"), PacketCodecs.INTEGER);
|
||||
public static final TrackableDataType<Float> FLOAT = of(Identifier.of("float"), PacketCodecs.FLOAT);
|
||||
|
@ -36,30 +42,30 @@ public record TrackableDataType<T>(int id, PacketCodec<PacketByteBuf, T> codec)
|
|||
public static final TrackableDataType<Optional<Vec3d>> OPTIONAL_VECTOR = of(Identifier.of("optional_vector"), PacketCodecUtils.OPTIONAL_VECTOR);
|
||||
private static final TrackableDataType<Optional<RegistryKey<?>>> OPTIONAL_REGISTRY_KEY = of(Identifier.of("optional_registry_key"), PacketCodecUtils.OPTIONAL_REGISTRY_KEY);
|
||||
|
||||
public static final TrackableDataType<Race> RACE = TrackableDataType.of(Unicopia.id("race"), PacketCodecs.registryValue(Race.REGISTRY_KEY));
|
||||
public static final TrackableDataType<Race> RACE = of(Unicopia.id("race"), PacketCodecs.registryValue(Race.REGISTRY_KEY));
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public static <T> TrackableDataType<Optional<RegistryKey<T>>> ofRegistryKey() {
|
||||
return (TrackableDataType)OPTIONAL_REGISTRY_KEY;
|
||||
return Untyped.cast(OPTIONAL_REGISTRY_KEY);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> TrackableDataType<T> of(PacketByteBuf buffer) {
|
||||
int id = buffer.readInt();
|
||||
return Objects.requireNonNull((TrackableDataType<T>)REGISTRY.get(id), "Unknown trackable data type id: " + id);
|
||||
public static <T> TrackableDataType<T> of(Identifier typeName, PacketCodec<? super RegistryByteBuf, T> codec) {
|
||||
return Untyped.cast(REGISTRY.computeIfAbsent(typeName.hashCode(), t -> {
|
||||
AtomicReference<TrackableDataType<T>> ref = new AtomicReference<>();
|
||||
ref.set(new TrackableDataType<>(t, codec.<RegistryByteBuf>cast().xmap(
|
||||
value -> new TypedValue<>(ref.get(), value),
|
||||
value -> value.value
|
||||
)));
|
||||
return ref.get();
|
||||
}));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> TrackableDataType<T> of(Identifier typeName, PacketCodec<? extends ByteBuf, T> codec) {
|
||||
return (TrackableDataType<T>)REGISTRY.computeIfAbsent(typeName.hashCode(), t -> new TrackableDataType<>(t, (PacketCodec<PacketByteBuf, T>)codec));
|
||||
}
|
||||
public static class TypedValue<T> {
|
||||
final TrackableDataType<T> type;
|
||||
public T value;
|
||||
|
||||
public T read(PacketByteBuf buffer) {
|
||||
return codec().decode(buffer);
|
||||
}
|
||||
|
||||
public void write(PacketByteBuf buffer, T value) {
|
||||
buffer.writeInt(id);
|
||||
codec().encode(buffer, value);
|
||||
public TypedValue(TrackableDataType<T> type, T value) {
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,22 +2,22 @@ package com.minelittlepony.unicopia.network.track;
|
|||
|
||||
import java.util.Optional;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.network.codec.PacketCodecs;
|
||||
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
|
||||
|
||||
public interface TrackableObject<T extends TrackableObject<T>> {
|
||||
Status getStatus();
|
||||
|
||||
default void read(PacketByteBuf buffer, WrapperLookup lookup) {
|
||||
default void read(ByteBuf buffer, WrapperLookup lookup) {
|
||||
readTrackedNbt(PacketCodecs.NBT_COMPOUND.decode(buffer), lookup);
|
||||
}
|
||||
|
||||
default Optional<PacketByteBuf> write(Status status, WrapperLookup lookup) {
|
||||
default Optional<? extends ByteBuf> write(Status status, WrapperLookup lookup) {
|
||||
if (status == Status.NEW || status == Status.UPDATED) {
|
||||
PacketByteBuf buffer = new PacketByteBuf(Unpooled.buffer());
|
||||
ByteBuf buffer = Unpooled.buffer();
|
||||
PacketCodecs.NBT_COMPOUND.encode(buffer, writeTrackedNbt(lookup));
|
||||
return Optional.of(buffer);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.function.IntFunction;
|
|||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.network.RegistryByteBuf;
|
||||
import net.minecraft.network.codec.PacketCodec;
|
||||
import net.minecraft.network.codec.PacketCodecs;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
|
@ -24,6 +25,13 @@ public interface PacketCodecUtils {
|
|||
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((buffer, bytes) -> {
|
||||
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);
|
||||
|
||||
PacketCodec<PacketByteBuf, RegistryKey<?>> REGISTRY_KEY = PacketCodec.tuple(
|
||||
Identifier.PACKET_CODEC, RegistryKey::getRegistry,
|
||||
Identifier.PACKET_CODEC, RegistryKey::getValue,
|
||||
|
|
Loading…
Reference in a new issue