From aa082c9cbfbb51c442d8593e1d58d323cede5448 Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Thu, 29 May 2025 16:51:20 -0400 Subject: [PATCH 1/4] Init 1.21.5 update --- fabric/build.gradle.kts | 2 +- fabric/gradle.properties | 16 ++++++++-------- .../client/config/ClothConfigIntegration.java | 16 ++++++++++------ .../gui/screens/SyncedInventoryScreen.java | 10 ++++++---- .../fabric/client/mixin/GuiMixin.java | 15 +++++++-------- .../fabric/client/mixin/InventoryAccessor.java | 12 ++++++++++++ .../client/sync/screen/ScreenSyncController.java | 7 +++++-- .../resources/spectatorplus.client.mixins.json | 3 ++- .../mixin/ServerGamePacketListenerImplMixin.java | 2 +- .../fabric/mixin/ServerPlayerMixin.java | 2 +- .../ClientboundSelectedSlotSyncPacket.java | 2 +- 11 files changed, 54 insertions(+), 33 deletions(-) create mode 100644 fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/mixin/InventoryAccessor.java diff --git a/fabric/build.gradle.kts b/fabric/build.gradle.kts index 7e94222..40ceb82 100644 --- a/fabric/build.gradle.kts +++ b/fabric/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("fabric-loom") version "1.9-SNAPSHOT" + id("fabric-loom") version "1.10.1" id("spectatorplus.platform") } diff --git a/fabric/gradle.properties b/fabric/gradle.properties index eec19dc..79c3d77 100644 --- a/fabric/gradle.properties +++ b/fabric/gradle.properties @@ -1,13 +1,13 @@ -minecraft_version=1.21.4 -yarn_mappings=1.21.4+build.8 -loader_version=0.16.9 +minecraft_version=1.21.5 +yarn_mappings=1.21.5+build.1 +loader_version=0.16.14 # Fabric API -fabric_version=0.114.1+1.21.4 +fabric_version=0.125.0+1.21.5 -parchment_minecraft_version=1.21.4 -parchment_version=2025.01.05 +parchment_minecraft_version=1.21.5 +parchment_version=2025.04.19 fabric_permissions_api_version=0.3.3 -cloth_config_version=17.0.144 -modmenu_version=13.0.0 +cloth_config_version=18.0.145 +modmenu_version=14.0.0-rc.2 diff --git a/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/config/ClothConfigIntegration.java b/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/config/ClothConfigIntegration.java index 4a8a866..810ded6 100644 --- a/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/config/ClothConfigIntegration.java +++ b/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/config/ClothConfigIntegration.java @@ -10,9 +10,11 @@ import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.HoverEvent; import net.minecraft.network.chat.MutableComponent; import java.io.IOException; +import java.net.URI; public class ClothConfigIntegration { private ClothConfigIntegration() { @@ -130,11 +132,13 @@ private static void setupServerConfig(ConfigBuilder builder) { .setDefaultValue(defaults.allowTransferBetweenLevels) .build()); - category.addEntry(entryBuilder.startBooleanToggle(Component.translatable("gui.spectatorplus.config.server.autoUpdatePosition.name") - .withStyle(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://bugs.mojang.com/browse/MC-148993"))), config.autoUpdatePosition) - .setTooltip(Component.translatable("gui.spectatorplus.config.server.autoUpdatePosition.tooltip", Component.literal("MC-148993").withStyle(ChatFormatting.BLUE, ChatFormatting.UNDERLINE))) - .setSaveConsumer(val -> config.autoUpdatePosition = val) - .setDefaultValue(defaults.autoUpdatePosition) - .build()); +// category.addEntry(entryBuilder.startBooleanToggle(Component.translatable("gui.spectatorplus.config.server.autoUpdatePosition.name") +// .withStyle(style -> style.withClickEvent(new ClickEvent.OpenUrl(URI.create("https://bugs.mojang.com/browse/MC-148993"))) +// .withHoverEvent(new HoverEvent.ShowText(Component.translatable("gui.spectatorplus.config.server.autoUpdatePosition.tooltip", Component.literal("MC-148993").withStyle(ChatFormatting.BLUE, ChatFormatting.UNDERLINE)))) +// +//// .setSaveConsumer(val -> config.autoUpdatePosition = val) +// // TODO: what +// .setDefaultValue(defaults.autoUpdatePosition) +// .build()); } } diff --git a/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/gui/screens/SyncedInventoryScreen.java b/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/gui/screens/SyncedInventoryScreen.java index f0f3256..5a9f92c 100644 --- a/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/gui/screens/SyncedInventoryScreen.java +++ b/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/gui/screens/SyncedInventoryScreen.java @@ -1,5 +1,6 @@ package com.hpfxd.spectatorplus.fabric.client.gui.screens; +import com.hpfxd.spectatorplus.fabric.client.mixin.InventoryAccessor; import com.hpfxd.spectatorplus.fabric.client.mixin.screen.AbstractRecipeBookScreenAccessor; import com.hpfxd.spectatorplus.fabric.client.mixin.screen.ImageButtonAccessor; import net.minecraft.client.gui.components.ImageButton; @@ -9,6 +10,7 @@ import net.minecraft.client.gui.narration.NarratableEntry; import net.minecraft.client.gui.screens.inventory.InventoryScreen; import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; +import net.minecraft.world.entity.EntityEquipment; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; @@ -36,11 +38,11 @@ private void syncOtherItems() { final Inventory playerInventory = menu.getOwner().getInventory(); final Inventory fakeInventory = menu.getInventory(); - for (int slot = 0; slot < playerInventory.armor.size(); slot++) { - fakeInventory.armor.set(slot, playerInventory.armor.get(slot)); - } + final EntityEquipment playerEquipment = ((InventoryAccessor) (menu.getOwner().getInventory())).getEquipment(); + final EntityEquipment fakeEquipment = ((InventoryAccessor) (menu.getInventory())).getEquipment(); - fakeInventory.offhand.set(0, playerInventory.offhand.get(0)); + fakeEquipment.setAll(playerEquipment); + fakeInventory.setItem(Inventory.SLOT_OFFHAND, playerInventory.getItem(Inventory.SLOT_OFFHAND)); } @Override diff --git a/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/mixin/GuiMixin.java b/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/mixin/GuiMixin.java index 9005700..349637f 100644 --- a/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/mixin/GuiMixin.java +++ b/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/mixin/GuiMixin.java @@ -16,7 +16,6 @@ import net.minecraft.client.multiplayer.MultiPlayerGameMode; import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.player.LocalPlayer; -import net.minecraft.core.NonNullList; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; @@ -163,12 +162,12 @@ public abstract class GuiMixin { return (ClientSyncController.syncData != null && ClientSyncController.syncData.foodData != null) || SpecUtil.getCameraPlayer(this.minecraft) == null; } - @Redirect(method = "renderItemHotbar(Lnet/minecraft/client/gui/GuiGraphics;Lnet/minecraft/client/DeltaTracker;)V", at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/player/Inventory;selected:I", opcode = Opcodes.GETFIELD)) + @Redirect(method = "renderItemHotbar(Lnet/minecraft/client/gui/GuiGraphics;Lnet/minecraft/client/DeltaTracker;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Inventory;getSelectedSlot()I", opcode = Opcodes.GETFIELD)) private int spectatorplus$showSyncedSelectedSlot(Inventory inventory) { if (ClientSyncController.syncData != null && ClientSyncController.syncData.selectedHotbarSlot != -1 && SpecUtil.getCameraPlayer(this.minecraft) != null) { return ClientSyncController.syncData.selectedHotbarSlot; } - return inventory.selected; + return inventory.getSelectedSlot(); } @Redirect(method = "renderFood(Lnet/minecraft/client/gui/GuiGraphics;Lnet/minecraft/world/entity/player/Player;II)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;getFoodData()Lnet/minecraft/world/food/FoodData;")) @@ -179,12 +178,12 @@ public abstract class GuiMixin { return instance.getFoodData(); } - @ModifyReceiver(method = "renderItemHotbar(Lnet/minecraft/client/gui/GuiGraphics;Lnet/minecraft/client/DeltaTracker;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/NonNullList;get(I)Ljava/lang/Object;", ordinal = 0)) - private NonNullList spectatorplus$showSyncedItems(NonNullList instance, int i) { + @Redirect(method = "renderItemHotbar(Lnet/minecraft/client/gui/GuiGraphics;Lnet/minecraft/client/DeltaTracker;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Inventory;getItem(I)Lnet/minecraft/world/item/ItemStack;")) + private ItemStack spectatorplus$showSyncedItems(Inventory instance, int slot) { if (ClientSyncController.syncData != null && ClientSyncController.syncData.selectedHotbarSlot != -1 && SpecUtil.getCameraPlayer(this.minecraft) != null) { - return ClientSyncController.syncData.hotbarItems; + return ClientSyncController.syncData.hotbarItems.get(slot); } - return instance; + return instance.getItem(slot); } @Redirect(method = "renderExperienceBar(Lnet/minecraft/client/gui/GuiGraphics;I)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;getXpNeededForNextLevel()I")) @@ -211,7 +210,7 @@ public abstract class GuiMixin { return instance.experienceLevel; } - @ModifyReceiver(method = "tick()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Inventory;getSelected()Lnet/minecraft/world/item/ItemStack;")) + @ModifyReceiver(method = "tick()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Inventory;getSelectedItem()Lnet/minecraft/world/item/ItemStack;")) private Inventory spectatorplus$modifyTooltipTick(Inventory instance) { if (this.minecraft.getCameraEntity() instanceof Player player) { return player.getInventory(); diff --git a/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/mixin/InventoryAccessor.java b/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/mixin/InventoryAccessor.java new file mode 100644 index 0000000..9a1f46d --- /dev/null +++ b/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/mixin/InventoryAccessor.java @@ -0,0 +1,12 @@ +package com.hpfxd.spectatorplus.fabric.client.mixin; + +import net.minecraft.world.entity.EntityEquipment; +import net.minecraft.world.entity.player.Inventory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(Inventory.class) +public interface InventoryAccessor { + @Accessor + EntityEquipment getEquipment(); +} diff --git a/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/sync/screen/ScreenSyncController.java b/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/sync/screen/ScreenSyncController.java index 1815087..a43e841 100644 --- a/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/sync/screen/ScreenSyncController.java +++ b/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/sync/screen/ScreenSyncController.java @@ -1,6 +1,7 @@ package com.hpfxd.spectatorplus.fabric.client.sync.screen; import com.hpfxd.spectatorplus.fabric.client.gui.screens.SyncedInventoryScreen; +import com.hpfxd.spectatorplus.fabric.client.mixin.InventoryAccessor; import com.hpfxd.spectatorplus.fabric.client.util.SpecUtil; import com.hpfxd.spectatorplus.fabric.sync.packet.ClientboundInventorySyncPacket; import com.hpfxd.spectatorplus.fabric.sync.packet.ClientboundScreenCursorSyncPacket; @@ -14,6 +15,7 @@ import net.minecraft.client.gui.screens.inventory.MenuAccess; import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.NonNullList; +import net.minecraft.world.entity.EntityEquipment; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; @@ -120,10 +122,11 @@ public static boolean createInventory(Player spectated) { return false; } - syncedInventory = new Inventory(spectated); + EntityEquipment equipment = ((InventoryAccessor)spectated.getInventory()).getEquipment(); + syncedInventory = new Inventory(spectated, equipment); for (int i = 0; i < syncData.screen.inventoryItems.size(); i++) { - syncedInventory.items.set(i, syncData.screen.inventoryItems.get(i)); + syncedInventory.setItem(i, syncData.screen.inventoryItems.get(i)); } return true; } diff --git a/fabric/src/client/resources/spectatorplus.client.mixins.json b/fabric/src/client/resources/spectatorplus.client.mixins.json index 39a0b36..360e842 100644 --- a/fabric/src/client/resources/spectatorplus.client.mixins.json +++ b/fabric/src/client/resources/spectatorplus.client.mixins.json @@ -26,7 +26,8 @@ "screen.ImageButtonAccessor", "screen.InventoryMenuMixin", "screen.InventoryScreenMixin", - "screen.MenuScreensMixin" + "screen.MenuScreensMixin", + "InventoryAccessor" ], "injectors": { "defaultRequire": 1 diff --git a/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/mixin/ServerGamePacketListenerImplMixin.java b/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/mixin/ServerGamePacketListenerImplMixin.java index 76e89a0..15d8e13 100644 --- a/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/mixin/ServerGamePacketListenerImplMixin.java +++ b/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/mixin/ServerGamePacketListenerImplMixin.java @@ -16,7 +16,7 @@ public abstract class ServerGamePacketListenerImplMixin { @Shadow public ServerPlayer player; - @Inject(method = "handleSetCarriedItem(Lnet/minecraft/network/protocol/game/ServerboundSetCarriedItemPacket;)V", at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/player/Inventory;selected:I", opcode = Opcodes.PUTFIELD)) + @Inject(method = "handleSetCarriedItem(Lnet/minecraft/network/protocol/game/ServerboundSetCarriedItemPacket;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Inventory;setSelectedSlot(I)V")) private void spectatorplus$syncSelectedSlot(ServerboundSetCarriedItemPacket packet, CallbackInfo ci) { ServerSyncController.broadcastPacketToSpectators(this.player, new ClientboundSelectedSlotSyncPacket(this.player.getUUID(), packet.getSlot())); } diff --git a/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/mixin/ServerPlayerMixin.java b/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/mixin/ServerPlayerMixin.java index 804b156..0f7f71c 100644 --- a/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/mixin/ServerPlayerMixin.java +++ b/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/mixin/ServerPlayerMixin.java @@ -68,7 +68,7 @@ public ServerPlayerMixin(Level level, BlockPos pos, float yRot, GameProfile game ServerSyncController.sendPacket(spectator, ClientboundSelectedSlotSyncPacket.initializing(target)); // Send initial map data patch packet if the target has a map in inventory - for (final ItemStack stack : target.getInventory().items) { + for (final ItemStack stack : target.getInventory().getNonEquipmentItems()) { if (stack.is(Items.FILLED_MAP)) { final MapId mapId = stack.get(DataComponents.MAP_ID); final MapItemSavedData mapItemSavedData = MapItem.getSavedData(mapId, this.level()); diff --git a/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/sync/packet/ClientboundSelectedSlotSyncPacket.java b/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/sync/packet/ClientboundSelectedSlotSyncPacket.java index de8e57e..756a9fa 100644 --- a/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/sync/packet/ClientboundSelectedSlotSyncPacket.java +++ b/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/sync/packet/ClientboundSelectedSlotSyncPacket.java @@ -21,7 +21,7 @@ public record ClientboundSelectedSlotSyncPacket( public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(ResourceLocation.parse("spectatorplus:selected_slot_sync")); public static ClientboundSelectedSlotSyncPacket initializing(ServerPlayer target) { - return new ClientboundSelectedSlotSyncPacket(target.getUUID(), target.getInventory().selected); + return new ClientboundSelectedSlotSyncPacket(target.getUUID(), target.getInventory().getSelectedSlot()); } public ClientboundSelectedSlotSyncPacket(FriendlyByteBuf buf) { From a7c7222fc0bb0df330472295dd54219b7a0bf977 Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Thu, 29 May 2025 17:17:32 -0400 Subject: [PATCH 2/4] Fix cloth config impl --- .../client/config/ClothConfigIntegration.java | 15 ++++++--------- .../fabric/client/mixin/GameRendererMixin.java | 2 +- .../resources/spectatorplus.client.mixins.json | 4 ++-- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/config/ClothConfigIntegration.java b/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/config/ClothConfigIntegration.java index 810ded6..116c30f 100644 --- a/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/config/ClothConfigIntegration.java +++ b/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/config/ClothConfigIntegration.java @@ -10,7 +10,6 @@ import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.HoverEvent; import net.minecraft.network.chat.MutableComponent; import java.io.IOException; @@ -132,13 +131,11 @@ private static void setupServerConfig(ConfigBuilder builder) { .setDefaultValue(defaults.allowTransferBetweenLevels) .build()); -// category.addEntry(entryBuilder.startBooleanToggle(Component.translatable("gui.spectatorplus.config.server.autoUpdatePosition.name") -// .withStyle(style -> style.withClickEvent(new ClickEvent.OpenUrl(URI.create("https://bugs.mojang.com/browse/MC-148993"))) -// .withHoverEvent(new HoverEvent.ShowText(Component.translatable("gui.spectatorplus.config.server.autoUpdatePosition.tooltip", Component.literal("MC-148993").withStyle(ChatFormatting.BLUE, ChatFormatting.UNDERLINE)))) -// -//// .setSaveConsumer(val -> config.autoUpdatePosition = val) -// // TODO: what -// .setDefaultValue(defaults.autoUpdatePosition) -// .build()); + category.addEntry(entryBuilder.startBooleanToggle(Component.translatable("gui.spectatorplus.config.server.autoUpdatePosition.name") + .withStyle(style -> style.withClickEvent(new ClickEvent.OpenUrl(URI.create("https://bugs.mojang.com/browse/MC-148993")))), config.autoUpdatePosition) + .setTooltip(Component.translatable("gui.spectatorplus.config.server.autoUpdatePosition.tooltip", Component.literal("MC-148993").withStyle(ChatFormatting.BLUE, ChatFormatting.UNDERLINE))) + .setSaveConsumer(val -> config.autoUpdatePosition = val) + .setDefaultValue(defaults.autoUpdatePosition) + .build()); } } diff --git a/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/mixin/GameRendererMixin.java b/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/mixin/GameRendererMixin.java index 456d7ac..5b560bc 100644 --- a/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/mixin/GameRendererMixin.java +++ b/fabric/src/client/java/com/hpfxd/spectatorplus/fabric/client/mixin/GameRendererMixin.java @@ -46,7 +46,7 @@ public abstract class GameRendererMixin { @Unique private float xBobO; @Unique private float yBobO; - @Inject(method = "renderItemInHand(Lnet/minecraft/client/Camera;FLorg/joml/Matrix4f;)V", at = @At(value = "INVOKE", target = "Lorg/joml/Matrix4fStack;popMatrix()Lorg/joml/Matrix4fStack;")) + @Inject(method = "renderItemInHand(Lnet/minecraft/client/Camera;FLorg/joml/Matrix4f;)V", at = @At(value = "INVOKE", target = "Lorg/joml/Matrix4fStack;popMatrix()Lorg/joml/Matrix4fStack;", remap = false)) public void spectatorplus$renderItemInHand(Camera camera, float partialTicks, Matrix4f matrix4f, CallbackInfo ci, @Local PoseStack poseStackIn) { if (SpectatorClientMod.config.renderArms && this.minecraft.player != null && this.minecraft.options.getCameraType().isFirstPerson() && !this.minecraft.options.hideGui) { final AbstractClientPlayer spectated = SpecUtil.getCameraPlayer(this.minecraft); diff --git a/fabric/src/client/resources/spectatorplus.client.mixins.json b/fabric/src/client/resources/spectatorplus.client.mixins.json index 360e842..cb31ffd 100644 --- a/fabric/src/client/resources/spectatorplus.client.mixins.json +++ b/fabric/src/client/resources/spectatorplus.client.mixins.json @@ -9,6 +9,7 @@ "GameRendererAccessor", "GameRendererMixin", "GuiMixin", + "InventoryAccessor", "ItemInHandRendererAccessor", "ItemInHandRendererMixin", "LevelRendererAccessor", @@ -26,8 +27,7 @@ "screen.ImageButtonAccessor", "screen.InventoryMenuMixin", "screen.InventoryScreenMixin", - "screen.MenuScreensMixin", - "InventoryAccessor" + "screen.MenuScreensMixin" ], "injectors": { "defaultRequire": 1 From 8573262a9879d435416c16226f0a7bd6d3fcb593 Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Thu, 29 May 2025 20:58:44 -0400 Subject: [PATCH 3/4] Revert "Use ItemStack stream codec for sync packets" This reverts commit 77453595b1aa68cb8b8ebd47954853da712dbe40. For some reason the ItemStack codecs arent working in the new 1.21.5 update? --- .../fabric/sync/CustomPacketCodecs.java | 48 ++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/sync/CustomPacketCodecs.java b/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/sync/CustomPacketCodecs.java index a6b19b8..d963987 100644 --- a/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/sync/CustomPacketCodecs.java +++ b/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/sync/CustomPacketCodecs.java @@ -1,9 +1,21 @@ package com.hpfxd.spectatorplus.fabric.sync; +import io.netty.handler.codec.EncoderException; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtAccounter; +import net.minecraft.nbt.NbtIo; import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.item.ItemStack; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + public final class CustomPacketCodecs { + public static final StreamCodec ITEM_CODEC = StreamCodec.of(CustomPacketCodecs::writeItem, CustomPacketCodecs::readItem); + public static final StreamCodec ITEM_ARRAY_CODEC = StreamCodec.of(CustomPacketCodecs::writeItems, CustomPacketCodecs::readItems); + private CustomPacketCodecs() { } @@ -35,10 +47,42 @@ public static void writeItems(RegistryFriendlyByteBuf buf, ItemStack[] items) { } public static ItemStack readItem(RegistryFriendlyByteBuf buf) { - return ItemStack.OPTIONAL_STREAM_CODEC.decode(buf); + final int len = buf.readInt(); + if (len == 0) { + return ItemStack.EMPTY; + } + + try { + final byte[] in = new byte[len]; + buf.readBytes(in); + + final CompoundTag tag = NbtIo.readCompressed(new ByteArrayInputStream(in), NbtAccounter.unlimitedHeap()); + return ItemStack.parse(buf.registryAccess(), tag).orElse(ItemStack.EMPTY); + } catch (IOException e) { + throw new EncoderException(e); + } } public static void writeItem(RegistryFriendlyByteBuf buf, ItemStack item) { - ItemStack.OPTIONAL_STREAM_CODEC.encode(buf, item); + if (item.isEmpty()) { + buf.writeInt(0); + return; + } + + final byte[] bytes; + try { + final CompoundTag tag = new CompoundTag(); + item.save(buf.registryAccess(), tag); + + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + NbtIo.writeCompressed(tag, out); + + bytes = out.toByteArray(); + } catch (IOException e) { + throw new EncoderException(e); + } + + buf.writeInt(bytes.length); + buf.writeBytes(bytes); } } From e7180c81cd3a204515d7c7ca5ebd0028897eee5a Mon Sep 17 00:00:00 2001 From: Connor Slade Date: Thu, 29 May 2025 23:08:18 -0400 Subject: [PATCH 4/4] Update Minecraft version in mod.json --- .../hpfxd/spectatorplus/fabric/sync/CustomPacketCodecs.java | 4 ---- fabric/src/main/resources/fabric.mod.json | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/sync/CustomPacketCodecs.java b/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/sync/CustomPacketCodecs.java index d963987..f0d56c3 100644 --- a/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/sync/CustomPacketCodecs.java +++ b/fabric/src/main/java/com/hpfxd/spectatorplus/fabric/sync/CustomPacketCodecs.java @@ -5,7 +5,6 @@ import net.minecraft.nbt.NbtAccounter; import net.minecraft.nbt.NbtIo; import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.item.ItemStack; import java.io.ByteArrayInputStream; @@ -13,9 +12,6 @@ import java.io.IOException; public final class CustomPacketCodecs { - public static final StreamCodec ITEM_CODEC = StreamCodec.of(CustomPacketCodecs::writeItem, CustomPacketCodecs::readItem); - public static final StreamCodec ITEM_ARRAY_CODEC = StreamCodec.of(CustomPacketCodecs::writeItems, CustomPacketCodecs::readItems); - private CustomPacketCodecs() { } diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 0709447..f217a85 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -51,13 +51,13 @@ ], "depends": { "fabricloader": ">=0.15.0", - "minecraft": "~1.21.3", + "minecraft": "~1.21.5", "java": ">=21", "fabric-api": "*", "fabric-permissions-api-v0": "*" }, "suggests": { - "cloth-config": "^17.0.0", - "modmenu": "^13.0.0" + "cloth-config": "^18.0.145", + "modmenu": "^14.0.0-rc.2" } }