diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 3af486f9f..0965479be 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -11,7 +11,7 @@ jobs: uses: actions/setup-java@v2 with: distribution: 'adopt' - java-version: '17' + java-version: '21' - name: Validate gradlew integrity uses: gradle/wrapper-validation-action@v1 - name: Restore cache diff --git a/Fabric/build.gradle b/Fabric/build.gradle index b172490b4..66ac61813 100644 --- a/Fabric/build.gradle +++ b/Fabric/build.gradle @@ -61,15 +61,15 @@ dependencies { minecraft "com.mojang:minecraft:${mc_version}" mappings loom.officialMojangMappings() - modImplementation "net.fabricmc:fabric-loader:0.15.3" + modImplementation "net.fabricmc:fabric-loader:0.15.11" - modImplementation "net.fabricmc.fabric-api:fabric-api:0.92.1+1.20.4" + modImplementation "net.fabricmc.fabric-api:fabric-api:0.100.0+1.20.6" compileOnly project(":Xplat") - modCompileOnly "mezz.jei:jei-1.20.4-common-api:17.0.0.30" + modCompileOnly "mezz.jei:jei-1.20.6-common-api:18.0.0.62" - modCompileOnly("me.shedaniel:RoughlyEnoughItems-api-fabric:14.0.688") { transitive = false } - modCompileOnly("me.shedaniel.cloth:cloth-config-fabric:13.0.121") { transitive = false } + modCompileOnly("me.shedaniel:RoughlyEnoughItems-api-fabric:16.0.729") { transitive = false } + modCompileOnly("me.shedaniel.cloth:cloth-config-fabric:14.0.126") { transitive = false } } compileJava { diff --git a/Fabric/src/main/java/vazkii/patchouli/fabric/client/FabricClientInitializer.java b/Fabric/src/main/java/vazkii/patchouli/fabric/client/FabricClientInitializer.java index 55b650314..dfb412879 100644 --- a/Fabric/src/main/java/vazkii/patchouli/fabric/client/FabricClientInitializer.java +++ b/Fabric/src/main/java/vazkii/patchouli/fabric/client/FabricClientInitializer.java @@ -33,6 +33,8 @@ import vazkii.patchouli.common.item.PatchouliItems; import vazkii.patchouli.fabric.network.FabricMessageOpenBookGui; import vazkii.patchouli.fabric.network.FabricMessageReloadBookContents; +import vazkii.patchouli.network.MessageOpenBookGui; +import vazkii.patchouli.network.MessageReloadBookContents; import org.jetbrains.annotations.Nullable; @@ -50,8 +52,8 @@ public void onInitializeClient() { UseBlockCallback.EVENT.register(MultiblockVisualizationHandler::onPlayerInteract); ClientTickEvents.END_CLIENT_TICK.register(MultiblockVisualizationHandler::onClientTick); HudRenderCallback.EVENT.register(MultiblockVisualizationHandler::onRenderHUD); - ClientPlayNetworking.registerGlobalReceiver(FabricMessageOpenBookGui.ID, FabricMessageOpenBookGui::handle); - ClientPlayNetworking.registerGlobalReceiver(FabricMessageReloadBookContents.ID, FabricMessageReloadBookContents::handle); + ClientPlayNetworking.registerGlobalReceiver(MessageOpenBookGui.TYPE, FabricMessageOpenBookGui::handle); + ClientPlayNetworking.registerGlobalReceiver(MessageReloadBookContents.TYPE, FabricMessageReloadBookContents::handle); ModelLoadingPlugin.register(pluginContext -> { for (Book book : BookRegistry.INSTANCE.books.values()) { diff --git a/Fabric/src/main/java/vazkii/patchouli/fabric/common/FabricModInitializer.java b/Fabric/src/main/java/vazkii/patchouli/fabric/common/FabricModInitializer.java index f197fc75b..e2839c8ca 100644 --- a/Fabric/src/main/java/vazkii/patchouli/fabric/common/FabricModInitializer.java +++ b/Fabric/src/main/java/vazkii/patchouli/fabric/common/FabricModInitializer.java @@ -5,6 +5,7 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.event.player.UseBlockCallback; import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; @@ -19,19 +20,25 @@ import vazkii.patchouli.common.handler.LecternEventHandler; import vazkii.patchouli.common.handler.ReloadContentsHandler; import vazkii.patchouli.common.item.ItemModBook; +import vazkii.patchouli.common.item.PatchouliDataComponents; import vazkii.patchouli.common.item.PatchouliItems; +import vazkii.patchouli.network.MessageOpenBookGui; +import vazkii.patchouli.network.MessageReloadBookContents; public class FabricModInitializer implements ModInitializer { @Override public void onInitialize() { PatchouliSounds.submitRegistrations((id, e) -> Registry.register(BuiltInRegistries.SOUND_EVENT, id, e)); + PatchouliDataComponents.submitDataComponentRegistrations((id, e) -> Registry.register(BuiltInRegistries.DATA_COMPONENT_TYPE, id, e)); PatchouliItems.submitItemRegistrations((id, e) -> Registry.register(BuiltInRegistries.ITEM, id, e)); - PatchouliItems.submitRecipeSerializerRegistrations((id, e) -> Registry.register(BuiltInRegistries.RECIPE_SERIALIZER, id, e)); PatchouliCriteriaTriggers.submitTriggerRegistrations((id, e) -> Registry.register(BuiltInRegistries.TRIGGER_TYPES, id, e)); FiberPatchouliConfig.setup(); CommandRegistrationCallback.EVENT.register((disp, buildCtx, selection) -> OpenBookCommand.register(disp)); UseBlockCallback.EVENT.register(LecternEventHandler::rightClick); + PayloadTypeRegistry.playS2C().register(MessageOpenBookGui.TYPE, MessageOpenBookGui.CODEC); + PayloadTypeRegistry.playS2C().register(MessageReloadBookContents.TYPE, MessageReloadBookContents.CODEC); + BookRegistry.INSTANCE.init(); ServerLifecycleEvents.END_DATA_PACK_RELOAD.register((server, _r, success) -> { diff --git a/Fabric/src/main/java/vazkii/patchouli/fabric/network/FabricMessageOpenBookGui.java b/Fabric/src/main/java/vazkii/patchouli/fabric/network/FabricMessageOpenBookGui.java index 808fcdde8..8506c2ac9 100644 --- a/Fabric/src/main/java/vazkii/patchouli/fabric/network/FabricMessageOpenBookGui.java +++ b/Fabric/src/main/java/vazkii/patchouli/fabric/network/FabricMessageOpenBookGui.java @@ -1,44 +1,25 @@ package vazkii.patchouli.fabric.network; -import net.fabricmc.fabric.api.networking.v1.PacketSender; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientPacketListener; -import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; -import vazkii.patchouli.api.PatchouliAPI; import vazkii.patchouli.client.book.ClientBookRegistry; +import vazkii.patchouli.network.MessageOpenBookGui; import org.jetbrains.annotations.Nullable; - -import io.netty.buffer.Unpooled; - public class FabricMessageOpenBookGui { - public static final ResourceLocation ID = new ResourceLocation(PatchouliAPI.MOD_ID, "open_book"); public static void send(ServerPlayer player, ResourceLocation book, @Nullable ResourceLocation entry, int page) { - FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer()); - buf.writeResourceLocation(book); - buf.writeUtf(entry == null ? "" : entry.toString()); - buf.writeVarInt(page); - ServerPlayNetworking.send(player, ID, buf); + ServerPlayNetworking.send(player, new MessageOpenBookGui(book, entry, page)); } - public static void handle(Minecraft client, ClientPacketListener handler, FriendlyByteBuf buf, PacketSender responseSender) { - ResourceLocation book = buf.readResourceLocation(); - ResourceLocation entry; - String tmp = buf.readUtf(); - if (tmp.isEmpty()) { - entry = null; - } else { - entry = ResourceLocation.tryParse(tmp); - } - - int page = buf.readVarInt(); - client.submit(() -> ClientBookRegistry.INSTANCE.displayBookGui(book, entry, page)); + public static void handle(MessageOpenBookGui message, ClientPlayNetworking.Context handler) { + Minecraft client = handler.client(); + client.submit(() -> ClientBookRegistry.INSTANCE.displayBookGui(message.book(), message.entry(), message.page())); } } diff --git a/Fabric/src/main/java/vazkii/patchouli/fabric/network/FabricMessageReloadBookContents.java b/Fabric/src/main/java/vazkii/patchouli/fabric/network/FabricMessageReloadBookContents.java index 16b8d63eb..c810c4796 100644 --- a/Fabric/src/main/java/vazkii/patchouli/fabric/network/FabricMessageReloadBookContents.java +++ b/Fabric/src/main/java/vazkii/patchouli/fabric/network/FabricMessageReloadBookContents.java @@ -1,34 +1,27 @@ package vazkii.patchouli.fabric.network; -import net.fabricmc.fabric.api.networking.v1.PacketSender; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.networking.v1.PlayerLookup; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientPacketListener; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; -import vazkii.patchouli.api.PatchouliAPI; import vazkii.patchouli.client.book.ClientBookRegistry; - - -import io.netty.buffer.Unpooled; +import vazkii.patchouli.network.MessageReloadBookContents; public class FabricMessageReloadBookContents { - public static final ResourceLocation ID = new ResourceLocation(PatchouliAPI.MOD_ID, "reload_books"); public static void sendToAll(MinecraftServer server) { PlayerLookup.all(server).forEach(FabricMessageReloadBookContents::send); } public static void send(ServerPlayer player) { - FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.EMPTY_BUFFER); - ServerPlayNetworking.send(player, ID, buf); + ServerPlayNetworking.send(player, new MessageReloadBookContents()); } - public static void handle(Minecraft client, ClientPacketListener handler, FriendlyByteBuf buf, PacketSender responseSender) { + public static void handle(MessageReloadBookContents message, ClientPlayNetworking.Context handler) { + Minecraft client = handler.client(); client.submit(() -> ClientBookRegistry.INSTANCE.reload()); } } diff --git a/Fabric/src/main/resources/fabric.mod.json b/Fabric/src/main/resources/fabric.mod.json index 5bb6b8b83..d19ee8dea 100644 --- a/Fabric/src/main/resources/fabric.mod.json +++ b/Fabric/src/main/resources/fabric.mod.json @@ -35,8 +35,8 @@ ], "depends": { - "fabricloader": ">=0.14.21", - "fabric": ">=0.87.0", - "minecraft": ">=1.20.1 <1.21" + "fabricloader": ">=0.15.10", + "fabric": ">=0.97.6", + "minecraft": ">=1.20.6 <1.21" } } diff --git a/Fabric/src/main/resources/patchouli_fabric.mixins.json b/Fabric/src/main/resources/patchouli_fabric.mixins.json index 292ac1483..6ade76686 100644 --- a/Fabric/src/main/resources/patchouli_fabric.mixins.json +++ b/Fabric/src/main/resources/patchouli_fabric.mixins.json @@ -2,7 +2,7 @@ "required": true, "minVersion": "0.8", "package": "vazkii.patchouli.mixin", - "compatibilityLevel": "JAVA_17", + "compatibilityLevel": "JAVA_21", "mixins": [ ], "client": [ diff --git a/Jenkinsfile b/Jenkinsfile index 098abeceb..a5968e837 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -6,7 +6,7 @@ pipeline { } agent any tools { - jdk "jdk-17.0.1" + jdk "jdk-21.0.2" } stages { stage('Clean') { diff --git a/NeoForge/build.gradle b/NeoForge/build.gradle index a5d8c16cc..06002dea0 100644 --- a/NeoForge/build.gradle +++ b/NeoForge/build.gradle @@ -37,11 +37,16 @@ runs { } dependencies { - implementation "net.neoforged:neoforge:20.4.173" + implementation "net.neoforged:neoforge:20.6.115" implementation project(":Xplat") - compileOnly "mezz.jei:jei-1.20.4-common-api:17.0.0.30" - testCompileOnly "mezz.jei:jei-1.20.4-common-api:17.0.0.30" + compileOnly "mezz.jei:jei-1.20.6-common-api:18.0.0.62" + testCompileOnly "mezz.jei:jei-1.20.6-common-api:18.0.0.62" +} + +tasks.named('test').configure { + //Disable builtin test as we have JUnit enabled in Xplat + enabled(false) } TaskCollection.metaClass.excludingNeoTasks = { -> diff --git a/NeoForge/src/main/java/vazkii/patchouli/neoforge/client/NeoForgeClientInitializer.java b/NeoForge/src/main/java/vazkii/patchouli/neoforge/client/NeoForgeClientInitializer.java index e0c0296ed..c715e3af7 100644 --- a/NeoForge/src/main/java/vazkii/patchouli/neoforge/client/NeoForgeClientInitializer.java +++ b/NeoForge/src/main/java/vazkii/patchouli/neoforge/client/NeoForgeClientInitializer.java @@ -9,12 +9,17 @@ import net.minecraft.world.InteractionResult; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.Mod; +import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; -import net.neoforged.neoforge.client.event.*; -import net.neoforged.neoforge.client.gui.overlay.VanillaGuiOverlay; +import net.neoforged.neoforge.client.event.ClientPlayerNetworkEvent; +import net.neoforged.neoforge.client.event.ClientTickEvent; +import net.neoforged.neoforge.client.event.ModelEvent; +import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent; +import net.neoforged.neoforge.client.event.RegisterGuiLayersEvent; +import net.neoforged.neoforge.client.event.RenderFrameEvent; +import net.neoforged.neoforge.client.event.RenderTooltipEvent; +import net.neoforged.neoforge.client.gui.VanillaGuiLayers; import net.neoforged.neoforge.common.NeoForge; -import net.neoforged.neoforge.event.TickEvent; import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent; import vazkii.patchouli.api.PatchouliAPI; @@ -36,7 +41,7 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -@Mod.EventBusSubscriber(modid = PatchouliAPI.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) +@EventBusSubscriber(modid = PatchouliAPI.MOD_ID, bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) public class NeoForgeClientInitializer { /** * Why are these necessary? @@ -99,12 +104,12 @@ public static void registerReloadListeners(RegisterClientReloadListenersEvent e) } @SubscribeEvent - public static void registerOverlays(RegisterGuiOverlaysEvent evt) { - evt.registerAbove(VanillaGuiOverlay.CROSSHAIR.id(), new ResourceLocation(PatchouliAPI.MOD_ID, "book_overlay"), - (gui, poseStack, partialTick, width, height) -> BookRightClickHandler.onRenderHUD(poseStack, partialTick) + public static void registerOverlays(RegisterGuiLayersEvent evt) { + evt.registerAbove(VanillaGuiLayers.CROSSHAIR, new ResourceLocation(PatchouliAPI.MOD_ID, "book_overlay"), + BookRightClickHandler::onRenderHUD ); - evt.registerBelow(VanillaGuiOverlay.BOSS_EVENT_PROGRESS.id(), new ResourceLocation(PatchouliAPI.MOD_ID, "multiblock_progress"), - (gui, poseStack, partialTick, width, height) -> MultiblockVisualizationHandler.onRenderHUD(poseStack, partialTick) + evt.registerBelow(VanillaGuiLayers.BOSS_OVERLAY, new ResourceLocation(PatchouliAPI.MOD_ID, "multiblock_progress"), + MultiblockVisualizationHandler::onRenderHUD ); } @@ -112,10 +117,8 @@ public static void registerOverlays(RegisterGuiOverlaysEvent evt) { public static void onInitializeClient(FMLClientSetupEvent evt) { ClientBookRegistry.INSTANCE.init(); PersistentData.setup(); - NeoForge.EVENT_BUS.addListener((TickEvent.ClientTickEvent e) -> { - if (e.phase == TickEvent.Phase.END) { - ClientTicker.endClientTick(Minecraft.getInstance()); - } + NeoForge.EVENT_BUS.addListener((ClientTickEvent.Post e) -> { + ClientTicker.endClientTick(Minecraft.getInstance()); }); NeoForge.EVENT_BUS.addListener((PlayerInteractEvent.RightClickBlock e) -> BookRightClickHandler.onRightClick(e.getEntity(), e.getLevel(), e.getHand(), e.getHitVec())); NeoForge.EVENT_BUS.addListener((PlayerInteractEvent.RightClickBlock e) -> { @@ -125,18 +128,15 @@ public static void onInitializeClient(FMLClientSetupEvent evt) { e.setCancellationResult(result); } }); - NeoForge.EVENT_BUS.addListener((TickEvent.ClientTickEvent e) -> { - if (e.phase == TickEvent.Phase.END) { - MultiblockVisualizationHandler.onClientTick(Minecraft.getInstance()); - } + NeoForge.EVENT_BUS.addListener((ClientTickEvent.Post e) -> { + MultiblockVisualizationHandler.onClientTick(Minecraft.getInstance()); }); - NeoForge.EVENT_BUS.addListener((TickEvent.RenderTickEvent e) -> { - if (e.phase == TickEvent.Phase.START) { - ClientTicker.renderTickStart(e.renderTickTime); - } else { - ClientTicker.renderTickEnd(); - } + NeoForge.EVENT_BUS.addListener((RenderFrameEvent.Pre e) -> { + ClientTicker.renderTickStart(e.getPartialTick()); + }); + NeoForge.EVENT_BUS.addListener((RenderFrameEvent.Post e) -> { + ClientTicker.renderTickEnd(); }); NeoForge.EVENT_BUS.addListener((ClientPlayerNetworkEvent.LoggingOut e) -> { diff --git a/NeoForge/src/main/java/vazkii/patchouli/neoforge/common/NeoForgeModInitializer.java b/NeoForge/src/main/java/vazkii/patchouli/neoforge/common/NeoForgeModInitializer.java index 0dbecd5ff..4a8b5c458 100644 --- a/NeoForge/src/main/java/vazkii/patchouli/neoforge/common/NeoForgeModInitializer.java +++ b/NeoForge/src/main/java/vazkii/patchouli/neoforge/common/NeoForgeModInitializer.java @@ -1,10 +1,14 @@ package vazkii.patchouli.neoforge.common; import net.minecraft.core.registries.Registries; +import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.CreativeModeTabs; import net.minecraft.world.item.ItemStack; +import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.Mod; import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; import net.neoforged.neoforge.common.CreativeModeTabRegistry; @@ -23,14 +27,15 @@ import vazkii.patchouli.common.handler.LecternEventHandler; import vazkii.patchouli.common.handler.ReloadContentsHandler; import vazkii.patchouli.common.item.ItemModBook; +import vazkii.patchouli.common.item.PatchouliDataComponents; import vazkii.patchouli.common.item.PatchouliItems; import vazkii.patchouli.neoforge.network.NeoForgeNetworkHandler; -@Mod.EventBusSubscriber(modid = PatchouliAPI.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) +@EventBusSubscriber(modid = PatchouliAPI.MOD_ID, bus = EventBusSubscriber.Bus.MOD) @Mod(PatchouliAPI.MOD_ID) public class NeoForgeModInitializer { - public NeoForgeModInitializer(IEventBus eventBus) { - NeoForgePatchouliConfig.setup(); + public NeoForgeModInitializer(IEventBus eventBus, Dist dist, ModContainer container) { + NeoForgePatchouliConfig.setup(container); eventBus.addListener(NeoForgeNetworkHandler::setupPackets); } @@ -40,12 +45,12 @@ public static void register(RegisterEvent evt) { evt.register(Registries.SOUND_EVENT, rh -> { PatchouliSounds.submitRegistrations(rh::register); }); + evt.register(Registries.DATA_COMPONENT_TYPE, rh -> { + PatchouliDataComponents.submitDataComponentRegistrations(rh::register); + }); evt.register(Registries.ITEM, rh -> { PatchouliItems.submitItemRegistrations(rh::register); }); - evt.register(Registries.RECIPE_SERIALIZER, rh -> { - PatchouliItems.submitRecipeSerializerRegistrations(rh::register); - }); evt.register(Registries.TRIGGER_TYPE, rh -> PatchouliCriteriaTriggers.submitTriggerRegistrations(rh::register)); } @@ -55,7 +60,7 @@ public static void processCreativeTabs(BuildCreativeModeTabContentsEvent evt) { if (!b.noBook) { ItemStack book = ItemModBook.forBook(b); if (evt.getTab() == CreativeModeTabs.searchTab()) { - evt.accept(book); + evt.accept(book, CreativeModeTab.TabVisibility.SEARCH_TAB_ONLY); } else if (b.creativeTab != null) { if (evt.getTab() == CreativeModeTabRegistry.getTab(b.creativeTab)) { evt.accept(book); diff --git a/NeoForge/src/main/java/vazkii/patchouli/neoforge/common/NeoForgePatchouliConfig.java b/NeoForge/src/main/java/vazkii/patchouli/neoforge/common/NeoForgePatchouliConfig.java index 66b1f1cff..21be1ca6d 100644 --- a/NeoForge/src/main/java/vazkii/patchouli/neoforge/common/NeoForgePatchouliConfig.java +++ b/NeoForge/src/main/java/vazkii/patchouli/neoforge/common/NeoForgePatchouliConfig.java @@ -1,7 +1,7 @@ package vazkii.patchouli.neoforge.common; import net.minecraft.resources.ResourceLocation; -import net.neoforged.fml.ModLoadingContext; +import net.neoforged.fml.ModContainer; import net.neoforged.fml.config.ModConfig; import net.neoforged.neoforge.common.ModConfigSpec; @@ -55,8 +55,8 @@ public class NeoForgePatchouliConfig { SPEC = builder.build(); } - public static void setup() { - ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, SPEC); + public static void setup(ModContainer container) { + container.registerConfig(ModConfig.Type.CLIENT, SPEC); PatchouliConfig.set(new PatchouliConfigAccess() { @Override public boolean disableAdvancementLocking() { diff --git a/NeoForge/src/main/java/vazkii/patchouli/neoforge/network/NeoForgeMessageReloadBookContents.java b/NeoForge/src/main/java/vazkii/patchouli/neoforge/network/NeoForgeMessageReloadBookContents.java deleted file mode 100644 index a9d84a080..000000000 --- a/NeoForge/src/main/java/vazkii/patchouli/neoforge/network/NeoForgeMessageReloadBookContents.java +++ /dev/null @@ -1,28 +0,0 @@ -package vazkii.patchouli.neoforge.network; - -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.neoforged.neoforge.network.PacketDistributor; - -import vazkii.patchouli.api.PatchouliAPI; - -public record NeoForgeMessageReloadBookContents() implements CustomPacketPayload { - public static final ResourceLocation ID = new ResourceLocation(PatchouliAPI.MOD_ID, "reload_books"); - - public NeoForgeMessageReloadBookContents(final FriendlyByteBuf packetBuffer) { - this(); - } - - public static void sendToAll(MinecraftServer server) { - PacketDistributor.ALL.noArg().send(new NeoForgeMessageReloadBookContents()); - } - - public void write(FriendlyByteBuf buf) {} - - @Override - public ResourceLocation id() { - return ID; - } -} diff --git a/NeoForge/src/main/java/vazkii/patchouli/neoforge/network/NeoForgeNetworkHandler.java b/NeoForge/src/main/java/vazkii/patchouli/neoforge/network/NeoForgeNetworkHandler.java index d8d2d5b15..55da7bb10 100644 --- a/NeoForge/src/main/java/vazkii/patchouli/neoforge/network/NeoForgeNetworkHandler.java +++ b/NeoForge/src/main/java/vazkii/patchouli/neoforge/network/NeoForgeNetworkHandler.java @@ -1,18 +1,32 @@ package vazkii.patchouli.neoforge.network; -import net.neoforged.neoforge.network.event.RegisterPayloadHandlerEvent; -import net.neoforged.neoforge.network.registration.IPayloadRegistrar; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; +import net.neoforged.neoforge.network.PacketDistributor; +import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; +import net.neoforged.neoforge.network.registration.PayloadRegistrar; import vazkii.patchouli.api.PatchouliAPI; import vazkii.patchouli.neoforge.network.handler.NeoForgeClientPayloadHandler; +import vazkii.patchouli.network.MessageOpenBookGui; +import vazkii.patchouli.network.MessageReloadBookContents; + +import org.jetbrains.annotations.Nullable; public class NeoForgeNetworkHandler { - public static void setupPackets(final RegisterPayloadHandlerEvent event) { - final IPayloadRegistrar registrar = event.registrar(PatchouliAPI.MOD_ID); - registrar.play(NeoForgeMessageOpenBookGui.ID, NeoForgeMessageOpenBookGui::new, handler -> handler - .client(NeoForgeClientPayloadHandler.getInstance()::handleData)); - registrar.play(NeoForgeMessageReloadBookContents.ID, NeoForgeMessageReloadBookContents::new, handler -> handler - .client(NeoForgeClientPayloadHandler.getInstance()::handleData)); + public static void setupPackets(final RegisterPayloadHandlersEvent event) { + final PayloadRegistrar registrar = event.registrar(PatchouliAPI.MOD_ID); + registrar.playToClient(MessageOpenBookGui.TYPE, MessageOpenBookGui.CODEC, NeoForgeClientPayloadHandler.getInstance()::handleData); + registrar.playToClient(MessageReloadBookContents.TYPE, MessageReloadBookContents.CODEC, NeoForgeClientPayloadHandler.getInstance()::handleData); + } + + public static void sendOpenBook(ServerPlayer player, ResourceLocation book, @Nullable ResourceLocation entry, int page) { + player.connection.send(new MessageOpenBookGui(book, entry, page)); + } + + public static void sendReloadBookContents(MinecraftServer server) { + PacketDistributor.sendToAllPlayers(new MessageReloadBookContents()); } } diff --git a/NeoForge/src/main/java/vazkii/patchouli/neoforge/network/handler/NeoForgeClientPayloadHandler.java b/NeoForge/src/main/java/vazkii/patchouli/neoforge/network/handler/NeoForgeClientPayloadHandler.java index e754d2581..e6b572807 100644 --- a/NeoForge/src/main/java/vazkii/patchouli/neoforge/network/handler/NeoForgeClientPayloadHandler.java +++ b/NeoForge/src/main/java/vazkii/patchouli/neoforge/network/handler/NeoForgeClientPayloadHandler.java @@ -1,11 +1,11 @@ package vazkii.patchouli.neoforge.network.handler; import net.minecraft.network.chat.Component; -import net.neoforged.neoforge.network.handling.PlayPayloadContext; +import net.neoforged.neoforge.network.handling.IPayloadContext; import vazkii.patchouli.client.book.ClientBookRegistry; -import vazkii.patchouli.neoforge.network.NeoForgeMessageOpenBookGui; -import vazkii.patchouli.neoforge.network.NeoForgeMessageReloadBookContents; +import vazkii.patchouli.network.MessageOpenBookGui; +import vazkii.patchouli.network.MessageReloadBookContents; public class NeoForgeClientPayloadHandler { private static final NeoForgeClientPayloadHandler INSTANCE = new NeoForgeClientPayloadHandler(); @@ -14,24 +14,24 @@ public static NeoForgeClientPayloadHandler getInstance() { return INSTANCE; } - public void handleData(final NeoForgeMessageOpenBookGui data, final PlayPayloadContext context) { - context.workHandler().submitAsync(() -> { + public void handleData(final MessageOpenBookGui data, final IPayloadContext context) { + context.enqueueWork(() -> { ClientBookRegistry.INSTANCE.displayBookGui(data.book(), data.entry(), data.page()); }) .exceptionally(e -> { // Handle exception - context.packetHandler().disconnect(Component.translatable("patchouli.networking.open_book.failed", e.getMessage())); + context.disconnect(Component.translatable("patchouli.networking.open_book.failed", e.getMessage())); return null; }); } - public void handleData(final NeoForgeMessageReloadBookContents data, final PlayPayloadContext context) { - context.workHandler().submitAsync(() -> { + public void handleData(final MessageReloadBookContents data, final IPayloadContext context) { + context.enqueueWork(() -> { ClientBookRegistry.INSTANCE.reload(); }) .exceptionally(e -> { // Handle exception - context.packetHandler().disconnect(Component.translatable("patchouli.networking.reload_contents.failed", e.getMessage())); + context.disconnect(Component.translatable("patchouli.networking.reload_contents.failed", e.getMessage())); return null; }); } diff --git a/NeoForge/src/main/java/vazkii/patchouli/neoforge/xplat/NeoForgeXplatImpl.java b/NeoForge/src/main/java/vazkii/patchouli/neoforge/xplat/NeoForgeXplatImpl.java index 51e66696b..98a132e0f 100644 --- a/NeoForge/src/main/java/vazkii/patchouli/neoforge/xplat/NeoForgeXplatImpl.java +++ b/NeoForge/src/main/java/vazkii/patchouli/neoforge/xplat/NeoForgeXplatImpl.java @@ -14,8 +14,7 @@ import vazkii.patchouli.api.BookContentsReloadEvent; import vazkii.patchouli.api.BookDrawScreenEvent; import vazkii.patchouli.neoforge.client.NeoForgeClientInitializer; -import vazkii.patchouli.neoforge.network.NeoForgeMessageOpenBookGui; -import vazkii.patchouli.neoforge.network.NeoForgeMessageReloadBookContents; +import vazkii.patchouli.neoforge.network.NeoForgeNetworkHandler; import vazkii.patchouli.xplat.IXplatAbstractions; import vazkii.patchouli.xplat.XplatModContainer; @@ -38,12 +37,12 @@ public void fireBookReload(ResourceLocation book) { @Override public void sendReloadContentsMessage(MinecraftServer server) { - NeoForgeMessageReloadBookContents.sendToAll(server); + NeoForgeNetworkHandler.sendReloadBookContents(server); } @Override public void sendOpenBookGui(ServerPlayer player, ResourceLocation book, @Nullable ResourceLocation entry, int page) { - NeoForgeMessageOpenBookGui.send(player, book, entry, page); + NeoForgeNetworkHandler.sendOpenBook(player, book, entry, page); } @Override diff --git a/NeoForge/src/main/resources/META-INF/mods.toml b/NeoForge/src/main/resources/META-INF/neoforge.mods.toml similarity index 86% rename from NeoForge/src/main/resources/META-INF/mods.toml rename to NeoForge/src/main/resources/META-INF/neoforge.mods.toml index 40f14d437..1fc449503 100644 --- a/NeoForge/src/main/resources/META-INF/mods.toml +++ b/NeoForge/src/main/resources/META-INF/neoforge.mods.toml @@ -1,6 +1,6 @@ modLoader="javafml" license="CC BY-NC-SA 3.0" -loaderVersion="[2,)" +loaderVersion="[3,)" issueTrackerURL="https://github.com/VazkiiMods/Patchouli" logoFile="logo.png" @@ -16,12 +16,12 @@ Accessible, Data-Driven, Dependency-Free Documentation for Minecraft Modders and [[dependencies.patchouli]] modId="neoforge" type="REQUIRED" -versionRange="[20.4.70-beta,)" +versionRange="[20.6.1-beta,)" [[dependencies.patchouli]] modId="minecraft" type="REQUIRED" -versionRange="[1.20.4,1.21)" +versionRange="[1.20.6,1.21)" [[mixins]] config="patchouli_xplat.mixins.json" \ No newline at end of file diff --git a/Xplat/build.gradle b/Xplat/build.gradle index a2af4b4d1..b82aac148 100644 --- a/Xplat/build.gradle +++ b/Xplat/build.gradle @@ -3,7 +3,9 @@ plugins { id 'org.spongepowered.gradle.vanilla' } -archivesBaseName = "${mod_name}-xplat" +base { + archivesName = "${mod_name}-xplat" +} version = "${mc_version}-${build_number}" if (System.getenv().RELEASE_MODE == null) { version += '-SNAPSHOT' @@ -25,7 +27,7 @@ repositories { dependencies { compileOnly group: 'org.spongepowered', name: 'mixin', version: '0.8.5' - compileOnly "mezz.jei:jei-1.20.4-common-api:17.0.0.30" + compileOnly "mezz.jei:jei-1.20.6-common-api:18.0.0.62" testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.1' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.1' } diff --git a/Xplat/src/main/java/vazkii/patchouli/api/IVariable.java b/Xplat/src/main/java/vazkii/patchouli/api/IVariable.java index ebf61a0c3..b8f4f9de9 100644 --- a/Xplat/src/main/java/vazkii/patchouli/api/IVariable.java +++ b/Xplat/src/main/java/vazkii/patchouli/api/IVariable.java @@ -7,6 +7,10 @@ import com.google.gson.JsonNull; import com.google.gson.JsonPrimitive; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.RegistryAccess; +import net.minecraft.core.registries.BuiltInRegistries; + import org.jetbrains.annotations.Nullable; import java.lang.reflect.Type; @@ -87,77 +91,77 @@ default boolean asBoolean(boolean def) { /** * Get this IVariable as a {@code Stream}, assuming it's backed by a JsonArray. */ - default Stream asStream() { + default Stream asStream(HolderLookup.Provider registries) { return StreamSupport.stream(unwrap().getAsJsonArray().spliterator(), false) - .map(IVariable::wrap); + .map((json) -> IVariable.wrap(json, registries)); } /** * Get this IVariable as a {@code List}, returning as singleton if it's not a JsonArray. */ - default Stream asStreamOrSingleton() { - return unwrap().isJsonArray() ? asStream() : Stream.of(this); + default Stream asStreamOrSingleton(HolderLookup.Provider registries) { + return unwrap().isJsonArray() ? asStream(registries) : Stream.of(this); } /** * Get this IVariable as a {@code List}, assuming it's backed by a JsonArray. */ - default List asList() { - return asStream().collect(Collectors.toList()); + default List asList(HolderLookup.Provider registries) { + return asStream(registries).collect(Collectors.toList()); } /** * Get this IVariable as a {@code List}, returning as singleton if it's not a JsonArray. */ - default List asListOrSingleton() { - return asStreamOrSingleton().collect(Collectors.toList()); + default List asListOrSingleton(HolderLookup.Provider registries) { + return asStreamOrSingleton(registries).collect(Collectors.toList()); } /** * Convenience method to create an IVariable from {@link VariableHelper#createFromObject}. */ - static IVariable from(@Nullable T object) { - return object != null ? VariableHelper.instance().createFromObject(object) : empty(); + static IVariable from(@Nullable T object, HolderLookup.Provider registries) { + return object != null ? VariableHelper.instance().createFromObject(object, registries) : empty(); } /** * Convenience method to create an IVariable from a JsonElement with {@link VariableHelper#createFromJson}. */ - static IVariable wrap(@Nullable JsonElement elem) { - return elem != null ? VariableHelper.instance().createFromJson(elem) : empty(); + static IVariable wrap(@Nullable JsonElement elem, HolderLookup.Provider registries) { + return elem != null ? VariableHelper.instance().createFromJson(elem, registries) : empty(); } /** * Convenience method to create an IVariable from a list of IVariables. */ - static IVariable wrapList(Iterable elems) { + static IVariable wrapList(Iterable elems, HolderLookup.Provider registries) { JsonArray arr = new JsonArray(); for (IVariable v : elems) { arr.add(v.unwrap()); } - return wrap(arr); + return wrap(arr, registries); } static IVariable wrap(@Nullable Number n) { - return n != null ? wrap(new JsonPrimitive(n)) : empty(); + return n != null ? wrap(new JsonPrimitive(n), RegistryAccess.EMPTY) : empty(); } static IVariable wrap(@Nullable Boolean b) { - return b != null ? wrap(new JsonPrimitive(b)) : empty(); + return b != null ? wrap(new JsonPrimitive(b), RegistryAccess.EMPTY) : empty(); } static IVariable wrap(@Nullable String s) { - return s != null ? wrap(new JsonPrimitive(s)) : empty(); + return s != null ? wrap(new JsonPrimitive(s), RegistryAccess.EMPTY) : empty(); } static IVariable empty() { - return wrap(JsonNull.INSTANCE); + return wrap(JsonNull.INSTANCE, RegistryAccess.EMPTY); } class Serializer implements JsonDeserializer { @Override public IVariable deserialize(JsonElement elem, Type t, JsonDeserializationContext c) { - return IVariable.wrap(elem); + return IVariable.wrap(elem, RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY)); } } } diff --git a/Xplat/src/main/java/vazkii/patchouli/api/IVariableProvider.java b/Xplat/src/main/java/vazkii/patchouli/api/IVariableProvider.java index 932a41e87..af23dd2c4 100644 --- a/Xplat/src/main/java/vazkii/patchouli/api/IVariableProvider.java +++ b/Xplat/src/main/java/vazkii/patchouli/api/IVariableProvider.java @@ -1,5 +1,7 @@ package vazkii.patchouli.api; +import net.minecraft.core.HolderLookup; + /** * A provider of variables to a template. Probably a JSON. */ @@ -9,7 +11,7 @@ public interface IVariableProvider { * Gets the value assigned to the variable passed in. * May throw an exception if it doesn't exist. */ - IVariable get(String key); + IVariable get(String key, HolderLookup.Provider registries); /** * Returns if a variable exists or not. diff --git a/Xplat/src/main/java/vazkii/patchouli/api/IVariableSerializer.java b/Xplat/src/main/java/vazkii/patchouli/api/IVariableSerializer.java index cbfe3b2e7..cbb9ffcf2 100644 --- a/Xplat/src/main/java/vazkii/patchouli/api/IVariableSerializer.java +++ b/Xplat/src/main/java/vazkii/patchouli/api/IVariableSerializer.java @@ -2,6 +2,8 @@ import com.google.gson.JsonElement; +import net.minecraft.core.HolderLookup; + /** * An instance of a class implementing this interface * provides conversions for the given type to/from {@link JsonElement}. @@ -12,10 +14,10 @@ public interface IVariableSerializer { /** * Deserialize an object of type T from JSON. */ - T fromJson(JsonElement json); + T fromJson(JsonElement json, HolderLookup.Provider registries); /** * Serialize an object of type T to JSON. */ - JsonElement toJson(T object); + JsonElement toJson(T object, HolderLookup.Provider registries); } diff --git a/Xplat/src/main/java/vazkii/patchouli/api/VariableHelper.java b/Xplat/src/main/java/vazkii/patchouli/api/VariableHelper.java index 0320aa2e5..7798036b9 100644 --- a/Xplat/src/main/java/vazkii/patchouli/api/VariableHelper.java +++ b/Xplat/src/main/java/vazkii/patchouli/api/VariableHelper.java @@ -3,6 +3,8 @@ import com.google.common.base.Suppliers; import com.google.gson.JsonElement; +import net.minecraft.core.HolderLookup; + import org.jetbrains.annotations.Nullable; import java.util.function.Supplier; @@ -30,14 +32,14 @@ static VariableHelper instance() { /** * Create an {@link IVariable} from a given object. */ - default IVariable createFromObject(T object) { + default IVariable createFromObject(T object, HolderLookup.Provider registries) { return null; } /** * Create an {@link IVariable} backed by the given {@link JsonElement}. */ - default IVariable createFromJson(JsonElement elem) { + default IVariable createFromJson(JsonElement elem, HolderLookup.Provider registries) { return null; } diff --git a/Xplat/src/main/java/vazkii/patchouli/client/book/BookEntry.java b/Xplat/src/main/java/vazkii/patchouli/client/book/BookEntry.java index 1fbe26fd9..09a2eda85 100644 --- a/Xplat/src/main/java/vazkii/patchouli/client/book/BookEntry.java +++ b/Xplat/src/main/java/vazkii/patchouli/client/book/BookEntry.java @@ -4,6 +4,8 @@ import com.google.common.reflect.TypeToken; import com.google.gson.JsonObject; +import net.minecraft.core.RegistryAccess; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; @@ -250,7 +252,7 @@ public void build(Level level, BookContentsBuilder builder) { List stacks; int pageNumber = entry.getValue(); try { - stacks = ItemStackUtil.loadStackListFromString(key); + stacks = ItemStackUtil.loadStackListFromString(key, RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY)); } catch (Exception e) { PatchouliAPI.LOGGER.warn("Invalid extra recipe mapping: {} to page {} in entry {}: {}", key, pageNumber, id, e.getMessage()); continue; diff --git a/Xplat/src/main/java/vazkii/patchouli/client/book/BookIcon.java b/Xplat/src/main/java/vazkii/patchouli/client/book/BookIcon.java index f1fd759d9..1501bc542 100644 --- a/Xplat/src/main/java/vazkii/patchouli/client/book/BookIcon.java +++ b/Xplat/src/main/java/vazkii/patchouli/client/book/BookIcon.java @@ -2,13 +2,15 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.core.RegistryAccess; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; import vazkii.patchouli.api.PatchouliAPI; import vazkii.patchouli.common.util.ItemStackUtil; -public sealed interface BookIcon permits BookIcon.StackIcon,BookIcon.TextureIcon { +public sealed interface BookIcon permits BookIcon.StackIcon, BookIcon.TextureIcon { void render(GuiGraphics graphics, int x, int y); record StackIcon(ItemStack stack) implements BookIcon { @@ -32,7 +34,7 @@ static BookIcon from(String str) { return new TextureIcon(new ResourceLocation(str)); } else { try { - ItemStack stack = ItemStackUtil.loadStackFromString(str); + ItemStack stack = ItemStackUtil.loadStackFromString(str, RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY)); return new StackIcon(stack); } catch (Exception e) { PatchouliAPI.LOGGER.warn("Invalid icon item stack: {}", e.getMessage()); diff --git a/Xplat/src/main/java/vazkii/patchouli/client/book/LiquidBlockVertexConsumer.java b/Xplat/src/main/java/vazkii/patchouli/client/book/LiquidBlockVertexConsumer.java index 2e258479d..8b255dbba 100644 --- a/Xplat/src/main/java/vazkii/patchouli/client/book/LiquidBlockVertexConsumer.java +++ b/Xplat/src/main/java/vazkii/patchouli/client/book/LiquidBlockVertexConsumer.java @@ -41,7 +41,7 @@ public VertexConsumer uv2(int u, int v) { @Override public VertexConsumer normal(float x, float y, float z) { - return prior.normal(pose.last().normal(), x, y, z); + return prior.normal(pose.last(), x, y, z); } @Override diff --git a/Xplat/src/main/java/vazkii/patchouli/client/book/page/PageSpotlight.java b/Xplat/src/main/java/vazkii/patchouli/client/book/page/PageSpotlight.java index 8fcd2fa47..97200cf83 100644 --- a/Xplat/src/main/java/vazkii/patchouli/client/book/page/PageSpotlight.java +++ b/Xplat/src/main/java/vazkii/patchouli/client/book/page/PageSpotlight.java @@ -6,7 +6,6 @@ import net.minecraft.client.gui.GuiGraphics; import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.level.Level; import vazkii.patchouli.api.IVariable; @@ -21,15 +20,15 @@ public class PageSpotlight extends PageWithText { String title; @SerializedName("link_recipe") boolean linkRecipe; - transient Ingredient ingredient; + transient ItemStack[] stacks; @Override public void build(Level level, BookEntry entry, BookContentsBuilder builder, int pageNum) { super.build(level, entry, builder, pageNum); - ingredient = item.as(Ingredient.class); + stacks = item.as(ItemStack[].class); if (linkRecipe) { - for (ItemStack stack : ingredient.getItems()) { + for (ItemStack stack : stacks) { entry.addRelevantStack(builder, stack, pageNum); } } @@ -47,11 +46,13 @@ public void render(GuiGraphics graphics, int mouseX, int mouseY, float pticks) { if (title != null && !title.isEmpty()) { toDraw = i18nText(title); } else { - toDraw = ingredient.getItems()[0].getHoverName(); + toDraw = stacks[0].getHoverName(); } parent.drawCenteredStringNoShadow(graphics, toDraw.getVisualOrderText(), GuiBook.PAGE_WIDTH / 2, 0, book.headerColor); - parent.renderIngredient(graphics, GuiBook.PAGE_WIDTH / 2 - 8, 15, mouseX, mouseY, ingredient); + if (stacks.length > 0) { + parent.renderItemStack(graphics, GuiBook.PAGE_WIDTH / 2 - 8, 15, mouseX, mouseY, stacks[(parent.ticksInBook / 20) % stacks.length]); + } super.render(graphics, mouseX, mouseY, pticks); } diff --git a/Xplat/src/main/java/vazkii/patchouli/client/book/template/JsonVariableWrapper.java b/Xplat/src/main/java/vazkii/patchouli/client/book/template/JsonVariableWrapper.java index 6201aee08..fb1422dc6 100644 --- a/Xplat/src/main/java/vazkii/patchouli/client/book/template/JsonVariableWrapper.java +++ b/Xplat/src/main/java/vazkii/patchouli/client/book/template/JsonVariableWrapper.java @@ -3,6 +3,8 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import net.minecraft.core.HolderLookup; + import vazkii.patchouli.api.IVariable; import vazkii.patchouli.api.IVariableProvider; @@ -15,13 +17,13 @@ public JsonVariableWrapper(JsonObject source) { } @Override - public IVariable get(String key) { + public IVariable get(String key, HolderLookup.Provider registries) { JsonElement prim = source.get(key); if (prim == null) { throw new IllegalArgumentException("Attempted to get variable " + key + " when it's not present"); } - return IVariable.wrap(prim); + return IVariable.wrap(prim, registries); } @Override diff --git a/Xplat/src/main/java/vazkii/patchouli/client/book/template/TemplateInclusion.java b/Xplat/src/main/java/vazkii/patchouli/client/book/template/TemplateInclusion.java index 15a2b87ca..9939b5248 100644 --- a/Xplat/src/main/java/vazkii/patchouli/client/book/template/TemplateInclusion.java +++ b/Xplat/src/main/java/vazkii/patchouli/client/book/template/TemplateInclusion.java @@ -4,6 +4,9 @@ import com.google.gson.JsonObject; import com.google.gson.annotations.SerializedName; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.RegistryAccess; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.world.level.Level; import vazkii.patchouli.api.IComponentProcessor; @@ -87,7 +90,7 @@ public String qualifyName(String name) { String query = prefixed ? name.substring(1) : name; // if it's an upreference, return the upreference - String result = IVariable.wrap(localBindings.get(query)).asString(); + String result = IVariable.wrap(localBindings.get(query), RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY)).asString(); if (result.startsWith("#")) { return result.substring(1); } @@ -102,7 +105,7 @@ public IVariable attemptVariableLookup(String key) { if (key.startsWith("#")) { key = key.substring(1); } - IVariable result = IVariable.wrap(localBindings.get(key)); + IVariable result = IVariable.wrap(localBindings.get(key), RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY)); return result.asString().isEmpty() || isUpreference(result) ? null : result; } @@ -121,9 +124,9 @@ public boolean has(String key) { } @Override - public IVariable get(String key) { + public IVariable get(String key, HolderLookup.Provider registries) { IVariable vari = attemptVariableLookup(key); - return vari == null ? provider.get(qualifyName(key)) : vari; + return vari == null ? provider.get(qualifyName(key), registries) : vari; } }; } diff --git a/Xplat/src/main/java/vazkii/patchouli/client/book/template/VariableAssigner.java b/Xplat/src/main/java/vazkii/patchouli/client/book/template/VariableAssigner.java index 1b98be9fc..409853d8f 100644 --- a/Xplat/src/main/java/vazkii/patchouli/client/book/template/VariableAssigner.java +++ b/Xplat/src/main/java/vazkii/patchouli/client/book/template/VariableAssigner.java @@ -1,6 +1,7 @@ package vazkii.patchouli.client.book.template; import net.minecraft.client.resources.language.I18n; +import net.minecraft.core.HolderLookup; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.level.Level; @@ -17,8 +18,8 @@ import java.util.HashMap; import java.util.Map; +import java.util.function.BiFunction; import java.util.function.Function; -import java.util.function.UnaryOperator; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -27,7 +28,7 @@ public class VariableAssigner { private static final Pattern INLINE_VAR_PATTERN = Pattern.compile("([^#]*)(#[^#]+)#(.*)"); private static final Pattern FUNCTION_PATTERN = Pattern.compile("(.+)->(.+)"); - private static final Map> FUNCTIONS = new HashMap<>(); + private static final Map> FUNCTIONS = new HashMap<>(); static { FUNCTIONS.put("iname", VariableAssigner::iname); FUNCTIONS.put("icount", VariableAssigner::icount); @@ -94,9 +95,9 @@ private static IVariable resolveStringFunctions(Level level, String curr, Contex String arg = m.group(1); if (FUNCTIONS.containsKey(funcStr)) { - UnaryOperator func = FUNCTIONS.get(funcStr); + BiFunction func = FUNCTIONS.get(funcStr); IVariable parsedArg = resolveStringFunctions(level, arg, c); - return c.cache(curr, func.apply(parsedArg)); + return c.cache(curr, func.apply(parsedArg, level.registryAccess())); } else { throw new IllegalArgumentException("Invalid Function " + funcStr); } @@ -133,7 +134,7 @@ private static IVariable resolveStringVar(Level level, String original, Context } if (val == null && c.variables.has(key)) { - val = c.variables.get(key); + val = c.variables.get(key, level.registryAccess()); } return val == null ? IVariable.empty() : val; @@ -141,35 +142,35 @@ private static IVariable resolveStringVar(Level level, String original, Context return IVariable.wrap(curr); } - private static UnaryOperator wrapStringFunc(Function inner) { - return x -> IVariable.wrap(inner.apply(x.asString())); + private static BiFunction wrapStringFunc(Function inner) { + return (x, r) -> IVariable.wrap(inner.apply(x.asString())); } - private static IVariable iname(IVariable arg) { + private static IVariable iname(IVariable arg, HolderLookup.Provider registries) { ItemStack stack = arg.as(ItemStack.class); return IVariable.wrap(stack.getHoverName().getString()); } - private static IVariable icount(IVariable arg) { + private static IVariable icount(IVariable arg, HolderLookup.Provider registries) { ItemStack stack = arg.as(ItemStack.class); return IVariable.wrap(stack.getCount()); } - private static IVariable exists(IVariable arg) { + private static IVariable exists(IVariable arg, HolderLookup.Provider registries) { return IVariable.wrap(!arg.unwrap().isJsonNull()); } - private static IVariable iexists(IVariable arg) { + private static IVariable iexists(IVariable arg, HolderLookup.Provider registries) { ItemStack stack = arg.as(ItemStack.class); return IVariable.wrap(stack != null && !stack.isEmpty()); } - private static IVariable inv(IVariable arg) { + private static IVariable inv(IVariable arg, HolderLookup.Provider registries) { return IVariable.wrap(!arg.unwrap().getAsBoolean()); } - private static IVariable stacks(IVariable arg) { - return IVariable.from(arg.as(Ingredient.class).getItems()); + private static IVariable stacks(IVariable arg, HolderLookup.Provider registries) { + return IVariable.from(arg.as(Ingredient.class).getItems(), registries); } private static String ename(String arg) { diff --git a/Xplat/src/main/java/vazkii/patchouli/client/book/template/test/EntityTestProcessor.java b/Xplat/src/main/java/vazkii/patchouli/client/book/template/test/EntityTestProcessor.java index ecaf75cb7..e8e3c144a 100644 --- a/Xplat/src/main/java/vazkii/patchouli/client/book/template/test/EntityTestProcessor.java +++ b/Xplat/src/main/java/vazkii/patchouli/client/book/template/test/EntityTestProcessor.java @@ -16,7 +16,7 @@ public class EntityTestProcessor implements IComponentProcessor { @Override public void setup(Level level, IVariableProvider variables) { - String entityType = variables.get("entity").unwrap().getAsString(); + String entityType = variables.get("entity", level.registryAccess()).unwrap().getAsString(); if (entityType.contains("{")) { entityType = entityType.substring(0, entityType.indexOf("{")); } diff --git a/Xplat/src/main/java/vazkii/patchouli/client/book/template/test/RecipeTestProcessor.java b/Xplat/src/main/java/vazkii/patchouli/client/book/template/test/RecipeTestProcessor.java index 100c8b792..9da52d1ca 100644 --- a/Xplat/src/main/java/vazkii/patchouli/client/book/template/test/RecipeTestProcessor.java +++ b/Xplat/src/main/java/vazkii/patchouli/client/book/template/test/RecipeTestProcessor.java @@ -18,7 +18,7 @@ public class RecipeTestProcessor implements IComponentProcessor { @Override public void setup(Level level, IVariableProvider variables) { // TODO probably add a recipe serializer? - String recipeId = variables.get("recipe").asString(); + String recipeId = variables.get("recipe", level.registryAccess()).asString(); RecipeManager manager = level.getRecipeManager(); recipe = manager.byKey(new ResourceLocation(recipeId)).orElseThrow(IllegalArgumentException::new).value(); } @@ -31,7 +31,7 @@ public IVariable process(Level level, String key) { ItemStack[] stacks = ingredient.getItems(); ItemStack stack = stacks.length == 0 ? ItemStack.EMPTY : stacks[0]; - return IVariable.from(stack); + return IVariable.from(stack, level.registryAccess()); } else if (key.equals("text")) { ItemStack out = recipe.getResultItem(level.registryAccess()); return IVariable.wrap(out.getCount() + "x$(br)" + out.getHoverName()); diff --git a/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/GenericArrayVariableSerializer.java b/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/GenericArrayVariableSerializer.java index 59d4e122a..217b05b16 100644 --- a/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/GenericArrayVariableSerializer.java +++ b/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/GenericArrayVariableSerializer.java @@ -3,6 +3,8 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; +import net.minecraft.core.HolderLookup; + import vazkii.patchouli.api.IVariableSerializer; import java.lang.reflect.Array; @@ -20,12 +22,12 @@ public GenericArrayVariableSerializer(IVariableSerializer inner, Class typ } @Override - public T[] fromJson(JsonElement json) { + public T[] fromJson(JsonElement json, HolderLookup.Provider registries) { if (json.isJsonArray()) { JsonArray array = json.getAsJsonArray(); List stacks = new ArrayList<>(); for (JsonElement e : array) { - stacks.add(inner.fromJson(e)); + stacks.add(inner.fromJson(e, registries)); } return stacks.toArray(empty); } @@ -33,10 +35,10 @@ public T[] fromJson(JsonElement json) { } @Override - public JsonArray toJson(T[] array) { + public JsonArray toJson(T[] array, HolderLookup.Provider registries) { JsonArray result = new JsonArray(); for (T elem : array) { - result.add(inner.toJson(elem)); + result.add(inner.toJson(elem, registries)); } return result; } diff --git a/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/IngredientVariableSerializer.java b/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/IngredientVariableSerializer.java index 75aeb4071..ca52c4704 100644 --- a/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/IngredientVariableSerializer.java +++ b/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/IngredientVariableSerializer.java @@ -3,20 +3,20 @@ import com.google.gson.JsonElement; import com.mojang.serialization.JsonOps; +import net.minecraft.core.HolderLookup; import net.minecraft.world.item.crafting.Ingredient; import vazkii.patchouli.api.IVariableSerializer; -import vazkii.patchouli.api.PatchouliAPI; import vazkii.patchouli.common.util.ItemStackUtil; public class IngredientVariableSerializer implements IVariableSerializer { @Override - public Ingredient fromJson(JsonElement json) { - return (json.isJsonPrimitive()) ? ItemStackUtil.loadIngredientFromString(json.getAsString()) : Ingredient.CODEC.parse(JsonOps.INSTANCE, json).getOrThrow(false, PatchouliAPI.LOGGER::error); + public Ingredient fromJson(JsonElement json, HolderLookup.Provider registries) { + return (json.isJsonPrimitive()) ? ItemStackUtil.loadIngredientFromString(json.getAsString(), registries) : Ingredient.CODEC.parse(registries.createSerializationContext(JsonOps.INSTANCE), json).result().orElseThrow(); } @Override - public JsonElement toJson(Ingredient stack) { - return Ingredient.CODEC.encodeStart(JsonOps.INSTANCE, stack).getOrThrow(false, PatchouliAPI.LOGGER::error); + public JsonElement toJson(Ingredient stack, HolderLookup.Provider registries) { + return Ingredient.CODEC.encodeStart(registries.createSerializationContext(JsonOps.INSTANCE), stack).result().orElseThrow(); } } diff --git a/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/ItemStackArrayVariableSerializer.java b/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/ItemStackArrayVariableSerializer.java index 232975be7..efd1e31bd 100644 --- a/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/ItemStackArrayVariableSerializer.java +++ b/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/ItemStackArrayVariableSerializer.java @@ -3,6 +3,7 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; +import net.minecraft.core.HolderLookup; import net.minecraft.world.item.ItemStack; import vazkii.patchouli.common.util.ItemStackUtil; @@ -17,27 +18,27 @@ public ItemStackArrayVariableSerializer() { } @Override - public ItemStack[] fromJson(JsonElement json) { + public ItemStack[] fromJson(JsonElement json, HolderLookup.Provider registries) { if (json.isJsonArray()) { JsonArray array = json.getAsJsonArray(); List stacks = new ArrayList<>(); for (JsonElement e : array) { - stacks.addAll(Arrays.asList(fromNonArray(e))); + stacks.addAll(Arrays.asList(fromNonArray(e, registries))); } return stacks.toArray(empty); } - return fromNonArray(json); + return fromNonArray(json, registries); } - public ItemStack[] fromNonArray(JsonElement json) { + public ItemStack[] fromNonArray(JsonElement json, HolderLookup.Provider registries) { if (json.isJsonNull()) { return empty; } if (json.isJsonPrimitive()) { - return ItemStackUtil.loadStackListFromString(json.getAsString()).toArray(empty); + return ItemStackUtil.loadStackListFromString(json.getAsString(), registries).toArray(empty); } if (json.isJsonObject()) { - return new ItemStack[] { ItemStackUtil.loadStackFromJson(json.getAsJsonObject()) }; + return new ItemStack[] { ItemStackUtil.loadStackFromJson(json.getAsJsonObject(), registries) }; } throw new IllegalArgumentException("Can't make an ItemStack from an array!"); } diff --git a/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/ItemStackVariableSerializer.java b/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/ItemStackVariableSerializer.java index 31420ce2b..67b827580 100644 --- a/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/ItemStackVariableSerializer.java +++ b/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/ItemStackVariableSerializer.java @@ -2,7 +2,10 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import com.mojang.serialization.JsonOps; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.component.DataComponentMap; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.world.item.ItemStack; @@ -11,29 +14,30 @@ public class ItemStackVariableSerializer implements IVariableSerializer { @Override - public ItemStack fromJson(JsonElement json) { + public ItemStack fromJson(JsonElement json, HolderLookup.Provider registries) { if (json.isJsonNull()) { return ItemStack.EMPTY; } if (json.isJsonPrimitive()) { - return ItemStackUtil.loadStackFromString(json.getAsString()); + return ItemStackUtil.loadStackFromString(json.getAsString(), registries); } if (json.isJsonObject()) { - return ItemStackUtil.loadStackFromJson(json.getAsJsonObject()); + return ItemStackUtil.loadStackFromJson(json.getAsJsonObject(), registries); } throw new IllegalArgumentException("Can't make an ItemStack from an array!"); } @Override - public JsonElement toJson(ItemStack stack) { + public JsonElement toJson(ItemStack stack, HolderLookup.Provider registries) { // Adapted from net.minecraftforge.common.crafting.StackList::toJson JsonObject ret = new JsonObject(); ret.addProperty("item", BuiltInRegistries.ITEM.getKey(stack.getItem()).toString()); if (stack.getCount() != 1) { ret.addProperty("count", stack.getCount()); } - if (stack.getTag() != null) { - ret.addProperty("nbt", stack.getTag().toString()); + if (!stack.getComponents().isEmpty()) { + DataComponentMap data = stack.getComponents(); + DataComponentMap.CODEC.encodeStart(registries.createSerializationContext(JsonOps.INSTANCE), data).result().ifPresent(e -> ret.add("components", e)); } return ret; } diff --git a/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/TextComponentVariableSerializer.java b/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/TextComponentVariableSerializer.java index e55552a0e..9c88babb4 100644 --- a/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/TextComponentVariableSerializer.java +++ b/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/TextComponentVariableSerializer.java @@ -1,26 +1,30 @@ package vazkii.patchouli.client.book.template.variable; import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.mojang.serialization.JsonOps; +import net.minecraft.core.HolderLookup; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component.Serializer; +import net.minecraft.network.chat.ComponentSerialization; import vazkii.patchouli.api.IVariableSerializer; public class TextComponentVariableSerializer implements IVariableSerializer { @Override - public Component fromJson(JsonElement json) { + public Component fromJson(JsonElement json, HolderLookup.Provider registries) { if (json.isJsonNull()) { return Component.literal(""); } - if (json.isJsonPrimitive() && json.getAsJsonPrimitive().isString()) { + if (json.isJsonPrimitive()) { return Component.literal(json.getAsString()); } - return Serializer.fromJson(json); + return Serializer.fromJson(json, registries); } @Override - public JsonElement toJson(Component stack) { - return Serializer.toJsonTree(stack); + public JsonElement toJson(Component stack, HolderLookup.Provider registries) { + return ComponentSerialization.CODEC.encodeStart(registries.createSerializationContext(JsonOps.INSTANCE), stack).getOrThrow(JsonParseException::new); } } diff --git a/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/Variable.java b/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/Variable.java index a7fdd21b4..ca67b6cf6 100644 --- a/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/Variable.java +++ b/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/Variable.java @@ -2,6 +2,8 @@ import com.google.gson.JsonElement; +import net.minecraft.core.HolderLookup; + import vazkii.patchouli.api.IVariable; import vazkii.patchouli.api.IVariableSerializer; import vazkii.patchouli.api.VariableHelper; @@ -14,10 +16,12 @@ public class Variable implements IVariable { private final JsonElement value; @Nullable private final Class sourceClass; + private final HolderLookup.Provider registries; - public Variable(JsonElement elem, Class c) { + public Variable(JsonElement elem, Class c, HolderLookup.Provider provider) { value = Objects.requireNonNull(elem); sourceClass = c; + registries = provider; } @Override @@ -28,7 +32,7 @@ public T as(Class clazz) { throw new IllegalArgumentException(String.format("Can't deserialize object of class %s from IVariable", clazz)); } - return serializer.fromJson(value); + return serializer.fromJson(value, registries); } @Override diff --git a/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/VariableHelperImpl.java b/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/VariableHelperImpl.java index e125e58cb..19d80e512 100644 --- a/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/VariableHelperImpl.java +++ b/Xplat/src/main/java/vazkii/patchouli/client/book/template/variable/VariableHelperImpl.java @@ -2,6 +2,7 @@ import com.google.gson.JsonElement; +import net.minecraft.core.HolderLookup; import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; @@ -44,11 +45,11 @@ public IVariableSerializer serializerForClass(Class clazz) { @Override @SuppressWarnings("unchecked") - public IVariable createFromObject(T object) { + public IVariable createFromObject(T object, HolderLookup.Provider registries) { Class clazz = object.getClass(); for (Entry, IVariableSerializer> e : serializers.entrySet()) { if (e.getKey().isAssignableFrom(clazz)) { - return create(((IVariableSerializer) e.getValue()).toJson(object), clazz); + return create(((IVariableSerializer) e.getValue()).toJson(object, registries), clazz, registries); } } @@ -56,12 +57,12 @@ public IVariable createFromObject(T object) { } @Override - public IVariable createFromJson(JsonElement elem) { - return create(elem, null); + public IVariable createFromJson(JsonElement elem, HolderLookup.Provider registries) { + return create(elem, null, registries); } - private IVariable create(JsonElement elem, Class originator) { - return new Variable(elem, originator); + private IVariable create(JsonElement elem, Class originator, HolderLookup.Provider registries) { + return new Variable(elem, originator, registries); } @Override diff --git a/Xplat/src/main/java/vazkii/patchouli/client/handler/MultiblockVisualizationHandler.java b/Xplat/src/main/java/vazkii/patchouli/client/handler/MultiblockVisualizationHandler.java index 5df401fff..30bb8de7f 100644 --- a/Xplat/src/main/java/vazkii/patchouli/client/handler/MultiblockVisualizationHandler.java +++ b/Xplat/src/main/java/vazkii/patchouli/client/handler/MultiblockVisualizationHandler.java @@ -165,9 +165,9 @@ public static void onRenderHUD(GuiGraphics graphics, float partialTicks) { } } - public static void onWorldRenderLast(PoseStack ms) { + public static void onWorldRenderLast(PoseStack ms, Matrix4f pose) { if (hasMultiblock && multiblock != null) { - renderMultiblock(Minecraft.getInstance().level, ms); + renderMultiblock(Minecraft.getInstance().level, ms, pose); } } @@ -198,7 +198,8 @@ public static void onClientTick(Minecraft mc) { } } - public static void renderMultiblock(Level world, PoseStack ms) { + public static void renderMultiblock(Level world, PoseStack ms, Matrix4f pose) { + ms.mulPose(pose); Minecraft mc = Minecraft.getInstance(); if (!isAnchored) { facingRotation = getRotation(mc.player); diff --git a/Xplat/src/main/java/vazkii/patchouli/client/jei/PatchouliJeiPlugin.java b/Xplat/src/main/java/vazkii/patchouli/client/jei/PatchouliJeiPlugin.java index f170e700a..38c7aa921 100644 --- a/Xplat/src/main/java/vazkii/patchouli/client/jei/PatchouliJeiPlugin.java +++ b/Xplat/src/main/java/vazkii/patchouli/client/jei/PatchouliJeiPlugin.java @@ -12,7 +12,7 @@ import net.minecraft.world.item.ItemStack; import vazkii.patchouli.api.PatchouliAPI; -import vazkii.patchouli.common.item.ItemModBook; +import vazkii.patchouli.common.item.PatchouliDataComponents; import vazkii.patchouli.common.item.PatchouliItems; import vazkii.patchouli.mixin.client.AccessorKeyMapping; @@ -46,10 +46,10 @@ public ResourceLocation getPluginUid() { @Override public void registerItemSubtypes(@NotNull ISubtypeRegistration registration) { registration.registerSubtypeInterpreter(VanillaTypes.ITEM_STACK, PatchouliItems.BOOK, (stack, context) -> { - if (!stack.hasTag() || !stack.getTag().contains(ItemModBook.TAG_BOOK)) { + if (!stack.has(PatchouliDataComponents.BOOK)) { return ""; } - return stack.getTag().getString(ItemModBook.TAG_BOOK); + return stack.get(PatchouliDataComponents.BOOK).toString(); }); } diff --git a/Xplat/src/main/java/vazkii/patchouli/common/advancement/BookOpenTrigger.java b/Xplat/src/main/java/vazkii/patchouli/common/advancement/BookOpenTrigger.java index 6daac7754..e2fcda377 100644 --- a/Xplat/src/main/java/vazkii/patchouli/common/advancement/BookOpenTrigger.java +++ b/Xplat/src/main/java/vazkii/patchouli/common/advancement/BookOpenTrigger.java @@ -6,7 +6,6 @@ import net.minecraft.advancements.critereon.*; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.util.ExtraCodecs; import vazkii.patchouli.api.PatchouliAPI; @@ -39,10 +38,10 @@ public void trigger(@NotNull ServerPlayer player, @NotNull ResourceLocation book public record TriggerInstance(Optional player, ResourceLocation book, Optional entry, MinMaxBounds.Ints page) implements SimpleInstance { public static Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - ExtraCodecs.strictOptionalField(EntityPredicate.ADVANCEMENT_CODEC, "player").forGetter(TriggerInstance::player), + EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(TriggerInstance::player), ResourceLocation.CODEC.fieldOf("book").forGetter(TriggerInstance::book), - ExtraCodecs.strictOptionalField(ResourceLocation.CODEC, "entry").forGetter(TriggerInstance::entry), - ExtraCodecs.strictOptionalField(MinMaxBounds.Ints.CODEC, "page", MinMaxBounds.Ints.ANY).forGetter(TriggerInstance::page) + ResourceLocation.CODEC.optionalFieldOf("entry").forGetter(TriggerInstance::entry), + MinMaxBounds.Ints.CODEC.optionalFieldOf("page", MinMaxBounds.Ints.ANY).forGetter(TriggerInstance::page) ).apply(instance, TriggerInstance::new)); public boolean matches(@NotNull ResourceLocation book, @Nullable ResourceLocation entry, int page) { diff --git a/Xplat/src/main/java/vazkii/patchouli/common/book/Book.java b/Xplat/src/main/java/vazkii/patchouli/common/book/Book.java index 416fcad8d..b37ee6ca6 100644 --- a/Xplat/src/main/java/vazkii/patchouli/common/book/Book.java +++ b/Xplat/src/main/java/vazkii/patchouli/common/book/Book.java @@ -5,6 +5,7 @@ import net.minecraft.Util; import net.minecraft.client.Minecraft; +import net.minecraft.data.registries.VanillaRegistries; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.Style; @@ -158,7 +159,7 @@ public Book(JsonObject root, XplatModContainer owner, ResourceLocation id, boole if (noBook) { // Parse on load to catch errors, but need lazy loading for mods // that load after Patchouli - var parsed = ItemStackUtil.parseItemStackString(customBookItem); + var parsed = ItemStackUtil.deserializeStack(customBookItem, VanillaRegistries.createLookup()); bookItem = Suppliers.memoize(() -> ItemStackUtil.loadFromParsed(parsed)); } else { bookItem = Suppliers.memoize(() -> ItemModBook.forBook(id)); diff --git a/Xplat/src/main/java/vazkii/patchouli/common/item/ItemModBook.java b/Xplat/src/main/java/vazkii/patchouli/common/item/ItemModBook.java index f8c9b9741..a5425165d 100644 --- a/Xplat/src/main/java/vazkii/patchouli/common/item/ItemModBook.java +++ b/Xplat/src/main/java/vazkii/patchouli/common/item/ItemModBook.java @@ -2,7 +2,6 @@ import net.minecraft.ChatFormatting; import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; @@ -26,8 +25,6 @@ public class ItemModBook extends Item { - public static final String TAG_BOOK = "patchouli:book"; - public ItemModBook() { super(new Item.Properties().stacksTo(1)); } @@ -62,9 +59,7 @@ public static ItemStack forBook(Book book) { public static ItemStack forBook(ResourceLocation book) { ItemStack stack = new ItemStack(PatchouliItems.BOOK); - CompoundTag cmp = new CompoundTag(); - cmp.putString(TAG_BOOK, book.toString()); - stack.setTag(cmp); + stack.set(PatchouliDataComponents.BOOK, book); return stack; } @@ -87,12 +82,11 @@ public static Book getBook(ItemStack stack) { } private static ResourceLocation getBookId(ItemStack stack) { - if (!stack.hasTag() || !stack.getTag().contains(TAG_BOOK)) { + if (!stack.has(PatchouliDataComponents.BOOK)) { return null; } - String bookStr = stack.getTag().getString(TAG_BOOK); - return ResourceLocation.tryParse(bookStr); + return stack.get(PatchouliDataComponents.BOOK); } @Override @@ -106,8 +100,8 @@ public Component getName(ItemStack stack) { } @Override - public void appendHoverText(ItemStack stack, Level worldIn, List tooltip, TooltipFlag flagIn) { - super.appendHoverText(stack, worldIn, tooltip, flagIn); + public void appendHoverText(ItemStack stack, TooltipContext context, List tooltip, TooltipFlag flagIn) { + super.appendHoverText(stack, context, tooltip, flagIn); ResourceLocation rl = getBookId(stack); if (flagIn.isAdvanced()) { diff --git a/Xplat/src/main/java/vazkii/patchouli/common/item/PatchouliDataComponents.java b/Xplat/src/main/java/vazkii/patchouli/common/item/PatchouliDataComponents.java new file mode 100644 index 000000000..9236eff7e --- /dev/null +++ b/Xplat/src/main/java/vazkii/patchouli/common/item/PatchouliDataComponents.java @@ -0,0 +1,21 @@ +package vazkii.patchouli.common.item; + +import net.minecraft.core.component.DataComponentType; +import net.minecraft.resources.ResourceLocation; + +import vazkii.patchouli.api.PatchouliAPI; + +import java.util.function.BiConsumer; + +public class PatchouliDataComponents { + + public static final ResourceLocation COMPONENT_ID = new ResourceLocation(PatchouliAPI.MOD_ID, "book"); + public static final DataComponentType BOOK = DataComponentType.builder() + .persistent(ResourceLocation.CODEC) + .networkSynchronized(ResourceLocation.STREAM_CODEC) + .build(); + + public static void submitDataComponentRegistrations(BiConsumer> consumer) { + consumer.accept(COMPONENT_ID, BOOK); + } +} diff --git a/Xplat/src/main/java/vazkii/patchouli/common/item/PatchouliItems.java b/Xplat/src/main/java/vazkii/patchouli/common/item/PatchouliItems.java index 0eb57e670..a469d6a58 100644 --- a/Xplat/src/main/java/vazkii/patchouli/common/item/PatchouliItems.java +++ b/Xplat/src/main/java/vazkii/patchouli/common/item/PatchouliItems.java @@ -2,11 +2,8 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; -import net.minecraft.world.item.crafting.RecipeSerializer; import vazkii.patchouli.api.PatchouliAPI; -import vazkii.patchouli.common.recipe.ShapedBookRecipe; -import vazkii.patchouli.common.recipe.ShapelessBookRecipe; import java.util.function.BiConsumer; @@ -18,9 +15,4 @@ public class PatchouliItems { public static void submitItemRegistrations(BiConsumer consumer) { consumer.accept(BOOK_ID, BOOK); } - - public static void submitRecipeSerializerRegistrations(BiConsumer> consumer) { - consumer.accept(new ResourceLocation(PatchouliAPI.MOD_ID, "shaped_book_recipe"), ShapedBookRecipe.SERIALIZER); - consumer.accept(new ResourceLocation(PatchouliAPI.MOD_ID, "shapeless_book_recipe"), ShapelessBookRecipe.SERIALIZER); - } } diff --git a/Xplat/src/main/java/vazkii/patchouli/common/recipe/ShapedBookRecipe.java b/Xplat/src/main/java/vazkii/patchouli/common/recipe/ShapedBookRecipe.java deleted file mode 100644 index 36968501b..000000000 --- a/Xplat/src/main/java/vazkii/patchouli/common/recipe/ShapedBookRecipe.java +++ /dev/null @@ -1,88 +0,0 @@ -package vazkii.patchouli.common.recipe; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; - -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.ExtraCodecs; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.CraftingBookCategory; -import net.minecraft.world.item.crafting.RecipeSerializer; -import net.minecraft.world.item.crafting.ShapedRecipe; -import net.minecraft.world.item.crafting.ShapedRecipePattern; - -import vazkii.patchouli.api.PatchouliAPI; - -import org.jetbrains.annotations.Nullable; - -/** - * Recipe type for shaped book recipes. - * The format is the same as vanilla shaped recipes, but the - * "result" object is replaced by a "book" string for the book ID. - */ -public class ShapedBookRecipe extends ShapedRecipe { - public static final RecipeSerializer SERIALIZER = new Serializer(); - - final ShapedRecipePattern pattern; - final ItemStack result; - final String group; - final @Nullable ResourceLocation outputBook; - - public ShapedBookRecipe(String group, ShapedRecipePattern recipePattern, ItemStack result, @Nullable ResourceLocation outputBook) { - super(group, CraftingBookCategory.MISC, recipePattern, getOutputBook(result, outputBook)); - this.pattern = recipePattern; - this.result = result; - this.group = group; - this.outputBook = outputBook; - } - - private static ItemStack getOutputBook(ItemStack result, @Nullable ResourceLocation outputBook) { - if (outputBook != null) { - return PatchouliAPI.get().getBookStack(outputBook); - } - return result; - } - - @Override - public RecipeSerializer getSerializer() { - return SERIALIZER; - } - - public static class Serializer implements RecipeSerializer { - public static final Codec CODEC = RecordCodecBuilder.create( - instance -> instance.group( - ExtraCodecs.strictOptionalField(Codec.STRING, "group", "").forGetter(bookRecipe -> bookRecipe.group), - ShapedRecipePattern.MAP_CODEC.forGetter(bookRecipe -> bookRecipe.pattern), - ExtraCodecs.strictOptionalField(ItemStack.ITEM_WITH_COUNT_CODEC, "result", ItemStack.EMPTY).forGetter(bookRecipe -> bookRecipe.result), - ExtraCodecs.strictOptionalField(ResourceLocation.CODEC, "book", null).forGetter(bookRecipe -> bookRecipe.outputBook) - ) - .apply(instance, ShapedBookRecipe::new) - ); - - @Override - public Codec codec() { - return CODEC; - } - - @Override - public ShapedBookRecipe fromNetwork(FriendlyByteBuf buf) { - String group = buf.readUtf(); - ShapedRecipePattern recipePattern = ShapedRecipePattern.fromNetwork(buf); - ItemStack result = buf.readItem(); - ResourceLocation outputBook = buf.readBoolean() ? buf.readResourceLocation() : null; - return new ShapedBookRecipe(group, recipePattern, result, outputBook); - } - - @Override - public void toNetwork(FriendlyByteBuf buf, ShapedBookRecipe bookRecipe) { - buf.writeUtf(bookRecipe.group); - bookRecipe.pattern.toNetwork(buf); - buf.writeItem(bookRecipe.result); - buf.writeBoolean(bookRecipe.outputBook != null); - if (bookRecipe.outputBook != null) { - buf.writeResourceLocation(bookRecipe.outputBook); - } - } - } -} diff --git a/Xplat/src/main/java/vazkii/patchouli/common/recipe/ShapelessBookRecipe.java b/Xplat/src/main/java/vazkii/patchouli/common/recipe/ShapelessBookRecipe.java deleted file mode 100644 index 8a3d74340..000000000 --- a/Xplat/src/main/java/vazkii/patchouli/common/recipe/ShapelessBookRecipe.java +++ /dev/null @@ -1,120 +0,0 @@ -package vazkii.patchouli.common.recipe; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.DataResult; -import com.mojang.serialization.codecs.RecordCodecBuilder; - -import net.minecraft.core.NonNullList; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.ExtraCodecs; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.CraftingBookCategory; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.RecipeSerializer; -import net.minecraft.world.item.crafting.ShapelessRecipe; - -import vazkii.patchouli.api.PatchouliAPI; - -import org.jetbrains.annotations.Nullable; - -/** - * Recipe type for shapeless book recipes. - * The format is the same as vanilla shapeless recipes, but the - * "result" object is replaced by a "book" string for the book ID. - */ -public class ShapelessBookRecipe extends ShapelessRecipe { - public static final RecipeSerializer SERIALIZER = new Serializer(); - - final String group; - final ItemStack result; - final NonNullList ingredients; - final @Nullable ResourceLocation outputBook; - - public ShapelessBookRecipe(String group, ItemStack result, NonNullList ingredients, @Nullable ResourceLocation outputBook) { - super(group, CraftingBookCategory.MISC, getOutputBook(result, outputBook), ingredients); - this.group = group; - this.result = result; - this.ingredients = ingredients; - this.outputBook = outputBook; - } - - private static ItemStack getOutputBook(ItemStack result, @Nullable ResourceLocation outputBook) { - if (outputBook != null) { - return PatchouliAPI.get().getBookStack(outputBook); - } - return result; - } - - @Override - public RecipeSerializer getSerializer() { - return SERIALIZER; - } - - public static class Serializer implements RecipeSerializer { - static int maxWidth = 3; - static int maxHeight = 3; - private static final Codec CODEC = RecordCodecBuilder.create( - instance -> instance.group( - ExtraCodecs.strictOptionalField(Codec.STRING, "group", "").forGetter(bookRecipe -> bookRecipe.group), - ExtraCodecs.strictOptionalField(ItemStack.ITEM_WITH_COUNT_CODEC, "result", ItemStack.EMPTY).forGetter(bookRecipe -> bookRecipe.result), - Ingredient.CODEC_NONEMPTY - .listOf() - .fieldOf("ingredients") - .flatXmap( - ingredientList -> { - Ingredient[] aingredient = ingredientList - .toArray(Ingredient[]::new); - if (aingredient.length == 0) { - return DataResult.error(() -> "No ingredients for shapeless book recipe"); - } else { - return aingredient.length > maxHeight * maxWidth - ? DataResult.error(() -> "Too many ingredients for shapeless book recipe. The maximum is: %s".formatted(maxHeight * maxWidth)) - : DataResult.success(NonNullList.of(Ingredient.EMPTY, aingredient)); - } - }, - DataResult::success - ) - .forGetter(bookRecipe -> bookRecipe.ingredients), - ExtraCodecs.strictOptionalField(ResourceLocation.CODEC, "book", null).forGetter(bookRecipe -> bookRecipe.outputBook) - ) - .apply(instance, ShapelessBookRecipe::new) - ); - - @Override - public Codec codec() { - return CODEC; - } - - @Override - public ShapelessBookRecipe fromNetwork(FriendlyByteBuf buf) { - String group = buf.readUtf(); - int i = buf.readVarInt(); - NonNullList ingredients = NonNullList.withSize(i, Ingredient.EMPTY); - - for (int j = 0; j < ingredients.size(); ++j) { - ingredients.set(j, Ingredient.fromNetwork(buf)); - } - - ItemStack result = buf.readItem(); - ResourceLocation outputBook = buf.readBoolean() ? buf.readResourceLocation() : null; - return new ShapelessBookRecipe(group, result, ingredients, outputBook); - } - - @Override - public void toNetwork(FriendlyByteBuf buf, ShapelessBookRecipe bookRecipe) { - buf.writeUtf(bookRecipe.group); - buf.writeVarInt(bookRecipe.ingredients.size()); - - for (Ingredient ingredient : bookRecipe.ingredients) { - ingredient.toNetwork(buf); - } - - buf.writeItem(bookRecipe.result); - buf.writeBoolean(bookRecipe.outputBook != null); - if (bookRecipe.outputBook != null) { - buf.writeResourceLocation(bookRecipe.outputBook); - } - } - } -} diff --git a/Xplat/src/main/java/vazkii/patchouli/common/util/ItemStackUtil.java b/Xplat/src/main/java/vazkii/patchouli/common/util/ItemStackUtil.java index 0233d9acb..907f4179b 100644 --- a/Xplat/src/main/java/vazkii/patchouli/common/util/ItemStackUtil.java +++ b/Xplat/src/main/java/vazkii/patchouli/common/util/ItemStackUtil.java @@ -1,15 +1,16 @@ package vazkii.patchouli.common.util; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.serialization.JsonOps; +import net.minecraft.commands.arguments.item.ItemParser; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.component.DataComponentMap; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.TagParser; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.util.GsonHelper; @@ -17,7 +18,6 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; -import org.apache.commons.lang3.tuple.ImmutableTriple; import org.apache.commons.lang3.tuple.Triple; import vazkii.patchouli.common.book.Book; @@ -26,74 +26,54 @@ import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; public final class ItemStackUtil { - private static final Gson GSON = new GsonBuilder().create(); - private ItemStackUtil() {} - public static Triple parseItemStackString(String res) { - String nbt = ""; - int nbtStart = res.indexOf("{"); - if (nbtStart > 0) { - nbt = res.substring(nbtStart).replaceAll("([^\\\\])'", "$1\"").replaceAll("\\\\'", "'"); - res = res.substring(0, nbtStart); - } - - String[] upper = res.split("#"); - String count = "1"; - if (upper.length > 1) { - res = upper[0]; - count = upper[1]; - } - - String[] tokens = res.split(":"); - if (tokens.length < 2) { - throw new RuntimeException("Malformed item ID " + res); - } - - ResourceLocation key = new ResourceLocation(tokens[0], tokens[1]); - int countn = Integer.parseInt(count); - CompoundTag tag = null; - - if (!nbt.isEmpty()) { - try { - tag = TagParser.parseTag(nbt); - } catch (CommandSyntaxException e) { - throw new RuntimeException("Failed to parse ItemStack JSON", e); + public static Triple, DataComponentMap, Integer> deserializeStack(String string, HolderLookup.Provider registries) { + StringReader reader = new StringReader(string.trim()); + ItemParser itemParser = new ItemParser(registries); + try { + ItemParser.ItemResult result = itemParser.parse(reader); + int count = 1; + if (reader.canRead()) { + reader.expect('#'); + count = reader.readInt(); } + return Triple.of(result.item(), result.components(), count); + } catch (CommandSyntaxException e) { + throw new RuntimeException(e); } - - return ImmutableTriple.of(key, countn, tag); } - public static ItemStack loadFromParsed(Triple parsed) { - var key = parsed.getLeft(); - var count = parsed.getMiddle(); - var nbt = parsed.getRight(); - Optional maybeItem = BuiltInRegistries.ITEM.getOptional(key); - if (maybeItem.isEmpty()) { - throw new RuntimeException("Unknown item ID: " + key); + public static ItemStack loadFromParsed(Triple, DataComponentMap, Integer> parsed) { + var holder = parsed.getLeft(); + var components = parsed.getMiddle(); + var count = parsed.getRight(); + if (!holder.isBound() && holder.unwrapKey().isPresent()) { + throw new RuntimeException("Unknown item ID: " + holder.unwrapKey().get().location()); } - Item item = maybeItem.get(); + Item item = holder.value(); ItemStack stack = new ItemStack(item, count); - if (nbt != null) { - stack.setTag(nbt); + if (!components.isEmpty()) { + stack.applyComponents(components); } return stack; } - public static ItemStack loadStackFromString(String res) { - return loadFromParsed(parseItemStackString(res)); + public static ItemStack loadStackFromString(String res, HolderLookup.Provider registries) { + return loadFromParsed(deserializeStack(res, registries)); } - public static Ingredient loadIngredientFromString(String ingredientString) { - return Ingredient.of(loadStackListFromString(ingredientString).toArray(new ItemStack[0])); + public static Ingredient loadIngredientFromString(String ingredientString, HolderLookup.Provider registries) { + return Ingredient.of(loadStackListFromString(ingredientString, registries).toArray(new ItemStack[0])); } - public static List loadStackListFromString(String ingredientString) { + public static List loadStackListFromString(String ingredientString, HolderLookup.Provider registries) { String[] stacksSerialized = splitStacksFromSerializedIngredient(ingredientString); List stacks = new ArrayList<>(); for (String s : stacksSerialized) { @@ -101,7 +81,7 @@ public static List loadStackListFromString(String ingredientString) { var key = TagKey.create(Registries.ITEM, new ResourceLocation(s.substring(4))); BuiltInRegistries.ITEM.getTag(key).ifPresent(tag -> tag.stream().forEach(item -> stacks.add(new ItemStack(item)))); } else { - stacks.add(loadStackFromString(s)); + stacks.add(loadStackFromString(s, registries)); } } return stacks; @@ -192,8 +172,7 @@ private static String[] splitStacksFromSerializedIngredient(String ingredientSer return result.toArray(new String[0]); } - public static ItemStack loadStackFromJson(JsonObject json) { - // Adapted from net.minecraftforge.common.crafting.CraftingHelper::getItemStack + public static ItemStack loadStackFromJson(JsonObject json, HolderLookup.Provider registries) { String itemName = json.get("item").getAsString(); Item item = BuiltInRegistries.ITEM.getOptional(new ResourceLocation(itemName)).orElseThrow(() -> new IllegalArgumentException("Unknown item '" + itemName + "'") @@ -201,19 +180,10 @@ public static ItemStack loadStackFromJson(JsonObject json) { ItemStack stack = new ItemStack(item, GsonHelper.getAsInt(json, "count", 1)); - if (json.has("nbt")) { - try { - JsonElement element = json.get("nbt"); - CompoundTag nbt; - if (element.isJsonObject()) { - nbt = TagParser.parseTag(GSON.toJson(element)); - } else { - nbt = TagParser.parseTag(element.getAsString()); - } - stack.setTag(nbt); - } catch (CommandSyntaxException e) { - throw new IllegalArgumentException("Invalid NBT Entry: " + e, e); - } + if (json.has("components")) { + DataComponentMap.CODEC.parse(registries.createSerializationContext(JsonOps.INSTANCE), json.get("components")).resultOrPartial(e -> { + throw new IllegalArgumentException("Failed to parse components: " + e); + }).ifPresent(stack::applyComponents); } return stack; diff --git a/Xplat/src/main/java/vazkii/patchouli/common/util/SerializationUtil.java b/Xplat/src/main/java/vazkii/patchouli/common/util/SerializationUtil.java index 943d2d8fa..fbb7cd5e3 100644 --- a/Xplat/src/main/java/vazkii/patchouli/common/util/SerializationUtil.java +++ b/Xplat/src/main/java/vazkii/patchouli/common/util/SerializationUtil.java @@ -11,7 +11,6 @@ import org.jetbrains.annotations.Nullable; -import java.io.*; import java.util.Locale; public final class SerializationUtil { diff --git a/Xplat/src/main/java/vazkii/patchouli/mixin/client/MixinLevelRenderer.java b/Xplat/src/main/java/vazkii/patchouli/mixin/client/MixinLevelRenderer.java index bc4117992..cad79f02b 100644 --- a/Xplat/src/main/java/vazkii/patchouli/mixin/client/MixinLevelRenderer.java +++ b/Xplat/src/main/java/vazkii/patchouli/mixin/client/MixinLevelRenderer.java @@ -18,7 +18,7 @@ @Mixin(LevelRenderer.class) public class MixinLevelRenderer { @Inject(at = @At("RETURN"), method = "renderLevel") - public void onRender(PoseStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightmapTextureManager, Matrix4f matrix4f, CallbackInfo info) { - MultiblockVisualizationHandler.onWorldRenderLast(matrices); + public void onRender(float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightmapTextureManager, Matrix4f pose, Matrix4f matrix4f, CallbackInfo info) { + MultiblockVisualizationHandler.onWorldRenderLast(new PoseStack(), pose); } } diff --git a/NeoForge/src/main/java/vazkii/patchouli/neoforge/network/NeoForgeMessageOpenBookGui.java b/Xplat/src/main/java/vazkii/patchouli/network/MessageOpenBookGui.java similarity index 56% rename from NeoForge/src/main/java/vazkii/patchouli/neoforge/network/NeoForgeMessageOpenBookGui.java rename to Xplat/src/main/java/vazkii/patchouli/network/MessageOpenBookGui.java index 805b06dc6..6a98edb66 100644 --- a/NeoForge/src/main/java/vazkii/patchouli/neoforge/network/NeoForgeMessageOpenBookGui.java +++ b/Xplat/src/main/java/vazkii/patchouli/network/MessageOpenBookGui.java @@ -1,19 +1,23 @@ -package vazkii.patchouli.neoforge.network; +package vazkii.patchouli.network; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerPlayer; import vazkii.patchouli.api.PatchouliAPI; import org.jetbrains.annotations.Nullable; -public record NeoForgeMessageOpenBookGui(ResourceLocation book, @Nullable ResourceLocation entry, int page) implements CustomPacketPayload { +public record MessageOpenBookGui(ResourceLocation book, @Nullable ResourceLocation entry, int page) implements CustomPacketPayload { public static final ResourceLocation ID = new ResourceLocation(PatchouliAPI.MOD_ID, "open_book"); + public static final StreamCodec CODEC = CustomPacketPayload.codec( + MessageOpenBookGui::write, + MessageOpenBookGui::new); + public static final Type TYPE = CustomPacketPayload.createType(ID.toString()); - public NeoForgeMessageOpenBookGui(FriendlyByteBuf buf) { + public MessageOpenBookGui(FriendlyByteBuf buf) { this(buf.readResourceLocation(), getEntry(buf), buf.readVarInt()); } @@ -28,12 +32,8 @@ public void write(FriendlyByteBuf buf) { buf.writeVarInt(page); } - public static void send(ServerPlayer player, ResourceLocation book, @Nullable ResourceLocation entry, int page) { - player.connection.send(new NeoForgeMessageOpenBookGui(book, entry, page)); - } - @Override - public ResourceLocation id() { - return ID; + public Type type() { + return TYPE; } } diff --git a/Xplat/src/main/java/vazkii/patchouli/network/MessageReloadBookContents.java b/Xplat/src/main/java/vazkii/patchouli/network/MessageReloadBookContents.java new file mode 100644 index 000000000..582d3202c --- /dev/null +++ b/Xplat/src/main/java/vazkii/patchouli/network/MessageReloadBookContents.java @@ -0,0 +1,27 @@ +package vazkii.patchouli.network; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; + +import vazkii.patchouli.api.PatchouliAPI; + +public record MessageReloadBookContents() implements CustomPacketPayload { + public static final ResourceLocation ID = new ResourceLocation(PatchouliAPI.MOD_ID, "reload_books"); + public static final StreamCodec CODEC = CustomPacketPayload.codec( + MessageReloadBookContents::write, + MessageReloadBookContents::new); + public static final Type TYPE = CustomPacketPayload.createType(ID.toString()); + + public MessageReloadBookContents(final FriendlyByteBuf packetBuffer) { + this(); + } + + public void write(FriendlyByteBuf buf) {} + + @Override + public Type type() { + return TYPE; + } +} diff --git a/Xplat/src/main/resources/assets/patchouli/lang/en_us.json b/Xplat/src/main/resources/assets/patchouli/lang/en_us.json index 77202d41f..b39f7a231 100644 --- a/Xplat/src/main/resources/assets/patchouli/lang/en_us.json +++ b/Xplat/src/main/resources/assets/patchouli/lang/en_us.json @@ -100,5 +100,5 @@ "patchouli.gui.lexicon.button.mark_category_read": "Mark this category as read", "patchouli.networking.open_book.failed": "Failed to open book %s", - "patchouli.networking.reload_contents.invalid": "Failed to reload contents %S" + "patchouli.networking.reload_contents.failed": "Failed to reload contents %S" } diff --git a/Xplat/src/main/resources/assets/patchouli/patchouli_books/comprehensive_test_book/en_us/entries/recipe_mapping/recipe.json b/Xplat/src/main/resources/assets/patchouli/patchouli_books/comprehensive_test_book/en_us/entries/recipe_mapping/recipe.json index c0e844324..8d66b58b2 100644 --- a/Xplat/src/main/resources/assets/patchouli/patchouli_books/comprehensive_test_book/en_us/entries/recipe_mapping/recipe.json +++ b/Xplat/src/main/resources/assets/patchouli/patchouli_books/comprehensive_test_book/en_us/entries/recipe_mapping/recipe.json @@ -14,7 +14,7 @@ }, { "type": "patchouli:blasting", - "recipe": "minecraft:iron_ingot_from_blasting" + "recipe": "minecraft:iron_ingot_from_blasting_iron_ore" }, { "type": "patchouli:smoking", diff --git a/Xplat/src/main/resources/assets/patchouli/patchouli_books/intro/en_us/categories/one.json b/Xplat/src/main/resources/assets/patchouli/patchouli_books/intro/en_us/categories/one.json index 9f9054e42..8ffffed3f 100644 --- a/Xplat/src/main/resources/assets/patchouli/patchouli_books/intro/en_us/categories/one.json +++ b/Xplat/src/main/resources/assets/patchouli/patchouli_books/intro/en_us/categories/one.json @@ -1,6 +1,6 @@ { "name": "Haha yes", "description": "Haha yes", - "icon": "minecraft:grass", + "icon": "minecraft:short_grass", "sortnum": 0 } \ No newline at end of file diff --git a/Xplat/src/main/resources/assets/patchouli/patchouli_books/test_completion/en_us/entries/not_a_pig.json b/Xplat/src/main/resources/assets/patchouli/patchouli_books/test_completion/en_us/entries/not_a_pig.json index e4efaf21d..328a57392 100644 --- a/Xplat/src/main/resources/assets/patchouli/patchouli_books/test_completion/en_us/entries/not_a_pig.json +++ b/Xplat/src/main/resources/assets/patchouli/patchouli_books/test_completion/en_us/entries/not_a_pig.json @@ -1,6 +1,6 @@ { "name": "1 - Pigman?", - "icon": "minecraft:zombie_pigman_spawn_egg", + "icon": "minecraft:zombified_piglin_spawn_egg", "category": "patchouli:regret", "advancement": "patchouli:not_a_pig", "pages": [ diff --git a/Xplat/src/main/resources/assets/patchouli/patchouli_books/testbook1/en_us/entries/intro/smelttest.json b/Xplat/src/main/resources/assets/patchouli/patchouli_books/testbook1/en_us/entries/intro/smelttest.json index 1a4e945ca..9cb78e126 100644 --- a/Xplat/src/main/resources/assets/patchouli/patchouli_books/testbook1/en_us/entries/intro/smelttest.json +++ b/Xplat/src/main/resources/assets/patchouli/patchouli_books/testbook1/en_us/entries/intro/smelttest.json @@ -9,7 +9,7 @@ "type": "patchouli:smelting", "text": "Haha yes", "recipe": "minecraft:stone", - "recipe2": "minecraft:iron_ingot" + "recipe2": "minecraft:iron_ingot_from_smelting_iron_ore" }, { "type": "patchouli:spotlight", @@ -18,18 +18,15 @@ "item": { "item": "minecraft:diamond_sword", "count": 293, - "nbt": { - "Enchantments": [ - { - "id": "minecraft:sharpness", - "lvl": 3 - } + "components": { + "minecraft:lore": [ + "\"This has lore!!!\"", + "\"Whoever redesigned this system to take \\\"stringified JSON\\\" should be fed to Ravagers on sight!\"" ], - "display": { - "Lore": [ - "\"This has lore!!!\"", - "\"Whoever redesigned this system to take \\\"stringified JSON\\\" should be fed to Ravagers on sight!\"" - ] + "minecraft:enchantments": { + "levels": { + "minecraft:sharpness": 3 + } } } } diff --git a/Xplat/src/main/resources/data/patchouli/advancements/bacon.json b/Xplat/src/main/resources/data/patchouli/advancements/bacon.json index 3012dbb76..52a9e5987 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/bacon.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/bacon.json @@ -1,7 +1,7 @@ { "display": { "icon": { - "item": "minecraft:book" + "id": "minecraft:book" }, "title": { "translate": "Bacon time!" diff --git a/Xplat/src/main/resources/data/patchouli/advancements/discover_pig.json b/Xplat/src/main/resources/data/patchouli/advancements/discover_pig.json index f74cb80fc..95bed909f 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/discover_pig.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/discover_pig.json @@ -1,7 +1,7 @@ { "display": { "icon": { - "item": "minecraft:porkchop" + "id": "minecraft:porkchop" }, "title": { "translate": "Find a Pig" diff --git a/Xplat/src/main/resources/data/patchouli/advancements/kill_chicken.json b/Xplat/src/main/resources/data/patchouli/advancements/kill_chicken.json index c7ed45e7d..da8a247fd 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/kill_chicken.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/kill_chicken.json @@ -1,7 +1,7 @@ { "display": { "icon": { - "item": "minecraft:feather" + "id": "minecraft:feather" }, "title": { "translate": "Kill Chicken" diff --git a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_0.json b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_0.json index 5f3546cb1..2c56b3461 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_0.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_0.json @@ -1,6 +1,6 @@ { "display": { - "icon": { "item": "minecraft:white_wool" }, + "icon": { "id": "minecraft:white_wool" }, "title": { "translate": "White Wool" }, "description": { "translate": "The MCP Foundation requires you to obtain this." } }, diff --git a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_1.json b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_1.json index 0550fbba6..ce775688c 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_1.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_1.json @@ -1,6 +1,6 @@ { "display": { - "icon": { "item": "minecraft:orange_wool" }, + "icon": { "id": "minecraft:orange_wool" }, "title": { "translate": "Orange Wool" }, "description": { "translate": "The MCP Foundation requires you to obtain this." } }, diff --git a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_10.json b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_10.json index d9a97b21a..1d9ae898c 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_10.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_10.json @@ -1,6 +1,6 @@ { "display": { - "icon": { "item": "minecraft:purple_wool" }, + "icon": { "id": "minecraft:purple_wool" }, "title": { "translate": "Purple Wool" }, "description": { "translate": "The MCP Foundation requires you to obtain this." } }, diff --git a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_11.json b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_11.json index e4cd15acf..f72b2b053 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_11.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_11.json @@ -1,6 +1,6 @@ { "display": { - "icon": { "item": "minecraft:blue_wool" }, + "icon": { "id": "minecraft:blue_wool" }, "title": { "translate": "Blue Wool" }, "description": { "translate": "The MCP Foundation requires you to obtain this." } }, diff --git a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_12.json b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_12.json index c8170d7e5..3ba40744d 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_12.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_12.json @@ -1,6 +1,6 @@ { "display": { - "icon": { "item": "minecraft:brown_wool" }, + "icon": { "id": "minecraft:brown_wool" }, "title": { "translate": "Brown Wool" }, "description": { "translate": "The MCP Foundation requires you to obtain this." } }, diff --git a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_13.json b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_13.json index 8cc6572cc..9283af094 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_13.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_13.json @@ -1,6 +1,6 @@ { "display": { - "icon": { "item": "minecraft:green_wool" }, + "icon": { "id": "minecraft:green_wool" }, "title": { "translate": "Green Wool" }, "description": { "translate": "The MCP Foundation requires you to obtain this." } }, diff --git a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_14.json b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_14.json index 85999dc79..8d7b642c8 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_14.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_14.json @@ -1,6 +1,6 @@ { "display": { - "icon": { "item": "minecraft:red_wool" }, + "icon": { "id": "minecraft:red_wool" }, "title": { "translate": "Red Wool" }, "description": { "translate": "The MCP Foundation requires you to obtain this." } }, diff --git a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_15.json b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_15.json index a89e4242c..c570eec93 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_15.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_15.json @@ -1,6 +1,6 @@ { "display": { - "icon": { "item": "minecraft:black_wool" }, + "icon": { "id": "minecraft:black_wool" }, "title": { "translate": "Black Wool" }, "description": { "translate": "The MCP Foundation requires you to obtain this." } }, diff --git a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_2.json b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_2.json index d0658f6a7..ff8c50efd 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_2.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_2.json @@ -1,6 +1,6 @@ { "display": { - "icon": { "item": "minecraft:magenta_wool" }, + "icon": { "id": "minecraft:magenta_wool" }, "title": { "translate": "Magenta Wool" }, "description": { "translate": "The MCP Foundation requires you to obtain this." } }, diff --git a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_3.json b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_3.json index 783ce2ebd..9f0a55cef 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_3.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_3.json @@ -1,6 +1,6 @@ { "display": { - "icon": { "item": "minecraft:light_blue_wool" }, + "icon": { "id": "minecraft:light_blue_wool" }, "title": { "translate": "Light Blue Wool" }, "description": { "translate": "The MCP Foundation requires you to obtain this." } }, diff --git a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_4.json b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_4.json index cf6c2bd75..8ac249f65 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_4.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_4.json @@ -1,6 +1,6 @@ { "display": { - "icon": { "item": "minecraft:yellow_wool" }, + "icon": { "id": "minecraft:yellow_wool" }, "title": { "translate": "Yellow Wool" }, "description": { "translate": "The MCP Foundation requires you to obtain this." } }, diff --git a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_5.json b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_5.json index 49ef13f4a..dfe071a83 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_5.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_5.json @@ -1,6 +1,6 @@ { "display": { - "icon": { "item": "minecraft:lime_wool" }, + "icon": { "id": "minecraft:lime_wool" }, "title": { "translate": "Lime Wool" }, "description": { "translate": "The MCP Foundation requires you to obtain this." } }, diff --git a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_6.json b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_6.json index 1543d77d4..702f59102 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_6.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_6.json @@ -1,6 +1,6 @@ { "display": { - "icon": { "item": "minecraft:pink_wool" }, + "icon": { "id": "minecraft:pink_wool" }, "title": { "translate": "Pink Wool" }, "description": { "translate": "The MCP Foundation requires you to obtain this." } }, diff --git a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_7.json b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_7.json index c04e2a5a7..517d9bf01 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_7.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_7.json @@ -1,6 +1,6 @@ { "display": { - "icon": { "item": "minecraft:gray_wool" }, + "icon": { "id": "minecraft:gray_wool" }, "title": { "translate": "Gray Wool" }, "description": { "translate": "The MCP Foundation requires you to obtain this." } }, diff --git a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_8.json b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_8.json index 96b557753..58f021981 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_8.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_8.json @@ -1,6 +1,6 @@ { "display": { - "icon": { "item": "minecraft:light_gray_wool" }, + "icon": { "id": "minecraft:light_gray_wool" }, "title": { "translate": "Light Gray Wool" }, "description": { "translate": "The MCP Foundation requires you to obtain this." } }, diff --git a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_9.json b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_9.json index 02ec95826..6af521952 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_9.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_9.json @@ -1,6 +1,6 @@ { "display": { - "icon": { "item": "minecraft:cyan_wool" }, + "icon": { "id": "minecraft:cyan_wool" }, "title": { "translate": "Cyan Wool" }, "description": { "translate": "The MCP Foundation requires you to obtain this." } }, diff --git a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_a.json b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_a.json index 0b90e46d6..29030d165 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_a.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/mcp_035_a.json @@ -1,7 +1,7 @@ { "display": { "icon": { - "item": "minecraft:mutton" + "id": "minecraft:mutton" }, "title": { "translate": "Find a Sheep" diff --git a/Xplat/src/main/resources/data/patchouli/advancements/not_a_pig.json b/Xplat/src/main/resources/data/patchouli/advancements/not_a_pig.json index 57f22a234..6afc21308 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/not_a_pig.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/not_a_pig.json @@ -1,7 +1,7 @@ { "display": { "icon": { - "item": "minecraft:rotten_flesh" + "id": "minecraft:rotten_flesh" }, "title": { "translate": "That's no pig..." diff --git a/Xplat/src/main/resources/data/patchouli/advancements/root.json b/Xplat/src/main/resources/data/patchouli/advancements/root.json index 6794bbcd6..a77539619 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/root.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/root.json @@ -1,7 +1,7 @@ { "display": { "icon": { - "item": "minecraft:book" + "id": "minecraft:book" }, "title": { "translate": "Patchouli" diff --git a/Xplat/src/main/resources/data/patchouli/advancements/test_book.json b/Xplat/src/main/resources/data/patchouli/advancements/test_book.json index 3f8d8e191..0f8dbc7be 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/test_book.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/test_book.json @@ -1,7 +1,7 @@ { "display": { "icon": { - "item": "minecraft:book" + "id": "minecraft:book" }, "title": { "translate": "Test" diff --git a/Xplat/src/main/resources/data/patchouli/advancements/yummy.json b/Xplat/src/main/resources/data/patchouli/advancements/yummy.json index 952628cd5..ef793b164 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/yummy.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/yummy.json @@ -1,7 +1,7 @@ { "display": { "icon": { - "item": "minecraft:book" + "id": "minecraft:book" }, "title": { "translate": "Yummy!" diff --git a/Xplat/src/main/resources/data/patchouli/advancements/yummy_anyway.json b/Xplat/src/main/resources/data/patchouli/advancements/yummy_anyway.json index d47310e46..5deda5f92 100644 --- a/Xplat/src/main/resources/data/patchouli/advancements/yummy_anyway.json +++ b/Xplat/src/main/resources/data/patchouli/advancements/yummy_anyway.json @@ -1,7 +1,7 @@ { "display": { "icon": { - "item": "minecraft:rotten_flesh" + "id": "minecraft:rotten_flesh" }, "title": { "translate": "Yummy...?" diff --git a/Xplat/src/main/resources/data/patchouli/recipes/test_recipe.json b/Xplat/src/main/resources/data/patchouli/recipes/test_recipe.json index de920251a..e30abab17 100644 --- a/Xplat/src/main/resources/data/patchouli/recipes/test_recipe.json +++ b/Xplat/src/main/resources/data/patchouli/recipes/test_recipe.json @@ -1,5 +1,5 @@ { - "type": "patchouli:shaped_book_recipe", + "type": "minecraft:crafting_shaped", "pattern": [ "##" ], @@ -8,5 +8,11 @@ "item": "minecraft:dirt" } }, - "book": "patchouli:comprehensive_test_book" + "result": { + "components": { + "patchouli:book": "patchouli:comprehensive_test_book" + }, + "count": 1, + "id": "patchouli:guide_book" + } } \ No newline at end of file diff --git a/Xplat/src/main/resources/data/patchouli/recipes/test_recipe_shapeless.json b/Xplat/src/main/resources/data/patchouli/recipes/test_recipe_shapeless.json index 7128a1ef5..57e1793d8 100644 --- a/Xplat/src/main/resources/data/patchouli/recipes/test_recipe_shapeless.json +++ b/Xplat/src/main/resources/data/patchouli/recipes/test_recipe_shapeless.json @@ -1,5 +1,5 @@ { - "type": "patchouli:shapeless_book_recipe", + "type": "minecraft:crafting_shapeless", "ingredients": [ { "item": "minecraft:gold_ingot" @@ -8,5 +8,11 @@ "item": "minecraft:dirt" } ], - "book": "patchouli:testbook1" + "result": { + "components": { + "patchouli:book": "patchouli:testbook1" + }, + "count": 1, + "id": "patchouli:guide_book" + } } \ No newline at end of file diff --git a/Xplat/src/main/resources/pack.mcmeta b/Xplat/src/main/resources/pack.mcmeta index 4858697ff..ad1f4b3a1 100644 --- a/Xplat/src/main/resources/pack.mcmeta +++ b/Xplat/src/main/resources/pack.mcmeta @@ -1,6 +1,6 @@ { "pack": { "description": "Patchouli Resources", - "pack_format": 8 + "pack_format": 32 } } diff --git a/Xplat/src/main/resources/patchouli_xplat.mixins.json b/Xplat/src/main/resources/patchouli_xplat.mixins.json index 4c8b55445..869b44658 100644 --- a/Xplat/src/main/resources/patchouli_xplat.mixins.json +++ b/Xplat/src/main/resources/patchouli_xplat.mixins.json @@ -1,8 +1,8 @@ { "required": true, - "minVersion": "0.8", + "minVersion": "0.8.4", "package": "vazkii.patchouli.mixin", - "compatibilityLevel": "JAVA_17", + "compatibilityLevel": "JAVA_21", "mixins": [ "AccessorSmithingTransformRecipe", "AccessorSmithingTrimRecipe" diff --git a/build.gradle b/build.gradle index 0b2fb63bb..3c8e4b878 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { } } dependencies { - classpath "com.diffplug.spotless:spotless-plugin-gradle:5.12.5" + classpath "com.diffplug.spotless:spotless-plugin-gradle:6.23.3" } } @@ -19,7 +19,7 @@ subprojects { apply plugin: 'pmd' apply plugin: "com.diffplug.spotless" apply plugin: 'maven-publish' - java.toolchain.languageVersion = JavaLanguageVersion.of(17) + java.toolchain.languageVersion = JavaLanguageVersion.of(21) java.withSourcesJar() archivesBaseName = "${mod_name}" @@ -34,7 +34,7 @@ subprojects { tasks.withType(JavaCompile).configureEach { it.options.encoding = 'UTF-8' - it.options.release = 17 + it.options.release = 21 } tasks.withType(GenerateModuleMetadata).configureEach { diff --git a/gradle.properties b/gradle.properties index 1688703e1..06288534b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ org.gradle.jvmargs=-Xmx1G \ --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED -mc_version=1.20.4 +mc_version=1.20.6 build_number=85 group=vazkii.patchouli mod_name=Patchouli diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7454180f2..d64cd4917 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fae08049a..b82aa23a4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 1b6c78733..1aa94a426 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,13 +80,11 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +131,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ @@ -205,6 +214,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index ac1b06f93..7101f8e46 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,13 +41,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -56,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/settings.gradle b/settings.gradle index 87e94df30..a0a9afaaf 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,9 +1,9 @@ pluginManagement { plugins { - id 'net.neoforged.gradle.userdev' version '7.0.84' apply false + id 'net.neoforged.gradle.userdev' version '7.0.142' apply false id 'org.spongepowered.mixin' version '0.7-SNAPSHOT' apply false id 'org.spongepowered.gradle.vanilla' version '0.2.1-SNAPSHOT' apply false - id 'fabric-loom' version '1.2.7' apply false + id 'fabric-loom' version '1.6-SNAPSHOT' apply false } repositories { maven { @@ -24,7 +24,7 @@ pluginManagement { plugins { // Required for NeoGradle - id 'org.gradle.toolchains.foojay-resolver-convention' version '0.5.0' + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0' } rootProject.name = 'Patchouli'