From 8d944a2dbfe147b56b942a3be545af35e4ec3a88 Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 18 Nov 2024 22:25:29 +0000 Subject: [PATCH] Fix crashes due to null uuids and fix entity references not serializing --- .../magic/spell/PlacementControlSpell.java | 18 ++++++--------- .../magic/spell/effect/PortalSpell.java | 22 ++++++++----------- .../render/spell/PortalSpellRenderer.java | 4 ---- .../unicopia/entity/EntityReference.java | 10 +++++++-- .../unicopia/entity/Living.java | 12 +++++----- .../network/track/TrackableDataType.java | 2 +- 6 files changed, 30 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlacementControlSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlacementControlSpell.java index 8107ef9d..46474740 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlacementControlSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/PlacementControlSpell.java @@ -20,12 +20,11 @@ import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.RegistryWrapper.WrapperLookup; import net.minecraft.util.Identifier; -import net.minecraft.util.Util; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; public class PlacementControlSpell extends AbstractSpell implements OrientedSpell { - private final DataTracker.Entry placedEntityId = dataTracker.startTracking(TrackableDataType.UUID, Util.NIL_UUID); + private final DataTracker.Entry> placedEntityId = dataTracker.startTracking(TrackableDataType.UUID, Optional.empty()); private final DataTracker.Entry>> dimension = dataTracker.startTracking(TrackableDataType.ofRegistryKey(), Optional.empty()); private final DataTracker.Entry> position = dataTracker.startTracking(TrackableDataType.OPTIONAL_VECTOR, Optional.empty()); private final DataTracker.Entry> orientation = dataTracker.startTracking(TrackableDataType.OPTIONAL_VECTOR, Optional.empty()); @@ -83,7 +82,7 @@ public class PlacementControlSpell extends AbstractSpell implements OrientedSpel public boolean tick(Caster source, Situation situation) { if (!source.isClient()) { - if (Util.NIL_UUID.equals(placedEntityId.getOrDefault(Util.NIL_UUID))) { + if (placedEntityId.get().isEmpty()) { if (dimension.get().isEmpty()) { setDimension(source.asWorld().getRegistryKey()); } @@ -99,7 +98,7 @@ public class PlacementControlSpell extends AbstractSpell implements OrientedSpel entity.updatePositionAndAngles(pos.x, pos.y, pos.z, (float)rot.y, (float)rot.x); entity.getWorld().spawnEntity(entity); - placedEntityId.set(entity.getUuid()); + placedEntityId.set(Optional.of(entity.getUuid())); } else { if (getConnection(source) == null) { setDead(); @@ -112,8 +111,8 @@ public class PlacementControlSpell extends AbstractSpell implements OrientedSpel @Nullable private Ether.Entry getConnection(Caster source) { - return delegate == null || Util.NIL_UUID.equals(placedEntityId.getOrDefault(Util.NIL_UUID)) ? null : getWorld(source) - .map(world -> Ether.get(world).get(getDelegate().getTypeAndTraits().type(), placedEntityId.get(), delegate.getUuid())) + return delegate == null || placedEntityId.get().isEmpty() ? null : getWorld(source) + .map(world -> Ether.get(world).get(getDelegate().getTypeAndTraits().type(), placedEntityId.get().get(), delegate.getUuid())) .orElse(null); } @@ -128,17 +127,14 @@ public class PlacementControlSpell extends AbstractSpell implements OrientedSpel position.get().ifPresent(pos -> compound.put("position", NbtSerialisable.writeVector(pos))); orientation.get().ifPresent(o -> compound.put("orientation", NbtSerialisable.writeVector(o))); dimension.get().ifPresent(d -> compound.putString("dimension", d.getValue().toString())); - @Nullable UUID placeEntityUuid = placedEntityId.getOrDefault(Util.NIL_UUID); - if (!Util.NIL_UUID.equals(placeEntityUuid)) { - compound.putUuid("placedEntityId", placeEntityUuid); - } + placedEntityId.get().ifPresent(i -> compound.putUuid("placedEntityId", i)); } @Override public void fromNBT(NbtCompound compound, WrapperLookup lookup) { super.fromNBT(compound, lookup); delegate = Spell.readNbt(compound.getCompound("spell"), lookup); - placedEntityId.set(compound.containsUuid("placedEntityId") ? compound.getUuid("placedEntityId") : Util.NIL_UUID); + placedEntityId.set(compound.containsUuid("placedEntityId") ? Optional.of(compound.getUuid("placedEntityId")) : Optional.empty()); position.set(compound.contains("position") ? Optional.of(NbtSerialisable.readVector(compound.getList("position", NbtElement.DOUBLE_TYPE))) : Optional.empty()); orientation.set(compound.contains("orientation") ? Optional.of(NbtSerialisable.readVector(compound.getList("orientation", NbtElement.DOUBLE_TYPE))) : Optional.empty()); dimension.set(compound.contains("dimension", NbtElement.STRING_TYPE) ? Optional.ofNullable(Identifier.tryParse(compound.getString("dimension"))).map(id -> RegistryKey.of(RegistryKeys.WORLD, id)) : Optional.empty()); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/PortalSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/PortalSpell.java index 18331330..fb72a347 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/PortalSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/PortalSpell.java @@ -1,5 +1,6 @@ package com.minelittlepony.unicopia.ability.magic.spell.effect; +import java.util.Optional; import java.util.UUID; import org.jetbrains.annotations.Nullable; @@ -29,7 +30,6 @@ import net.minecraft.particle.ParticleTypes; import net.minecraft.registry.RegistryWrapper.WrapperLookup; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.Util; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; @@ -43,8 +43,7 @@ public class PortalSpell extends AbstractSpell implements PlacementControlSpell. .build(); private static final Shape PARTICLE_AREA = new Sphere(true, 2, 1, 1, 0); - @Nullable - private final DataTracker.Entry targetPortalId = dataTracker.startTracking(TrackableDataType.UUID, Util.NIL_UUID); + private final DataTracker.Entry> targetPortalId = dataTracker.startTracking(TrackableDataType.UUID, Optional.empty()); private final DataTracker.Entry targetPortalPitch = dataTracker.startTracking(TrackableDataType.FLOAT, 0F); private final DataTracker.Entry targetPortalYaw = dataTracker.startTracking(TrackableDataType.FLOAT, 0F); private final EntityReference teleportationTarget = dataTracker.startTracking(new EntityReference<>()); @@ -84,11 +83,11 @@ public class PortalSpell extends AbstractSpell implements PlacementControlSpell. @SuppressWarnings("unchecked") private Ether.Entry getDestination(Caster source) { - return Util.NIL_UUID.equals(targetPortalId.getOrDefault(Util.NIL_UUID)) ? null : getDestinationReference() + return targetPortalId.get().flatMap(id -> getDestinationReference() .getTarget() - .map(target -> Ether.get(source.asWorld()).get((SpellType)getType(), target.uuid(), targetPortalId.get())) + .map(target -> Ether.get(source.asWorld()).get((SpellType)getType(), target.uuid(), id)) .filter(destination -> destination.isClaimedBy(getUuid())) - .orElse(null); + ).orElse(null); } @Override @@ -99,10 +98,10 @@ public class PortalSpell extends AbstractSpell implements PlacementControlSpell. protected void setDestination(@Nullable Ether.Entry destination) { if (destination == null) { teleportationTarget.set(null); - targetPortalId.set(Util.NIL_UUID); + targetPortalId.set(Optional.empty()); } else { teleportationTarget.copyFrom(destination.entity); - targetPortalId.set(destination.getSpellId()); + targetPortalId.set(Optional.of(destination.getSpellId())); targetPortalPitch.set(destination.getPitch()); targetPortalYaw.set(destination.getYaw()); } @@ -229,10 +228,7 @@ public class PortalSpell extends AbstractSpell implements PlacementControlSpell. @Override public void toNBT(NbtCompound compound, WrapperLookup lookup) { super.toNBT(compound, lookup); - @Nullable UUID otherPortalUuid = targetPortalId.getOrDefault(Util.NIL_UUID); - if (!Util.NIL_UUID.equals(otherPortalUuid)) { - compound.putUuid("targetPortalId", otherPortalUuid); - } + targetPortalId.get().ifPresent(i -> compound.putUuid("targetPortalId", i)); compound.put("teleportationTarget", teleportationTarget.toNBT(lookup)); compound.putFloat("pitch", getPitch()); compound.putFloat("yaw", getYaw()); @@ -243,7 +239,7 @@ public class PortalSpell extends AbstractSpell implements PlacementControlSpell. @Override public void fromNBT(NbtCompound compound, WrapperLookup lookup) { super.fromNBT(compound, lookup); - targetPortalId.set(compound.containsUuid("targetPortalId") ? compound.getUuid("targetPortalId") : Util.NIL_UUID); + targetPortalId.set(compound.containsUuid("targetPortalId") ? Optional.of(compound.getUuid("targetPortalId")) : Optional.empty()); teleportationTarget.fromNBT(compound.getCompound("teleportationTarget"), lookup); pitch.set(compound.getFloat("pitch")); yaw.set(compound.getFloat("yaw")); diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/spell/PortalSpellRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/render/spell/PortalSpellRenderer.java index 0f3973d5..42996391 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/spell/PortalSpellRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/spell/PortalSpellRenderer.java @@ -42,10 +42,6 @@ public class PortalSpellRenderer extends SpellRenderer { return; } - // Fancy portal rendering is disabled for now - // Need to fix: - // 1. Transparent parts of the sky (because the game sets the clear to (0,0,0,0) - if (caster.asEntity().distanceTo(client.cameraEntity) > 50) { return; // don't bother rendering if too far away } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/EntityReference.java b/src/main/java/com/minelittlepony/unicopia/entity/EntityReference.java index 04b5408c..0d9f4c28 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/EntityReference.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/EntityReference.java @@ -74,6 +74,7 @@ public class EntityReference implements NbtSerialisable, Track public void copyFrom(EntityReference other) { this.reference = ((EntityReference)other).reference; this.directReference = new WeakReference<>(other.directReference.get()); + dirty = true; } public boolean set(@Nullable T entity) { @@ -128,7 +129,9 @@ public class EntityReference implements NbtSerialisable, Track @Override public void toNBT(NbtCompound tag, WrapperLookup lookup) { - getTarget().ifPresent(ref -> EntityValues.CODEC.encode(ref, lookup.getOps(NbtOps.INSTANCE), tag)); + getTarget().ifPresent(ref -> { + EntityValues.CODEC.encodeStart(lookup.getOps(NbtOps.INSTANCE), ref).result().ifPresent(nbt -> tag.copyFrom((NbtCompound)nbt)); + }); } @SuppressWarnings("unchecked") @@ -160,7 +163,10 @@ public class EntityReference implements NbtSerialisable, Track @Override public NbtCompound writeTrackedNbt(WrapperLookup lookup) { - return toNBT(lookup); + return getTarget() + .flatMap(ref -> EntityValues.CODEC.encodeStart(lookup.getOps(NbtOps.INSTANCE), ref).result()) + .map(NbtCompound.class::cast) + .orElseGet(NbtCompound::new); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Living.java b/src/main/java/com/minelittlepony/unicopia/entity/Living.java index ad988d8a..a63b6c01 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Living.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Living.java @@ -73,7 +73,6 @@ import net.minecraft.sound.BlockSoundGroup; import net.minecraft.sound.SoundCategory; import net.minecraft.util.Hand; import net.minecraft.util.Identifier; -import net.minecraft.util.Util; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; @@ -110,7 +109,7 @@ public abstract class Living implements Equine, Caste protected final DataTrackerManager trackers; protected final DataTracker tracker; - protected final DataTracker.Entry carrierId; + protected final DataTracker.Entry> carrierId; protected Living(T entity) { this.entity = entity; @@ -121,7 +120,7 @@ public abstract class Living implements Equine, Caste this.landedHeuristic = addTicker(new Interactable(entity::isOnGround)); this.jumpingHeuristic = addTicker(new Interactable(((LivingEntityDuck)entity)::isJumping)); - carrierId = tracker.startTracking(TrackableDataType.UUID, Util.NIL_UUID); + carrierId = tracker.startTracking(TrackableDataType.UUID, Optional.empty()); } public Q addTicker(Q tickable) { @@ -176,16 +175,15 @@ public abstract class Living implements Equine, Caste } public Optional getCarrierId() { - UUID carrierId = this.carrierId.get(); - return carrierId == Util.NIL_UUID ? Optional.empty() : Optional.of(carrierId); + return carrierId.get(); } public void setCarrier(UUID carrier) { - carrierId.set(carrier == null ? Util.NIL_UUID : carrier); + carrierId.set(Optional.ofNullable(carrier)); } public void setCarrier(Entity carrier) { - setCarrier(carrier == null ? Util.NIL_UUID : carrier.getUuid()); + setCarrier(carrier == null ? null : carrier.getUuid()); } @Nullable diff --git a/src/main/java/com/minelittlepony/unicopia/network/track/TrackableDataType.java b/src/main/java/com/minelittlepony/unicopia/network/track/TrackableDataType.java index 7f08c698..110dbeac 100644 --- a/src/main/java/com/minelittlepony/unicopia/network/track/TrackableDataType.java +++ b/src/main/java/com/minelittlepony/unicopia/network/track/TrackableDataType.java @@ -32,7 +32,7 @@ public record TrackableDataType(int id, PacketCodec INT = of(Identifier.of("integer"), PacketCodecs.INTEGER); public static final TrackableDataType FLOAT = of(Identifier.of("float"), PacketCodecs.FLOAT); public static final TrackableDataType BOOLEAN = of(Identifier.of("boolean"), PacketCodecs.BOOL); - public static final TrackableDataType UUID = of(Identifier.of("uuid"), Uuids.PACKET_CODEC); + public static final TrackableDataType> UUID = of(Identifier.of("uuid"), PacketCodecs.optional(Uuids.PACKET_CODEC)); public static final TrackableDataType NBT = of(Identifier.of("nbt"), PacketCodecs.NBT_COMPOUND); public static final TrackableDataType COMPRESSED_NBT = of(Identifier.of("compressed_nbt"), PacketCodecs.NBT_COMPOUND);