From 3c484ef82915b83ce49da790cdbacdab44f08c0b Mon Sep 17 00:00:00 2001 From: "James (Jamalam)" Date: Mon, 20 May 2024 22:00:21 +0100 Subject: [PATCH 1/6] feat: 1.20.6 port --- .github/workflows/build.yml | 4 +- build.gradle | 2 +- .../jamalam360/utility_belt/UtilityBelt.java | 83 +++++----- .../utility_belt/UtilityBeltInventory.java | 118 ++++++++------ .../utility_belt/UtilityBeltItem.java | 30 ++-- .../utility_belt/UtilityBeltPackets.java | 70 ++++++++ .../utility_belt/client/ClientNetworking.java | 79 +++++---- .../client/UtilityBeltClient.java | 4 +- .../utility_belt/mixin/LivingEntityMixin.java | 7 +- .../utility_belt/mixin/ServerPlayerMixin.java | 2 +- .../utility_belt/mixin/client/GuiMixin.java | 2 +- .../utility_belt/screen/UtilityBeltMenu.java | 11 +- .../utility_belt/server/ServerNetworking.java | 152 +++++++++--------- .../utility_belt/recipes/utility_belt.json | 2 +- fabric/build.gradle | 6 +- gradle.properties | 4 +- libs.versions.toml | 16 +- neoforge/build.gradle | 8 +- .../{mods.toml => neoforge.mods.toml} | 0 19 files changed, 344 insertions(+), 256 deletions(-) create mode 100644 common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltPackets.java rename neoforge/src/main/resources/META-INF/{mods.toml => neoforge.mods.toml} (100%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 07cc6e7..908a15d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,10 +27,10 @@ jobs: - name: Validate Gradle Wrapper uses: gradle/wrapper-validation-action@v1 - - name: Setup JDK 17 + - name: Setup JDK 21 uses: actions/setup-java@v1 with: - java-version: 17 + java-version: 21 - name: Build run: ./gradlew clean neoforge:build fabric:build diff --git a/build.gradle b/build.gradle index 10179df..6d86b44 100644 --- a/build.gradle +++ b/build.gradle @@ -87,7 +87,7 @@ allprojects { tasks.withType(JavaCompile) { options.encoding = "UTF-8" - options.release = 17 + options.release = 21 } tasks.create("prepareWorkspace") {} diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBelt.java b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBelt.java index b2297bf..e49bf83 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBelt.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBelt.java @@ -16,6 +16,7 @@ import io.github.jamalam360.utility_belt.server.ServerStateManager; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; +import net.minecraft.core.component.DataComponentType; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; @@ -27,50 +28,48 @@ import org.slf4j.LoggerFactory; public class UtilityBelt { - public static final String MOD_ID = "utility_belt"; - public static final String MOD_NAME = "Utility Belt"; - public static final Logger LOGGER = LoggerFactory.getLogger(MOD_NAME); - public static final ConfigManager CONFIG = new ConfigManager<>(MOD_ID, Config.class); - public static final TagKey ALLOWED_IN_UTILITY_BELT = TagKey.create(Registries.ITEM, id("allowed_in_utility_belt")); - public static final ResourceLocation C2S_UPDATE_STATE = id("update_state"); - public static final ResourceLocation C2S_OPEN_SCREEN = id("open_screen"); - public static final ResourceLocation S2C_UPDATE_INV = id("update_inv"); - public static final ResourceLocation S2C_SET_BELT_SLOT = id("set_belt_slot"); - public static final ResourceLocation S2C_SET_HOTBAR_SLOT = id("set_hotbar_slot"); - private static final DeferredRegister ITEMS = DeferredRegister.create(MOD_ID, Registries.ITEM); - public static final RegistrySupplier UTILITY_BELT_ITEM = ITEMS.register("utility_belt", UtilityBeltItem::new); - public static final DeferredRegister> MENUS = DeferredRegister.create(MOD_ID, Registries.MENU); - public static final RegistrySupplier> MENU_TYPE = MENUS.register("utility_belt", () -> new MenuType<>(UtilityBeltMenu::new, FeatureFlagSet.of())); - public static void init() { - JamLib.checkForJarRenaming(UtilityBelt.class); - ITEMS.register(); - MENUS.register(); - UTILITY_BELT_ITEM.listen((belt) -> CreativeTabRegistry.append(CreativeModeTabs.TOOLS_AND_UTILITIES, belt)); - ServerNetworking.init(); - StateManager.setServerInstance(new ServerStateManager()); - EnvExecutor.runInEnv(Env.CLIENT, () -> UtilityBeltClient::init); + public static final String MOD_ID = "utility_belt"; + public static final String MOD_NAME = "Utility Belt"; + public static final Logger LOGGER = LoggerFactory.getLogger(MOD_NAME); + public static final ConfigManager CONFIG = new ConfigManager<>(MOD_ID, Config.class); + public static final TagKey ALLOWED_IN_UTILITY_BELT = TagKey.create(Registries.ITEM, id("allowed_in_utility_belt")); - if (Platform.isDevelopmentEnvironment()) { - CommandRegistrationEvent.EVENT.register(((dispatcher, registry, selection) -> - dispatcher.register( - Commands.literal("dumpstate") - .executes(ctx -> { - CommandSourceStack source = ctx.getSource(); - StateManager stateManager = StateManager.getServerInstance(); - System.out.println("In belt: " + stateManager.isInBelt(source.getPlayerOrException())); - System.out.println("Selected slot: " + stateManager.getSelectedBeltSlot(source.getPlayerOrException())); - System.out.println("Belt NBT: " + UtilityBeltItem.getBelt(source.getPlayerOrException()).getTag()); - return 0; - }) - ) - )); - } + private static final DeferredRegister ITEMS = DeferredRegister.create(MOD_ID, Registries.ITEM); + private static final DeferredRegister> MENUS = DeferredRegister.create(MOD_ID, Registries.MENU); + private static final DeferredRegister> COMPONENT_TYPES = DeferredRegister.create(MOD_ID, Registries.DATA_COMPONENT_TYPE); - LOGGER.info(MOD_NAME + " initialized on " + JamLibPlatform.getPlatform()); - } + public static final RegistrySupplier UTILITY_BELT_ITEM = ITEMS.register("utility_belt", UtilityBeltItem::new); + public static final RegistrySupplier> MENU_TYPE = MENUS.register("utility_belt", () -> new MenuType<>(UtilityBeltMenu::new, FeatureFlagSet.of())); + public static final RegistrySupplier> UTILITY_BELT_INVENTORY_COMPONENT_TYPE = COMPONENT_TYPES.register("utility_belt_inventory", () -> + DataComponentType.builder().persistent(UtilityBeltInventory.CODEC).networkSynchronized(UtilityBeltInventory.STREAM_CODEC).build() + ); - public static ResourceLocation id(String path) { - return new ResourceLocation(MOD_ID, path); - } + public static void init() { + JamLib.checkForJarRenaming(UtilityBelt.class); + ITEMS.register(); + MENUS.register(); + COMPONENT_TYPES.register(); + UTILITY_BELT_ITEM.listen((belt) -> CreativeTabRegistry.append(CreativeModeTabs.TOOLS_AND_UTILITIES, belt)); + ServerNetworking.init(); + StateManager.setServerInstance(new ServerStateManager()); + EnvExecutor.runInEnv(Env.CLIENT, () -> UtilityBeltClient::init); + + if (Platform.isDevelopmentEnvironment()) { + CommandRegistrationEvent.EVENT.register(((dispatcher, registry, selection) -> dispatcher.register(Commands.literal("dumpstate").executes(ctx -> { + CommandSourceStack source = ctx.getSource(); + StateManager stateManager = StateManager.getServerInstance(); + System.out.println("In belt: " + stateManager.isInBelt(source.getPlayerOrException())); + System.out.println("Selected slot: " + stateManager.getSelectedBeltSlot(source.getPlayerOrException())); + System.out.println("Belt NBT: " + UtilityBeltItem.getBelt(source.getPlayerOrException()).get(UTILITY_BELT_INVENTORY_COMPONENT_TYPE.get())); + return 0; + })))); + } + + LOGGER.info(MOD_NAME + " initialized on " + JamLibPlatform.getPlatform()); + } + + public static ResourceLocation id(String path) { + return new ResourceLocation(MOD_ID, path); + } } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltInventory.java b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltInventory.java index 0464567..76d0af6 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltInventory.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltInventory.java @@ -1,59 +1,73 @@ package io.github.jamalam360.utility_belt; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; +import com.mojang.serialization.Codec; +import java.util.List; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.SimpleContainer; import net.minecraft.world.item.ItemStack; public class UtilityBeltInventory extends SimpleContainer { - public UtilityBeltInventory() { - super(4); - } - - @Override - public void fromTag(ListTag listTag) { - this.clearContent(); - - for (int i = 0; i < listTag.size(); ++i) { - this.setItem(i, ItemStack.of(listTag.getCompound(i))); - } - } - - @Override - public ListTag createTag() { - ListTag listTag = new ListTag(); - - for (int i = 0; i < this.getContainerSize(); ++i) { - listTag.add(this.getItem(i).save(new CompoundTag())); - } - - return listTag; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof UtilityBeltInventory other) { - if (other.getContainerSize() == this.getContainerSize()) { - for (int i = 0; i < this.getContainerSize(); i++) { - if (!ItemStack.matches(this.getItem(i), other.getItem(i))) { - return false; - } - } - - return true; - } - } - - return false; - } - - @Override - public UtilityBeltInventory clone() { - UtilityBeltInventory inv = new UtilityBeltInventory(); - for (int i = 0; i < this.getContainerSize(); i++) { - inv.setItem(i, this.getItem(i).copy()); - } - - return inv; - } + + public static final Codec CODEC = Codec + .list(ItemStack.CODEC) + .xmap(UtilityBeltInventory::new, UtilityBeltInventory::getItems); + + public static final StreamCodec STREAM_CODEC = StreamCodec + .composite( + ItemStack.STREAM_CODEC.apply(ByteBufCodecs.list(4)), + UtilityBeltInventory::getItems, + UtilityBeltInventory::new + ); + + + public UtilityBeltInventory() { + super(4); + } + + private UtilityBeltInventory(List stacks) { + super(4); + + for (int i = 0; i < stacks.size(); i++) { + this.setItem(i, stacks.get(i)); + } + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof UtilityBeltInventory other) { + if (other.getContainerSize() == this.getContainerSize()) { + for (int i = 0; i < this.getContainerSize(); i++) { + if (!ItemStack.matches(this.getItem(i), other.getItem(i))) { + return false; + } + } + + return true; + } + } + + return false; + } + + @Override + public int hashCode() { + int hash = 0; + for (int i = 0; i < this.getContainerSize(); i++) { + hash += this.getItem(i).hashCode(); + } + + return hash; + } + + @Override + public UtilityBeltInventory clone() { + UtilityBeltInventory inv = new UtilityBeltInventory(); + for (int i = 0; i < this.getContainerSize(); i++) { + inv.setItem(i, this.getItem(i).copy()); + } + + return inv; + } } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltItem.java b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltItem.java index 725a85f..1e33f29 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltItem.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltItem.java @@ -3,7 +3,6 @@ import io.github.jamalam360.utility_belt.client.ClientNetworking; import java.util.List; import java.util.function.Consumer; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.sounds.SoundEvents; import net.minecraft.util.Mth; @@ -24,7 +23,6 @@ import net.minecraft.world.item.TieredItem; import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.TridentItem; -import net.minecraft.world.level.Level; import org.jetbrains.annotations.Nullable; public class UtilityBeltItem extends Item { @@ -32,7 +30,7 @@ public class UtilityBeltItem extends Item { private static final int BAR_COLOR = Mth.color(0.4F, 0.4F, 1.0F); public UtilityBeltItem() { - super(new Item.Properties().stacksTo(1)); + super(new Item.Properties().stacksTo(1).component(UtilityBelt.UTILITY_BELT_INVENTORY_COMPONENT_TYPE.get(), new UtilityBeltInventory())); } @SuppressWarnings("BooleanMethodIsAlwaysInverted") @@ -66,26 +64,24 @@ public static boolean isValidItem(ItemStack stack) { return stack.getItem() instanceof TieredItem || stack.getItem() instanceof ProjectileWeaponItem || stack.getItem() instanceof FishingRodItem || stack.getItem() instanceof SpyglassItem || stack.getItem() instanceof TridentItem || stack.getItem() instanceof FlintAndSteelItem || stack.getItem() instanceof ShearsItem || stack.getItem() instanceof BrushItem || stack.isEmpty() || stack.is(UtilityBelt.ALLOWED_IN_UTILITY_BELT); } + // Going to keep this name as is until 1.20.4 support is dropped, to keep the diffs smaller public static UtilityBeltInventory getInventoryFromTag(ItemStack stack) { - UtilityBeltInventory inv = new UtilityBeltInventory(); - - if (stack != null) { - CompoundTag tag = stack.getOrCreateTag(); - if (!tag.contains("Inventory")) { - tag.put("Inventory", inv.createTag()); - } else { - inv.fromTag(tag.getList("Inventory", CompoundTag.TAG_COMPOUND)); - } + if (!stack.has(UtilityBelt.UTILITY_BELT_INVENTORY_COMPONENT_TYPE.get())) { + stack.set(UtilityBelt.UTILITY_BELT_INVENTORY_COMPONENT_TYPE.get(), new UtilityBeltInventory()); } - return inv; + return stack.get(UtilityBelt.UTILITY_BELT_INVENTORY_COMPONENT_TYPE.get()); + } + + public static void setInventory(ItemStack stack, UtilityBeltInventory inv) { + stack.set(UtilityBelt.UTILITY_BELT_INVENTORY_COMPONENT_TYPE.get(), inv); } @Nullable public static ItemStack getBelt(Player player) { ItemStack stack = UtilityBeltPlatform.getStackInBeltSlot(player); - if (stack != null && stack.getItem() == UtilityBelt.UTILITY_BELT_ITEM.get()) { + if (stack != null && stack.getItem() == UtilityBelt.UTILITY_BELT_ITEM.get()) { return stack; } else { return null; @@ -109,7 +105,7 @@ public int getBarColor(ItemStack itemStack) { } @Override - public void appendHoverText(ItemStack itemStack, @Nullable Level level, List list, TooltipFlag tooltipFlag) { + public void appendHoverText(ItemStack itemStack, TooltipContext tooltipContext, List list, TooltipFlag tooltipFlag) { UtilityBeltInventory inv = getInventoryFromTag(itemStack); for (int i = 0; i < inv.getContainerSize(); i++) { @@ -134,7 +130,7 @@ public boolean overrideStackedOnOther(ItemStack belt, Slot slot, ClickAction cli } playInsertSound(player); - belt.getOrCreateTag().put("Inventory", inv.createTag()); + setInventory(belt, inv); return true; } @@ -151,7 +147,7 @@ public boolean overrideOtherStackedOnMe(ItemStack belt, ItemStack otherStack, Sl } playInsertSound(player); - belt.getOrCreateTag().put("Inventory", inv.createTag()); + setInventory(belt, inv); return true; } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltPackets.java b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltPackets.java new file mode 100644 index 0000000..21015d3 --- /dev/null +++ b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltPackets.java @@ -0,0 +1,70 @@ +package io.github.jamalam360.utility_belt; + +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; + +public class UtilityBeltPackets { + + public static final CustomPacketPayload.Type C2S_UPDATE_STATE = new CustomPacketPayload.Type<>(UtilityBelt.id("update_state")); + public static final CustomPacketPayload.Type C2S_OPEN_SCREEN = new CustomPacketPayload.Type<>(UtilityBelt.id("open_screen")); + public static final CustomPacketPayload.Type S2C_SET_BELT_SLOT = new CustomPacketPayload.Type<>(UtilityBelt.id("set_belt_slot")); + public static final CustomPacketPayload.Type S2C_SET_HOTBAR_SLOT = new CustomPacketPayload.Type<>(UtilityBelt.id("set_hotbar_slot")); + + public record C2SUpdateState(boolean inBelt, int slot, boolean swapItems) implements CustomPacketPayload { + + public static final StreamCodec STREAM_CODEC = StreamCodec.of( + (buf, payload) -> { + buf.writeBoolean(payload.inBelt()); + buf.writeInt(payload.slot()); + buf.writeBoolean(payload.swapItems()); + }, + (buf) -> new C2SUpdateState(buf.readBoolean(), buf.readInt(), buf.readBoolean()) + ); + + @Override + public Type type() { + return C2S_UPDATE_STATE; + } + } + + public record C2SOpenScreen() implements CustomPacketPayload { + + public static final StreamCodec STREAM_CODEC = StreamCodec.of( + (buf, payload) -> { + }, + (buf) -> new C2SOpenScreen() + ); + + @Override + public Type type() { + return C2S_OPEN_SCREEN; + } + } + + public record S2CSetBeltSlot(int slot) implements CustomPacketPayload { + + public static final StreamCodec STREAM_CODEC = StreamCodec.of( + (buf, payload) -> buf.writeInt(payload.slot()), + (buf) -> new S2CSetBeltSlot(buf.readInt()) + ); + + @Override + public Type type() { + return S2C_SET_BELT_SLOT; + } + } + + public record S2CSetHotbarSlot(int slot) implements CustomPacketPayload { + + public static final StreamCodec STREAM_CODEC = StreamCodec.of( + (buf, payload) -> buf.writeInt(payload.slot()), + (buf) -> new S2CSetHotbarSlot(buf.readInt()) + ); + + @Override + public Type type() { + return S2C_SET_HOTBAR_SLOT; + } + } +} diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/client/ClientNetworking.java b/common/src/main/java/io/github/jamalam360/utility_belt/client/ClientNetworking.java index 3e4c4be..ccc62b7 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/client/ClientNetworking.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/client/ClientNetworking.java @@ -3,52 +3,49 @@ import dev.architectury.networking.NetworkManager; import io.github.jamalam360.utility_belt.StateManager; import io.github.jamalam360.utility_belt.UtilityBelt; -import io.github.jamalam360.utility_belt.UtilityBeltItem; +import io.github.jamalam360.utility_belt.UtilityBeltPackets; +import io.github.jamalam360.utility_belt.UtilityBeltPackets.C2SOpenScreen; +import io.github.jamalam360.utility_belt.UtilityBeltPackets.C2SUpdateState; +import io.github.jamalam360.utility_belt.UtilityBeltPackets.S2CSetBeltSlot; +import io.github.jamalam360.utility_belt.UtilityBeltPackets.S2CSetHotbarSlot; import io.netty.buffer.Unpooled; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.world.item.ItemStack; @Environment(EnvType.CLIENT) public class ClientNetworking { - public static void init() { - NetworkManager.registerReceiver(NetworkManager.Side.S2C, UtilityBelt.S2C_UPDATE_INV, ClientNetworking::handleUpdateInventory); - NetworkManager.registerReceiver(NetworkManager.Side.S2C, UtilityBelt.S2C_SET_BELT_SLOT, ClientNetworking::handleSetBeltSlot); - NetworkManager.registerReceiver(NetworkManager.Side.S2C, UtilityBelt.S2C_SET_HOTBAR_SLOT, ClientNetworking::handleSetHotbarSlot); - } - - public static void sendNewStateToServer(boolean inBelt, int slot, boolean swapItems) { -// swapItems |= UtilityBelt.CONFIG.get().useSneakSwapping; - - if (swapItems && !UtilityBelt.CONFIG.get().useSneakSwapping) { - swapItems = false; - } - - FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer()); - buf.writeBoolean(inBelt); - buf.writeInt(slot); - buf.writeBoolean(swapItems); - NetworkManager.sendToServer(UtilityBelt.C2S_UPDATE_STATE, buf); - } - - public static void sendOpenScreenToServer() { - NetworkManager.sendToServer(UtilityBelt.C2S_OPEN_SCREEN, new FriendlyByteBuf(Unpooled.buffer())); - } - - private static void handleUpdateInventory(FriendlyByteBuf buf, NetworkManager.PacketContext ctx) { - CompoundTag tag = buf.readNbt(); - ItemStack belt = UtilityBeltItem.getBelt(ctx.getPlayer()); - belt.getTag().put("Inventory", tag.getList("Inventory", CompoundTag.TAG_COMPOUND)); - } - - private static void handleSetBeltSlot(FriendlyByteBuf buf, NetworkManager.PacketContext ctx) { - int slot = buf.readInt(); - StateManager.getClientInstance().setSelectedBeltSlot(ctx.getPlayer(), slot); - } - - private static void handleSetHotbarSlot(FriendlyByteBuf buf, NetworkManager.PacketContext ctx) { - ctx.getPlayer().getInventory().selected = buf.readInt(); - } + + public static void init() { +// NetworkManager.registerReceiver(NetworkManager.Side.S2C, UtilityBelt.S2C_UPDATE_INV, ClientNetworking::handleUpdateInventory); + NetworkManager.registerReceiver(NetworkManager.Side.S2C, UtilityBeltPackets.S2C_SET_BELT_SLOT, S2CSetBeltSlot.STREAM_CODEC, ClientNetworking::handleSetBeltSlot); + NetworkManager.registerReceiver(NetworkManager.Side.S2C, UtilityBeltPackets.S2C_SET_HOTBAR_SLOT, S2CSetHotbarSlot.STREAM_CODEC, ClientNetworking::handleSetHotbarSlot); + } + + public static void sendNewStateToServer(boolean inBelt, int slot, boolean swapItems) { + if (swapItems && !UtilityBelt.CONFIG.get().useSneakSwapping) { + swapItems = false; + } + + UtilityBeltPackets.C2SUpdateState packet = new C2SUpdateState(inBelt, slot, swapItems); + NetworkManager.sendToServer(packet); + } + + public static void sendOpenScreenToServer() { + NetworkManager.sendToServer(new C2SOpenScreen()); + } + + private static void handleUpdateInventory(FriendlyByteBuf buf, NetworkManager.PacketContext ctx) { +// CompoundTag tag = buf.readNbt(); +// ItemStack belt = UtilityBeltItem.getBelt(ctx.getPlayer()); +// belt.getTag().put("Inventory", tag.getList("Inventory", CompoundTag.TAG_COMPOUND)); + } + + private static void handleSetBeltSlot(S2CSetBeltSlot payload, NetworkManager.PacketContext ctx) { + StateManager.getClientInstance().setSelectedBeltSlot(ctx.getPlayer(), payload.slot()); + } + + private static void handleSetHotbarSlot(S2CSetHotbarSlot payload, NetworkManager.PacketContext ctx) { + ctx.getPlayer().getInventory().selected = payload.slot(); + } } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/client/UtilityBeltClient.java b/common/src/main/java/io/github/jamalam360/utility_belt/client/UtilityBeltClient.java index 3bac63c..a9b326f 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/client/UtilityBeltClient.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/client/UtilityBeltClient.java @@ -74,12 +74,12 @@ public static void init() { StateManager stateManager = StateManager.getClientInstance(); System.out.println("In belt: " + stateManager.isInBelt(Minecraft.getInstance().player)); System.out.println("Selected slot: " + stateManager.getSelectedBeltSlot(Minecraft.getInstance().player)); - System.out.println("Belt NBT: " + UtilityBeltItem.getBelt(Minecraft.getInstance().player).getTag()); + System.out.println("Belt NBT: " + UtilityBeltItem.getBelt(Minecraft.getInstance().player).get(UtilityBelt.UTILITY_BELT_INVENTORY_COMPONENT_TYPE.get())); StateManager stateManagerS = StateManager.getServerInstance(); System.out.println("In belt (client but server): " + stateManagerS.isInBelt(Minecraft.getInstance().player)); System.out.println("Selected slot (client but server): " + stateManagerS.getSelectedBeltSlot(Minecraft.getInstance().player)); - System.out.println("Belt NBT (client but server): " + UtilityBeltItem.getBelt(Minecraft.getInstance().player).getTag()); + System.out.println("Belt NBT (client but server): " + UtilityBeltItem.getBelt(Minecraft.getInstance().player).get(UtilityBelt.UTILITY_BELT_INVENTORY_COMPONENT_TYPE.get())); return 0; }) ) diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/LivingEntityMixin.java b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/LivingEntityMixin.java index e5fbc5d..0d4a9fb 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/LivingEntityMixin.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/LivingEntityMixin.java @@ -6,6 +6,7 @@ import io.github.jamalam360.utility_belt.UtilityBeltItem; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; @@ -22,11 +23,11 @@ public abstract class LivingEntityMixin implements Duck.LivingEntity { @SuppressWarnings("ConstantValue") @Inject( - method = "broadcastBreakEvent(Lnet/minecraft/world/InteractionHand;)V", + method = "broadcastBreakEvent", at = @At("HEAD") ) - private void utilitybelt$broadcastBreakEvent(InteractionHand interactionHand, CallbackInfo ci) { - if (interactionHand == InteractionHand.MAIN_HAND && (Object) this instanceof ServerPlayer player) { + private void utilitybelt$broadcastBreakEvent(EquipmentSlot slot, CallbackInfo ci) { + if (slot == EquipmentSlot.MAINHAND && (Object) this instanceof ServerPlayer player) { StateManager stateManager = StateManager.getServerInstance(); if (stateManager.isInBelt(player)) { ItemStack belt = UtilityBeltItem.getBelt(player); diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/ServerPlayerMixin.java b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/ServerPlayerMixin.java index de5cf82..575ae40 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/ServerPlayerMixin.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/ServerPlayerMixin.java @@ -28,7 +28,7 @@ public class ServerPlayerMixin { UtilityBeltInventory nbtInv = UtilityBeltItem.getInventoryFromTag(belt); if (!inv.equals(nbtInv)) { - belt.getOrCreateTag().put("Inventory", inv.createTag()); + UtilityBeltItem.setInventory(belt, inv); ServerNetworking.sendNewInventoryToClient((ServerPlayer) (Object) this); } } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/client/GuiMixin.java b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/client/GuiMixin.java index 741f384..f0b35e2 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/client/GuiMixin.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/client/GuiMixin.java @@ -19,7 +19,7 @@ public abstract class GuiMixin { protected abstract Player getCameraPlayer(); @WrapWithCondition( - method = "renderHotbar", + method = "renderItemHotbar", at = @At( value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiGraphics;blitSprite(Lnet/minecraft/resources/ResourceLocation;IIII)V", diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/screen/UtilityBeltMenu.java b/common/src/main/java/io/github/jamalam360/utility_belt/screen/UtilityBeltMenu.java index d3d1b4b..5a4a294 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/screen/UtilityBeltMenu.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/screen/UtilityBeltMenu.java @@ -109,9 +109,16 @@ public void removed(Player player) { private void markDirty(Player player) { ItemStack belt = UtilityBeltItem.getBelt(player); - belt.getTag().put("Inventory", this.inventory.createTag()); - if (player instanceof ServerPlayer sPlayer) { + if (belt == null) { + // uh oh + // anyways + return; + } + + UtilityBeltItem.setInventory(belt, this.inventory); + + if (player instanceof ServerPlayer) { ((ServerStateManager) StateManager.getServerInstance()).getInventoryFromTag(player); } } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/server/ServerNetworking.java b/common/src/main/java/io/github/jamalam360/utility_belt/server/ServerNetworking.java index e9218da..1acc12a 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/server/ServerNetworking.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/server/ServerNetworking.java @@ -2,95 +2,97 @@ import dev.architectury.networking.NetworkManager; import dev.architectury.registry.menu.MenuRegistry; -import io.github.jamalam360.utility_belt.*; +import io.github.jamalam360.utility_belt.Duck; +import io.github.jamalam360.utility_belt.StateManager; +import io.github.jamalam360.utility_belt.UtilityBelt; +import io.github.jamalam360.utility_belt.UtilityBeltInventory; +import io.github.jamalam360.utility_belt.UtilityBeltItem; +import io.github.jamalam360.utility_belt.UtilityBeltPackets; +import io.github.jamalam360.utility_belt.UtilityBeltPackets.C2SOpenScreen; +import io.github.jamalam360.utility_belt.UtilityBeltPackets.C2SUpdateState; +import io.github.jamalam360.utility_belt.UtilityBeltPackets.S2CSetBeltSlot; import io.github.jamalam360.utility_belt.screen.UtilityBeltMenu; -import io.netty.buffer.Unpooled; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; import net.minecraft.world.item.ItemStack; public class ServerNetworking { - public static void init() { - NetworkManager.registerReceiver(NetworkManager.Side.C2S, UtilityBelt.C2S_UPDATE_STATE, ServerNetworking::handleUpdateState); - NetworkManager.registerReceiver(NetworkManager.Side.C2S, UtilityBelt.C2S_OPEN_SCREEN, ServerNetworking::handleOpenScreen); - } - public static void sendNewInventoryToClient(ServerPlayer player) { - FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer()); - UtilityBeltInventory inv = StateManager.getServerInstance().getInventory(player); - CompoundTag tag = new CompoundTag(); - tag.put("Inventory", inv.createTag()); - buf.writeNbt(tag); - NetworkManager.sendToPlayer(player, UtilityBelt.S2C_UPDATE_INV, buf); - } + public static void init() { + NetworkManager.registerReceiver(NetworkManager.Side.C2S, UtilityBeltPackets.C2S_UPDATE_STATE, C2SUpdateState.STREAM_CODEC, ServerNetworking::handleUpdateState); + NetworkManager.registerReceiver(NetworkManager.Side.C2S, UtilityBeltPackets.C2S_OPEN_SCREEN, C2SOpenScreen.STREAM_CODEC, ServerNetworking::handleOpenScreen); + } - private static void handleUpdateState(FriendlyByteBuf buf, NetworkManager.PacketContext ctx) { - boolean inBelt = buf.readBoolean(); - int slot = buf.readInt(); - boolean swap = buf.readBoolean(); + public static void sendNewInventoryToClient(ServerPlayer player) { +// FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer()); +// UtilityBeltInventory inv = StateManager.getServerInstance().getInventory(player); +// CompoundTag tag = new CompoundTag(); +// tag.put("Inventory", inv.createTag()); +// buf.writeNbt(tag); +// NetworkManager.sendToPlayer(player, UtilityBelt.S2C_UPDATE_INV, buf); + } - ctx.queue(() -> { - int beltSlot = slot; - StateManager stateManager = StateManager.getServerInstance(); - stateManager.setInBelt(ctx.getPlayer(), inBelt); - stateManager.setSelectedBeltSlot(ctx.getPlayer(), beltSlot); - ctx.getPlayer().swing(InteractionHand.MAIN_HAND, true); + private static void handleUpdateState(C2SUpdateState payload, NetworkManager.PacketContext ctx) { + boolean inBelt = payload.inBelt(); + int slot = payload.slot(); + boolean swap = payload.swapItems(); - if (swap) { - ItemStack belt = UtilityBeltItem.getBelt(ctx.getPlayer()); + ctx.queue(() -> { + int beltSlot = slot; + StateManager stateManager = StateManager.getServerInstance(); + stateManager.setInBelt(ctx.getPlayer(), inBelt); + stateManager.setSelectedBeltSlot(ctx.getPlayer(), beltSlot); + ctx.getPlayer().swing(InteractionHand.MAIN_HAND, true); - if (belt == null) { - UtilityBelt.LOGGER.warn("Received swap request packet from client without a belt equipped"); - return; - } + if (swap) { + ItemStack belt = UtilityBeltItem.getBelt(ctx.getPlayer()); - UtilityBeltInventory inv = stateManager.getInventory(ctx.getPlayer()); - ItemStack stackInHand = ctx.getPlayer().getInventory().getItem(ctx.getPlayer().getInventory().selected); - int hotbarSlot = ctx.getPlayer().getInventory().selected; - ItemStack stackInBelt = inv.getItem(beltSlot); + if (belt == null) { + UtilityBelt.LOGGER.warn("Received swap request packet from client without a belt equipped"); + return; + } - if (!stackInHand.isEmpty() && !stateManager.isInBelt(ctx.getPlayer())) { - for (int i = 0; i < 10; i++) { - if (ctx.getPlayer().getInventory().getItem(i).isEmpty()) { - hotbarSlot = i; - stackInHand = ctx.getPlayer().getInventory().getItem(i); - break; - } - } - } else if (!stackInBelt.isEmpty() && stateManager.isInBelt(ctx.getPlayer())) { - for (int i = 0; i < inv.getContainerSize(); i++) { - if (inv.getItem(i).isEmpty()) { - beltSlot = i; - stackInBelt = inv.getItem(i); - break; - } - } - } + UtilityBeltInventory inv = stateManager.getInventory(ctx.getPlayer()); + ItemStack stackInHand = ctx.getPlayer().getInventory().getItem(ctx.getPlayer().getInventory().selected); + int hotbarSlot = ctx.getPlayer().getInventory().selected; + ItemStack stackInBelt = inv.getItem(beltSlot); - if (UtilityBeltItem.isValidItem(stackInHand)) { - ctx.getPlayer().getInventory().setItem(hotbarSlot, stackInBelt); - inv.setItem(beltSlot, stackInHand); - ((Duck.LivingEntity) ctx.getPlayer()).utilitybelt$detectEquipmentUpdates(); + if (!stackInHand.isEmpty() && !stateManager.isInBelt(ctx.getPlayer())) { + for (int i = 0; i < 10; i++) { + if (ctx.getPlayer().getInventory().getItem(i).isEmpty()) { + hotbarSlot = i; + stackInHand = ctx.getPlayer().getInventory().getItem(i); + break; + } + } + } else if (!stackInBelt.isEmpty() && stateManager.isInBelt(ctx.getPlayer())) { + for (int i = 0; i < inv.getContainerSize(); i++) { + if (inv.getItem(i).isEmpty()) { + beltSlot = i; + stackInBelt = inv.getItem(i); + break; + } + } + } - if (beltSlot != slot) { - stateManager.setSelectedBeltSlot(ctx.getPlayer(), beltSlot); - FriendlyByteBuf buf2 = new FriendlyByteBuf(Unpooled.buffer()); - buf2.writeInt(beltSlot); - NetworkManager.sendToPlayer((ServerPlayer) ctx.getPlayer(), UtilityBelt.S2C_SET_BELT_SLOT, buf2); - } else if (hotbarSlot != ctx.getPlayer().getInventory().selected) { - ctx.getPlayer().getInventory().selected = hotbarSlot; - FriendlyByteBuf buf2 = new FriendlyByteBuf(Unpooled.buffer()); - buf2.writeInt(hotbarSlot); - NetworkManager.sendToPlayer((ServerPlayer) ctx.getPlayer(), UtilityBelt.S2C_SET_HOTBAR_SLOT, buf2); - } - } - } - }); - } + if (UtilityBeltItem.isValidItem(stackInHand)) { + ctx.getPlayer().getInventory().setItem(hotbarSlot, stackInBelt); + inv.setItem(beltSlot, stackInHand); + ((Duck.LivingEntity) ctx.getPlayer()).utilitybelt$detectEquipmentUpdates(); - private static void handleOpenScreen(FriendlyByteBuf buf, NetworkManager.PacketContext ctx) { - ctx.queue(() -> MenuRegistry.openMenu((ServerPlayer) ctx.getPlayer(), UtilityBeltMenu.Factory.INSTANCE)); - } + if (beltSlot != slot) { + stateManager.setSelectedBeltSlot(ctx.getPlayer(), beltSlot); + NetworkManager.sendToPlayer((ServerPlayer) ctx.getPlayer(), new S2CSetBeltSlot(beltSlot)); + } else if (hotbarSlot != ctx.getPlayer().getInventory().selected) { + ctx.getPlayer().getInventory().selected = hotbarSlot; + NetworkManager.sendToPlayer((ServerPlayer) ctx.getPlayer(), new S2CSetBeltSlot(hotbarSlot)); + } + } + } + }); + } + + private static void handleOpenScreen(C2SOpenScreen payload, NetworkManager.PacketContext ctx) { + ctx.queue(() -> MenuRegistry.openMenu((ServerPlayer) ctx.getPlayer(), UtilityBeltMenu.Factory.INSTANCE)); + } } diff --git a/common/src/main/resources/data/utility_belt/recipes/utility_belt.json b/common/src/main/resources/data/utility_belt/recipes/utility_belt.json index d3b801d..13bf926 100644 --- a/common/src/main/resources/data/utility_belt/recipes/utility_belt.json +++ b/common/src/main/resources/data/utility_belt/recipes/utility_belt.json @@ -17,7 +17,7 @@ } }, "result": { - "item": "utility_belt:utility_belt", + "id": "utility_belt:utility_belt", "count": 1 } } diff --git a/fabric/build.gradle b/fabric/build.gradle index 78f0669..d0b7457 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -1,5 +1,5 @@ plugins { - id "com.github.johnrengelman.shadow" version "7.1.2" + id "com.github.johnrengelman.shadow" version "8.1.1" id "me.shedaniel.unified-publishing" } @@ -22,8 +22,8 @@ configurations { dependencies { modImplementation libs.fabric.loader - modApi libs.fabric.api - modApi libs.architectury.fabric + modImplementation libs.fabric.api + modImplementation libs.architectury.fabric modRuntimeOnly libs.modmenu modImplementation libs.jamlib.fabric modImplementation libs.trinkets diff --git a/gradle.properties b/gradle.properties index dc2ae6d..259620f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,8 +2,8 @@ org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false org.gradle.parallel=true -version=2.1.0+1.20.4 -minecraft_version=1.20.4 +version=2.1.0+1.20.6 +minecraft_version=1.20.6 branch=main group=io.github.jamalam360 mod_name=Utility Belt diff --git a/libs.versions.toml b/libs.versions.toml index d2251cb..7c8608b 100644 --- a/libs.versions.toml +++ b/libs.versions.toml @@ -1,28 +1,28 @@ [versions] # https://modrinth.com/mod/architectury-api/versions -architectury = "11.1.17" +architectury = "12.0.1" # https://projects.neoforged.net/neoforged/neoforge -neoforge = "20.4.198" +neoforge = "20.6.72-beta" # https://fabricmc.net/develop -fabric-loader = "0.15.7" -fabric-api = "0.96.4+1.20.4" +fabric-loader = "0.15.11" +fabric-api = "0.99.0+1.20.6" # https://maven.jamalam.tech/#/releases -jamlib = "1.0.9+1.20.4" +jamlib = "1.0.9+1.20.6" # https://modrinth.com/mod/trinkets/versions trinkets = "3.8.1" # https://modrinth.com/mod/curios/versions -curios = "7.4.1+1.20.4" +curios = "8.0.0-beta.2+1.20.6" # https://github.com/LlamaLad7/MixinExtras/releases -mixin-extras = "0.3.5" +mixin-extras = "0.3.6" # https://modrinth.com/mod/modmenu/versions -modmenu = "9.0.0" +modmenu = "10.0.0-beta.1" [libraries] architectury-common = { module = "dev.architectury:architectury", version.ref = "architectury" } diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 0d0b77c..1ebdd5e 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -1,5 +1,5 @@ plugins { - id "com.github.johnrengelman.shadow" version "7.1.2" + id "com.github.johnrengelman.shadow" version "8.1.1" id "me.shedaniel.unified-publishing" } @@ -29,8 +29,10 @@ repositories { dependencies { neoForge libs.neoforge - modApi libs.architectury.neoforge - modImplementation libs.jamlib.neoforge + modImplementation libs.architectury.neoforge + modImplementation(libs.jamlib.neoforge) { + exclude group: "dev.architectury" // Exclude the Architectury dependency, it's currently modApi for some reason + } modImplementation libs.curios.neoforge // Dependency of JamLib diff --git a/neoforge/src/main/resources/META-INF/mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml similarity index 100% rename from neoforge/src/main/resources/META-INF/mods.toml rename to neoforge/src/main/resources/META-INF/neoforge.mods.toml From d9a0be8585e777289836be9e13a657d46d302c7f Mon Sep 17 00:00:00 2001 From: "James (Jamalam)" Date: Tue, 21 May 2024 17:02:52 +0100 Subject: [PATCH 2/6] feat: datafixer for componentization 1.20.6 release is waiting on Trinkets release --- CHANGELOG.md | 11 +++++---- common/build.gradle | 4 ++++ .../ItemStackComponentizationFixMixin.java | 24 +++++++++++++++++++ .../main/resources/architectury.common.json | 3 +++ .../main/resources/utility_belt.accesswidener | 3 +++ .../main/resources/utility_belt.mixins.json | 3 ++- fabric/build.gradle | 4 ++++ fabric/src/main/resources/fabric.mod.json | 1 + neoforge/build.gradle | 5 ++++ 9 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 common/src/main/java/io/github/jamalam360/utility_belt/mixin/datafixer/ItemStackComponentizationFixMixin.java create mode 100644 common/src/main/resources/architectury.common.json create mode 100644 common/src/main/resources/utility_belt.accesswidener diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ca4e3f..63a9cf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,7 @@ -- Remove the Baubly dependency - - This also fixes #42 -- Drop Forge and Quilt support (see Discord for reasoning). This was done pre-1.20.6 to reduce the - work needed to remove Baubly. +- Port to 1.20.6 + - It should be safe to update worlds from 1.20.4 to 1.20.6 **ON FABRIC** as a datafixer has been + implemented + to migrate from NBT to components, but as always make a backup in case. + - If [Curios#411](https://github.com/TheIllusiveC4/Curios/issues/411) is implemented, it will be + safe to do so on Neoforge. For now, upgrading Neoforge worlds **WILL CAUSE LOSS OF ITEMS IN + THE BELT**. diff --git a/common/build.gradle b/common/build.gradle index 2538b62..1854929 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -2,6 +2,10 @@ architectury { common(rootProject.enabled_platforms.split(",")) } +loom { + accessWidenerPath = file("src/main/resources/utility_belt.accesswidener") +} + dependencies { modImplementation libs.fabric.loader modApi libs.architectury.common diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/datafixer/ItemStackComponentizationFixMixin.java b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/datafixer/ItemStackComponentizationFixMixin.java new file mode 100644 index 0000000..a1b5494 --- /dev/null +++ b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/datafixer/ItemStackComponentizationFixMixin.java @@ -0,0 +1,24 @@ +package io.github.jamalam360.utility_belt.mixin.datafixer; + +import com.mojang.serialization.Dynamic; +import io.github.jamalam360.utility_belt.UtilityBelt; +import java.util.stream.Stream; +import net.minecraft.util.datafix.fixes.ItemStackComponentizationFix; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ItemStackComponentizationFix.class) +public class ItemStackComponentizationFixMixin { + @Inject( + method = "fixItemStack", + at = @At("TAIL") + ) + private static void utilitybelt$moveNbtToComponent(ItemStackComponentizationFix.ItemStackData itemStackData, Dynamic dynamic, CallbackInfo ci) { + if (itemStackData.is(UtilityBelt.id("utility_belt").toString())) { + System.out.println("fixed belt"); + itemStackData.moveTagToComponent("Inventory", "utility_belt:utility_belt_inventory", dynamic.createList(Stream.empty())); + } + } +} diff --git a/common/src/main/resources/architectury.common.json b/common/src/main/resources/architectury.common.json new file mode 100644 index 0000000..b75ff8d --- /dev/null +++ b/common/src/main/resources/architectury.common.json @@ -0,0 +1,3 @@ +{ + "accessWidener": "utility_belt.accesswidener" +} diff --git a/common/src/main/resources/utility_belt.accesswidener b/common/src/main/resources/utility_belt.accesswidener new file mode 100644 index 0000000..cc17a66 --- /dev/null +++ b/common/src/main/resources/utility_belt.accesswidener @@ -0,0 +1,3 @@ +accessWidener v2 named + +accessible class net/minecraft/util/datafix/fixes/ItemStackComponentizationFix$ItemStackData diff --git a/common/src/main/resources/utility_belt.mixins.json b/common/src/main/resources/utility_belt.mixins.json index 8cad663..6d69e70 100644 --- a/common/src/main/resources/utility_belt.mixins.json +++ b/common/src/main/resources/utility_belt.mixins.json @@ -8,7 +8,8 @@ "LivingEntityMixin", "PlayerMixin", "ServerGamePacketListenerImplMixin", - "ServerPlayerMixin" + "ServerPlayerMixin", + "datafixer.ItemStackComponentizationFixMixin" ], "client": [ "client.ClientPacketListenerMixin", diff --git a/fabric/build.gradle b/fabric/build.gradle index d0b7457..bea40bf 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -8,6 +8,10 @@ architectury { fabric() } +loom { + accessWidenerPath = project(":common").loom.accessWidenerPath +} + base { archivesName = "utility-belt-fabric" } diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index d6e5cf8..2ed0229 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -26,6 +26,7 @@ "mixins": [ "utility_belt.mixins.json" ], + "accessWidener": "utility_belt.accesswidener", "depends": { "fabricloader": ">=0.15.0", "fabric": ">=${fabric_api_version}", diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 1ebdd5e..72f7c47 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -8,6 +8,10 @@ architectury { neoForge() } +loom { + accessWidenerPath = project(":common").loom.accessWidenerPath +} + base { archivesName = "utility-belt-neoforge" } @@ -108,6 +112,7 @@ shadowJar { remapJar { input.set shadowJar.archiveFile dependsOn shadowJar + atAccessWideners.add "utility_belt.accesswidener" } sourcesJar { From 7944b583405b3b3604af546a5dc3c8288ffc68ea Mon Sep 17 00:00:00 2001 From: "James (Jamalam)" Date: Tue, 21 May 2024 19:41:35 +0100 Subject: [PATCH 3/6] fix: 2.1.1, fixing the dupe exploit closes #44 --- CHANGELOG.md | 8 +------- .../mixin/ServerGamePacketListenerImplMixin.java | 2 +- gradle.properties | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63a9cf9..6f61730 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1 @@ -- Port to 1.20.6 - - It should be safe to update worlds from 1.20.4 to 1.20.6 **ON FABRIC** as a datafixer has been - implemented - to migrate from NBT to components, but as always make a backup in case. - - If [Curios#411](https://github.com/TheIllusiveC4/Curios/issues/411) is implemented, it will be - safe to do so on Neoforge. For now, upgrading Neoforge worlds **WILL CAUSE LOSS OF ITEMS IN - THE BELT**. +- Fix a dupe exploit (#44) diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/ServerGamePacketListenerImplMixin.java b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/ServerGamePacketListenerImplMixin.java index 36bb7f2..6ea8622 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/ServerGamePacketListenerImplMixin.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/ServerGamePacketListenerImplMixin.java @@ -25,6 +25,6 @@ public class ServerGamePacketListenerImplMixin { ) ) private boolean utilitybelt$disallowOffhandWhenInBelt(boolean original) { - return original && !StateManager.getServerInstance().isInBelt(this.player); + return original || StateManager.getServerInstance().isInBelt(this.player); } } diff --git a/gradle.properties b/gradle.properties index 259620f..a196e12 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false org.gradle.parallel=true -version=2.1.0+1.20.6 +version=2.1.1+1.20.6 minecraft_version=1.20.6 branch=main group=io.github.jamalam360 From a09a4ccad9c8f2b680056b6af9bd5a32aa995f55 Mon Sep 17 00:00:00 2001 From: "James (Jamalam)" Date: Fri, 7 Jun 2024 18:54:59 +0100 Subject: [PATCH 4/6] feat: internal rework --- CHANGELOG.md | 12 +- .../jamalam360/utility_belt/StateManager.java | 9 +- .../jamalam360/utility_belt/UtilityBelt.java | 2 +- .../utility_belt/UtilityBeltInventory.java | 99 +++++--- .../utility_belt/UtilityBeltItem.java | 28 ++- .../utility_belt/UtilityBeltPackets.java | 11 + .../client/BeltHotbarRenderer.java | 102 ++++---- .../utility_belt/client/ClientNetworking.java | 16 +- .../client/ClientStateManager.java | 21 +- .../client/UtilityBeltClient.java | 11 +- .../utility_belt/mixin/InventoryMixin.java | 37 ++- .../utility_belt/mixin/LivingEntityMixin.java | 9 +- .../utility_belt/mixin/PlayerMixin.java | 3 +- .../utility_belt/mixin/ServerPlayerMixin.java | 39 +-- .../mixin/client/MinecraftMixin.java | 6 +- .../utility_belt/screen/UtilityBeltMenu.java | 238 +++++++++--------- .../utility_belt/server/ServerNetworking.java | 12 +- .../server/ServerStateManager.java | 24 +- gradle.properties | 2 +- .../neoforge/UtilityBeltCurio.java | 5 + 20 files changed, 395 insertions(+), 291 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f61730..febef1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1 +1,11 @@ -- Fix a dupe exploit (#44) +This release brings about a significant internal rework with should make Utility Belt significantly +less buggy. I have conducted a long play testing session before this release to try to verify +everything works as intended. + +## Closed Issues + +- #47: fishing rod flickering +- #46: dupe bug +- #45: dupe bug + +Alongside the issues that were reported, many others have been fixed. diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/StateManager.java b/common/src/main/java/io/github/jamalam360/utility_belt/StateManager.java index 8462dfa..a009f47 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/StateManager.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/StateManager.java @@ -28,9 +28,6 @@ public boolean hasBelt(Player player) { return belt != null && belt.is(UtilityBelt.UTILITY_BELT_ITEM.get()); } - public void onStartTick(Player player) { - } - public abstract boolean isInBelt(Player player); public abstract void setInBelt(Player player, boolean inBelt); @@ -40,4 +37,10 @@ public void onStartTick(Player player) { public abstract void setSelectedBeltSlot(Player player, int slot); public abstract UtilityBeltInventory getInventory(Player player); + + public UtilityBeltInventory.Mutable getMutableInventory(Player player) { + return new UtilityBeltInventory.Mutable(this.getInventory(player)); + } + + public abstract void setInventory(Player player, UtilityBeltInventory.Mutable inventory); } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBelt.java b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBelt.java index e49bf83..aff63e4 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBelt.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBelt.java @@ -42,7 +42,7 @@ public class UtilityBelt { public static final RegistrySupplier UTILITY_BELT_ITEM = ITEMS.register("utility_belt", UtilityBeltItem::new); public static final RegistrySupplier> MENU_TYPE = MENUS.register("utility_belt", () -> new MenuType<>(UtilityBeltMenu::new, FeatureFlagSet.of())); public static final RegistrySupplier> UTILITY_BELT_INVENTORY_COMPONENT_TYPE = COMPONENT_TYPES.register("utility_belt_inventory", () -> - DataComponentType.builder().persistent(UtilityBeltInventory.CODEC).networkSynchronized(UtilityBeltInventory.STREAM_CODEC).build() + DataComponentType.builder().persistent(UtilityBeltInventory.CODEC).cacheEncoding().build() ); public static void init() { diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltInventory.java b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltInventory.java index 76d0af6..7bc53cb 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltInventory.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltInventory.java @@ -1,73 +1,110 @@ package io.github.jamalam360.utility_belt; import com.mojang.serialization.Codec; +import java.util.ArrayList; import java.util.List; +import net.minecraft.core.NonNullList; +import net.minecraft.core.component.DataComponents; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.SimpleContainer; import net.minecraft.world.item.ItemStack; -public class UtilityBeltInventory extends SimpleContainer { +public record UtilityBeltInventory(List items) { + public static final UtilityBeltInventory EMPTY = new UtilityBeltInventory(NonNullList.withSize(4, ItemStack.EMPTY)); public static final Codec CODEC = Codec - .list(ItemStack.CODEC) - .xmap(UtilityBeltInventory::new, UtilityBeltInventory::getItems); + .list(ItemStack.OPTIONAL_CODEC) + .xmap(UtilityBeltInventory::new, UtilityBeltInventory::items); public static final StreamCodec STREAM_CODEC = StreamCodec .composite( - ItemStack.STREAM_CODEC.apply(ByteBufCodecs.list(4)), - UtilityBeltInventory::getItems, + ItemStack.OPTIONAL_STREAM_CODEC.apply(ByteBufCodecs.list(4)), + UtilityBeltInventory::items, UtilityBeltInventory::new ); + public UtilityBeltInventory { + if (items.size() != 4) { + throw new IllegalArgumentException("Utility belt inventory must have exactly 4 items"); + } + } - public UtilityBeltInventory() { - super(4); + public ItemStack getItem(int index) { + return items.get(index); } - private UtilityBeltInventory(List stacks) { - super(4); + public int getContainerSize() { + return 4; + } - for (int i = 0; i < stacks.size(); i++) { - this.setItem(i, stacks.get(i)); - } + public UtilityBeltInventory clone() { + return new UtilityBeltInventory(new ArrayList<>(items)); } @Override public boolean equals(Object obj) { if (obj instanceof UtilityBeltInventory other) { - if (other.getContainerSize() == this.getContainerSize()) { - for (int i = 0; i < this.getContainerSize(); i++) { - if (!ItemStack.matches(this.getItem(i), other.getItem(i))) { - return false; - } - } - - return true; - } + return ItemStack.listMatches(items, other.items); } return false; } + @SuppressWarnings("deprecation") @Override public int hashCode() { - int hash = 0; - for (int i = 0; i < this.getContainerSize(); i++) { - hash += this.getItem(i).hashCode(); + return ItemStack.hashStackList(items); + } + + @Override + public String toString() { + return invToString("UtilityBeltInventory[", items); + } + + public static class Mutable extends SimpleContainer { + + public Mutable(UtilityBeltInventory inv) { + super(4); + + for (int i = 0; i < inv.getContainerSize(); i++) { + this.setItem(i, inv.getItem(i)); + } + } + + public UtilityBeltInventory toImmutable() { + return new UtilityBeltInventory(new ArrayList<>(this.getItems())); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof UtilityBeltInventory other) { + return ItemStack.listMatches(this.getItems(), other.items); + } + + return false; } - return hash; + @Override + public String toString() { + return invToString("UtilityBeltInventory$Mutable[", this.getItems()); + } } - @Override - public UtilityBeltInventory clone() { - UtilityBeltInventory inv = new UtilityBeltInventory(); - for (int i = 0; i < this.getContainerSize(); i++) { - inv.setItem(i, this.getItem(i).copy()); + private static String invToString(String prefix, List items) { + StringBuilder string = new StringBuilder(prefix); + + for (int i = 0; i < items.size(); i++) { + string.append(items.get(i)); + string.append(" {"); + string.append(items.get(i).getComponents().get(DataComponents.DAMAGE)); + string.append("}"); + if (i < items.size() - 1) { + string.append(", "); + } } - return inv; + return string.toString(); } } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltItem.java b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltItem.java index 1e33f29..90cbd86 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltItem.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltItem.java @@ -1,5 +1,6 @@ package io.github.jamalam360.utility_belt; +import io.github.jamalam360.utility_belt.UtilityBeltInventory.Mutable; import io.github.jamalam360.utility_belt.client.ClientNetworking; import java.util.List; import java.util.function.Consumer; @@ -7,6 +8,7 @@ import net.minecraft.sounds.SoundEvents; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.SlotAccess; import net.minecraft.world.entity.player.Player; @@ -30,11 +32,11 @@ public class UtilityBeltItem extends Item { private static final int BAR_COLOR = Mth.color(0.4F, 0.4F, 1.0F); public UtilityBeltItem() { - super(new Item.Properties().stacksTo(1).component(UtilityBelt.UTILITY_BELT_INVENTORY_COMPONENT_TYPE.get(), new UtilityBeltInventory())); + super(new Item.Properties().stacksTo(1).component(UtilityBelt.UTILITY_BELT_INVENTORY_COMPONENT_TYPE.get(), UtilityBeltInventory.EMPTY)); } @SuppressWarnings("BooleanMethodIsAlwaysInverted") - private static boolean handleStack(ItemStack stack, UtilityBeltInventory inv, Consumer slotAccess) { + private static boolean handleStack(ItemStack stack, UtilityBeltInventory.Mutable inv, Consumer slotAccess) { if (stack.isEmpty()) { for (int i = 0; i < inv.getContainerSize(); i++) { if (!inv.getItem(i).isEmpty()) { @@ -67,12 +69,13 @@ public static boolean isValidItem(ItemStack stack) { // Going to keep this name as is until 1.20.4 support is dropped, to keep the diffs smaller public static UtilityBeltInventory getInventoryFromTag(ItemStack stack) { if (!stack.has(UtilityBelt.UTILITY_BELT_INVENTORY_COMPONENT_TYPE.get())) { - stack.set(UtilityBelt.UTILITY_BELT_INVENTORY_COMPONENT_TYPE.get(), new UtilityBeltInventory()); + stack.set(UtilityBelt.UTILITY_BELT_INVENTORY_COMPONENT_TYPE.get(), UtilityBeltInventory.EMPTY); } return stack.get(UtilityBelt.UTILITY_BELT_INVENTORY_COMPONENT_TYPE.get()); } + // This should only be called by the state managers, or when the belt is NOT equipped public static void setInventory(ItemStack stack, UtilityBeltInventory inv) { stack.set(UtilityBelt.UTILITY_BELT_INVENTORY_COMPONENT_TYPE.get(), inv); } @@ -90,12 +93,12 @@ public static ItemStack getBelt(Player player) { @Override public boolean isBarVisible(ItemStack itemStack) { - return getInventoryFromTag(itemStack).hasAnyMatching(s -> !s.isEmpty()); + return getInventoryFromTag(itemStack).items().stream().anyMatch(s -> !s.isEmpty()); } @Override public int getBarWidth(ItemStack itemStack) { - long size = getInventoryFromTag(itemStack).getItems().stream().filter((s) -> !s.isEmpty()).count(); + long size = getInventoryFromTag(itemStack).items().stream().filter((s) -> !s.isEmpty()).count(); return size == 4L ? 13 : (int) (size * 3); } @@ -123,14 +126,13 @@ public boolean overrideStackedOnOther(ItemStack belt, Slot slot, ClickAction cli } ItemStack slotStack = slot.getItem(); - UtilityBeltInventory inv = getInventoryFromTag(belt); + UtilityBeltInventory.Mutable inv = new Mutable(getInventoryFromTag(belt)); if (!handleStack(slotStack, inv, slot::set)) { return false; } - playInsertSound(player); - setInventory(belt, inv); + setInventory(belt, inv.toImmutable()); return true; } @@ -140,17 +142,23 @@ public boolean overrideOtherStackedOnMe(ItemStack belt, ItemStack otherStack, Sl return false; } - UtilityBeltInventory inv = getInventoryFromTag(belt); + UtilityBeltInventory.Mutable inv = new Mutable(getInventoryFromTag(belt)); if (!handleStack(otherStack, inv, slotAccess::set)) { return false; } playInsertSound(player); - setInventory(belt, inv); + setInventory(belt, inv.toImmutable()); return true; } + public void onEquip(LivingEntity wearer, ItemStack belt) { + if (wearer instanceof Player player && !player.level().isClientSide) { + StateManager.getServerInstance().setInventory(player, new Mutable(getInventoryFromTag(belt))); + } + } + public void onUnequip(LivingEntity wearer) { if (wearer instanceof Player player && player.level().isClientSide) { StateManager.getClientInstance().setInBelt(player, false); diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltPackets.java b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltPackets.java index 21015d3..dd2190c 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltPackets.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltPackets.java @@ -10,6 +10,7 @@ public class UtilityBeltPackets { public static final CustomPacketPayload.Type C2S_OPEN_SCREEN = new CustomPacketPayload.Type<>(UtilityBelt.id("open_screen")); public static final CustomPacketPayload.Type S2C_SET_BELT_SLOT = new CustomPacketPayload.Type<>(UtilityBelt.id("set_belt_slot")); public static final CustomPacketPayload.Type S2C_SET_HOTBAR_SLOT = new CustomPacketPayload.Type<>(UtilityBelt.id("set_hotbar_slot")); + public static final CustomPacketPayload.Type S2C_UPDATE_BELT_INVENTORY = new CustomPacketPayload.Type<>(UtilityBelt.id("update_belt_inventory")); public record C2SUpdateState(boolean inBelt, int slot, boolean swapItems) implements CustomPacketPayload { @@ -67,4 +68,14 @@ public Type type() { return S2C_SET_HOTBAR_SLOT; } } + + public record S2CUpdateBeltInventory(UtilityBeltInventory inventory) implements CustomPacketPayload { + + public static final StreamCodec STREAM_CODEC = UtilityBeltInventory.STREAM_CODEC.map(S2CUpdateBeltInventory::new, S2CUpdateBeltInventory::inventory); + + @Override + public Type type() { + return new CustomPacketPayload.Type<>(UtilityBelt.id("update_belt_inventory")); + } + } } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/client/BeltHotbarRenderer.java b/common/src/main/java/io/github/jamalam360/utility_belt/client/BeltHotbarRenderer.java index 1987332..03d2120 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/client/BeltHotbarRenderer.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/client/BeltHotbarRenderer.java @@ -1,7 +1,6 @@ package io.github.jamalam360.utility_belt.client; import com.mojang.blaze3d.systems.RenderSystem; -import io.github.jamalam360.utility_belt.Config; import io.github.jamalam360.utility_belt.StateManager; import io.github.jamalam360.utility_belt.UtilityBelt; import io.github.jamalam360.utility_belt.UtilityBeltInventory; @@ -16,64 +15,65 @@ @Environment(EnvType.CLIENT) public class BeltHotbarRenderer { - private static final ResourceLocation UTILITY_BELT_WIDGET_TEXTURE = UtilityBelt - .id("textures/gui/utility_belt_widget.png"); - private static final ResourceLocation HOTBAR_SELECTION_SPRITE = new ResourceLocation("hud/hotbar_selection"); - public static void render(GuiGraphics graphics, float tickDelta) { - Player player = Minecraft.getInstance().player; - StateManager stateManager = StateManager.getClientInstance(); + private static final ResourceLocation UTILITY_BELT_WIDGET_TEXTURE = UtilityBelt + .id("textures/gui/utility_belt_widget.png"); + private static final ResourceLocation HOTBAR_SELECTION_SPRITE = new ResourceLocation("hud/hotbar_selection"); - if (player != null && stateManager.hasBelt(player) && (stateManager.isInBelt(player) - || UtilityBelt.CONFIG.get().displayUtilityBeltWhenNotSelected)) { - int scaledHeight = Minecraft.getInstance().getWindow().getGuiScaledHeight(); - int x = switch (UtilityBelt.CONFIG.get().hotbarPosition) { - case TOP_LEFT, MIDDLE_LEFT, BOTTOM_LEFT -> 2; - case TOP_RIGHT, MIDDLE_RIGHT, BOTTOM_RIGHT -> Minecraft.getInstance().getWindow().getGuiScaledWidth() - 24; - }; - int y = switch (UtilityBelt.CONFIG.get().hotbarPosition) { - case TOP_LEFT, TOP_RIGHT -> 2; - case MIDDLE_LEFT, MIDDLE_RIGHT -> scaledHeight / 2 - 44; - case BOTTOM_LEFT, BOTTOM_RIGHT -> scaledHeight - 84; - }; + public static void render(GuiGraphics graphics, float tickDelta) { + Player player = Minecraft.getInstance().player; + StateManager stateManager = StateManager.getClientInstance(); - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.setShader(GameRenderer::getPositionTexShader); + if (player != null && stateManager.hasBelt(player) && (stateManager.isInBelt(player) + || UtilityBelt.CONFIG.get().displayUtilityBeltWhenNotSelected)) { + int scaledHeight = Minecraft.getInstance().getWindow().getGuiScaledHeight(); + int x = switch (UtilityBelt.CONFIG.get().hotbarPosition) { + case TOP_LEFT, MIDDLE_LEFT, BOTTOM_LEFT -> 2; + case TOP_RIGHT, MIDDLE_RIGHT, BOTTOM_RIGHT -> Minecraft.getInstance().getWindow().getGuiScaledWidth() - 24; + }; + int y = switch (UtilityBelt.CONFIG.get().hotbarPosition) { + case TOP_LEFT, TOP_RIGHT -> 2; + case MIDDLE_LEFT, MIDDLE_RIGHT -> scaledHeight / 2 - 44; + case BOTTOM_LEFT, BOTTOM_RIGHT -> scaledHeight - 84; + }; - graphics.blit(UTILITY_BELT_WIDGET_TEXTURE, x, y, 0, 0, 22, 88); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + RenderSystem.setShader(GameRenderer::getPositionTexShader); - if (stateManager.isInBelt(player)) { - graphics.blitSprite(HOTBAR_SELECTION_SPRITE, x - 1, y - 1 + stateManager.getSelectedBeltSlot(player) * 20, 0, 24, 23); - } + graphics.blit(UTILITY_BELT_WIDGET_TEXTURE, x, y, 0, 0, 22, 88); - UtilityBeltInventory inv = stateManager.getInventory(player); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - int m = 1; + if (stateManager.isInBelt(player)) { + graphics.blitSprite(HOTBAR_SELECTION_SPRITE, x - 1, y - 1 + stateManager.getSelectedBeltSlot(player) * 20, 0, 24, 23); + } - for (int n = 0; n < inv.getContainerSize(); ++n) { - renderHotbarItem(graphics, x, y + n * 20 + 3, tickDelta, player, inv.getItem(n), m++); - } - } - } + UtilityBeltInventory inv = stateManager.getInventory(player); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + int m = 1; - private static void renderHotbarItem(GuiGraphics graphics, int x, int y, float tickDelta, Player player, ItemStack stack, int seed) { - if (!stack.isEmpty()) { - float f = (float) stack.getPopTime() - tickDelta; - if (f > 0.0F) { - float g = 1.0F + f / 5.0F; - graphics.pose().pushPose(); - graphics.pose().translate(12, y + 12, 0); - graphics.pose().scale(1.0F / g, (g + 1.0F) / 2.0F, 1); - graphics.pose().translate(-12, -(y + 12), 0); - } + for (int n = 0; n < inv.getContainerSize(); ++n) { + renderHotbarItem(graphics, x, y + n * 20 + 3, tickDelta, player, inv.getItem(n), m++); + } + } + } - graphics.renderItem(player, stack, x + 3, y, seed); - if (f > 0.0F) { - graphics.pose().popPose(); - } + private static void renderHotbarItem(GuiGraphics graphics, int x, int y, float tickDelta, Player player, ItemStack stack, int seed) { + if (!stack.isEmpty()) { + float f = (float) stack.getPopTime() - tickDelta; + if (f > 0.0F) { + float g = 1.0F + f / 5.0F; + graphics.pose().pushPose(); + graphics.pose().translate(12, y + 12, 0); + graphics.pose().scale(1.0F / g, (g + 1.0F) / 2.0F, 1); + graphics.pose().translate(-12, -(y + 12), 0); + } - graphics.renderItemDecorations(Minecraft.getInstance().font, stack, x + 3, y); - } - } + graphics.renderItem(player, stack, x + 3, y, seed); + if (f > 0.0F) { + graphics.pose().popPose(); + } + + graphics.renderItemDecorations(Minecraft.getInstance().font, stack, x + 3, y); + } + } } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/client/ClientNetworking.java b/common/src/main/java/io/github/jamalam360/utility_belt/client/ClientNetworking.java index ccc62b7..5619bed 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/client/ClientNetworking.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/client/ClientNetworking.java @@ -3,23 +3,23 @@ import dev.architectury.networking.NetworkManager; import io.github.jamalam360.utility_belt.StateManager; import io.github.jamalam360.utility_belt.UtilityBelt; +import io.github.jamalam360.utility_belt.UtilityBeltInventory.Mutable; import io.github.jamalam360.utility_belt.UtilityBeltPackets; import io.github.jamalam360.utility_belt.UtilityBeltPackets.C2SOpenScreen; import io.github.jamalam360.utility_belt.UtilityBeltPackets.C2SUpdateState; import io.github.jamalam360.utility_belt.UtilityBeltPackets.S2CSetBeltSlot; import io.github.jamalam360.utility_belt.UtilityBeltPackets.S2CSetHotbarSlot; -import io.netty.buffer.Unpooled; +import io.github.jamalam360.utility_belt.UtilityBeltPackets.S2CUpdateBeltInventory; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.network.FriendlyByteBuf; @Environment(EnvType.CLIENT) public class ClientNetworking { public static void init() { -// NetworkManager.registerReceiver(NetworkManager.Side.S2C, UtilityBelt.S2C_UPDATE_INV, ClientNetworking::handleUpdateInventory); NetworkManager.registerReceiver(NetworkManager.Side.S2C, UtilityBeltPackets.S2C_SET_BELT_SLOT, S2CSetBeltSlot.STREAM_CODEC, ClientNetworking::handleSetBeltSlot); NetworkManager.registerReceiver(NetworkManager.Side.S2C, UtilityBeltPackets.S2C_SET_HOTBAR_SLOT, S2CSetHotbarSlot.STREAM_CODEC, ClientNetworking::handleSetHotbarSlot); + NetworkManager.registerReceiver(NetworkManager.Side.S2C, UtilityBeltPackets.S2C_UPDATE_BELT_INVENTORY, S2CUpdateBeltInventory.STREAM_CODEC, ClientNetworking::handleUpdateBeltInventory); } public static void sendNewStateToServer(boolean inBelt, int slot, boolean swapItems) { @@ -35,12 +35,6 @@ public static void sendOpenScreenToServer() { NetworkManager.sendToServer(new C2SOpenScreen()); } - private static void handleUpdateInventory(FriendlyByteBuf buf, NetworkManager.PacketContext ctx) { -// CompoundTag tag = buf.readNbt(); -// ItemStack belt = UtilityBeltItem.getBelt(ctx.getPlayer()); -// belt.getTag().put("Inventory", tag.getList("Inventory", CompoundTag.TAG_COMPOUND)); - } - private static void handleSetBeltSlot(S2CSetBeltSlot payload, NetworkManager.PacketContext ctx) { StateManager.getClientInstance().setSelectedBeltSlot(ctx.getPlayer(), payload.slot()); } @@ -48,4 +42,8 @@ private static void handleSetBeltSlot(S2CSetBeltSlot payload, NetworkManager.Pac private static void handleSetHotbarSlot(S2CSetHotbarSlot payload, NetworkManager.PacketContext ctx) { ctx.getPlayer().getInventory().selected = payload.slot(); } + + private static void handleUpdateBeltInventory(S2CUpdateBeltInventory payload, NetworkManager.PacketContext ctx) { + StateManager.getClientInstance().setInventory(ctx.getPlayer(), new Mutable(payload.inventory())); + } } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/client/ClientStateManager.java b/common/src/main/java/io/github/jamalam360/utility_belt/client/ClientStateManager.java index 522bd81..0c5ae5e 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/client/ClientStateManager.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/client/ClientStateManager.java @@ -16,32 +16,41 @@ public class ClientStateManager extends StateManager { @Override public boolean isInBelt(Player player) { - assert player == Minecraft.getInstance().player; return this.isInUtilityBelt; } @Override public void setInBelt(Player player, boolean inBelt) { - assert player == Minecraft.getInstance().player; this.isInUtilityBelt = inBelt; } @Override public int getSelectedBeltSlot(Player player) { - assert player == Minecraft.getInstance().player; return this.selectedSlot; } @Override public void setSelectedBeltSlot(Player player, int slot) { - assert player == Minecraft.getInstance().player; this.selectedSlot = slot; } @Override public UtilityBeltInventory getInventory(Player player) { ItemStack belt = UtilityBeltItem.getBelt(player); - assert belt != null; - return UtilityBeltItem.getInventoryFromTag(belt); + + if (belt == null) { + return UtilityBeltInventory.EMPTY; + } else { + return UtilityBeltItem.getInventoryFromTag(belt); + } + } + + @Override + public void setInventory(Player player, UtilityBeltInventory.Mutable inventory) { + ItemStack belt = UtilityBeltItem.getBelt(player); + + if (belt != null) { + UtilityBeltItem.setInventory(belt, inventory.toImmutable()); + } } } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/client/UtilityBeltClient.java b/common/src/main/java/io/github/jamalam360/utility_belt/client/UtilityBeltClient.java index a9b326f..9b7e0d4 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/client/UtilityBeltClient.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/client/UtilityBeltClient.java @@ -112,7 +112,11 @@ private static EventResult onMouseScrolled(Minecraft client, double scrollX, dou if (scrollY != 0 && stateManager.isInBelt(client.player)) { int slot = stateManager.getSelectedBeltSlot(client.player); ItemStack belt = UtilityBeltItem.getBelt(client.player); - assert belt != null; + + if (belt == null) { + return EventResult.pass(); + } + int beltSize = stateManager.getInventory(client.player).getContainerSize(); if (UtilityBelt.CONFIG.get().invertScrolling) { @@ -168,9 +172,7 @@ public static void onClientDisconnect() { } private static void toggleInBelt(Minecraft client) { - assert client.player != null; - - if (UtilityBeltItem.getBelt(client.player) == null) { + if (client.player == null || UtilityBeltItem.getBelt(client.player) == null) { return; } @@ -181,7 +183,6 @@ private static void toggleInBelt(Minecraft client) { } private static void playSwapSound(Minecraft client) { - assert client.level != null; client.getSoundManager().play(SimpleSoundInstance.forUI( SoundEvents.ARMOR_EQUIP_LEATHER, client.level.random.nextFloat() + 0.50f)); } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/InventoryMixin.java b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/InventoryMixin.java index a27ae78..322774d 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/InventoryMixin.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/InventoryMixin.java @@ -34,7 +34,11 @@ public abstract class InventoryMixin { StateManager stateManager = StateManager.getServerInstance(); if (stateManager.isInBelt(this.player)) { ItemStack belt = UtilityBeltItem.getBelt(this.player); - assert belt != null; + + if (belt == null) { + return; + } + UtilityBeltInventory inv = stateManager.getInventory(this.player); cir.setReturnValue(inv.getItem(stateManager.getSelectedBeltSlot(this.player))); } @@ -52,7 +56,11 @@ public abstract class InventoryMixin { StateManager stateManager = StateManager.getServerInstance(); if (stateManager.isInBelt(this.player)) { ItemStack belt = UtilityBeltItem.getBelt(this.player); - assert belt != null; + + if (belt == null) { + return; + } + UtilityBeltInventory inv = stateManager.getInventory(this.player); cir.setReturnValue(inv.getItem(stateManager.getSelectedBeltSlot(this.player)).getDestroySpeed(blockState)); } @@ -63,10 +71,14 @@ public abstract class InventoryMixin { at = @At("RETURN") ) private void utilitybelt$tick(CallbackInfo ci) { - ItemStack belt = UtilityBeltItem.getBelt(this.player); StateManager stateManager = StateManager.getServerInstance(); if (stateManager.isInBelt(this.player)) { - assert belt != null; + ItemStack belt = UtilityBeltItem.getBelt(this.player); + + if (belt == null) { + return; + } + UtilityBeltInventory inv = stateManager.getInventory(this.player); int selectedSlot = stateManager.getSelectedBeltSlot(this.player); @@ -83,7 +95,7 @@ public abstract class InventoryMixin { private void utilitybelt$patchRemoveOneForHeldItems(ItemStack stack, CallbackInfo ci) { ItemStack belt = UtilityBeltItem.getBelt(this.player); if (belt != null) { - UtilityBeltInventory inv = StateManager.getServerInstance().getInventory(this.player); + UtilityBeltInventory.Mutable inv = StateManager.getServerInstance().getMutableInventory(this.player); int found = -1; for (int i = 0; i < inv.getContainerSize(); i++) { @@ -95,6 +107,7 @@ public abstract class InventoryMixin { if (found != -1) { inv.setItem(found, ItemStack.EMPTY); + StateManager.getServerInstance().setInventory(this.player, inv); ci.cancel(); } } @@ -117,16 +130,19 @@ public abstract class InventoryMixin { StateManager stateManager = StateManager.getServerInstance(); if (stateManager.isInBelt(this.player)) { int slot = stateManager.getSelectedBeltSlot(this.player); - UtilityBeltInventory inv = stateManager.getInventory(this.player); + UtilityBeltInventory.Mutable inv = stateManager.getMutableInventory(this.player); ItemStack selected = inv.getItem(slot); if (this.player.isLocalPlayer()) { + //TODO: is this needed? // Because of how the inventory is synced, we fake the return value on the clientside (not actually removing it) ItemStack fakeReturn = selected.copy(); fakeReturn.setCount(entireStack ? selected.getCount() : 1); cir.setReturnValue(selected.isEmpty() ? ItemStack.EMPTY : fakeReturn); } else { - cir.setReturnValue(selected.isEmpty() ? ItemStack.EMPTY : inv.removeItem(slot, entireStack ? selected.getCount() : 1)); + ItemStack item = selected.isEmpty() ? ItemStack.EMPTY : inv.removeItem(slot, entireStack ? selected.getCount() : 1); + stateManager.setInventory(this.player, inv); + cir.setReturnValue(item); } } } @@ -135,8 +151,9 @@ public abstract class InventoryMixin { private void utilitybelt$clearUtilityBelt(CallbackInfo ci) { ItemStack belt = UtilityBeltItem.getBelt(this.player); if (belt != null) { - UtilityBeltInventory inv = StateManager.getServerInstance().getInventory(this.player); + UtilityBeltInventory.Mutable inv = StateManager.getServerInstance().getMutableInventory(this.player); inv.clearContent(); + StateManager.getServerInstance().setInventory(this.player, inv); } } @@ -172,7 +189,7 @@ public abstract class InventoryMixin { private void utilitybelt$dropAllFromUtilityBelt(CallbackInfo ci) { ItemStack belt = UtilityBeltItem.getBelt(this.player); if (belt != null) { - UtilityBeltInventory inv = StateManager.getServerInstance().getInventory(this.player); + UtilityBeltInventory.Mutable inv = StateManager.getServerInstance().getMutableInventory(this.player); for (int i = 0; i < inv.getContainerSize(); i++) { ItemStack itemStack = inv.getItem(i); @@ -181,6 +198,8 @@ public abstract class InventoryMixin { inv.setItem(i, ItemStack.EMPTY); } } + + StateManager.getServerInstance().setInventory(this.player, inv); } } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/LivingEntityMixin.java b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/LivingEntityMixin.java index 0d4a9fb..57c5973 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/LivingEntityMixin.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/LivingEntityMixin.java @@ -31,9 +31,14 @@ public abstract class LivingEntityMixin implements Duck.LivingEntity { StateManager stateManager = StateManager.getServerInstance(); if (stateManager.isInBelt(player)) { ItemStack belt = UtilityBeltItem.getBelt(player); - assert belt != null; - UtilityBeltInventory inv = stateManager.getInventory(player); + + if (belt == null) { + return; + } + + UtilityBeltInventory.Mutable inv = stateManager.getMutableInventory(player); inv.setItem(stateManager.getSelectedBeltSlot(player), ItemStack.EMPTY); + stateManager.setInventory(player, inv); } } } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/PlayerMixin.java b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/PlayerMixin.java index 9b3ef52..9f12cdf 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/PlayerMixin.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/PlayerMixin.java @@ -24,8 +24,9 @@ public class PlayerMixin { if (equipmentSlot == EquipmentSlot.MAINHAND && (Object) this instanceof ServerPlayer player) { StateManager stateManager = StateManager.getServerInstance(); if (stateManager.isInBelt(player)) { - UtilityBeltInventory inv = stateManager.getInventory(player); + UtilityBeltInventory.Mutable inv = stateManager.getMutableInventory(player); inv.setItem(stateManager.getSelectedBeltSlot(player), itemStack); + stateManager.setInventory(player, inv); } } } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/ServerPlayerMixin.java b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/ServerPlayerMixin.java index 575ae40..cba0df9 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/ServerPlayerMixin.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/ServerPlayerMixin.java @@ -8,31 +8,34 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ServerPlayer.class) public class ServerPlayerMixin { - @SuppressWarnings("UnreachableCode") - @Inject( - method = "tick", - at = @At("HEAD") - ) - private void utilitybelt$startPlayerTick(CallbackInfo ci) { - StateManager stateManager = StateManager.getServerInstance(); - ItemStack belt = UtilityBeltItem.getBelt((Player) (Object) this); - if (belt != null) { - UtilityBeltInventory inv = stateManager.getInventory((Player) (Object) this); - UtilityBeltInventory nbtInv = UtilityBeltItem.getInventoryFromTag(belt); + @Unique + private int utilitybelt$lastSyncedInventoryHash = 0; + + @SuppressWarnings("UnreachableCode") + @Inject( + method = "tick", + at = @At("HEAD") + ) + private void utilitybelt$startPlayerTick(CallbackInfo ci) { + StateManager stateManager = StateManager.getServerInstance(); + ItemStack belt = UtilityBeltItem.getBelt((Player) (Object) this); - if (!inv.equals(nbtInv)) { - UtilityBeltItem.setInventory(belt, inv); - ServerNetworking.sendNewInventoryToClient((ServerPlayer) (Object) this); - } - } + if (belt != null) { + UtilityBeltInventory inv = stateManager.getInventory((Player) (Object) this); - stateManager.onStartTick((Player) (Object) this); - } + if (this.utilitybelt$lastSyncedInventoryHash != inv.hashCode()) { + this.utilitybelt$lastSyncedInventoryHash = inv.hashCode(); + ServerNetworking.sendInventoryToClient((ServerPlayer) (Object) this, inv); + UtilityBeltItem.setInventory(belt, inv); + } + } + } } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/client/MinecraftMixin.java b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/client/MinecraftMixin.java index 8768719..64bc9e3 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/client/MinecraftMixin.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/client/MinecraftMixin.java @@ -55,7 +55,11 @@ public class MinecraftMixin { return true; case SWITCH_BELT_SLOT: ItemStack belt = UtilityBeltItem.getBelt(this.player); - assert belt != null; + + if (belt == null) { + return false; + } + int beltSize = stateManager.getInventory(this.player).getContainerSize(); if (i >= 0 && i < beltSize) { diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/screen/UtilityBeltMenu.java b/common/src/main/java/io/github/jamalam360/utility_belt/screen/UtilityBeltMenu.java index 5a4a294..1cff805 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/screen/UtilityBeltMenu.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/screen/UtilityBeltMenu.java @@ -3,6 +3,7 @@ import io.github.jamalam360.utility_belt.StateManager; import io.github.jamalam360.utility_belt.UtilityBelt; import io.github.jamalam360.utility_belt.UtilityBeltInventory; +import io.github.jamalam360.utility_belt.UtilityBeltInventory.Mutable; import io.github.jamalam360.utility_belt.UtilityBeltItem; import io.github.jamalam360.utility_belt.server.ServerStateManager; import net.minecraft.network.chat.Component; @@ -18,124 +19,121 @@ import org.jetbrains.annotations.Nullable; public class UtilityBeltMenu extends AbstractContainerMenu { - private final UtilityBeltInventory inventory; - - public UtilityBeltMenu(int syncId, Inventory playerInventory) { - this(syncId, playerInventory, new UtilityBeltInventory()); - } - - public UtilityBeltMenu(int syncId, Inventory playerInventory, UtilityBeltInventory inventory) { - super(UtilityBelt.MENU_TYPE.get(), syncId); - this.inventory = inventory; - - int m; - int l; - - for (l = 0; l < this.inventory.getContainerSize(); ++l) { - this.addSlot(new Slot(inventory, l, 53 + l * 18, 17) { - @Override - public boolean mayPlace(ItemStack stack) { - return UtilityBeltItem.isValidItem(stack); - } - }); - } - - for (m = 0; m < 3; ++m) { - for (l = 0; l < 9; ++l) { - this.addSlot(new Slot(playerInventory, l + m * 9 + 9, 8 + l * 18, 48 + m * 18)); - } - } - - for (m = 0; m < 9; ++m) { - this.addSlot(new Slot(playerInventory, m, 8 + m * 18, 106)); - } - } - - @Override - public boolean canTakeItemForPickAll(ItemStack stack, Slot slot) { - if (slot.getContainerSlot() < this.inventory.getContainerSize()) { - return UtilityBeltItem.isValidItem(stack); - } - - return super.canTakeItemForPickAll(stack, slot); - } - - @Override - public @NotNull ItemStack quickMoveStack(Player player, int index) { - ItemStack newStack = ItemStack.EMPTY; - Slot slot = this.slots.get(index); - - if (slot.hasItem()) { - ItemStack originalStack = slot.getItem(); - newStack = originalStack.copy(); - if (index < this.inventory.getContainerSize()) { - if (!this.moveItemStackTo(originalStack, this.inventory.getContainerSize(), this.slots.size(), true)) { - return ItemStack.EMPTY; - } - } else if (!this.moveItemStackTo(originalStack, 0, this.inventory.getContainerSize(), false)) { - return ItemStack.EMPTY; - } - - if (originalStack.isEmpty()) { - slot.set(ItemStack.EMPTY); - } else { - slot.setChanged(); - } - } - - this.markDirty(player); - return newStack; - } - - @Override - public void clicked(int slotIndex, int button, ClickType clickType, Player player) { - super.clicked(slotIndex, button, clickType, player); - - if (slotIndex < this.inventory.getContainerSize()) { - this.markDirty(player); - } - } - - @Override - public boolean stillValid(Player player) { - return UtilityBeltItem.getBelt(player) != null; - } - - @Override - public void removed(Player player) { - this.markDirty(player); - super.removed(player); - } - - private void markDirty(Player player) { - ItemStack belt = UtilityBeltItem.getBelt(player); - - if (belt == null) { - // uh oh - // anyways - return; - } - - UtilityBeltItem.setInventory(belt, this.inventory); - - if (player instanceof ServerPlayer) { - ((ServerStateManager) StateManager.getServerInstance()).getInventoryFromTag(player); - } - } - - public static class Factory implements MenuProvider { - - public static final Factory INSTANCE = new Factory(); - - @Override - public @NotNull Component getDisplayName() { - return Component.translatable("container.utility_belt.utility_belt"); - } - - @Nullable - @Override - public AbstractContainerMenu createMenu(int i, Inventory inventory, Player player) { - return new UtilityBeltMenu(i, inventory, UtilityBeltItem.getInventoryFromTag(UtilityBeltItem.getBelt(player))); - } - } + + private final UtilityBeltInventory.Mutable inventory; + + public UtilityBeltMenu(int syncId, Inventory playerInventory) { + this(syncId, playerInventory, new Mutable(UtilityBeltInventory.EMPTY)); + } + + public UtilityBeltMenu(int syncId, Inventory playerInventory, UtilityBeltInventory.Mutable inventory) { + super(UtilityBelt.MENU_TYPE.get(), syncId); + this.inventory = inventory; + + int m; + int l; + + for (l = 0; l < this.inventory.getContainerSize(); ++l) { + this.addSlot(new Slot(inventory, l, 53 + l * 18, 17) { + @Override + public boolean mayPlace(ItemStack stack) { + return UtilityBeltItem.isValidItem(stack); + } + }); + } + + for (m = 0; m < 3; ++m) { + for (l = 0; l < 9; ++l) { + this.addSlot(new Slot(playerInventory, l + m * 9 + 9, 8 + l * 18, 48 + m * 18)); + } + } + + for (m = 0; m < 9; ++m) { + this.addSlot(new Slot(playerInventory, m, 8 + m * 18, 106)); + } + } + + @Override + public boolean canTakeItemForPickAll(ItemStack stack, Slot slot) { + if (slot.getContainerSlot() < this.inventory.getContainerSize()) { + return UtilityBeltItem.isValidItem(stack); + } + + return super.canTakeItemForPickAll(stack, slot); + } + + @Override + public @NotNull ItemStack quickMoveStack(Player player, int index) { + ItemStack newStack = ItemStack.EMPTY; + Slot slot = this.slots.get(index); + + if (slot.hasItem()) { + ItemStack originalStack = slot.getItem(); + newStack = originalStack.copy(); + if (index < this.inventory.getContainerSize()) { + if (!this.moveItemStackTo(originalStack, this.inventory.getContainerSize(), this.slots.size(), true)) { + return ItemStack.EMPTY; + } + } else if (!this.moveItemStackTo(originalStack, 0, this.inventory.getContainerSize(), false)) { + return ItemStack.EMPTY; + } + + if (originalStack.isEmpty()) { + slot.set(ItemStack.EMPTY); + } else { + slot.setChanged(); + } + } + + this.markDirty(player); + return newStack; + } + + @Override + public void clicked(int slotIndex, int button, ClickType clickType, Player player) { + super.clicked(slotIndex, button, clickType, player); + + if (slotIndex < this.inventory.getContainerSize()) { + this.markDirty(player); + } + } + + @Override + public boolean stillValid(Player player) { + return UtilityBeltItem.getBelt(player) != null; + } + + @Override + public void removed(Player player) { + this.markDirty(player); + super.removed(player); + } + + private void markDirty(Player player) { + ItemStack belt = UtilityBeltItem.getBelt(player); + + if (belt == null) { + // uh oh + // anyways + return; + } + + StateManager.getServerInstance().setInventory(player, this.inventory); + } + + public static class Factory implements MenuProvider { + + public static final Factory INSTANCE = new Factory(); + + @Override + public @NotNull Component getDisplayName() { + return Component.translatable("container.utility_belt.utility_belt"); + } + + @Nullable + @Override + public AbstractContainerMenu createMenu(int i, Inventory inventory, Player player) { + return new UtilityBeltMenu(i, inventory, new Mutable(UtilityBeltItem.getInventoryFromTag(UtilityBeltItem.getBelt(player)))); + } + } } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/server/ServerNetworking.java b/common/src/main/java/io/github/jamalam360/utility_belt/server/ServerNetworking.java index 1acc12a..143296e 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/server/ServerNetworking.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/server/ServerNetworking.java @@ -23,13 +23,8 @@ public static void init() { NetworkManager.registerReceiver(NetworkManager.Side.C2S, UtilityBeltPackets.C2S_OPEN_SCREEN, C2SOpenScreen.STREAM_CODEC, ServerNetworking::handleOpenScreen); } - public static void sendNewInventoryToClient(ServerPlayer player) { -// FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer()); -// UtilityBeltInventory inv = StateManager.getServerInstance().getInventory(player); -// CompoundTag tag = new CompoundTag(); -// tag.put("Inventory", inv.createTag()); -// buf.writeNbt(tag); -// NetworkManager.sendToPlayer(player, UtilityBelt.S2C_UPDATE_INV, buf); + public static void sendInventoryToClient(ServerPlayer player, UtilityBeltInventory inventory) { + NetworkManager.sendToPlayer(player, new UtilityBeltPackets.S2CUpdateBeltInventory(inventory)); } private static void handleUpdateState(C2SUpdateState payload, NetworkManager.PacketContext ctx) { @@ -52,7 +47,7 @@ private static void handleUpdateState(C2SUpdateState payload, NetworkManager.Pac return; } - UtilityBeltInventory inv = stateManager.getInventory(ctx.getPlayer()); + UtilityBeltInventory.Mutable inv = stateManager.getMutableInventory(ctx.getPlayer()); ItemStack stackInHand = ctx.getPlayer().getInventory().getItem(ctx.getPlayer().getInventory().selected); int hotbarSlot = ctx.getPlayer().getInventory().selected; ItemStack stackInBelt = inv.getItem(beltSlot); @@ -78,6 +73,7 @@ private static void handleUpdateState(C2SUpdateState payload, NetworkManager.Pac if (UtilityBeltItem.isValidItem(stackInHand)) { ctx.getPlayer().getInventory().setItem(hotbarSlot, stackInBelt); inv.setItem(beltSlot, stackInHand); + stateManager.setInventory(ctx.getPlayer(), inv); ((Duck.LivingEntity) ctx.getPlayer()).utilitybelt$detectEquipmentUpdates(); if (beltSlot != slot) { diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/server/ServerStateManager.java b/common/src/main/java/io/github/jamalam360/utility_belt/server/ServerStateManager.java index faa32c5..08a9883 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/server/ServerStateManager.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/server/ServerStateManager.java @@ -19,19 +19,6 @@ private PlayerState getState(Player player) { return playerStates.computeIfAbsent(player.getUUID(), uuid -> new PlayerState(false, 0)); } - @Override - public void onStartTick(Player player) { - if (this.hasBelt(player)) { - getState(player).inventory = UtilityBeltItem.getInventoryFromTag(UtilityBeltItem.getBelt(player)); - } else { - getState(player).inventory = null; - } - } - - public void getInventoryFromTag(Player player) { - getState(player).inventory = UtilityBeltItem.getInventoryFromTag(UtilityBeltItem.getBelt(player)); - } - @Override public boolean isInBelt(Player player) { return getState(player).inBelt; @@ -58,13 +45,22 @@ public UtilityBeltInventory getInventory(Player player) { if (state.inventory == null) { ItemStack belt = UtilityBeltItem.getBelt(player); - assert belt != null; + + if (belt == null) { + return UtilityBeltInventory.EMPTY; + } + state.inventory = UtilityBeltItem.getInventoryFromTag(belt); } return state.inventory; } + @Override + public void setInventory(Player player, UtilityBeltInventory.Mutable inventory) { + getState(player).inventory = inventory.toImmutable(); + } + private static class PlayerState { boolean inBelt; int selectedBeltSlot; diff --git a/gradle.properties b/gradle.properties index a196e12..b92ee5c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false org.gradle.parallel=true -version=2.1.1+1.20.6 +version=2.1.2+1.20.6 minecraft_version=1.20.6 branch=main group=io.github.jamalam360 diff --git a/neoforge/src/main/java/io/github/jamalam360/utility_belt/neoforge/UtilityBeltCurio.java b/neoforge/src/main/java/io/github/jamalam360/utility_belt/neoforge/UtilityBeltCurio.java index d9474d8..10adec4 100644 --- a/neoforge/src/main/java/io/github/jamalam360/utility_belt/neoforge/UtilityBeltCurio.java +++ b/neoforge/src/main/java/io/github/jamalam360/utility_belt/neoforge/UtilityBeltCurio.java @@ -10,6 +10,11 @@ public class UtilityBeltCurio implements ICurioItem { + @Override + public void onEquip(SlotContext slotContext, ItemStack prevStack, ItemStack stack) { + ((UtilityBeltItem) stack.getItem()).onEquip(slotContext.entity(), stack); + } + @Override public void onUnequip(SlotContext slotContext, ItemStack newStack, ItemStack stack) { ((UtilityBeltItem) stack.getItem()).onUnequip(slotContext.entity()); From 54583cb2f729ce1929e342127204caf14f2e8edd Mon Sep 17 00:00:00 2001 From: "James (Jamalam)" Date: Sun, 9 Jun 2024 18:30:34 +0100 Subject: [PATCH 5/6] feat: finalize 2.2.0 --- common/build.gradle | 4 ---- .../jamalam360/utility_belt/UtilityBelt.java | 4 ++-- .../utility_belt/UtilityBeltItem.java | 2 +- .../utility_belt/mixin/ServerPlayerMixin.java | 9 +++++++ .../ItemStackComponentizationFixMixin.java | 24 ------------------- .../main/resources/architectury.common.json | 3 --- .../assets/utility_belt/lang/en_us.json | 1 + .../advancements/obtain_belt.json | 2 +- .../main/resources/utility_belt.accesswidener | 3 --- .../main/resources/utility_belt.mixins.json | 3 +-- fabric/build.gradle | 5 ---- .../fabric/UtilityBeltTrinket.java | 9 ++++--- fabric/src/main/resources/fabric.mod.json | 1 - gradle.properties | 2 +- libs.versions.toml | 2 +- 15 files changed, 23 insertions(+), 51 deletions(-) delete mode 100644 common/src/main/java/io/github/jamalam360/utility_belt/mixin/datafixer/ItemStackComponentizationFixMixin.java delete mode 100644 common/src/main/resources/architectury.common.json delete mode 100644 common/src/main/resources/utility_belt.accesswidener diff --git a/common/build.gradle b/common/build.gradle index 1854929..2538b62 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -2,10 +2,6 @@ architectury { common(rootProject.enabled_platforms.split(",")) } -loom { - accessWidenerPath = file("src/main/resources/utility_belt.accesswidener") -} - dependencies { modImplementation libs.fabric.loader modApi libs.architectury.common diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBelt.java b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBelt.java index aff63e4..da122ee 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBelt.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBelt.java @@ -40,16 +40,16 @@ public class UtilityBelt { private static final DeferredRegister> COMPONENT_TYPES = DeferredRegister.create(MOD_ID, Registries.DATA_COMPONENT_TYPE); public static final RegistrySupplier UTILITY_BELT_ITEM = ITEMS.register("utility_belt", UtilityBeltItem::new); - public static final RegistrySupplier> MENU_TYPE = MENUS.register("utility_belt", () -> new MenuType<>(UtilityBeltMenu::new, FeatureFlagSet.of())); public static final RegistrySupplier> UTILITY_BELT_INVENTORY_COMPONENT_TYPE = COMPONENT_TYPES.register("utility_belt_inventory", () -> DataComponentType.builder().persistent(UtilityBeltInventory.CODEC).cacheEncoding().build() ); + public static final RegistrySupplier> MENU_TYPE = MENUS.register("utility_belt", () -> new MenuType<>(UtilityBeltMenu::new, FeatureFlagSet.of())); public static void init() { JamLib.checkForJarRenaming(UtilityBelt.class); + COMPONENT_TYPES.register(); // needs to be before items ITEMS.register(); MENUS.register(); - COMPONENT_TYPES.register(); UTILITY_BELT_ITEM.listen((belt) -> CreativeTabRegistry.append(CreativeModeTabs.TOOLS_AND_UTILITIES, belt)); ServerNetworking.init(); StateManager.setServerInstance(new ServerStateManager()); diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltItem.java b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltItem.java index 90cbd86..762db78 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltItem.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/UtilityBeltItem.java @@ -8,7 +8,6 @@ import net.minecraft.sounds.SoundEvents; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.SlotAccess; import net.minecraft.world.entity.player.Player; @@ -132,6 +131,7 @@ public boolean overrideStackedOnOther(ItemStack belt, Slot slot, ClickAction cli return false; } + playInsertSound(player); setInventory(belt, inv.toImmutable()); return true; } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/ServerPlayerMixin.java b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/ServerPlayerMixin.java index cba0df9..64be061 100644 --- a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/ServerPlayerMixin.java +++ b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/ServerPlayerMixin.java @@ -18,6 +18,8 @@ public class ServerPlayerMixin { @Unique private int utilitybelt$lastSyncedInventoryHash = 0; + @Unique + private boolean utilitybelt$hasBeltLastTick = false; @SuppressWarnings("UnreachableCode") @Inject( @@ -29,6 +31,11 @@ public class ServerPlayerMixin { ItemStack belt = UtilityBeltItem.getBelt((Player) (Object) this); if (belt != null) { + if (!this.utilitybelt$hasBeltLastTick) { + this.utilitybelt$hasBeltLastTick = true; + return; + } + UtilityBeltInventory inv = stateManager.getInventory((Player) (Object) this); if (this.utilitybelt$lastSyncedInventoryHash != inv.hashCode()) { @@ -36,6 +43,8 @@ public class ServerPlayerMixin { ServerNetworking.sendInventoryToClient((ServerPlayer) (Object) this, inv); UtilityBeltItem.setInventory(belt, inv); } + } else { + this.utilitybelt$hasBeltLastTick = false; } } } diff --git a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/datafixer/ItemStackComponentizationFixMixin.java b/common/src/main/java/io/github/jamalam360/utility_belt/mixin/datafixer/ItemStackComponentizationFixMixin.java deleted file mode 100644 index a1b5494..0000000 --- a/common/src/main/java/io/github/jamalam360/utility_belt/mixin/datafixer/ItemStackComponentizationFixMixin.java +++ /dev/null @@ -1,24 +0,0 @@ -package io.github.jamalam360.utility_belt.mixin.datafixer; - -import com.mojang.serialization.Dynamic; -import io.github.jamalam360.utility_belt.UtilityBelt; -import java.util.stream.Stream; -import net.minecraft.util.datafix.fixes.ItemStackComponentizationFix; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ItemStackComponentizationFix.class) -public class ItemStackComponentizationFixMixin { - @Inject( - method = "fixItemStack", - at = @At("TAIL") - ) - private static void utilitybelt$moveNbtToComponent(ItemStackComponentizationFix.ItemStackData itemStackData, Dynamic dynamic, CallbackInfo ci) { - if (itemStackData.is(UtilityBelt.id("utility_belt").toString())) { - System.out.println("fixed belt"); - itemStackData.moveTagToComponent("Inventory", "utility_belt:utility_belt_inventory", dynamic.createList(Stream.empty())); - } - } -} diff --git a/common/src/main/resources/architectury.common.json b/common/src/main/resources/architectury.common.json deleted file mode 100644 index b75ff8d..0000000 --- a/common/src/main/resources/architectury.common.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "accessWidener": "utility_belt.accesswidener" -} diff --git a/common/src/main/resources/assets/utility_belt/lang/en_us.json b/common/src/main/resources/assets/utility_belt/lang/en_us.json index da24fe4..1329830 100644 --- a/common/src/main/resources/assets/utility_belt/lang/en_us.json +++ b/common/src/main/resources/assets/utility_belt/lang/en_us.json @@ -1,5 +1,6 @@ { "item.utility_belt.utility_belt": "Utility Belt", + "tag.item.utility_belt.allowed_in_utility_belt": "Allowed in Utility Belt", "container.utility_belt.utility_belt": "Utility Belt", "key.category.utility_belt": "Utility Belt", "key.utility_belt.swap_toggle": "Switch to Belt (Toggle)", diff --git a/common/src/main/resources/data/utility_belt/advancements/obtain_belt.json b/common/src/main/resources/data/utility_belt/advancements/obtain_belt.json index 7c54b6f..7717367 100644 --- a/common/src/main/resources/data/utility_belt/advancements/obtain_belt.json +++ b/common/src/main/resources/data/utility_belt/advancements/obtain_belt.json @@ -2,7 +2,7 @@ "parent": "minecraft:story/smelt_iron", "display": { "icon": { - "item": "utility_belt:utility_belt" + "id": "utility_belt:utility_belt" }, "title": { "translate": "advancements.utility_belt.utility_belt.title" diff --git a/common/src/main/resources/utility_belt.accesswidener b/common/src/main/resources/utility_belt.accesswidener deleted file mode 100644 index cc17a66..0000000 --- a/common/src/main/resources/utility_belt.accesswidener +++ /dev/null @@ -1,3 +0,0 @@ -accessWidener v2 named - -accessible class net/minecraft/util/datafix/fixes/ItemStackComponentizationFix$ItemStackData diff --git a/common/src/main/resources/utility_belt.mixins.json b/common/src/main/resources/utility_belt.mixins.json index 6d69e70..8cad663 100644 --- a/common/src/main/resources/utility_belt.mixins.json +++ b/common/src/main/resources/utility_belt.mixins.json @@ -8,8 +8,7 @@ "LivingEntityMixin", "PlayerMixin", "ServerGamePacketListenerImplMixin", - "ServerPlayerMixin", - "datafixer.ItemStackComponentizationFixMixin" + "ServerPlayerMixin" ], "client": [ "client.ClientPacketListenerMixin", diff --git a/fabric/build.gradle b/fabric/build.gradle index bea40bf..ef5a727 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -8,10 +8,6 @@ architectury { fabric() } -loom { - accessWidenerPath = project(":common").loom.accessWidenerPath -} - base { archivesName = "utility-belt-fabric" } @@ -37,7 +33,6 @@ dependencies { } if (System.getenv("CURSEFORGE_API_KEY") != null && System.getenv("MODRINTH_API_KEY") != null) { -// Uncomment these lines and fill in the IDs when ready to publish :) unifiedPublishing { project { displayName = "V${project.version} (Fabric ${project.minecraft_version})" diff --git a/fabric/src/main/java/io/github/jamalam360/utility_belt/fabric/UtilityBeltTrinket.java b/fabric/src/main/java/io/github/jamalam360/utility_belt/fabric/UtilityBeltTrinket.java index 09ac996..7a3026a 100644 --- a/fabric/src/main/java/io/github/jamalam360/utility_belt/fabric/UtilityBeltTrinket.java +++ b/fabric/src/main/java/io/github/jamalam360/utility_belt/fabric/UtilityBeltTrinket.java @@ -11,10 +11,13 @@ public class UtilityBeltTrinket implements Trinket { @Override - public void onUnequip(ItemStack stack, SlotReference slot, LivingEntity entity) { - // FIXME: for some reason, Trinkets is calling this even when the item is not being unequipped - // To test, go into survival and break a block/attack an entity using an item in the belt + public void onEquip(ItemStack stack, SlotReference slot, LivingEntity entity) { + ((UtilityBeltItem) stack.getItem()).onEquip(entity, stack); + } + @Override + public void onUnequip(ItemStack stack, SlotReference slot, LivingEntity entity) { + // Trinkets is calling this even when the item is not being unequipped if (UtilityBeltPlatform.getStackInBeltSlot(entity) == null) { ((UtilityBeltItem) stack.getItem()).onUnequip(entity); } diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 2ed0229..d6e5cf8 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -26,7 +26,6 @@ "mixins": [ "utility_belt.mixins.json" ], - "accessWidener": "utility_belt.accesswidener", "depends": { "fabricloader": ">=0.15.0", "fabric": ">=${fabric_api_version}", diff --git a/gradle.properties b/gradle.properties index b92ee5c..c05d633 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false org.gradle.parallel=true -version=2.1.2+1.20.6 +version=2.2.0+1.20.6 minecraft_version=1.20.6 branch=main group=io.github.jamalam360 diff --git a/libs.versions.toml b/libs.versions.toml index 7c8608b..4e33399 100644 --- a/libs.versions.toml +++ b/libs.versions.toml @@ -13,7 +13,7 @@ fabric-api = "0.99.0+1.20.6" jamlib = "1.0.9+1.20.6" # https://modrinth.com/mod/trinkets/versions -trinkets = "3.8.1" +trinkets = "3.9.0" # https://modrinth.com/mod/curios/versions curios = "8.0.0-beta.2+1.20.6" From 1b8d8053ab2e4a97ae68baec79945113050facf0 Mon Sep 17 00:00:00 2001 From: "James (Jamalam)" Date: Sun, 9 Jun 2024 18:32:36 +0100 Subject: [PATCH 6/6] fix: resolve issue with access wideners --- neoforge/build.gradle | 5 ----- 1 file changed, 5 deletions(-) diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 72f7c47..1ebdd5e 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -8,10 +8,6 @@ architectury { neoForge() } -loom { - accessWidenerPath = project(":common").loom.accessWidenerPath -} - base { archivesName = "utility-belt-neoforge" } @@ -112,7 +108,6 @@ shadowJar { remapJar { input.set shadowJar.archiveFile dependsOn shadowJar - atAccessWideners.add "utility_belt.accesswidener" } sourcesJar {