diff --git a/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/Component.java b/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/Component.java index b33f4432..42f7607f 100644 --- a/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/Component.java +++ b/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/Component.java @@ -24,6 +24,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.RegistryWrapper; import org.jetbrains.annotations.Contract; /** @@ -40,21 +41,23 @@ public interface Component { /** * Reads this component's properties from a {@link NbtCompound}. * - * @param tag a {@code NbtCompound} on which this component's serializable data has been written + * @param tag a {@code NbtCompound} on which this component's serializable data has been written + * @param registryLookup access to dynamic registry data * @implNote implementations should not assert that the data written on the tag corresponds to any * specific scheme, as saved data is susceptible to external tempering, and may come from an earlier * version. */ @Contract(mutates = "this") - void readFromNbt(NbtCompound tag); + void readFromNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup); /** * Writes this component's properties to a {@link NbtCompound}. * - * @param tag a {@code NbtCompound} on which to write this component's serializable data + * @param tag a {@code NbtCompound} on which to write this component's serializable data + * @param registryLookup access to dynamic registry data */ - @Contract(mutates = "param") - void writeToNbt(NbtCompound tag); + @Contract(mutates = "param1") + void writeToNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup); /** * Indicates whether some other object is "equal to" this component. diff --git a/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/ComponentContainer.java b/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/ComponentContainer.java index cf27c068..ab93c0d3 100644 --- a/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/ComponentContainer.java +++ b/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/ComponentContainer.java @@ -25,6 +25,7 @@ import com.demonwav.mcdev.annotations.CheckEnv; import com.demonwav.mcdev.annotations.Env; import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.RegistryWrapper; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Nullable; @@ -60,7 +61,7 @@ public interface ComponentContainer extends NbtSerializable { boolean hasComponents(); @Contract(mutates = "this") - void copyFrom(ComponentContainer other); + void copyFrom(ComponentContainer other, RegistryWrapper.WrapperLookup registryLookup); @AsmGeneratedCallback(ServerTickingComponent.class) void tickServerComponents(); @@ -110,23 +111,25 @@ default ComponentKey getKey(Component component) { /** * Reads this object's properties from a {@link NbtCompound}. * - * @param tag a {@code NbtCompound} on which this object's serializable data has been written + * @param tag a {@code NbtCompound} on which this object's serializable data has been written + * @param registryLookup access to dynamic registry data * @implNote implementations must not assert that the data written on the tag corresponds to any * specific scheme, as saved data is susceptible to external tempering, and may come from an earlier * version. They should also store values into {@code tag} using only unique namespaced keys, as other * information may be stored in said tag. */ @Contract(mutates = "this") - void fromTag(NbtCompound tag); + void fromTag(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup); /** * Writes this object's properties to a {@link NbtCompound}. * - * @param tag a {@code NbtCompound} on which to write this component's serializable data + * @param tag a {@code NbtCompound} on which to write this component's serializable data + * @param registryLookup access to dynamic registry data * @return {@code tag} for easy chaining */ @Contract(mutates = "param") - NbtCompound toTag(NbtCompound tag); + NbtCompound toTag(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup); /** * A factory for {@link ComponentContainer}s. diff --git a/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/CopyableComponent.java b/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/CopyableComponent.java index 3a6e511d..5a472924 100644 --- a/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/CopyableComponent.java +++ b/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/CopyableComponent.java @@ -23,6 +23,7 @@ package org.ladysnake.cca.api.v3.component; import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.RegistryWrapper; /** * A component that can copy its data from another component of the same type. @@ -34,12 +35,12 @@ public interface CopyableComponent extends Component { /** * Copies the data from {@code other} into {@code this}. * - * @implSpec The default implementation {@linkplain #writeToNbt(NbtCompound) serializes} - * the component data to a {@link NbtCompound} and calls {@link #readFromNbt(NbtCompound)}. + * @implSpec The default implementation {@linkplain Component#writeToNbt(NbtCompound, RegistryWrapper.WrapperLookup) serializes} + * the component data to a {@link NbtCompound} and calls {@link Component#readFromNbt(NbtCompound, RegistryWrapper.WrapperLookup)}. * @implNote The default implementation should generally be overridden. * The serialization done by the default implementation assumes NBT consistency * between implementations, and is generally slower than a direct copy. * Implementing classes can nearly always provide a better implementation. */ - void copyFrom(C other); + void copyFrom(C other, RegistryWrapper.WrapperLookup registryLookup); } diff --git a/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/TransientComponent.java b/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/TransientComponent.java index a38e3cce..456e13c1 100644 --- a/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/TransientComponent.java +++ b/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/TransientComponent.java @@ -23,6 +23,7 @@ package org.ladysnake.cca.api.v3.component; import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.RegistryWrapper; import org.jetbrains.annotations.Nullable; /** @@ -30,12 +31,12 @@ */ public interface TransientComponent extends Component { @Override - default void readFromNbt(NbtCompound tag) { + default void readFromNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { // Nothing to read } @Override - default void writeToNbt(NbtCompound tag) { + default void writeToNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { // Nothing to write } diff --git a/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/sync/AutoSyncedComponent.java b/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/sync/AutoSyncedComponent.java index 08e36682..55de7823 100644 --- a/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/sync/AutoSyncedComponent.java +++ b/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/component/sync/AutoSyncedComponent.java @@ -27,6 +27,7 @@ import net.minecraft.entity.Entity; import net.minecraft.nbt.NbtCompound; import net.minecraft.network.RegistryByteBuf; +import net.minecraft.registry.RegistryWrapper.WrapperLookup; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.world.World; import org.jetbrains.annotations.Contract; @@ -67,7 +68,7 @@ default boolean shouldSyncWith(ServerPlayerEntity player) { * @param buf the buffer to write the data to * @param recipient the player to which the packet will be sent * @implSpec The default implementation writes the whole NBT representation - * of this component to the buffer using {@link #writeToNbt(NbtCompound)}. + * of this component to the buffer using {@link Component#writeToNbt(NbtCompound, WrapperLookup)}. * @implNote The default implementation should generally be overridden. * The serialization done by the default implementation sends possibly hidden * information to clients, uses a wasteful data format, and does not support @@ -81,7 +82,7 @@ default boolean shouldSyncWith(ServerPlayerEntity player) { @Override default void writeSyncPacket(RegistryByteBuf buf, ServerPlayerEntity recipient) { NbtCompound tag = new NbtCompound(); - this.writeToNbt(tag); + this.writeToNbt(tag, buf.getRegistryManager()); buf.writeNbt(tag); } @@ -89,7 +90,7 @@ default void writeSyncPacket(RegistryByteBuf buf, ServerPlayerEntity recipient) * Reads this component's data from {@code buf}. * * @implSpec The default implementation converts the buffer's content - * to a {@link NbtCompound} and calls {@link #readFromNbt(NbtCompound)}. + * to a {@link NbtCompound} and calls {@link Component#readFromNbt(NbtCompound, WrapperLookup)}. * @implNote any implementing class overriding {@link #writeSyncPacket(RegistryByteBuf, ServerPlayerEntity)} * such that it uses a different data format must override this method. * @see #writeSyncPacket(RegistryByteBuf, ServerPlayerEntity) @@ -98,7 +99,7 @@ default void writeSyncPacket(RegistryByteBuf buf, ServerPlayerEntity recipient) default void applySyncPacket(RegistryByteBuf buf) { NbtCompound tag = buf.readNbt(); if (tag != null) { - this.readFromNbt(tag); + this.readFromNbt(tag, buf.getRegistryManager()); } } } diff --git a/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/util/NbtSerializable.java b/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/util/NbtSerializable.java index 9e449f1a..6810dd31 100644 --- a/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/util/NbtSerializable.java +++ b/cardinal-components-base/src/main/java/org/ladysnake/cca/api/v3/util/NbtSerializable.java @@ -25,6 +25,7 @@ import com.mojang.serialization.Dynamic; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtOps; +import net.minecraft.registry.RegistryWrapper; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; @@ -33,31 +34,33 @@ public interface NbtSerializable { /** * Reads this object's properties from a {@link NbtCompound}. * - * @param tag a {@code NbtCompound} on which this object's serializable data has been written + * @param tag a {@code NbtCompound} on which this object's serializable data has been written + * @param registryLookup access to dynamic registry data * @implNote implementations must not assert that the data written on the tag corresponds to any * specific scheme, as saved data is susceptible to external tempering, and may come from an earlier * version. They should also store values into {@code tag} using only unique namespaced keys, as other * information may be stored in said tag. */ @Contract(mutates = "this") - void fromTag(NbtCompound tag); + void fromTag(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup); /** * Writes this object's properties to a {@link NbtCompound}. * - * @param tag a {@code NbtCompound} on which to write this component's serializable data + * @param tag a {@code NbtCompound} on which to write this component's serializable data + * @param registryLookup access to dynamic registry data * @return {@code tag} for easy chaining */ @Contract(mutates = "param") - NbtCompound toTag(NbtCompound tag); + NbtCompound toTag(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup); @Contract(mutates = "this") - default void fromDynamic(Dynamic dynamic) { - this.fromTag((NbtCompound) dynamic.convert(NbtOps.INSTANCE).getValue()); + default void fromDynamic(Dynamic dynamic, RegistryWrapper.WrapperLookup registryLookup) { + this.fromTag((NbtCompound) dynamic.convert(NbtOps.INSTANCE).getValue(), registryLookup); } @Contract(pure = true) - default Dynamic toDynamic(Dynamic dynamic) { - return dynamic.convert(NbtOps.INSTANCE).map(tag -> this.toTag((NbtCompound)tag)).convert(dynamic.getOps()); + default Dynamic toDynamic(Dynamic dynamic, RegistryWrapper.WrapperLookup wrapperLookup) { + return dynamic.convert(NbtOps.INSTANCE).map(tag -> this.toTag((NbtCompound)tag, wrapperLookup)).convert(dynamic.getOps()); } } diff --git a/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/AbstractComponentContainer.java b/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/AbstractComponentContainer.java index 8a834e15..2f219df6 100644 --- a/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/AbstractComponentContainer.java +++ b/cardinal-components-base/src/main/java/org/ladysnake/cca/internal/base/AbstractComponentContainer.java @@ -25,6 +25,7 @@ import net.fabricmc.fabric.api.util.NbtType; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtList; +import net.minecraft.registry.RegistryWrapper; import net.minecraft.util.Identifier; import org.ladysnake.cca.api.v3.component.Component; import org.ladysnake.cca.api.v3.component.ComponentContainer; @@ -42,20 +43,20 @@ public abstract class AbstractComponentContainer implements ComponentContainer { public static final String NBT_KEY = "cardinal_components"; @Override - public void copyFrom(ComponentContainer other) { + public void copyFrom(ComponentContainer other, RegistryWrapper.WrapperLookup registryLookup) { for (ComponentKey key : this.keys()) { Component theirs = key.getInternal(other); Component ours = key.getInternal(this); assert ours != null; if (theirs != null && !ours.equals(theirs)) { - if (ours instanceof CopyableComponent) { + if (ours instanceof CopyableComponent) { @SuppressWarnings("unchecked") CopyableComponent copyable = (CopyableComponent) ours; - copyable.copyFrom(theirs); + copyable.copyFrom(theirs, registryLookup); } else { NbtCompound tag = new NbtCompound(); - theirs.writeToNbt(tag); - ours.readFromNbt(tag); + theirs.writeToNbt(tag, registryLookup); + ours.readFromNbt(tag, registryLookup); } } } @@ -72,7 +73,7 @@ public void copyFrom(ComponentContainer other) { * type, the component tag is skipped. */ @Override - public void fromTag(NbtCompound tag) { + public void fromTag(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { if(tag.contains(NBT_KEY, NbtType.LIST)) { NbtList componentList = tag.getList(NBT_KEY, NbtType.COMPOUND); for (int i = 0; i < componentList.size(); i++) { @@ -81,7 +82,7 @@ public void fromTag(NbtCompound tag) { if (type != null) { Component component = type.getInternal(this); if (component != null) { - component.readFromNbt(nbt); + component.readFromNbt(nbt, registryLookup); } } } @@ -94,7 +95,7 @@ public void fromTag(NbtCompound tag) { if (componentMap.contains(keyId, NbtType.COMPOUND)) { Component component = key.getInternal(this); assert component != null; - component.readFromNbt(componentMap.getCompound(keyId)); + component.readFromNbt(componentMap.getCompound(keyId), registryLookup); componentMap.remove(keyId); } } @@ -109,19 +110,19 @@ public void fromTag(NbtCompound tag) { * @implSpec This implementation first checks if the container is empty; if so it * returns immediately. Then, it iterates over this container's mappings, and creates * a compound tag for each component. The tag is then passed to the component's - * {@link Component#writeToNbt(NbtCompound)} method. Every such serialized component is appended + * {@link Component#writeToNbt(NbtCompound, RegistryWrapper.WrapperLookup)} method. Every such serialized component is appended * to a {@code NbtCompound}, using the component type's identifier as the key. * The serialized map is finally appended to the passed in tag using the "cardinal_components" key. */ @Override - public NbtCompound toTag(NbtCompound tag) { + public NbtCompound toTag(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { if(this.hasComponents()) { NbtCompound componentMap = null; NbtCompound componentTag = new NbtCompound(); for (ComponentKey type : this.keys()) { Component component = type.getFromContainer(this); - component.writeToNbt(componentTag); + component.writeToNbt(componentTag, registryLookup); if (!componentTag.isEmpty()) { if (componentMap == null) { diff --git a/cardinal-components-base/src/main/resources/fabric.mod.json b/cardinal-components-base/src/main/resources/fabric.mod.json index 1d073b27..39724473 100644 --- a/cardinal-components-base/src/main/resources/fabric.mod.json +++ b/cardinal-components-base/src/main/resources/fabric.mod.json @@ -26,6 +26,14 @@ "minecraft": ">=1.17-", "fabric-api-base": ">=0.1.2" }, + "breaks": { + "cardinal-components-block": "<6.0.0-beta.2", + "cardinal-components-chunk": "<6.0.0-beta.2", + "cardinal-components-entity": "<6.0.0-beta.2", + "cardinal-components-level": "<6.0.0-beta.2", + "cardinal-components-scoreboard": "<6.0.0-beta.2", + "cardinal-components-world": "<6.0.0-beta.2" + }, "authors": [ { "name": "UpcraftLP", diff --git a/cardinal-components-base/src/testmod/java/org/ladysnake/cca/internal/base/ComponentRegistryImplTest.java b/cardinal-components-base/src/testmod/java/org/ladysnake/cca/internal/base/ComponentRegistryImplTest.java index d2e1375f..d5617e02 100644 --- a/cardinal-components-base/src/testmod/java/org/ladysnake/cca/internal/base/ComponentRegistryImplTest.java +++ b/cardinal-components-base/src/testmod/java/org/ladysnake/cca/internal/base/ComponentRegistryImplTest.java @@ -24,6 +24,7 @@ import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.RegistryWrapper; import net.minecraft.test.GameTest; import net.minecraft.util.Identifier; import org.junit.Assert; @@ -64,10 +65,10 @@ interface TestNotComponentItf {} public static class TestComponentNotItf implements Component { @Override - public void readFromNbt(NbtCompound tag) { } + public void readFromNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { } @Override - public void writeToNbt(NbtCompound tag) { throw new UnsupportedOperationException(); } + public void writeToNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { throw new UnsupportedOperationException(); } } interface TestComponentItf extends Component {} diff --git a/cardinal-components-base/src/testmod/java/org/ladysnake/cca/test/base/BaseVita.java b/cardinal-components-base/src/testmod/java/org/ladysnake/cca/test/base/BaseVita.java index c7409561..b79da934 100644 --- a/cardinal-components-base/src/testmod/java/org/ladysnake/cca/test/base/BaseVita.java +++ b/cardinal-components-base/src/testmod/java/org/ladysnake/cca/test/base/BaseVita.java @@ -23,6 +23,7 @@ package org.ladysnake.cca.test.base; import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.RegistryWrapper; import org.ladysnake.cca.api.v3.component.Component; import org.ladysnake.cca.api.v3.component.CopyableComponent; @@ -48,17 +49,17 @@ public void setVitality(int value) { } @Override - public void readFromNbt(NbtCompound tag) { + public void readFromNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { this.vitality = tag.getInt("vitality"); } @Override - public void writeToNbt(NbtCompound tag) { + public void writeToNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { tag.putInt("vitality", this.vitality); } @Override - public void copyFrom(BaseVita other) { + public void copyFrom(BaseVita other, RegistryWrapper.WrapperLookup registryLookup) { this.vitality = other.getVitality(); } diff --git a/cardinal-components-base/src/testmod/java/org/ladysnake/cca/test/base/TickingTestComponent.java b/cardinal-components-base/src/testmod/java/org/ladysnake/cca/test/base/TickingTestComponent.java index 8b6b8fbd..2c66bbf6 100644 --- a/cardinal-components-base/src/testmod/java/org/ladysnake/cca/test/base/TickingTestComponent.java +++ b/cardinal-components-base/src/testmod/java/org/ladysnake/cca/test/base/TickingTestComponent.java @@ -23,6 +23,7 @@ package org.ladysnake.cca.test.base; import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.RegistryWrapper; import net.minecraft.util.Identifier; import org.ladysnake.cca.api.v3.component.ComponentKey; import org.ladysnake.cca.api.v3.component.ComponentRegistry; @@ -36,13 +37,13 @@ public class TickingTestComponent implements ServerTickingComponent, ClientTicki private int serverTicks; @Override - public void readFromNbt(NbtCompound tag) { + public void readFromNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { this.clientTicks = tag.getInt("clientTicks"); this.serverTicks = tag.getInt("serverTicks"); } @Override - public void writeToNbt(NbtCompound tag) { + public void writeToNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { tag.putInt("clientTicks", this.clientTicks); tag.putInt("serverTicks", this.serverTicks); } diff --git a/cardinal-components-block/src/main/java/org/ladysnake/cca/mixin/block/common/MixinBlockEntity.java b/cardinal-components-block/src/main/java/org/ladysnake/cca/mixin/block/common/MixinBlockEntity.java index de23dd30..e6341ceb 100644 --- a/cardinal-components-block/src/main/java/org/ladysnake/cca/mixin/block/common/MixinBlockEntity.java +++ b/cardinal-components-block/src/main/java/org/ladysnake/cca/mixin/block/common/MixinBlockEntity.java @@ -75,13 +75,13 @@ private void init(BlockEntityType type, BlockPos pos, BlockState state, Callb } @Inject(method = "createNbt", at = @At("RETURN")) - private void writeNbt(CallbackInfoReturnable cir) { - this.components.toTag(cir.getReturnValue()); + private void writeNbt(RegistryWrapper.WrapperLookup registryLookup, CallbackInfoReturnable cir) { + this.components.toTag(cir.getReturnValue(), registryLookup); } @Inject(method = "read", at = @At(value = "RETURN")) private void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup, CallbackInfo ci) { - this.components.fromTag(nbt); + this.components.fromTag(nbt, registryLookup); } @Nonnull diff --git a/cardinal-components-block/src/main/resources/fabric.mod.json b/cardinal-components-block/src/main/resources/fabric.mod.json index 1c826142..db1510b9 100644 --- a/cardinal-components-block/src/main/resources/fabric.mod.json +++ b/cardinal-components-block/src/main/resources/fabric.mod.json @@ -35,7 +35,7 @@ "fabric-api-base": "*", "fabric-api-lookup-api-v1": "*", "fabric-networking-api-v1": "*", - "cardinal-components-base": "*" + "cardinal-components-base": ">=6.0.0-beta.2" }, "authors": [ { diff --git a/cardinal-components-block/src/testmod/java/org/ladysnake/cca/test/block/VitaCompound.java b/cardinal-components-block/src/testmod/java/org/ladysnake/cca/test/block/VitaCompound.java index 7f79fc81..79e1eb5b 100644 --- a/cardinal-components-block/src/testmod/java/org/ladysnake/cca/test/block/VitaCompound.java +++ b/cardinal-components-block/src/testmod/java/org/ladysnake/cca/test/block/VitaCompound.java @@ -26,6 +26,7 @@ import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtElement; import net.minecraft.network.RegistryByteBuf; +import net.minecraft.registry.RegistryWrapper; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.Identifier; import net.minecraft.util.Util; @@ -51,17 +52,17 @@ public VitaCompound(BlockEntity owner) { } @Override - public void readFromNbt(NbtCompound tag) { + public void readFromNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { for (Map.Entry entry : this.storage.entrySet()) { if (tag.contains(entry.getKey().name(), NbtElement.COMPOUND_TYPE)) { - entry.getValue().readFromNbt(tag.getCompound(entry.getKey().name())); + entry.getValue().readFromNbt(tag.getCompound(entry.getKey().name()), registryLookup); } } } @Override - public void writeToNbt(NbtCompound tag) { - storage.forEach((side, vita) -> tag.put(side.name(), Util.make(new NbtCompound(), vita::writeToNbt))); + public void writeToNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { + storage.forEach((side, vita) -> tag.put(side.name(), Util.make(new NbtCompound(), tag1 -> vita.writeToNbt(tag1, registryLookup)))); } @Override diff --git a/cardinal-components-chunk/src/main/java/org/ladysnake/cca/mixin/chunk/common/MixinChunkSerializer.java b/cardinal-components-chunk/src/main/java/org/ladysnake/cca/mixin/chunk/common/MixinChunkSerializer.java index 305053b1..e00f0db9 100644 --- a/cardinal-components-chunk/src/main/java/org/ladysnake/cca/mixin/chunk/common/MixinChunkSerializer.java +++ b/cardinal-components-chunk/src/main/java/org/ladysnake/cca/mixin/chunk/common/MixinChunkSerializer.java @@ -41,12 +41,12 @@ public abstract class MixinChunkSerializer { private static void deserialize(ServerWorld world, PointOfInterestStorage pointOfInterestStorage, ChunkPos chunkPos, NbtCompound tag, CallbackInfoReturnable cir) { ProtoChunk ret = cir.getReturnValue(); Chunk chunk = ret instanceof WrapperProtoChunk ? ((WrapperProtoChunk) ret).getWrappedChunk() : ret; - chunk.asComponentProvider().getComponentContainer().fromTag(tag); + chunk.asComponentProvider().getComponentContainer().fromTag(tag, world.getRegistryManager()); } @Inject(method = "serialize", at = @At("RETURN")) private static void serialize(ServerWorld world, Chunk chunk, CallbackInfoReturnable cir) { NbtCompound ret = cir.getReturnValue(); - chunk.asComponentProvider().getComponentContainer().toTag(ret); + chunk.asComponentProvider().getComponentContainer().toTag(ret, world.getRegistryManager()); } } diff --git a/cardinal-components-chunk/src/main/java/org/ladysnake/cca/mixin/chunk/common/MixinWorldChunk.java b/cardinal-components-chunk/src/main/java/org/ladysnake/cca/mixin/chunk/common/MixinWorldChunk.java index 01834376..065d99aa 100644 --- a/cardinal-components-chunk/src/main/java/org/ladysnake/cca/mixin/chunk/common/MixinWorldChunk.java +++ b/cardinal-components-chunk/src/main/java/org/ladysnake/cca/mixin/chunk/common/MixinWorldChunk.java @@ -81,6 +81,6 @@ public Iterable getRecipientsForComponentSync() { @Inject(method = "(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/world/chunk/ProtoChunk;Lnet/minecraft/world/chunk/WorldChunk$EntityLoader;)V", at = @At("RETURN")) private void copyFromProto(ServerWorld world, ProtoChunk proto, WorldChunk.EntityLoader entityLoader, CallbackInfo ci) { - this.getComponentContainer().copyFrom(proto.asComponentProvider().getComponentContainer()); + this.getComponentContainer().copyFrom(proto.asComponentProvider().getComponentContainer(), world.getRegistryManager()); } } diff --git a/cardinal-components-chunk/src/main/resources/fabric.mod.json b/cardinal-components-chunk/src/main/resources/fabric.mod.json index f91af7c8..b22ed700 100644 --- a/cardinal-components-chunk/src/main/resources/fabric.mod.json +++ b/cardinal-components-chunk/src/main/resources/fabric.mod.json @@ -33,7 +33,7 @@ "depends": { "minecraft": ">=1.17-", "fabric-api-base": "*", - "cardinal-components-base": "*", + "cardinal-components-base": ">=6.0.0-beta.2", "fabric-networking-api-v1": "*" }, "authors": [ diff --git a/cardinal-components-entity/src/main/java/org/ladysnake/cca/api/v3/entity/RespawnCopyStrategy.java b/cardinal-components-entity/src/main/java/org/ladysnake/cca/api/v3/entity/RespawnCopyStrategy.java index cb181030..2530e3b4 100644 --- a/cardinal-components-entity/src/main/java/org/ladysnake/cca/api/v3/entity/RespawnCopyStrategy.java +++ b/cardinal-components-entity/src/main/java/org/ladysnake/cca/api/v3/entity/RespawnCopyStrategy.java @@ -24,6 +24,7 @@ import net.minecraft.entity.LivingEntity; import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.RegistryWrapper; import net.minecraft.util.Identifier; import net.minecraft.world.GameRules; import org.ladysnake.cca.api.v3.component.Component; @@ -49,7 +50,7 @@ public interface RespawnCopyStrategy { *

This strategy is relevant for persistent metadata such as statistics, or knowledge the player * cannot lose. */ - RespawnCopyStrategy ALWAYS_COPY = (from, to, lossless, keepInventory, sameCharacter) -> copy(from, to); + RespawnCopyStrategy ALWAYS_COPY = (from, to, registryLookup, lossless, keepInventory, sameCharacter) -> copy(from, to, registryLookup); /** * Always copy a component, unless the player is switching to another character. @@ -58,9 +59,9 @@ public interface RespawnCopyStrategy { * The difference becomes apparent with mods that let players have multiple bodies, or take * over the body of another player. */ - RespawnCopyStrategy CHARACTER = (from, to, lossless, keepInventory, sameCharacter) -> { + RespawnCopyStrategy CHARACTER = (from, to, registryLookup, lossless, keepInventory, sameCharacter) -> { if (sameCharacter) { - copy(from, to); + copy(from, to, registryLookup); } }; @@ -69,9 +70,9 @@ public interface RespawnCopyStrategy { * *

This strategy is relevant for any data storage tied to items or experience. */ - RespawnCopyStrategy INVENTORY = (from, to, lossless, keepInventory, sameCharacter) -> { + RespawnCopyStrategy INVENTORY = (from, to, registryLookup, lossless, keepInventory, sameCharacter) -> { if (lossless || keepInventory) { - copy(from, to); + copy(from, to, registryLookup); } }; @@ -80,9 +81,9 @@ public interface RespawnCopyStrategy { * *

This strategy is the default. */ - RespawnCopyStrategy LOSSLESS_ONLY = (from, to, lossless, keepInventory, sameCharacter) -> { + RespawnCopyStrategy LOSSLESS_ONLY = (from, to, registryLookup, lossless, keepInventory, sameCharacter) -> { if (lossless) { - copy(from, to); + copy(from, to, registryLookup); } }; @@ -92,7 +93,7 @@ public interface RespawnCopyStrategy { *

This strategy can be used when {@code RespawnCopyStrategy} does not offer enough context, * in which case {@link net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents#COPY_FROM} may be used directly. */ - RespawnCopyStrategy NEVER_COPY = (from, to, lossless, keepInventory, sameCharacter) -> { }; + RespawnCopyStrategy NEVER_COPY = (from, to, registryLookup, lossless, keepInventory, sameCharacter) -> { }; /** * The event phase used by CCA to copy components @@ -112,33 +113,34 @@ static RespawnCopyStrategy get(ComponentKey /** * Copies data from one component to the other. * - *

If {@code to} implements {@link CopyableComponent}, its {@link CopyableComponent#copyFrom(Component)} + *

If {@code to} implements {@link CopyableComponent}, its {@link CopyableComponent#copyFrom(Component, RegistryWrapper.WrapperLookup)} * method will be called, otherwise data will be copied using NBT serialization. * * @param from the component to copy data from * @param to the component to copy data to * @param the common component type */ - static void copy(C from, C to) { - if (to instanceof CopyableComponent) { - CardinalEntityInternals.copyAsCopyable(from, (CopyableComponent) to); + static void copy(C from, C to, RegistryWrapper.WrapperLookup registryLookup) { + if (to instanceof CopyableComponent copyable) { + CardinalEntityInternals.copyAsCopyable(from, copyable, registryLookup); } else { NbtCompound tag = new NbtCompound(); - from.writeToNbt(tag); - to.readFromNbt(tag); + from.writeToNbt(tag, registryLookup); + to.readFromNbt(tag, registryLookup); } } /** * Copy data from a component to another as part of a player respawn. * - * @param from the component to copy data from - * @param to the component to copy data to - * @param lossless {@code true} if the player is copied exactly, such as when coming back from the End - * @param keepInventory {@code true} if the player's inventory and XP are kept, such as when - * {@link GameRules#KEEP_INVENTORY} is enabled or the player is in spectator mode - * @param sameCharacter {@code true} if the player is not switching to an unrelated body. - * Can only be {@code false} with other mods installed. + * @param from the component to copy data from + * @param to the component to copy data to + * @param registryLookup used to decode registry data + * @param lossless {@code true} if the player is copied exactly, such as when coming back from the End + * @param keepInventory {@code true} if the player's inventory and XP are kept, such as when + * {@link GameRules#KEEP_INVENTORY} is enabled or the player is in spectator mode + * @param sameCharacter {@code true} if the player is not switching to an unrelated body. + * Can only be {@code false} with other mods installed. */ - void copyForRespawn(C from, C to, boolean lossless, boolean keepInventory, boolean sameCharacter); + void copyForRespawn(C from, C to, RegistryWrapper.WrapperLookup registryLookup, boolean lossless, boolean keepInventory, boolean sameCharacter); } diff --git a/cardinal-components-entity/src/main/java/org/ladysnake/cca/api/v3/entity/RespawnableComponent.java b/cardinal-components-entity/src/main/java/org/ladysnake/cca/api/v3/entity/RespawnableComponent.java index 14b6cc01..70254d5b 100644 --- a/cardinal-components-entity/src/main/java/org/ladysnake/cca/api/v3/entity/RespawnableComponent.java +++ b/cardinal-components-entity/src/main/java/org/ladysnake/cca/api/v3/entity/RespawnableComponent.java @@ -23,6 +23,7 @@ package org.ladysnake.cca.api.v3.entity; import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.RegistryWrapper; import net.minecraft.world.GameRules; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; @@ -49,22 +50,23 @@ default boolean shouldCopyForRespawn(boolean lossless, boolean keepInventory, bo /** * Copy data from a component to another as part of a player respawn. * - * @param original the component to copy data from - * @param lossless {@code true} if the player is copied exactly, such as when coming back from the End - * @param keepInventory {@code true} if the player's inventory and XP are kept, such as when - * {@link GameRules#KEEP_INVENTORY} is enabled or the player is in spectator mode - * @param sameCharacter {@code true} if the player is not switching to an unrelated body. - * Can only be {@code false} with other mods installed. - * @implNote the default implementation delegates to {@link #copyFrom} + * @param original the component to copy data from + * @param registryLookup access to dynamic registry data + * @param lossless {@code true} if the player is copied exactly, such as when coming back from the End + * @param keepInventory {@code true} if the player's inventory and XP are kept, such as when + * {@link GameRules#KEEP_INVENTORY} is enabled or the player is in spectator mode + * @param sameCharacter {@code true} if the player is not switching to an unrelated body. + * Can only be {@code false} with other mods installed. + * @implNote the default implementation delegates to {@link CopyableComponent#copyFrom} */ - default void copyForRespawn(C original, boolean lossless, boolean keepInventory, boolean sameCharacter) { - this.copyFrom(original); + default void copyForRespawn(C original, RegistryWrapper.WrapperLookup registryLookup, boolean lossless, boolean keepInventory, boolean sameCharacter) { + this.copyFrom(original, registryLookup); } @Override - default void copyFrom(C other) { + default void copyFrom(C other, RegistryWrapper.WrapperLookup registryLookup) { NbtCompound tag = new NbtCompound(); - other.writeToNbt(tag); - this.readFromNbt(tag); + other.writeToNbt(tag, registryLookup); + this.readFromNbt(tag, registryLookup); } } diff --git a/cardinal-components-entity/src/main/java/org/ladysnake/cca/internal/entity/CardinalComponentsEntity.java b/cardinal-components-entity/src/main/java/org/ladysnake/cca/internal/entity/CardinalComponentsEntity.java index 4cae0564..397d340d 100644 --- a/cardinal-components-entity/src/main/java/org/ladysnake/cca/internal/entity/CardinalComponentsEntity.java +++ b/cardinal-components-entity/src/main/java/org/ladysnake/cca/internal/entity/CardinalComponentsEntity.java @@ -31,10 +31,10 @@ import net.fabricmc.loader.api.FabricLoader; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; -import net.minecraft.network.PacketByteBuf; import net.minecraft.network.codec.PacketCodecs; import net.minecraft.network.packet.CustomPayload; import net.minecraft.network.packet.s2c.common.CustomPayloadS2CPacket; +import net.minecraft.registry.RegistryWrapper; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.Identifier; import net.minecraft.world.GameRules; @@ -67,7 +67,7 @@ public final class CardinalComponentsEntity { * *

Packets emitted on this channel must begin with the {@link ComponentKey#getId() component's type} (as an Identifier). * - *

Components synchronized through this channel will have {@linkplain org.ladysnake.cca.api.v3.entity.C2SSelfMessagingComponent#handleC2SMessage(PacketByteBuf)} + *

Components synchronized through this channel will have {@linkplain org.ladysnake.cca.api.v3.entity.C2SSelfMessagingComponent#handleC2SMessage(net.minecraft.network.RegistryByteBuf)} * called on the game thread. */ public static final CustomPayload.Id> C2S_SELF_PACKET_ID = CustomPayload.id("cardinal-components:player_message_c2s"); @@ -110,7 +110,7 @@ private static void copyData(LivingEntity original, LivingEntity clone, boolean for (ComponentKey key : keys) { if (key.isProvidedBy(clone)) { - copyData(original, clone, false, keepInventory, key, true); + copyData(original, clone, original.getRegistryManager(), false, keepInventory, true, key); } } } @@ -120,14 +120,14 @@ private static void copyData(ServerPlayerEntity original, ServerPlayerEntity clo Set> keys = ((ComponentProvider) original).getComponentContainer().keys(); for (ComponentKey key : keys) { - copyData(original, clone, lossless, keepInventory, key, !((SwitchablePlayerEntity) original).cca$isSwitchingCharacter()); + copyData(original, clone, original.getRegistryManager(), lossless, keepInventory, !((SwitchablePlayerEntity) original).cca$isSwitchingCharacter(), key); } } - private static void copyData(LivingEntity original, LivingEntity clone, boolean lossless, boolean keepInventory, ComponentKey key, boolean sameCharacter) { + private static void copyData(LivingEntity original, LivingEntity clone, RegistryWrapper.WrapperLookup registryLookup, boolean lossless, boolean keepInventory, boolean sameCharacter, ComponentKey key) { C from = key.get(original); C to = key.get(clone); - RespawnCopyStrategy.get(key, original.getClass()).copyForRespawn(from, to, lossless, keepInventory, sameCharacter); + RespawnCopyStrategy.get(key, original.getClass()).copyForRespawn(from, to, registryLookup, lossless, keepInventory, sameCharacter); } private static void syncEntityComponents(ServerPlayerEntity player, Entity tracked) { diff --git a/cardinal-components-entity/src/main/java/org/ladysnake/cca/internal/entity/CardinalEntityInternals.java b/cardinal-components-entity/src/main/java/org/ladysnake/cca/internal/entity/CardinalEntityInternals.java index b13a0ea4..f04d1ae4 100644 --- a/cardinal-components-entity/src/main/java/org/ladysnake/cca/internal/entity/CardinalEntityInternals.java +++ b/cardinal-components-entity/src/main/java/org/ladysnake/cca/internal/entity/CardinalEntityInternals.java @@ -24,13 +24,14 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; +import net.minecraft.registry.RegistryWrapper; import org.jetbrains.annotations.Nullable; import org.ladysnake.cca.api.v3.component.Component; import org.ladysnake.cca.api.v3.component.ComponentContainer; import org.ladysnake.cca.api.v3.component.ComponentKey; import org.ladysnake.cca.api.v3.component.CopyableComponent; -import org.ladysnake.cca.api.v3.entity.RespawnableComponent; import org.ladysnake.cca.api.v3.entity.RespawnCopyStrategy; +import org.ladysnake.cca.api.v3.entity.RespawnableComponent; import org.ladysnake.cca.internal.base.ComponentsInternals; import java.util.HashMap; @@ -98,23 +99,23 @@ public static RespawnCopyStrategy getRespawnCop return strat == null ? DEFAULT_COPY_STRATEGY : (RespawnCopyStrategy) strat; } - private static void defaultCopyStrategy(Component from, Component to, boolean lossless, boolean keepInventory, boolean sameCharacter) { + private static void defaultCopyStrategy(Component from, Component to, RegistryWrapper.WrapperLookup registryLookup, boolean lossless, boolean keepInventory, boolean sameCharacter) { if (to instanceof RespawnableComponent) { - playerComponentCopy(from, (RespawnableComponent) to, lossless, keepInventory, sameCharacter); + playerComponentCopy(from, (RespawnableComponent) to, registryLookup, lossless, keepInventory, sameCharacter); } else { - RespawnCopyStrategy.LOSSLESS_ONLY.copyForRespawn(from, to, lossless, keepInventory, sameCharacter); + RespawnCopyStrategy.LOSSLESS_ONLY.copyForRespawn(from, to, registryLookup, lossless, keepInventory, sameCharacter); } } @SuppressWarnings("unchecked") - private static void playerComponentCopy(Component from, RespawnableComponent to, boolean lossless, boolean keepInventory, boolean sameCharacter) { + private static void playerComponentCopy(Component from, RespawnableComponent to, RegistryWrapper.WrapperLookup registryLookup, boolean lossless, boolean keepInventory, boolean sameCharacter) { if (to.shouldCopyForRespawn(lossless, keepInventory, sameCharacter)) { - to.copyForRespawn((C) from, lossless, keepInventory, sameCharacter); + to.copyForRespawn((C) from, registryLookup, lossless, keepInventory, sameCharacter); } } @SuppressWarnings("unchecked") - public static void copyAsCopyable(Component from, CopyableComponent to) { - to.copyFrom((C) from); + public static void copyAsCopyable(Component from, CopyableComponent to, RegistryWrapper.WrapperLookup registryLookup) { + to.copyFrom((C) from, registryLookup); } } diff --git a/cardinal-components-entity/src/main/java/org/ladysnake/cca/mixin/entity/common/BucketableMixin.java b/cardinal-components-entity/src/main/java/org/ladysnake/cca/mixin/entity/common/BucketableMixin.java index c2d0dbcb..c03bf093 100644 --- a/cardinal-components-entity/src/main/java/org/ladysnake/cca/mixin/entity/common/BucketableMixin.java +++ b/cardinal-components-entity/src/main/java/org/ladysnake/cca/mixin/entity/common/BucketableMixin.java @@ -22,10 +22,8 @@ */ package org.ladysnake.cca.mixin.entity.common; -import net.minecraft.component.DataComponentTypes; import net.minecraft.entity.Bucketable; import net.minecraft.entity.mob.MobEntity; -import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -36,11 +34,11 @@ public interface BucketableMixin { @Inject(method = "method_57302", at = @At("RETURN")) private static void writeComponentsToStack(MobEntity mobEntity, NbtCompound nbtCompound, CallbackInfo ci) { - mobEntity.asComponentProvider().getComponentContainer().toTag(nbtCompound); + mobEntity.asComponentProvider().getComponentContainer().toTag(nbtCompound, mobEntity.getRegistryManager()); } @Inject(method = "copyDataFromNbt(Lnet/minecraft/entity/mob/MobEntity;Lnet/minecraft/nbt/NbtCompound;)V", at = @At("RETURN")) private static void readComponentsFromStack(MobEntity entity, NbtCompound nbt, CallbackInfo ci) { - entity.asComponentProvider().getComponentContainer().fromTag(nbt); + entity.asComponentProvider().getComponentContainer().fromTag(nbt, entity.getRegistryManager()); } } diff --git a/cardinal-components-entity/src/main/java/org/ladysnake/cca/mixin/entity/common/MixinEntity.java b/cardinal-components-entity/src/main/java/org/ladysnake/cca/mixin/entity/common/MixinEntity.java index a4b4b136..efb2db7c 100644 --- a/cardinal-components-entity/src/main/java/org/ladysnake/cca/mixin/entity/common/MixinEntity.java +++ b/cardinal-components-entity/src/main/java/org/ladysnake/cca/mixin/entity/common/MixinEntity.java @@ -26,6 +26,7 @@ import net.minecraft.entity.Entity; import net.minecraft.nbt.NbtCompound; import net.minecraft.network.RegistryByteBuf; +import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.world.World; import org.ladysnake.cca.api.v3.component.ComponentContainer; @@ -58,6 +59,8 @@ public abstract class MixinEntity implements ComponentProvider { @Shadow public abstract int getId(); + @Shadow public abstract DynamicRegistryManager getRegistryManager(); + @Inject(method = "*", at = @At("RETURN")) private void initDataTracker(CallbackInfo ci) { this.components = CardinalEntityInternals.createEntityComponentContainer((Entity) (Object) this); @@ -65,12 +68,12 @@ private void initDataTracker(CallbackInfo ci) { @Inject(method = "writeNbt", at = @At("RETURN")) private void toTag(NbtCompound inputTag, CallbackInfoReturnable cir) { - this.components.toTag(cir.getReturnValue()); + this.components.toTag(cir.getReturnValue(), getRegistryManager()); } @Inject(method = "readNbt", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;readCustomDataFromNbt(Lnet/minecraft/nbt/NbtCompound;)V", shift = At.Shift.AFTER)) private void fromTag(NbtCompound tag, CallbackInfo ci) { - this.components.fromTag(tag); + this.components.fromTag(tag, getRegistryManager()); } @Nonnull diff --git a/cardinal-components-entity/src/main/resources/fabric.mod.json b/cardinal-components-entity/src/main/resources/fabric.mod.json index e7baede6..e84a16ca 100644 --- a/cardinal-components-entity/src/main/resources/fabric.mod.json +++ b/cardinal-components-entity/src/main/resources/fabric.mod.json @@ -33,7 +33,7 @@ "depends": { "minecraft": ">=1.17-", "fabric-api-base": "*", - "cardinal-components-base": "*" + "cardinal-components-base": ">=6.0.0-beta.2" }, "recommends": { "fabric-networking-api-v1": "*" diff --git a/cardinal-components-entity/src/testmod/java/org/ladysnake/cca/test/entity/PlayerVita.java b/cardinal-components-entity/src/testmod/java/org/ladysnake/cca/test/entity/PlayerVita.java index 3663c353..c8f83b99 100644 --- a/cardinal-components-entity/src/testmod/java/org/ladysnake/cca/test/entity/PlayerVita.java +++ b/cardinal-components-entity/src/testmod/java/org/ladysnake/cca/test/entity/PlayerVita.java @@ -27,6 +27,7 @@ import net.minecraft.network.PacketByteBuf; import net.minecraft.network.RegistryByteBuf; import net.minecraft.particle.ParticleTypes; +import net.minecraft.registry.RegistryWrapper; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import org.jetbrains.annotations.NotNull; @@ -104,8 +105,8 @@ public boolean shouldCopyForRespawn(boolean lossless, boolean keepInventory, boo } @Override - public void copyForRespawn(@NotNull BaseVita original, boolean lossless, boolean keepInventory, boolean switchingCharacter) { - RespawnableComponent.super.copyForRespawn(original, lossless, keepInventory, switchingCharacter); + public void copyForRespawn(@NotNull BaseVita original, RegistryWrapper.WrapperLookup registryLookup, boolean lossless, boolean keepInventory, boolean switchingCharacter) { + RespawnableComponent.super.copyForRespawn(original, registryLookup, lossless, keepInventory, switchingCharacter); if (!lossless && !keepInventory) { this.vitality -= 5; } diff --git a/cardinal-components-level/src/main/java/org/ladysnake/cca/mixin/level/common/LevelStorageMixin.java b/cardinal-components-level/src/main/java/org/ladysnake/cca/mixin/level/common/LevelStorageMixin.java new file mode 100644 index 00000000..416ed8bb --- /dev/null +++ b/cardinal-components-level/src/main/java/org/ladysnake/cca/mixin/level/common/LevelStorageMixin.java @@ -0,0 +1,47 @@ +/* + * Cardinal-Components-API + * Copyright (C) 2019-2024 Ladysnake + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE + * OR OTHER DEALINGS IN THE SOFTWARE. + */ +package org.ladysnake.cca.mixin.level.common; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Local; +import com.mojang.serialization.Dynamic; +import com.mojang.serialization.Lifecycle; +import net.minecraft.registry.DynamicRegistryManager; +import net.minecraft.world.gen.GeneratorOptions; +import net.minecraft.world.level.LevelInfo; +import net.minecraft.world.level.LevelProperties; +import net.minecraft.world.level.storage.LevelStorage; +import org.ladysnake.cca.api.v3.component.ComponentProvider; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(LevelStorage.class) +public class LevelStorageMixin { + @WrapOperation(method = "parseSaveProperties", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/LevelProperties;readProperties(Lcom/mojang/serialization/Dynamic;Lnet/minecraft/world/level/LevelInfo;Lnet/minecraft/world/level/LevelProperties$SpecialProperty;Lnet/minecraft/world/gen/GeneratorOptions;Lcom/mojang/serialization/Lifecycle;)Lnet/minecraft/world/level/LevelProperties;")) + private static LevelProperties readComponents(Dynamic dynamic, LevelInfo info, LevelProperties.SpecialProperty specialProperty, GeneratorOptions generatorOptions, Lifecycle lifecycle, Operation original, @Local(argsOnly = true) DynamicRegistryManager.Immutable registryManager) { + LevelProperties props = original.call(dynamic, info, specialProperty, generatorOptions, lifecycle); + ((ComponentProvider) props).getComponentContainer().fromDynamic(dynamic, registryManager); + return props; + } +} diff --git a/cardinal-components-level/src/main/java/org/ladysnake/cca/mixin/level/common/MixinLevelProperties.java b/cardinal-components-level/src/main/java/org/ladysnake/cca/mixin/level/common/MixinLevelProperties.java index f369ff42..073e5093 100644 --- a/cardinal-components-level/src/main/java/org/ladysnake/cca/mixin/level/common/MixinLevelProperties.java +++ b/cardinal-components-level/src/main/java/org/ladysnake/cca/mixin/level/common/MixinLevelProperties.java @@ -23,7 +23,6 @@ package org.ladysnake.cca.mixin.level.common; import com.mojang.datafixers.util.Unit; -import com.mojang.serialization.Dynamic; import com.mojang.serialization.Lifecycle; import net.minecraft.entity.boss.dragon.EnderDragonFight; import net.minecraft.nbt.NbtCompound; @@ -49,7 +48,6 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import javax.annotation.Nonnull; import java.util.Set; @@ -65,14 +63,9 @@ private void initComponents(NbtCompound playerData, boolean modded, BlockPos spa this.components = StaticLevelComponentPlugin.createContainer(this); } - @Inject(method = "readProperties", at = @At("RETURN")) - private static void readComponents(Dynamic dynamic, LevelInfo info, LevelProperties.SpecialProperty specialProperty, GeneratorOptions generatorOptions, Lifecycle lifecycle, CallbackInfoReturnable cir) { - ((ComponentProvider) cir.getReturnValue()).getComponentContainer().fromDynamic(dynamic); - } - @Inject(method = "updateProperties", at = @At("RETURN")) - private void writeComponents(DynamicRegistryManager tracker, NbtCompound data, NbtCompound player, CallbackInfo ci) { - this.components.toTag(data); + private void writeComponents(DynamicRegistryManager registryManager, NbtCompound data, NbtCompound player, CallbackInfo ci) { + this.components.toTag(data, registryManager); } @Nonnull diff --git a/cardinal-components-level/src/main/resources/fabric.mod.json b/cardinal-components-level/src/main/resources/fabric.mod.json index aa58ece8..cb69ddff 100644 --- a/cardinal-components-level/src/main/resources/fabric.mod.json +++ b/cardinal-components-level/src/main/resources/fabric.mod.json @@ -33,7 +33,7 @@ "depends": { "minecraft": ">=1.17-", "fabric-api-base": "*", - "cardinal-components-base": "*", + "cardinal-components-base": ">=6.0.0-beta.2", "fabric-networking-api-v1": "*" }, "recommends": { diff --git a/cardinal-components-level/src/main/resources/mixins.cardinal_components_level.json b/cardinal-components-level/src/main/resources/mixins.cardinal_components_level.json index b321dc95..6d2ffb08 100644 --- a/cardinal-components-level/src/main/resources/mixins.cardinal_components_level.json +++ b/cardinal-components-level/src/main/resources/mixins.cardinal_components_level.json @@ -7,6 +7,7 @@ "client.MixinClientWorldProperties" ], "mixins": [ + "common.LevelStorageMixin", "common.MixinLevelProperties", "common.MixinMinecraftServer", "common.MixinUnmodifiableLevelProperties", diff --git a/cardinal-components-scoreboard/src/main/java/org/ladysnake/cca/mixin/scoreboard/MixinScoreboardState.java b/cardinal-components-scoreboard/src/main/java/org/ladysnake/cca/mixin/scoreboard/MixinScoreboardState.java index 19d1ac96..7a3b65ad 100644 --- a/cardinal-components-scoreboard/src/main/java/org/ladysnake/cca/mixin/scoreboard/MixinScoreboardState.java +++ b/cardinal-components-scoreboard/src/main/java/org/ladysnake/cca/mixin/scoreboard/MixinScoreboardState.java @@ -26,11 +26,9 @@ import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtList; import net.minecraft.registry.RegistryWrapper; -import net.minecraft.scoreboard.AbstractTeam; import net.minecraft.scoreboard.Scoreboard; import net.minecraft.scoreboard.ScoreboardState; import net.minecraft.scoreboard.Team; -import net.minecraft.text.Text; import org.ladysnake.cca.api.v3.component.ComponentProvider; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -39,10 +37,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -import java.util.Collection; -import java.util.Iterator; @Mixin(ScoreboardState.class) public abstract class MixinScoreboardState { @@ -51,13 +45,13 @@ public abstract class MixinScoreboardState { private Scoreboard scoreboard; @Inject(method = "writeNbt", at = @At("RETURN")) - private void saveComponents(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup, CallbackInfoReturnable cir) { - ((ComponentProvider) this.scoreboard).getComponentContainer().toTag(tag); + private void saveComponents(NbtCompound tag, RegistryWrapper.WrapperLookup registries, CallbackInfoReturnable cir) { + ((ComponentProvider) this.scoreboard).getComponentContainer().toTag(tag, registries); } @Inject(method = "readNbt", at = @At("RETURN")) private void loadComponents(NbtCompound tag, RegistryWrapper.WrapperLookup registries, CallbackInfoReturnable cir) { - ((ComponentProvider) this.scoreboard).getComponentContainer().fromTag(tag); + ((ComponentProvider) this.scoreboard).getComponentContainer().fromTag(tag, registries); } @Inject( @@ -69,7 +63,7 @@ private void loadComponents(NbtCompound tag, RegistryWrapper.WrapperLookup regis ) ) private void loadTeamComponents(NbtList nbt, RegistryWrapper.WrapperLookup registries, CallbackInfo ci, @Local NbtCompound teamData, @Local Team team) { - ((ComponentProvider) team).getComponentContainer().fromTag(teamData); + ((ComponentProvider) team).getComponentContainer().fromTag(teamData, registries); } @Inject( @@ -80,10 +74,11 @@ private void loadTeamComponents(NbtList nbt, RegistryWrapper.WrapperLookup regis ) ) private void saveTeamComponents( + RegistryWrapper.WrapperLookup registries, CallbackInfoReturnable cir, @Local Team team, @Local NbtCompound teamData ) { - ((ComponentProvider) team).getComponentContainer().toTag(teamData); + ((ComponentProvider) team).getComponentContainer().toTag(teamData, registries); } } diff --git a/cardinal-components-scoreboard/src/main/resources/fabric.mod.json b/cardinal-components-scoreboard/src/main/resources/fabric.mod.json index dd09340a..2c17d9ac 100644 --- a/cardinal-components-scoreboard/src/main/resources/fabric.mod.json +++ b/cardinal-components-scoreboard/src/main/resources/fabric.mod.json @@ -36,7 +36,7 @@ "depends": { "minecraft": ">=1.17-", "fabric-api-base": "*", - "cardinal-components-base": "*" + "cardinal-components-base": ">=6.0.0-beta.2" }, "authors": [ "Pyrofab" diff --git a/cardinal-components-world/src/main/java/org/ladysnake/cca/internal/world/ComponentPersistentState.java b/cardinal-components-world/src/main/java/org/ladysnake/cca/internal/world/ComponentPersistentState.java index 4db75e25..eea68a2e 100644 --- a/cardinal-components-world/src/main/java/org/ladysnake/cca/internal/world/ComponentPersistentState.java +++ b/cardinal-components-world/src/main/java/org/ladysnake/cca/internal/world/ComponentPersistentState.java @@ -34,7 +34,7 @@ public class ComponentPersistentState extends PersistentState { public static Type getType(ComponentContainer components) { return new Type<>( () -> new ComponentPersistentState(components), - (tag, w) -> ComponentPersistentState.fromNbt(components, tag), + (tag, registryLookup) -> ComponentPersistentState.fromNbt(components, tag, registryLookup), DataFixTypes.LEVEL ); } @@ -52,13 +52,13 @@ public boolean isDirty() { } @Override - public NbtCompound writeNbt(NbtCompound tag, RegistryWrapper.WrapperLookup w) { - return this.components.toTag(tag); + public NbtCompound writeNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { + return this.components.toTag(tag, registryLookup); } - public static ComponentPersistentState fromNbt(ComponentContainer components, NbtCompound tag) { + public static ComponentPersistentState fromNbt(ComponentContainer components, NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) { ComponentPersistentState state = new ComponentPersistentState(components); - state.components.fromTag(tag); + state.components.fromTag(tag, registryLookup); return state; } } diff --git a/cardinal-components-world/src/main/resources/fabric.mod.json b/cardinal-components-world/src/main/resources/fabric.mod.json index 1556faf7..d88b3be0 100644 --- a/cardinal-components-world/src/main/resources/fabric.mod.json +++ b/cardinal-components-world/src/main/resources/fabric.mod.json @@ -33,7 +33,7 @@ "depends": { "minecraft": ">=1.17-", "fabric-api-base": "*", - "cardinal-components-base": "*", + "cardinal-components-base": ">=6.0.0-beta.2", "fabric-networking-api-v1": "*" }, "authors": [ diff --git a/changelog.md b/changelog.md index 622501cc..ebe8e6ca 100644 --- a/changelog.md +++ b/changelog.md @@ -5,6 +5,18 @@ Updated to 1.20.5 This update introduces multiple breaking changes - a migration guide is available on [the Ladysnake website](https://ladysnake.org/wiki/cardinal-components-api/upgrade-instructions/CCA-6-changes). +### Beta 2 + +**Changes** +- All the serialization methods now take an additional registry lookup argument + - [Relevant migration guide](https://ladysnake.org/wiki/cardinal-components-api/upgrade-instructions/CCA-6-changes#serialization) +- Warning: due to the above change, level components may not be deserialized correctly if a mod calls `LevelProperties.readProperties` instead of `LevelStorage.parseSaveProperties` + +**Removals** +- The deprecated `util` package in `cardinal-components-block` has been removed + +### Beta 1 + **Additions** - Added `C2SSelfMessagingComponent`, a new experimental utility interface to simplify client-to-server messaging on player components - Added `WorldComponentRegistry#registerFor` methods, allowing for dimension-specific world components diff --git a/gradle.properties b/gradle.properties index dd47753f..bd6f480e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ org.gradle.parallel=true fabric.loom.multiProjectOptimisation=true #see https://fabricmc.net/develop/ -minecraft_version=1.20.5-rc2 +minecraft_version=1.20.5 yarn_mappings=1 loader_version=0.15.10 #Fabric api @@ -13,11 +13,11 @@ fabric_api_version=0.97.3+1.20.5 elmendorf_version=0.12.0-SNAPSHOT #Publishing -mod_version = 6.0.0-beta.1 +mod_version = 6.0.0-beta.2 curseforge_id = 318449 modrinth_id = K01OU20C -curseforge_versions = 1.20.5-Snapshot -modrinth_versions = 1.20.5-rc2 +curseforge_versions = 1.20.5 +modrinth_versions = 1.20.5 release_type = beta display_name = Cardinal-Components-API owners = Ladysnake