From c9d82ab2d87e05388c950e5d84b27c63f21961fd Mon Sep 17 00:00:00 2001 From: fishshi <2855691008@qq.com> Date: Tue, 19 Nov 2024 02:07:45 +0800 Subject: [PATCH 1/8] Change outdated setPredicate to addPredicate. (#4234) --- .../fabric/api/command/v2/EntitySelectorOptionRegistry.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fabric-command-api-v2/src/main/java/net/fabricmc/fabric/api/command/v2/EntitySelectorOptionRegistry.java b/fabric-command-api-v2/src/main/java/net/fabricmc/fabric/api/command/v2/EntitySelectorOptionRegistry.java index 376da379b4..22edcb091c 100644 --- a/fabric-command-api-v2/src/main/java/net/fabricmc/fabric/api/command/v2/EntitySelectorOptionRegistry.java +++ b/fabric-command-api-v2/src/main/java/net/fabricmc/fabric/api/command/v2/EntitySelectorOptionRegistry.java @@ -46,7 +46,7 @@ private EntitySelectorOptionRegistry() { * final float minHealth = reader.getReader().readFloat(); * * if (minHealth > 0) { - * reader.setPredicate((entity) -> entity instanceof LivingEntity livingEntity && livingEntity.getHealth() >= minHealth); + * reader.addPredicate((entity) -> entity instanceof LivingEntity livingEntity && livingEntity.getHealth() >= minHealth); * } * }, * (reader) -> true From 119c825665ad17f4872c9e64d795b22c47222c45 Mon Sep 17 00:00:00 2001 From: modmuss Date: Mon, 18 Nov 2024 18:07:19 +0000 Subject: [PATCH 2/8] Fix client test random crashes (#4224) * Fix client test random crashes * Improve * Even easier (cherry picked from commit 8ca5486fd5d46fc1995a01f65b2eb0b6e3d10607) --- .../base/client/mixin/MinecraftDedicatedServerMixin.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fabric-api-base/src/testmodClient/java/net/fabricmc/fabric/test/base/client/mixin/MinecraftDedicatedServerMixin.java b/fabric-api-base/src/testmodClient/java/net/fabricmc/fabric/test/base/client/mixin/MinecraftDedicatedServerMixin.java index c8fff56a39..e53a5256ed 100644 --- a/fabric-api-base/src/testmodClient/java/net/fabricmc/fabric/test/base/client/mixin/MinecraftDedicatedServerMixin.java +++ b/fabric-api-base/src/testmodClient/java/net/fabricmc/fabric/test/base/client/mixin/MinecraftDedicatedServerMixin.java @@ -16,6 +16,8 @@ package net.fabricmc.fabric.test.base.client.mixin; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -32,4 +34,10 @@ private void captureServerInstance(CallbackInfoReturnable cir) { // Capture the server instance once the server is ready to be connected to TestDedicatedServer.DEDICATED_SERVER_REF.set((MinecraftDedicatedServer) (Object) this); } + + // Don't call shutdownExecutors as we are running the dedi server within the client process. + @WrapOperation(method = "shutdown", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Util;shutdownExecutors()V")) + private void dontStopExecutors(Operation original) { + // Never needed, as this is a client mixin. + } } From dbad41f1cb79e3f4c6f9de44635e3d38dbbc6051 Mon Sep 17 00:00:00 2001 From: modmuss Date: Mon, 18 Nov 2024 18:07:34 +0000 Subject: [PATCH 3/8] Provide a RegistryByteBuf for attachment syncing (#4223) * Provide a RegistryByteBuf for attachment syncing * None breaking? * Slight improvement * Test syncing an item stack * Jdoc fix * Jdoc fix (cherry picked from commit 9aea556b88ab720cc2739c291841ed290e50fb92) --- .../api/attachment/v1/AttachmentRegistry.java | 4 +-- .../attachment/AttachmentRegistryImpl.java | 7 ++-- .../impl/attachment/AttachmentTargetImpl.java | 3 ++ .../impl/attachment/AttachmentTypeImpl.java | 4 +-- .../attachment/sync/AttachmentChange.java | 35 +++++++++++++------ .../attachment/AttachmentTargetsMixin.java | 4 +-- .../mixin/attachment/BlockEntityMixin.java | 6 ++++ .../fabric/mixin/attachment/ChunkMixin.java | 7 ++++ .../fabric/mixin/attachment/EntityMixin.java | 6 ++++ .../mixin/attachment/ServerWorldMixin.java | 5 +++ .../mixin/attachment/WorldChunkMixin.java | 6 ++++ .../fabric/mixin/attachment/WorldMixin.java | 9 +++++ .../attachment/WrapperProtoChunkMixin.java | 6 ++++ .../test/attachment/AttachmentTestMod.java | 25 ++++++++++--- .../client/AttachmentTestModClient.java | 6 ++++ 15 files changed, 110 insertions(+), 23 deletions(-) diff --git a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/api/attachment/v1/AttachmentRegistry.java b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/api/attachment/v1/AttachmentRegistry.java index f549342529..2a9b9d96f3 100644 --- a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/api/attachment/v1/AttachmentRegistry.java +++ b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/api/attachment/v1/AttachmentRegistry.java @@ -22,7 +22,7 @@ import com.mojang.serialization.Codec; import org.jetbrains.annotations.ApiStatus; -import net.minecraft.network.PacketByteBuf; +import net.minecraft.network.RegistryByteBuf; import net.minecraft.network.codec.PacketCodec; import net.minecraft.util.Identifier; @@ -157,7 +157,7 @@ public interface Builder { * @param syncPredicate an {@link AttachmentSyncPredicate} determining with which clients to synchronize data * @return the builder */ - AttachmentRegistry.Builder syncWith(PacketCodec packetCodec, AttachmentSyncPredicate syncPredicate); + AttachmentRegistry.Builder syncWith(PacketCodec packetCodec, AttachmentSyncPredicate syncPredicate); /** * Builds and registers the {@link AttachmentType}. diff --git a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentRegistryImpl.java b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentRegistryImpl.java index ae60764783..305c24105a 100644 --- a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentRegistryImpl.java +++ b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentRegistryImpl.java @@ -29,7 +29,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import net.minecraft.network.PacketByteBuf; +import net.minecraft.network.RegistryByteBuf; import net.minecraft.network.codec.PacketCodec; import net.minecraft.util.Identifier; @@ -80,7 +80,7 @@ public static class BuilderImpl implements AttachmentRegistry.Builder { @Nullable private Codec persistenceCodec = null; @Nullable - private PacketCodec packetCodec = null; + private PacketCodec packetCodec = null; @Nullable private AttachmentSyncPredicate syncPredicate = null; private boolean copyOnDeath = false; @@ -107,7 +107,8 @@ public AttachmentRegistry.Builder initializer(Supplier initializer) { return this; } - public AttachmentRegistry.Builder syncWith(PacketCodec packetCodec, AttachmentSyncPredicate syncPredicate) { + @Deprecated + public AttachmentRegistry.Builder syncWith(PacketCodec packetCodec, AttachmentSyncPredicate syncPredicate) { Objects.requireNonNull(packetCodec, "packet codec cannot be null"); Objects.requireNonNull(syncPredicate, "sync predicate cannot be null"); diff --git a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentTargetImpl.java b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentTargetImpl.java index 0794002fa2..0b445cbe86 100644 --- a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentTargetImpl.java +++ b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentTargetImpl.java @@ -22,6 +22,7 @@ import org.jetbrains.annotations.Nullable; import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.registry.RegistryWrapper; import net.minecraft.server.network.ServerPlayerEntity; @@ -93,4 +94,6 @@ default void fabric_markChanged(AttachmentType type) { default boolean fabric_shouldTryToSync() { throw new UnsupportedOperationException("Implemented via mixin"); } + + DynamicRegistryManager fabric_getDynamicRegistryManager(); } diff --git a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentTypeImpl.java b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentTypeImpl.java index a316442e27..7d44bd1663 100644 --- a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentTypeImpl.java +++ b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/AttachmentTypeImpl.java @@ -21,7 +21,7 @@ import com.mojang.serialization.Codec; import org.jetbrains.annotations.Nullable; -import net.minecraft.network.PacketByteBuf; +import net.minecraft.network.RegistryByteBuf; import net.minecraft.network.codec.PacketCodec; import net.minecraft.util.Identifier; @@ -32,7 +32,7 @@ public record AttachmentTypeImpl( Identifier identifier, @Nullable Supplier initializer, @Nullable Codec persistenceCodec, - @Nullable PacketCodec packetCodec, + @Nullable PacketCodec packetCodec, @Nullable AttachmentSyncPredicate syncPredicate, boolean copyOnDeath ) implements AttachmentType { diff --git a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/sync/AttachmentChange.java b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/sync/AttachmentChange.java index ca4eab840b..990659fc16 100644 --- a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/sync/AttachmentChange.java +++ b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/impl/attachment/sync/AttachmentChange.java @@ -20,15 +20,16 @@ import java.util.Comparator; import java.util.List; import java.util.Objects; -import java.util.Optional; import java.util.Set; import io.netty.buffer.Unpooled; import org.jetbrains.annotations.Nullable; 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.DynamicRegistryManager; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.Identifier; import net.minecraft.world.World; @@ -57,12 +58,20 @@ public record AttachmentChange(AttachmentTargetInfo targetInfo, AttachmentTyp private static final int MAX_DATA_SIZE_IN_BYTES = CustomPayloadS2CPacketAccessor.getMaxPayloadSize() - MAX_PADDING_SIZE_IN_BYTES; @SuppressWarnings("unchecked") - public static AttachmentChange create(AttachmentTargetInfo targetInfo, AttachmentType type, @Nullable Object value) { - PacketCodec codec = (PacketCodec) ((AttachmentTypeImpl) type).packetCodec(); + public static AttachmentChange create(AttachmentTargetInfo targetInfo, AttachmentType type, @Nullable Object value, DynamicRegistryManager dynamicRegistryManager) { + PacketCodec codec = (PacketCodec) ((AttachmentTypeImpl) type).packetCodec(); Objects.requireNonNull(codec, "attachment packet codec cannot be null"); + Objects.requireNonNull(dynamicRegistryManager, "dynamic registry manager cannot be null"); + + RegistryByteBuf buf = new RegistryByteBuf(PacketByteBufs.create(), dynamicRegistryManager); + + if (value != null) { + buf.writeBoolean(true); + codec.encode(buf, value); + } else { + buf.writeBoolean(false); + } - PacketByteBuf buf = PacketByteBufs.create(); - buf.writeOptional(Optional.ofNullable(value), codec); byte[] encoded = buf.array(); if (encoded.length > MAX_DATA_SIZE_IN_BYTES) { @@ -109,15 +118,21 @@ public static void partitionAndSendPackets(List changes, Serve @SuppressWarnings("unchecked") @Nullable - public Object decodeValue() { - PacketCodec codec = (PacketCodec) ((AttachmentTypeImpl) type).packetCodec(); + public Object decodeValue(DynamicRegistryManager dynamicRegistryManager) { + PacketCodec codec = (PacketCodec) ((AttachmentTypeImpl) type).packetCodec(); Objects.requireNonNull(codec, "codec was null"); + Objects.requireNonNull(dynamicRegistryManager, "dynamic registry manager cannot be null"); + + RegistryByteBuf buf = new RegistryByteBuf(Unpooled.copiedBuffer(data), dynamicRegistryManager); + + if (!buf.readBoolean()) { + return null; + } - PacketByteBuf buf = new PacketByteBuf(Unpooled.copiedBuffer(data)); - return buf.readOptional(codec).orElse(null); + return codec.decode(buf); } public void apply(World world) { - targetInfo.getTarget(world).setAttached((AttachmentType) type, decodeValue()); + targetInfo.getTarget(world).setAttached((AttachmentType) type, decodeValue(world.getRegistryManager())); } } diff --git a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/AttachmentTargetsMixin.java b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/AttachmentTargetsMixin.java index 2ff585c7ef..bdf2edda75 100644 --- a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/AttachmentTargetsMixin.java +++ b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/AttachmentTargetsMixin.java @@ -61,7 +61,7 @@ public T setAttached(AttachmentType type, @Nullable T value) { this.fabric_markChanged(type); if (this.fabric_shouldTryToSync() && type.isSynced()) { - AttachmentChange change = AttachmentChange.create(fabric_getSyncTargetInfo(), type, value); + AttachmentChange change = AttachmentChange.create(fabric_getSyncTargetInfo(), type, value, fabric_getDynamicRegistryManager()); acknowledgeSyncedEntry(type, change); this.fabric_syncChange(type, new AttachmentSyncPayloadS2C(List.of(change))); } @@ -118,7 +118,7 @@ public boolean fabric_hasPersistentAttachments() { @Unique private void acknowledgeSynced(AttachmentType type, Object value) { - acknowledgeSyncedEntry(type, AttachmentChange.create(fabric_getSyncTargetInfo(), type, value)); + acknowledgeSyncedEntry(type, AttachmentChange.create(fabric_getSyncTargetInfo(), type, value, fabric_getDynamicRegistryManager())); } @Unique diff --git a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/BlockEntityMixin.java b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/BlockEntityMixin.java index 4155442394..4409821079 100644 --- a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/BlockEntityMixin.java +++ b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/BlockEntityMixin.java @@ -27,6 +27,7 @@ import net.minecraft.block.entity.BlockEntity; import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.registry.RegistryWrapper; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -95,4 +96,9 @@ public boolean fabric_shouldTryToSync() { // Persistent attachments are read at a time with no world return !this.hasWorld() || !this.world.isClient(); } + + @Override + public DynamicRegistryManager fabric_getDynamicRegistryManager() { + return this.world.getRegistryManager(); + } } diff --git a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/ChunkMixin.java b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/ChunkMixin.java index e819d8be53..20c5eaa280 100644 --- a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/ChunkMixin.java +++ b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/ChunkMixin.java @@ -20,6 +20,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.util.math.ChunkPos; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.ChunkStatus; @@ -67,4 +68,10 @@ public boolean fabric_shouldTryToSync() { // ProtoChunk or EmptyChunk return false; } + + @Override + public DynamicRegistryManager fabric_getDynamicRegistryManager() { + // Should never happen as this is only used for sync + throw new UnsupportedOperationException("Chunk does not have a DynamicRegistryManager."); + } } diff --git a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/EntityMixin.java b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/EntityMixin.java index 1bfffcccf4..c5c21499c6 100644 --- a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/EntityMixin.java +++ b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/EntityMixin.java @@ -25,6 +25,7 @@ import net.minecraft.entity.Entity; import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.world.World; @@ -89,4 +90,9 @@ public void fabric_syncChange(AttachmentType type, AttachmentSyncPayloadS2C p public boolean fabric_shouldTryToSync() { return !this.getWorld().isClient(); } + + @Override + public DynamicRegistryManager fabric_getDynamicRegistryManager() { + return this.getWorld().getRegistryManager(); + } } diff --git a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/ServerWorldMixin.java b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/ServerWorldMixin.java index 84c6849c87..0caf25cc97 100644 --- a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/ServerWorldMixin.java +++ b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/ServerWorldMixin.java @@ -89,4 +89,9 @@ public void fabric_syncChange(AttachmentType type, AttachmentSyncPayloadS2C p public AttachmentTargetInfo fabric_getSyncTargetInfo() { return AttachmentTargetInfo.WorldTarget.INSTANCE; } + + @Override + public DynamicRegistryManager fabric_getDynamicRegistryManager() { + return getRegistryManager(); + } } diff --git a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/WorldChunkMixin.java b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/WorldChunkMixin.java index 4fae99a96b..e7d774e61a 100644 --- a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/WorldChunkMixin.java +++ b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/WorldChunkMixin.java @@ -27,6 +27,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import net.minecraft.block.entity.BlockEntity; +import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; @@ -83,4 +84,9 @@ public void fabric_syncChange(AttachmentType type, AttachmentSyncPayloadS2C p public boolean fabric_shouldTryToSync() { return !this.world.isClient(); } + + @Override + public DynamicRegistryManager fabric_getDynamicRegistryManager() { + return world.getRegistryManager(); + } } diff --git a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/WorldMixin.java b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/WorldMixin.java index bc8a89c690..1c983fbffc 100644 --- a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/WorldMixin.java +++ b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/WorldMixin.java @@ -19,6 +19,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.world.World; import net.fabricmc.fabric.impl.attachment.AttachmentTargetImpl; @@ -28,8 +29,16 @@ abstract class WorldMixin implements AttachmentTargetImpl { @Shadow public abstract boolean isClient(); + @Shadow + public abstract DynamicRegistryManager getRegistryManager(); + @Override public boolean fabric_shouldTryToSync() { return !this.isClient(); } + + @Override + public DynamicRegistryManager fabric_getDynamicRegistryManager() { + return getRegistryManager(); + } } diff --git a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/WrapperProtoChunkMixin.java b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/WrapperProtoChunkMixin.java index 870dd55210..4fce194e5a 100644 --- a/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/WrapperProtoChunkMixin.java +++ b/fabric-data-attachment-api-v1/src/main/java/net/fabricmc/fabric/mixin/attachment/WrapperProtoChunkMixin.java @@ -25,6 +25,7 @@ import org.spongepowered.asm.mixin.Shadow; import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.registry.RegistryWrapper; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.world.chunk.WorldChunk; @@ -103,4 +104,9 @@ public void fabric_syncChange(AttachmentType type, AttachmentSyncPayloadS2C p public void fabric_markChanged(AttachmentType type) { ((AttachmentTargetImpl) wrapped).fabric_markChanged(type); } + + @Override + public DynamicRegistryManager fabric_getDynamicRegistryManager() { + return ((AttachmentTargetImpl) wrapped).fabric_getDynamicRegistryManager(); + } } diff --git a/fabric-data-attachment-api-v1/src/testmod/java/net/fabricmc/fabric/test/attachment/AttachmentTestMod.java b/fabric-data-attachment-api-v1/src/testmod/java/net/fabricmc/fabric/test/attachment/AttachmentTestMod.java index 2b68408a48..ef99103ec8 100644 --- a/fabric-data-attachment-api-v1/src/testmod/java/net/fabricmc/fabric/test/attachment/AttachmentTestMod.java +++ b/fabric-data-attachment-api-v1/src/testmod/java/net/fabricmc/fabric/test/attachment/AttachmentTestMod.java @@ -34,12 +34,15 @@ import net.minecraft.command.argument.BlockPosArgumentType; import net.minecraft.command.argument.ColumnPosArgumentType; import net.minecraft.command.argument.EntityArgumentType; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.item.ItemStack; import net.minecraft.network.codec.PacketCodecs; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKeys; import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.text.Text; import net.minecraft.util.Identifier; @@ -63,6 +66,7 @@ import net.fabricmc.fabric.api.biome.v1.BiomeSelectors; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; public class AttachmentTestMod implements ModInitializer { @@ -80,28 +84,35 @@ public class AttachmentTestMod implements ModInitializer { builder -> builder .initializer(() -> false) .persistent(Codec.BOOL) - .syncWith(PacketCodecs.BOOL.cast(), AttachmentSyncPredicate.all()) + .syncWith(PacketCodecs.BOOL, AttachmentSyncPredicate.all()) ); public static final AttachmentType SYNCED_WITH_TARGET = AttachmentRegistry.create( Identifier.of(MOD_ID, "synced_target"), builder -> builder .initializer(() -> false) .persistent(Codec.BOOL) - .syncWith(PacketCodecs.BOOL.cast(), AttachmentSyncPredicate.targetOnly()) + .syncWith(PacketCodecs.BOOL, AttachmentSyncPredicate.targetOnly()) ); public static final AttachmentType SYNCED_EXCEPT_TARGET = AttachmentRegistry.create( Identifier.of(MOD_ID, "synced_except_target"), builder -> builder .initializer(() -> false) .persistent(Codec.BOOL) - .syncWith(PacketCodecs.BOOL.cast(), AttachmentSyncPredicate.allButTarget()) + .syncWith(PacketCodecs.BOOL, AttachmentSyncPredicate.allButTarget()) ); public static final AttachmentType SYNCED_CREATIVE_ONLY = AttachmentRegistry.create( Identifier.of(MOD_ID, "synced_custom"), builder -> builder .initializer(() -> false) .persistent(Codec.BOOL) - .syncWith(PacketCodecs.BOOL.cast(), (target, player) -> player.isCreative()) + .syncWith(PacketCodecs.BOOL, (target, player) -> player.isCreative()) + ); + public static final AttachmentType SYNCED_ITEM = AttachmentRegistry.create( + Identifier.of(MOD_ID, "synced_item"), + builder -> builder + .initializer(() -> ItemStack.EMPTY) + .persistent(ItemStack.CODEC) + .syncWith(ItemStack.OPTIONAL_PACKET_CODEC, AttachmentSyncPredicate.all()) ); public static final SimpleCommandExceptionType TARGET_NOT_FOUND = new SimpleCommandExceptionType(Text.literal("Target not found")); @@ -196,6 +207,12 @@ public void onInitialize() { .then(buildCommandForKind("others_only", "all but self", SYNCED_EXCEPT_TARGET)) .then(buildCommandForKind("creative_only", "creative players only", SYNCED_CREATIVE_ONLY)) )); + + ServerEntityEvents.EQUIPMENT_CHANGE.register((livingEntity, equipmentSlot, previousStack, currentStack) -> { + if (equipmentSlot == EquipmentSlot.HEAD && livingEntity instanceof ServerPlayerEntity player) { + player.setAttached(SYNCED_ITEM, currentStack); + } + }); } private static LiteralArgumentBuilder buildCommandForKind(String id, String syncedWith, AttachmentType type) { diff --git a/fabric-data-attachment-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/attachment/client/AttachmentTestModClient.java b/fabric-data-attachment-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/attachment/client/AttachmentTestModClient.java index 3f8e7068ea..1d9f9c33ce 100644 --- a/fabric-data-attachment-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/attachment/client/AttachmentTestModClient.java +++ b/fabric-data-attachment-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/attachment/client/AttachmentTestModClient.java @@ -37,6 +37,7 @@ import net.minecraft.command.argument.UuidArgumentType; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; import net.minecraft.text.Text; import net.minecraft.util.Colors; import net.minecraft.util.math.BlockPos; @@ -99,6 +100,11 @@ private static void displayClientAttachmentInfo( Text.literal("Synced-with-creative attachment: %s".formatted(attCustom)) .withColor(attCustom ? target instanceof PlayerEntity p && p.isCreative() ? Colors.GREEN : Colors.RED : Colors.WHITE) ); + ItemStack stack = target.getAttachedOrCreate(AttachmentTestMod.SYNCED_ITEM); + context.getSource().sendFeedback( + Text.literal("Synced-item attachment: %s".formatted(stack)) + .withColor(attOther ? target != MinecraftClient.getInstance().player ? Colors.GREEN : Colors.RED : Colors.WHITE) + ); } @Override From b3265b6593c8d020eb8a753df9736e0f62b9a180 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Mon, 18 Nov 2024 18:34:11 +0000 Subject: [PATCH 4/8] Bump version --- gradle.properties | 72 +++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/gradle.properties b/gradle.properties index 86923fb2ed..b390eb0f7a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ org.gradle.jvmargs=-Xmx2560M org.gradle.parallel=true -version=0.108.0 +version=0.109.0 minecraft_version=1.21.3 yarn_version=+build.1 loader_version=0.16.8 @@ -11,51 +11,51 @@ prerelease=false curseforge_minecraft_version=1.21.3 # Do not manually update, use the bumpversions task: -fabric-api-base-version=0.4.49 -fabric-api-lookup-api-v1-version=1.6.80 +fabric-api-base-version=0.4.50 +fabric-api-lookup-api-v1-version=1.6.81 fabric-biome-api-v1-version=14.0.6 fabric-block-api-v1-version=1.0.28 fabric-block-view-api-v2-version=1.0.16 -fabric-blockrenderlayer-v1-version=2.0.3 -fabric-command-api-v1-version=1.2.57 -fabric-command-api-v2-version=2.2.36 -fabric-commands-v0-version=0.2.74 -fabric-content-registries-v0-version=9.1.7 +fabric-blockrenderlayer-v1-version=2.0.4 +fabric-command-api-v1-version=1.2.58 +fabric-command-api-v2-version=2.2.37 +fabric-commands-v0-version=0.2.75 +fabric-content-registries-v0-version=9.1.8 fabric-crash-report-info-v1-version=0.3.3 -fabric-data-attachment-api-v1-version=1.3.0 -fabric-data-generation-api-v1-version=21.0.16 +fabric-data-attachment-api-v1-version=1.4.0 +fabric-data-generation-api-v1-version=21.0.17 fabric-dimensions-v1-version=4.0.7 -fabric-entity-events-v1-version=2.0.7 -fabric-events-interaction-v0-version=2.0.11 +fabric-entity-events-v1-version=2.0.8 +fabric-events-interaction-v0-version=2.0.12 fabric-game-rule-api-v1-version=1.0.59 -fabric-gametest-api-v1-version=2.0.14 -fabric-item-api-v1-version=11.1.6 -fabric-item-group-api-v1-version=4.1.16 +fabric-gametest-api-v1-version=2.0.15 +fabric-item-api-v1-version=11.1.7 +fabric-item-group-api-v1-version=4.1.17 fabric-key-binding-api-v1-version=1.0.53 fabric-keybindings-v0-version=0.2.51 -fabric-lifecycle-events-v1-version=2.5.0 -fabric-loot-api-v2-version=3.0.25 -fabric-loot-api-v3-version=1.0.13 -fabric-message-api-v1-version=6.0.20 -fabric-model-loading-api-v1-version=3.0.8 -fabric-networking-api-v1-version=4.3.4 -fabric-object-builder-api-v1-version=17.0.8 -fabric-particles-v1-version=4.0.9 -fabric-recipe-api-v1-version=7.0.3 -fabric-registry-sync-v0-version=5.2.1 -fabric-renderer-api-v1-version=4.0.4 -fabric-renderer-indigo-version=1.9.4 +fabric-lifecycle-events-v1-version=2.5.1 +fabric-loot-api-v2-version=3.0.26 +fabric-loot-api-v3-version=1.0.14 +fabric-message-api-v1-version=6.0.21 +fabric-model-loading-api-v1-version=3.0.9 +fabric-networking-api-v1-version=4.3.5 +fabric-object-builder-api-v1-version=17.0.9 +fabric-particles-v1-version=4.0.10 +fabric-recipe-api-v1-version=7.0.4 +fabric-registry-sync-v0-version=5.2.2 +fabric-renderer-api-v1-version=4.0.5 +fabric-renderer-indigo-version=1.9.5 fabric-rendering-data-attachment-v1-version=0.3.54 -fabric-rendering-fluids-v1-version=3.1.14 -fabric-rendering-v0-version=1.1.82 -fabric-rendering-v1-version=8.0.6 +fabric-rendering-fluids-v1-version=3.1.15 +fabric-rendering-v0-version=1.1.83 +fabric-rendering-v1-version=8.0.7 fabric-resource-conditions-api-v1-version=5.0.8 fabric-resource-loader-v0-version=3.0.6 -fabric-screen-api-v1-version=2.0.33 -fabric-screen-handler-api-v1-version=1.3.99 +fabric-screen-api-v1-version=2.0.34 +fabric-screen-handler-api-v1-version=1.3.100 fabric-sound-api-v1-version=1.0.29 -fabric-transfer-api-v1-version=5.4.2 +fabric-transfer-api-v1-version=5.4.3 fabric-transitive-access-wideners-v1-version=6.1.8 -fabric-convention-tags-v1-version=2.1.2 -fabric-convention-tags-v2-version=2.9.2 -fabric-client-tags-api-v1-version=1.1.23 +fabric-convention-tags-v1-version=2.1.3 +fabric-convention-tags-v2-version=2.9.3 +fabric-client-tags-api-v1-version=1.1.24 From 54a41b1cc9c5db2f89c85e18a34c3bcff27e2b8e Mon Sep 17 00:00:00 2001 From: Daniel Orr Date: Mon, 25 Nov 2024 18:13:21 +0000 Subject: [PATCH 5/8] Add transitive access wideners for tracked data related creator entity methods (#4229) * feat: transitive access wideners for display entity fields * fix: change display transitive access widener collector to check for dataTracker accesses * fix: incorrect method names & comments * refactor: move getMethodParameterCount to use existing lib * feat: InteractionEntity methods & missing method from DisplayEntity --- .../build.gradle | 63 ++++++++++++++++++- ...ransitive-access-wideners-v1.accesswidener | 49 +++++++++++++++ 2 files changed, 110 insertions(+), 2 deletions(-) diff --git a/fabric-transitive-access-wideners-v1/build.gradle b/fabric-transitive-access-wideners-v1/build.gradle index 07d55ff508..0225e34bfb 100644 --- a/fabric-transitive-access-wideners-v1/build.gradle +++ b/fabric-transitive-access-wideners-v1/build.gradle @@ -11,6 +11,8 @@ testDependencies(project, [ import org.objectweb.asm.ClassReader +import org.objectweb.asm.ClassVisitor +import org.objectweb.asm.MethodVisitor import org.objectweb.asm.Opcodes import org.objectweb.asm.Type import org.objectweb.asm.tree.ClassNode @@ -19,7 +21,6 @@ import java.nio.file.FileSystem import java.nio.file.FileSystems import java.nio.file.Files import java.nio.file.Path -import java.util.stream.Collectors task generateAccessWidener { doLast { @@ -38,6 +39,8 @@ task generateAccessWidener { lines.add("") generateItemConstructors(lines, fs) lines.add("") + generateCreatorEntityTrackedDataMethods(lines, fs) + lines.add("") } Path clientJar = loom.namedMinecraftProvider.parentMinecraftProvider.clientOnlyJar.path @@ -128,11 +131,67 @@ def generateRenderPhaseInnerClasses(List lines, FileSystem fs) { } } +def generateTrackedDataFields(String className, List lines, FileSystem fs, String... extraMethods) { + // using a set to prevent duplicates from multiple dataTracker references in a single method + // linked to preserve order and improve generated access widener readability + Set collectedWideners = new LinkedHashSet<>() + + loadClass(fs.getPath("${className}.class")).accept( + new ClassVisitor(Opcodes.ASM9) { + @Override + MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { + boolean isExtra = extraMethods.contains(name) + if (!isExtra) { + // check for desired methods + if (!name.startsWith("get") && !name.startsWith("set")) { + return null + } + + // check methods as genuine basic getter/setters + int parameterCount = Type.getArgumentCount(descriptor) + + if (name.startsWith("get") && parameterCount != 0) { + return null + } + + if (name.startsWith("set") && parameterCount != 1) { + return null + } + } else { + println name + } + + return new MethodVisitor(Opcodes.ASM9) { + @Override + void visitFieldInsn(int opcode, String owner, String fieldName, String fieldDescriptor) { + // check references its dataTracker field + if (isExtra || (fieldName == "dataTracker" && opcode == Opcodes.GETFIELD)) { + collectedWideners.add("transitive-accessible method $className $name $descriptor") + } + } + } + } + } + ) + + lines.addAll(collectedWideners) +} + +def generateCreatorEntityTrackedDataMethods(List lines, FileSystem fs) { + lines.add("# Private tracked data related methods of DisplayEntity (plus its subclasses) and InteractionEntity") + + generateTrackedDataFields("net/minecraft/entity/decoration/DisplayEntity", lines, fs, "getTransformation") + generateTrackedDataFields("net/minecraft/entity/decoration/DisplayEntity\$ItemDisplayEntity", lines, fs) + generateTrackedDataFields("net/minecraft/entity/decoration/DisplayEntity\$BlockDisplayEntity", lines, fs) + generateTrackedDataFields("net/minecraft/entity/decoration/DisplayEntity\$TextDisplayEntity", lines, fs) + generateTrackedDataFields("net/minecraft/entity/decoration/InteractionEntity", lines, fs, "shouldRespond") +} + ClassNode loadClass(Path path) { def node = new ClassNode() Files.newInputStream(path).withCloseable { is -> - new ClassReader(is).accept(node, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES) + new ClassReader(is).accept(node, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES) } return node diff --git a/fabric-transitive-access-wideners-v1/src/main/resources/fabric-transitive-access-wideners-v1.accesswidener b/fabric-transitive-access-wideners-v1/src/main/resources/fabric-transitive-access-wideners-v1.accesswidener index d1686acf2e..7f1e267a1d 100644 --- a/fabric-transitive-access-wideners-v1/src/main/resources/fabric-transitive-access-wideners-v1.accesswidener +++ b/fabric-transitive-access-wideners-v1/src/main/resources/fabric-transitive-access-wideners-v1.accesswidener @@ -242,6 +242,55 @@ transitive-accessible method net/minecraft/block/WitherSkullBlock (Lnet/m # Constructors of non-abstract item classes transitive-accessible method net/minecraft/item/MiningToolItem (Lnet/minecraft/item/ToolMaterial;Lnet/minecraft/registry/tag/TagKey;FFLnet/minecraft/item/Item$Settings;)V +# Private tracked data related methods of DisplayEntity (plus its subclasses) and InteractionEntity +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getTransformation (Lnet/minecraft/entity/data/DataTracker;)Lnet/minecraft/util/math/AffineTransformation; +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setTransformation (Lnet/minecraft/util/math/AffineTransformation;)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setInterpolationDuration (I)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getInterpolationDuration ()I +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setStartInterpolation (I)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getStartInterpolation ()I +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setTeleportDuration (I)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getTeleportDuration ()I +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setBillboardMode (Lnet/minecraft/entity/decoration/DisplayEntity$BillboardMode;)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getBillboardMode ()Lnet/minecraft/entity/decoration/DisplayEntity$BillboardMode; +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setBrightness (Lnet/minecraft/entity/decoration/Brightness;)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getBrightnessUnpacked ()Lnet/minecraft/entity/decoration/Brightness; +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getBrightness ()I +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setViewRange (F)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getViewRange ()F +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setShadowRadius (F)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getShadowRadius ()F +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setShadowStrength (F)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getShadowStrength ()F +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setDisplayWidth (F)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getDisplayWidth ()F +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setDisplayHeight (F)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getGlowColorOverride ()I +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity setGlowColorOverride (I)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity getDisplayHeight ()F +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$ItemDisplayEntity getItemStack ()Lnet/minecraft/item/ItemStack; +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$ItemDisplayEntity setItemStack (Lnet/minecraft/item/ItemStack;)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$ItemDisplayEntity setTransformationMode (Lnet/minecraft/item/ModelTransformationMode;)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$ItemDisplayEntity getTransformationMode ()Lnet/minecraft/item/ModelTransformationMode; +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$BlockDisplayEntity getBlockState ()Lnet/minecraft/block/BlockState; +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$BlockDisplayEntity setBlockState (Lnet/minecraft/block/BlockState;)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity getText ()Lnet/minecraft/text/Text; +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity setText (Lnet/minecraft/text/Text;)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity getLineWidth ()I +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity setLineWidth (I)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity getTextOpacity ()B +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity setTextOpacity (B)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity getBackground ()I +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity setBackground (I)V +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity getDisplayFlags ()B +transitive-accessible method net/minecraft/entity/decoration/DisplayEntity$TextDisplayEntity setDisplayFlags (B)V +transitive-accessible method net/minecraft/entity/decoration/InteractionEntity setInteractionWidth (F)V +transitive-accessible method net/minecraft/entity/decoration/InteractionEntity getInteractionWidth ()F +transitive-accessible method net/minecraft/entity/decoration/InteractionEntity setInteractionHeight (F)V +transitive-accessible method net/minecraft/entity/decoration/InteractionEntity getInteractionHeight ()F +transitive-accessible method net/minecraft/entity/decoration/InteractionEntity setResponse (Z)V +transitive-accessible method net/minecraft/entity/decoration/InteractionEntity shouldRespond ()Z + # Protected static fields of RenderPhase transitive-accessible field net/minecraft/client/render/RenderPhase NO_TRANSPARENCY Lnet/minecraft/client/render/RenderPhase$Transparency; transitive-accessible field net/minecraft/client/render/RenderPhase ADDITIVE_TRANSPARENCY Lnet/minecraft/client/render/RenderPhase$Transparency; From 2758bfbf6642e58959c4b9ed375a7235822338a0 Mon Sep 17 00:00:00 2001 From: modmuss Date: Mon, 25 Nov 2024 18:12:59 +0000 Subject: [PATCH 6/8] Add RegistryEntryAddedCallback.allEntries (#4235) * Add RegistryEntryAddedCallback.allEntries * Pass a RegistryEntry.Reference * Remove some temp test code * Add note about recursion. (cherry picked from commit aa5b2ca19e535fb47029fb360d297b085b9a21f9) --- .../registry/RegistryEntryAddedCallback.java | 37 +++++++ .../sync/RegistryEntryAddedCallbackTest.java | 98 +++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 fabric-registry-sync-v0/src/test/java/net/fabricmc/fabric/test/registry/sync/RegistryEntryAddedCallbackTest.java diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/RegistryEntryAddedCallback.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/RegistryEntryAddedCallback.java index dc6cf7056d..d4f7aba294 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/RegistryEntryAddedCallback.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/api/event/registry/RegistryEntryAddedCallback.java @@ -16,17 +16,54 @@ package net.fabricmc.fabric.api.event.registry; +import java.util.function.Consumer; + import net.minecraft.registry.Registry; +import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.util.Identifier; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.impl.registry.sync.ListenableRegistry; +/** + * An event for when an entry is added to a registry. + * + * @param the type of the entry within the registry + */ @FunctionalInterface public interface RegistryEntryAddedCallback { + /** + * Called when a new entry is added to the registry. + * + * @param rawId the raw id of the entry + * @param id the identifier of the entry + * @param object the object that was added + */ void onEntryAdded(int rawId, Identifier id, T object); + /** + * Get the {@link Event} for the {@link RegistryEntryAddedCallback} for the given registry. + * + * @param registry the registry to get the event for + * @return the event + */ static Event> event(Registry registry) { return ListenableRegistry.get(registry).fabric_getAddObjectEvent(); } + + /** + * Register a callback for all present and future entries in the registry. + * + *

Note: The callback is recursive and will be invoked for anything registered within the callback itself. + * + * @param registry the registry to listen to + * @param consumer the callback that accepts a {@link RegistryEntry.Reference} + */ + static void allEntries(Registry registry, Consumer> consumer) { + event(registry).register((rawId, id, object) -> consumer.accept(registry.getEntry(id).orElseThrow())); + // Call the consumer for all existing entries, after registering the callback. + // This way if the callback registers a new entry, it will also be called for that entry. + // It is also important to take a copy of the registry with .toList() to avoid concurrent modification exceptions if the callback modifies the registry. + registry.streamEntries().toList().forEach(consumer); + } } diff --git a/fabric-registry-sync-v0/src/test/java/net/fabricmc/fabric/test/registry/sync/RegistryEntryAddedCallbackTest.java b/fabric-registry-sync-v0/src/test/java/net/fabricmc/fabric/test/registry/sync/RegistryEntryAddedCallbackTest.java new file mode 100644 index 0000000000..16f3bc0e14 --- /dev/null +++ b/fabric-registry-sync-v0/src/test/java/net/fabricmc/fabric/test/registry/sync/RegistryEntryAddedCallbackTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.test.registry.sync; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import java.util.List; +import java.util.UUID; +import java.util.function.Consumer; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import net.minecraft.Bootstrap; +import net.minecraft.SharedConstants; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.SimpleRegistry; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.util.Identifier; + +import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder; +import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback; + +public class RegistryEntryAddedCallbackTest { + @Mock + private Consumer> mockConsumer; + + @Captor + private ArgumentCaptor> captor; + + @BeforeAll + static void beforeAll() { + SharedConstants.createGameVersion(); + Bootstrap.initialize(); + } + + @BeforeEach + void beforeEach() { + MockitoAnnotations.openMocks(this); + } + + @Test + void testEntryAddedCallback() { + RegistryKey> testRegistryKey = RegistryKey.ofRegistry(id(UUID.randomUUID().toString())); + SimpleRegistry testRegistry = FabricRegistryBuilder.createSimple(testRegistryKey) + .buildAndRegister(); + + Registry.register(testRegistry, id("before"), "before"); + RegistryEntryAddedCallback.allEntries(testRegistry, mockConsumer); + + // Test that the callback can register new entries. + RegistryEntryAddedCallback.allEntries(testRegistry, s -> { + if (s.value().equals("before")) { + Registry.register(testRegistry, id("during"), "during"); + } + }); + + Registry.register(testRegistry, id("after"), "after"); + + verify(mockConsumer, times(3)).accept(captor.capture()); + + List values = captor.getAllValues() + .stream() + .map(RegistryEntry.Reference::value) + .toList(); + + assertEquals(3, values.size()); + assertEquals("before", values.getFirst()); + assertEquals("during", values.get(1)); + assertEquals("after", values.get(2)); + } + + private static Identifier id(String path) { + return Identifier.of("registry_sync_test_entry_added_test", path); + } +} From 69228316a925a5727f40c0cf4560ecfa01d8e5cb Mon Sep 17 00:00:00 2001 From: JustRed23 Date: Mon, 25 Nov 2024 19:23:30 +0100 Subject: [PATCH 7/8] Fix AFTER_SETUP event not being able to render (#4219) * Add BEFORE_TERRAIN world render event * Add 1.21.2 rendering issue warning * Add comment to injection point * close b tag * Undo all new event changes * Move AFTER_SETUP event to new mixin * Remove event interface * Refine mixin --- .../mixin/client/rendering/WorldRendererMixin.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/WorldRendererMixin.java b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/WorldRendererMixin.java index 4ad26b87c4..81caf02f3f 100644 --- a/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/WorldRendererMixin.java +++ b/fabric-rendering-v1/src/client/java/net/fabricmc/fabric/mixin/client/rendering/WorldRendererMixin.java @@ -80,6 +80,18 @@ private void beforeRender(ObjectAllocator objectAllocator, RenderTickCounter tic @Inject(method = "setupTerrain", at = @At("RETURN")) private void afterTerrainSetup(Camera camera, Frustum frustum, boolean hasForcedFrustum, boolean spectator, CallbackInfo ci) { context.setFrustum(frustum); + } + + @Inject( + method = "method_62214", + at = @At( + value = "INVOKE_STRING", + target = "Lnet/minecraft/util/profiler/Profiler;push(Ljava/lang/String;)V", + args = "ldc=terrain", + shift = Shift.AFTER + ) // Points to after profiler.push("terrain"); + ) + private void beforeTerrainSolid(CallbackInfo ci) { WorldRenderEvents.AFTER_SETUP.invoker().afterSetup(context); } From 57a05fcb162f4a3c92ca2fca74148090b315ceb4 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Mon, 25 Nov 2024 18:27:34 +0000 Subject: [PATCH 8/8] Bump version --- gradle.properties | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gradle.properties b/gradle.properties index b390eb0f7a..63d79c4564 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ org.gradle.jvmargs=-Xmx2560M org.gradle.parallel=true -version=0.109.0 +version=0.110.0 minecraft_version=1.21.3 yarn_version=+build.1 loader_version=0.16.8 @@ -23,7 +23,7 @@ fabric-commands-v0-version=0.2.75 fabric-content-registries-v0-version=9.1.8 fabric-crash-report-info-v1-version=0.3.3 fabric-data-attachment-api-v1-version=1.4.0 -fabric-data-generation-api-v1-version=21.0.17 +fabric-data-generation-api-v1-version=21.0.18 fabric-dimensions-v1-version=4.0.7 fabric-entity-events-v1-version=2.0.8 fabric-events-interaction-v0-version=2.0.12 @@ -42,20 +42,20 @@ fabric-networking-api-v1-version=4.3.5 fabric-object-builder-api-v1-version=17.0.9 fabric-particles-v1-version=4.0.10 fabric-recipe-api-v1-version=7.0.4 -fabric-registry-sync-v0-version=5.2.2 +fabric-registry-sync-v0-version=5.3.0 fabric-renderer-api-v1-version=4.0.5 fabric-renderer-indigo-version=1.9.5 fabric-rendering-data-attachment-v1-version=0.3.54 fabric-rendering-fluids-v1-version=3.1.15 -fabric-rendering-v0-version=1.1.83 -fabric-rendering-v1-version=8.0.7 +fabric-rendering-v0-version=1.1.84 +fabric-rendering-v1-version=8.0.8 fabric-resource-conditions-api-v1-version=5.0.8 fabric-resource-loader-v0-version=3.0.6 fabric-screen-api-v1-version=2.0.34 -fabric-screen-handler-api-v1-version=1.3.100 +fabric-screen-handler-api-v1-version=1.3.101 fabric-sound-api-v1-version=1.0.29 fabric-transfer-api-v1-version=5.4.3 -fabric-transitive-access-wideners-v1-version=6.1.8 +fabric-transitive-access-wideners-v1-version=6.2.0 fabric-convention-tags-v1-version=2.1.3 fabric-convention-tags-v2-version=2.9.3 fabric-client-tags-api-v1-version=1.1.24