From 796511d928848b9cdcc44851ba7749ce48d99bfa Mon Sep 17 00:00:00 2001 From: kill05 Date: Sun, 16 Jun 2024 00:39:58 +0200 Subject: [PATCH 1/7] Removed vanilla gui logic override to allow vanilla clients to open guis --- .../java/turniplabs/halplibe/HalpLibe.java | 1 - .../turniplabs/halplibe/helper/gui/Guis.java | 182 ------------------ .../helper/gui/registered/RegisteredGui.java | 2 +- .../mixin/mixins/NetClientHandlerMixin.java | 17 -- .../mixin/mixins/TileEntityMixin.java | 25 --- .../mixin/mixins/gui/BlockChestMixin.java | 30 --- .../mixin/mixins/gui/EntityPlayerMPMixin.java | 102 ---------- .../mixin/mixins/gui/EntityPlayerSPMixin.java | 124 ------------ .../PlayerManager_PlayerInstanceMixin.java | 24 --- src/main/resources/halplibe.mixins.json | 5 - 10 files changed, 1 insertion(+), 511 deletions(-) delete mode 100644 src/main/java/turniplabs/halplibe/helper/gui/Guis.java delete mode 100644 src/main/java/turniplabs/halplibe/mixin/mixins/TileEntityMixin.java delete mode 100644 src/main/java/turniplabs/halplibe/mixin/mixins/gui/BlockChestMixin.java delete mode 100644 src/main/java/turniplabs/halplibe/mixin/mixins/gui/EntityPlayerMPMixin.java delete mode 100644 src/main/java/turniplabs/halplibe/mixin/mixins/gui/EntityPlayerSPMixin.java delete mode 100644 src/main/java/turniplabs/halplibe/mixin/mixins/gui/PlayerManager_PlayerInstanceMixin.java diff --git a/src/main/java/turniplabs/halplibe/HalpLibe.java b/src/main/java/turniplabs/halplibe/HalpLibe.java index fd6425b..c87cad3 100644 --- a/src/main/java/turniplabs/halplibe/HalpLibe.java +++ b/src/main/java/turniplabs/halplibe/HalpLibe.java @@ -9,7 +9,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import turniplabs.halplibe.helper.*; -import turniplabs.halplibe.helper.gui.Guis; import turniplabs.halplibe.helper.gui.packet.PacketOpenBlockGui; import turniplabs.halplibe.helper.gui.packet.PacketOpenGui; import turniplabs.halplibe.helper.gui.packet.PacketOpenItemGui; diff --git a/src/main/java/turniplabs/halplibe/helper/gui/Guis.java b/src/main/java/turniplabs/halplibe/helper/gui/Guis.java deleted file mode 100644 index 93d22c3..0000000 --- a/src/main/java/turniplabs/halplibe/helper/gui/Guis.java +++ /dev/null @@ -1,182 +0,0 @@ -package turniplabs.halplibe.helper.gui; - -import net.minecraft.client.entity.player.EntityPlayerSP; -import net.minecraft.client.gui.*; -import net.minecraft.core.block.BlockChest; -import net.minecraft.core.block.entity.*; -import net.minecraft.core.entity.player.EntityPlayer; -import net.minecraft.core.item.ItemStack; -import net.minecraft.core.player.inventory.*; -import net.minecraft.server.entity.player.EntityPlayerMP; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import turniplabs.halplibe.helper.gui.factory.base.GuiFactory; -import turniplabs.halplibe.helper.gui.factory.block.BlockGuiFactory; -import turniplabs.halplibe.helper.gui.factory.block.TileGuiFactory; -import turniplabs.halplibe.helper.gui.factory.item.ItemGuiFactory; -import turniplabs.halplibe.helper.gui.registered.RegisteredGui; - -public final class Guis { - - /* ============== - Client Guis - ============== */ - - public static final RegisteredGui EDIT_SIGN = GuiHelper.registerClientGui("minecraft", "edit_sign", new TileGuiFactory() { - @Override - public @NotNull GuiScreen createGui(@NotNull RegisteredGui gui, @NotNull EntityPlayerSP player, @NotNull TileEntitySign tile) { - return new GuiEditSign(tile); - } - - @Override - public @Nullable Container createContainer(@NotNull RegisteredGui gui, @NotNull EntityPlayerMP player, @NotNull TileEntitySign tile) { - return null; - } - }); - - public static final RegisteredGui EDIT_LABEL = GuiHelper.registerClientGui("minecraft", "edit_label", new ItemGuiFactory() { - @Override - public @NotNull GuiScreen createGui(@NotNull RegisteredGui gui, @NotNull EntityPlayerSP player, @NotNull ItemStack itemStack) { - return new GuiEditLabel(itemStack, getSlot(player, itemStack)); - } - - @Override - public @Nullable Container createContainer(@NotNull RegisteredGui gui, @NotNull EntityPlayerMP player, @NotNull ItemStack itemStack) { - return null; - } - - private int getSlot(EntityPlayer player, ItemStack itemStack) { - for (int i = 0; i < player.inventory.mainInventory.length; ++i) { - if (player.inventory.mainInventory[i] == itemStack) return i; - } - - throw new AssertionError(); - } - }); - - public static final RegisteredGui MOB_SPAWNER_PICKER = GuiHelper.registerClientGui("minecraft", "mob_spawner_picker", new TileGuiFactory() { - @Override - public @NotNull GuiScreen createGui(@NotNull RegisteredGui gui, @NotNull EntityPlayerSP player, @NotNull TileEntityMobSpawner tile) { - return new GuiPickMonster(tile.getMobId(), tile.x, tile.y, tile.z); - } - - @Override - public @Nullable Container createContainer(@NotNull RegisteredGui gui, @NotNull EntityPlayerMP player, @NotNull TileEntityMobSpawner tile) { - return null; - } - }); - - public static final RegisteredGui WAND_MONSTER_PICKER = GuiHelper.registerClientGui("minecraft", "wand_monster_picker", new ItemGuiFactory() { - @Override - public @NotNull GuiScreen createGui(@NotNull RegisteredGui gui, @NotNull EntityPlayerSP player, @NotNull ItemStack itemStack) { - String mobId = itemStack.getData().getStringOrDefault("monster", "Pig"); - return new GuiWandPickerMonster(mobId, itemStack); - } - - @Override - public @Nullable Container createContainer(@NotNull RegisteredGui gui, @NotNull EntityPlayerMP player, @NotNull ItemStack itemStack) { - return null; - } - }); - - - /* ============== - Server Guis - ============== */ - - public static final RegisteredGui CHEST = GuiHelper.registerServerGui("minecraft", "chest", new BlockGuiFactory() { - @Override - public @NotNull GuiScreen createGui(@NotNull RegisteredGui gui, @NotNull EntityPlayerSP player, int x, int y, int z) { - return new GuiChest(player.inventory, BlockChest.getInventory(player.world, x, y, z)); - } - - @Override - public @NotNull Container createContainer(@NotNull RegisteredGui gui, @NotNull EntityPlayerMP player, int x, int y, int z) { - return new ContainerChest(player.inventory, BlockChest.getInventory(player.world, x, y, z)); - } - }); - - public static final RegisteredGui WORKBENCH = GuiHelper.registerServerGui("minecraft", "workbench", new BlockGuiFactory() { - @Override - public @NotNull GuiScreen createGui(@NotNull RegisteredGui gui, @NotNull EntityPlayerSP player, int x, int y, int z) { - return new GuiCrafting(player.inventory, player.world, x, y, z); - } - - @Override - public @NotNull Container createContainer(@NotNull RegisteredGui gui, @NotNull EntityPlayerMP player, int x, int y, int z) { - return new ContainerWorkbench(player.inventory, player.world, x, y, z); - } - }); - - public static final RegisteredGui FURNACE = GuiHelper.registerServerGui("minecraft", "furnace", new TileGuiFactory() { - @Override - public @NotNull GuiScreen createGui(@NotNull RegisteredGui gui, @NotNull EntityPlayerSP player, @NotNull TileEntityFurnace tile) { - return new GuiFurnace(player.inventory, tile); - } - - @Override - public @NotNull Container createContainer(@NotNull RegisteredGui gui, @NotNull EntityPlayerMP player, @NotNull TileEntityFurnace tile) { - return new ContainerFurnace(player.inventory, tile); - } - }); - - public static final RegisteredGui DISPENSER = GuiHelper.registerServerGui("minecraft", "dispenser", new TileGuiFactory() { - @Override - public @NotNull GuiScreen createGui(@NotNull RegisteredGui gui, @NotNull EntityPlayerSP player, @NotNull TileEntityDispenser tile) { - return new GuiDispenser(player.inventory, tile); - } - - @Override - public @NotNull Container createContainer(@NotNull RegisteredGui gui, @NotNull EntityPlayerMP player, @NotNull TileEntityDispenser tile) { - return new ContainerDispenser(player.inventory, tile); - } - }); - - public static final RegisteredGui BLAST_FURNACE = GuiHelper.registerServerGui("minecraft", "blast_furnace", new TileGuiFactory() { - @Override - public @NotNull GuiScreen createGui(@NotNull RegisteredGui gui, @NotNull EntityPlayerSP player, @NotNull TileEntityFurnace tile) { - return new GuiFurnace(player.inventory, tile); - } - - @Override - public @NotNull Container createContainer(@NotNull RegisteredGui gui, @NotNull EntityPlayerMP player, @NotNull TileEntityFurnace tile) { - return new ContainerFurnace(player.inventory, tile); - } - }); - - public static final RegisteredGui TROMMEL = GuiHelper.registerServerGui("minecraft", "trommel", new TileGuiFactory() { - @Override - public @NotNull GuiScreen createGui(@NotNull RegisteredGui gui, @NotNull EntityPlayerSP player, @NotNull TileEntityTrommel tile) { - return new GuiTrommel(player.inventory, tile); - } - - @Override - public @NotNull Container createContainer(@NotNull RegisteredGui gui, @NotNull EntityPlayerMP player, @NotNull TileEntityTrommel tile) { - return new ContainerTrommel(player.inventory, tile); - } - }); - - public static final RegisteredGui PAINTING_PICKER = GuiHelper.registerServerGui("minecraft", "painting_picker", new GuiFactory() { - @Override - public @NotNull GuiScreen createGui(@NotNull RegisteredGui gui, @NotNull EntityPlayerSP player) { - return new GuiPaintingPicker(player); - } - - @Override - public @Nullable Container createContainer(@NotNull RegisteredGui gui, @NotNull EntityPlayerMP player) { - return null; - } - }); - - public static final RegisteredGui EDIT_FLAG = GuiHelper.registerServerGui("minecraft", "edit_flag", new TileGuiFactory() { - @Override - public @NotNull GuiScreen createGui(@NotNull RegisteredGui gui, @NotNull EntityPlayerSP player, @NotNull TileEntityFlag tile) { - return new GuiEditFlag(player, tile); - } - - @Override - public @NotNull Container createContainer(@NotNull RegisteredGui gui, @NotNull EntityPlayerMP player, @NotNull TileEntityFlag tile) { - return new ContainerFlag(player.inventory, tile); - } - }); -} diff --git a/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java b/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java index fadafe7..16771db 100644 --- a/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java +++ b/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java @@ -36,7 +36,7 @@ public RegisteredGui(@NotNull String modId, @NotNull String id, @NotNull IGuiFac this.serverSide = serverSide; if (!ID_PATTERN.matcher(modId + id).matches()) - throw new IllegalArgumentException(String.format("Invalid namespace:%s. Must match the following regex '[a-zA-Z0-9_-]+'.", getNamespace())); + throw new IllegalArgumentException(String.format("Invalid namespace: %s. Must match the following regex '[a-zA-Z0-9_-]+'.", getNamespace())); if(GuiHelper.REGISTRY.getItem(getNamespace()) != null) throw new IllegalArgumentException(String.format("Duplicate namespace: %s.", getNamespace())); diff --git a/src/main/java/turniplabs/halplibe/mixin/mixins/NetClientHandlerMixin.java b/src/main/java/turniplabs/halplibe/mixin/mixins/NetClientHandlerMixin.java index be655eb..70a5a6c 100644 --- a/src/main/java/turniplabs/halplibe/mixin/mixins/NetClientHandlerMixin.java +++ b/src/main/java/turniplabs/halplibe/mixin/mixins/NetClientHandlerMixin.java @@ -1,38 +1,21 @@ package turniplabs.halplibe.mixin.mixins; import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.client.Minecraft; import net.minecraft.client.net.handler.NetClientHandler; import net.minecraft.core.net.handler.NetHandler; -import net.minecraft.core.net.packet.Packet100OpenWindow; import net.minecraft.core.net.packet.Packet1Login; -import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import turniplabs.halplibe.helper.gui.GuiHelper; import turniplabs.halplibe.util.RecipeEntrypoint; @Mixin(value = NetClientHandler.class,remap = false) public abstract class NetClientHandlerMixin extends NetHandler { - @Shadow @Final private Minecraft mc; - @Inject(method = "handleLogin", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/crafting/legacy/CraftingManager;reset()V", shift = At.Shift.BEFORE)) public void handleLogin(Packet1Login packet1login, CallbackInfo ci) { FabricLoader.getInstance().getEntrypoints("recipesReady", RecipeEntrypoint.class).forEach(RecipeEntrypoint::initNamespaces); } - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void handleOpenWindow(Packet100OpenWindow packet) { - GuiHelper.reportVanillaGuiCall("Received BTA open window packet"); - } - } diff --git a/src/main/java/turniplabs/halplibe/mixin/mixins/TileEntityMixin.java b/src/main/java/turniplabs/halplibe/mixin/mixins/TileEntityMixin.java deleted file mode 100644 index 609eab6..0000000 --- a/src/main/java/turniplabs/halplibe/mixin/mixins/TileEntityMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package turniplabs.halplibe.mixin.mixins; - -import net.minecraft.core.block.entity.TileEntity; -import net.minecraft.core.net.packet.Packet; -import net.minecraft.core.net.packet.Packet140TileEntityData; -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.CallbackInfoReturnable; - -@Mixin( - value = TileEntity.class, - remap = false -) -public abstract class TileEntityMixin { - - @Inject( - method = "getDescriptionPacket", - at = @At(value = "HEAD"), - cancellable = true - ) - public void injectGetDescriptionPacket(CallbackInfoReturnable cir) { - cir.setReturnValue(new Packet140TileEntityData((TileEntity) ((Object)this))); - } -} diff --git a/src/main/java/turniplabs/halplibe/mixin/mixins/gui/BlockChestMixin.java b/src/main/java/turniplabs/halplibe/mixin/mixins/gui/BlockChestMixin.java deleted file mode 100644 index bbcd8a7..0000000 --- a/src/main/java/turniplabs/halplibe/mixin/mixins/gui/BlockChestMixin.java +++ /dev/null @@ -1,30 +0,0 @@ -package turniplabs.halplibe.mixin.mixins.gui; - -import net.minecraft.core.block.BlockChest; -import net.minecraft.core.block.BlockTileEntity; -import net.minecraft.core.block.material.Material; -import net.minecraft.core.entity.player.EntityPlayer; -import net.minecraft.core.world.World; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import turniplabs.halplibe.helper.gui.Guis; - -@Mixin( - value = BlockChest.class, - remap = false -) -public abstract class BlockChestMixin extends BlockTileEntity { - - @Shadow public abstract void checkIfOtherHalfExists(World world, int x, int y, int z); - - public BlockChestMixin(String key, int id, Material material) { - super(key, id, material); - } - - @Override - public boolean blockActivated(World world, int x, int y, int z, EntityPlayer player) { - if(!world.isClientSide) checkIfOtherHalfExists(world, x, y, z); - Guis.CHEST.open(player, x, y, z); - return true; - } -} diff --git a/src/main/java/turniplabs/halplibe/mixin/mixins/gui/EntityPlayerMPMixin.java b/src/main/java/turniplabs/halplibe/mixin/mixins/gui/EntityPlayerMPMixin.java deleted file mode 100644 index acebe26..0000000 --- a/src/main/java/turniplabs/halplibe/mixin/mixins/gui/EntityPlayerMPMixin.java +++ /dev/null @@ -1,102 +0,0 @@ -package turniplabs.halplibe.mixin.mixins.gui; - -import net.minecraft.core.block.entity.*; -import net.minecraft.core.net.packet.Packet; -import net.minecraft.core.player.inventory.IInventory; -import net.minecraft.server.entity.player.EntityPlayerMP; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; -import turniplabs.halplibe.helper.gui.GuiHelper; -import turniplabs.halplibe.helper.gui.Guis; - -@Mixin( - value = EntityPlayerMP.class, - remap = false -) -public abstract class EntityPlayerMPMixin { - - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void displayGUIEditFlag(TileEntityFlag tile) { - Guis.EDIT_FLAG.open(getPlayer(), tile.x, tile.y, tile.z); - } - - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void displayGUIChest(IInventory iinventory) { - GuiHelper.reportVanillaGuiCall("BTA display gui method called"); - } - - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void displayGUIWorkbench(int x, int y, int z) { - Guis.WORKBENCH.open(getPlayer(), x, y, z); - } - - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void displayGUIPaintingPicker() { - Guis.PAINTING_PICKER.open(getPlayer()); - } - - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void displayGUIFurnace(TileEntityFurnace tile) { - Guis.FURNACE.open(getPlayer(), tile.x, tile.y, tile.z); - } - - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void displayGUITrommel(TileEntityTrommel tile) { - Guis.TROMMEL.open(getPlayer(), tile.x, tile.y, tile.z); - } - - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void displayGUIDispenser(TileEntityDispenser tile) { - Guis.DISPENSER.open(getPlayer(), tile.x, tile.y, tile.z); - } - - - @Redirect( - method = "getTileEntityInfo", - at = @At(value = "INVOKE", target = "Lnet/minecraft/core/block/entity/TileEntity;getDescriptionPacket()Lnet/minecraft/core/net/packet/Packet;") - ) - public Packet redirectUpdateTileEntity(TileEntity tile) { - Packet packet = tile.getDescriptionPacket(); - if(packet == null) throw new IllegalStateException(String.format("Tile entity '%s' returned null description packet.", tile)); - return packet; - } - - - @Unique - private EntityPlayerMP getPlayer() { - return (EntityPlayerMP) ((Object) this); - } - - -} diff --git a/src/main/java/turniplabs/halplibe/mixin/mixins/gui/EntityPlayerSPMixin.java b/src/main/java/turniplabs/halplibe/mixin/mixins/gui/EntityPlayerSPMixin.java deleted file mode 100644 index 8d9b896..0000000 --- a/src/main/java/turniplabs/halplibe/mixin/mixins/gui/EntityPlayerSPMixin.java +++ /dev/null @@ -1,124 +0,0 @@ -package turniplabs.halplibe.mixin.mixins.gui; - -import net.minecraft.client.entity.player.EntityPlayerSP; -import net.minecraft.core.block.entity.*; -import net.minecraft.core.item.ItemStack; -import net.minecraft.core.player.inventory.IInventory; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Unique; -import turniplabs.halplibe.helper.gui.GuiHelper; -import turniplabs.halplibe.helper.gui.Guis; - -@Mixin( - value = EntityPlayerSP.class, - remap = false -) -public abstract class EntityPlayerSPMixin { - - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void displayGUIEditSign(TileEntitySign tile) { - Guis.EDIT_SIGN.open(getPlayer(), tile.x, tile.y, tile.z); - } - - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void displayGUIEditFlag(TileEntityFlag tile) { - Guis.EDIT_FLAG.open(getPlayer(), tile.x, tile.y, tile.z); - } - - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void displayGUIChest(IInventory iinventory) { - GuiHelper.reportVanillaGuiCall("BTA display gui method called"); - } - - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void displayGUIWorkbench(int x, int y, int z) { - Guis.WORKBENCH.open(getPlayer(), x, y, z); - } - - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void displayGUIEditLabel(ItemStack itemstack, int slot) { - Guis.EDIT_LABEL.open(getPlayer(), itemstack); - } - - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void displayGUIPaintingPicker() { - Guis.PAINTING_PICKER.open(getPlayer()); - } - - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void displayGUIMobSpawnerPicker(int x, int y, int z) { - Guis.MOB_SPAWNER_PICKER.open(getPlayer(), x, y, z); - } - - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void displayGUIWandMonsterPicker(ItemStack stack) { - Guis.WAND_MONSTER_PICKER.open(getPlayer(), stack); - } - - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void displayGUIFurnace(TileEntityFurnace tile) { - Guis.FURNACE.open(getPlayer(), tile.x, tile.y, tile.z); - } - - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void displayGUITrommel(TileEntityTrommel tile) { - Guis.TROMMEL.open(getPlayer(), tile.x, tile.y, tile.z); - } - - /** - * @author kill05 - * @reason gui rewrite - */ - @Overwrite - public void displayGUIDispenser(TileEntityDispenser tile) { - Guis.DISPENSER.open(getPlayer(), tile.x, tile.y, tile.z); - } - - - @Unique - private EntityPlayerSP getPlayer() { - return (EntityPlayerSP) ((Object) this); - } - -} diff --git a/src/main/java/turniplabs/halplibe/mixin/mixins/gui/PlayerManager_PlayerInstanceMixin.java b/src/main/java/turniplabs/halplibe/mixin/mixins/gui/PlayerManager_PlayerInstanceMixin.java deleted file mode 100644 index 1428cf6..0000000 --- a/src/main/java/turniplabs/halplibe/mixin/mixins/gui/PlayerManager_PlayerInstanceMixin.java +++ /dev/null @@ -1,24 +0,0 @@ -package turniplabs.halplibe.mixin.mixins.gui; - -import net.minecraft.core.block.entity.TileEntity; -import net.minecraft.core.net.packet.Packet; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin( - targets = "net.minecraft.server.player.PlayerManager$PlayerInstance", - remap = false -) -public abstract class PlayerManager_PlayerInstanceMixin { - - @Redirect( - method = "updateTileEntity", - at = @At(value = "INVOKE", target = "Lnet/minecraft/core/block/entity/TileEntity;getDescriptionPacket()Lnet/minecraft/core/net/packet/Packet;") - ) - public Packet redirectUpdateTileEntity(TileEntity tile) { - Packet packet = tile.getDescriptionPacket(); - if(packet == null) throw new IllegalStateException(String.format("Tile entity '%s' returned null description packet.", tile)); - return packet; - } -} diff --git a/src/main/resources/halplibe.mixins.json b/src/main/resources/halplibe.mixins.json index ec29539..763b684 100644 --- a/src/main/resources/halplibe.mixins.json +++ b/src/main/resources/halplibe.mixins.json @@ -17,9 +17,7 @@ "mixins.ContainerPlayerCreativeMixin", "mixins.I18nMixin", "mixins.StatMixin", - "mixins.TileEntityMixin", "mixins.commands.CommandsCoreMixin", - "mixins.gui.BlockChestMixin", "mixins.network.PacketMixin", "mixins.registry.BlockMixin", "mixins.registry.ItemMixin", @@ -34,7 +32,6 @@ "mixins.MinecraftMixin", "mixins.NetClientHandlerMixin", "mixins.commands.CommandsClientMixin", - "mixins.gui.EntityPlayerSPMixin", "mixins.models.BlockColorDispatcherMixin", "mixins.models.BlockModelDispatcherMixin", "mixins.models.EntityRenderDispatcherMixin", @@ -46,8 +43,6 @@ "server": [ "mixins.MinecraftServerMixin", "mixins.commands.CommandsServerMixin", - "mixins.gui.EntityPlayerMPMixin", - "mixins.gui.PlayerManager_PlayerInstanceMixin", "mixins.network.MinecraftServerMixin", "mixins.version.NetLoginHandlerMixin" ], From 3c976940016d98683abf963c489b42fa9f64c95d Mon Sep 17 00:00:00 2001 From: kill05 Date: Sun, 16 Jun 2024 00:43:25 +0200 Subject: [PATCH 2/7] Removed vanilla gui initialization --- src/main/java/turniplabs/halplibe/HalpLibe.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/turniplabs/halplibe/HalpLibe.java b/src/main/java/turniplabs/halplibe/HalpLibe.java index c87cad3..f3d1131 100644 --- a/src/main/java/turniplabs/halplibe/HalpLibe.java +++ b/src/main/java/turniplabs/halplibe/HalpLibe.java @@ -87,11 +87,6 @@ public void onInitialize() { NetworkHelper.register(PacketOpenGui.class, false, true); NetworkHelper.register(PacketOpenItemGui.class, false, true); NetworkHelper.register(PacketOpenBlockGui.class, false, true); - try { - Class.forName(Guis.class.getName()); // init vanilla guis - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } LOGGER.info("HalpLibe initialized."); } From 243b27e6c9611b731da209c36d951fffe13c37b6 Mon Sep 17 00:00:00 2001 From: kill05 Date: Mon, 17 Jun 2024 02:22:57 +0200 Subject: [PATCH 3/7] Added method --- .../halplibe/helper/gui/registered/RegisteredGui.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java b/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java index 16771db..a406d83 100644 --- a/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java +++ b/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java @@ -2,6 +2,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.entity.player.EntityPlayerSP; +import net.minecraft.core.block.entity.TileEntity; import net.minecraft.core.entity.player.EntityPlayer; import net.minecraft.core.item.ItemStack; import net.minecraft.core.player.inventory.Container; @@ -13,6 +14,7 @@ import turniplabs.halplibe.helper.gui.factory.IGuiFactory; import turniplabs.halplibe.helper.gui.factory.base.GuiFactory; import turniplabs.halplibe.helper.gui.factory.block.BlockGuiFactory; +import turniplabs.halplibe.helper.gui.factory.block.TileGuiFactory; import turniplabs.halplibe.helper.gui.factory.item.ItemGuiFactory; import turniplabs.halplibe.helper.gui.packet.PacketOpenGui; @@ -63,6 +65,13 @@ public void open(@NotNull EntityPlayer player, int x, int y, int z) { open(player, null, x, y, z); } + public void open(@NotNull EntityPlayer player, TileEntity tile) { + if(!(factory instanceof TileGuiFactory)) + throw new IllegalStateException("Gui is not a tile gui!"); + + open(player, null, tile.x, tile.y, tile.z); + } + protected void open(@NotNull EntityPlayer player, @Nullable ItemStack itemStack, int x, int y, int z) { if (player.world.isClientSide && serverSide) return; From 2191bea54a71d5abfe8dbc5debb0c7ca36548507 Mon Sep 17 00:00:00 2001 From: kill05 Date: Mon, 17 Jun 2024 02:50:35 +0200 Subject: [PATCH 4/7] Added missing check --- .../halplibe/helper/gui/factory/block/BlockGuiFactory.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/turniplabs/halplibe/helper/gui/factory/block/BlockGuiFactory.java b/src/main/java/turniplabs/halplibe/helper/gui/factory/block/BlockGuiFactory.java index 5765832..84160a5 100644 --- a/src/main/java/turniplabs/halplibe/helper/gui/factory/block/BlockGuiFactory.java +++ b/src/main/java/turniplabs/halplibe/helper/gui/factory/block/BlockGuiFactory.java @@ -25,6 +25,7 @@ default GuiScreen createGui(@NotNull RegisteredGui gui, @NotNull EntityPlayerSP @Override default @Nullable Container createContainer(@NotNull RegisteredGui gui, @NotNull EntityPlayerMP player, @Nullable ItemStack itemStack, int x, int y, int z) { + if(y < 0) throwInvalidException("y value of block coordinates must be set to a positive value. This either means a wrong value has been used as an argument or that the wrong gui method has been called."); return createContainer(gui, player, x, y, z); } } From 619b9622423c3b6c343d297c28f4e5e732e72fa8 Mon Sep 17 00:00:00 2001 From: kill05 Date: Mon, 17 Jun 2024 03:15:21 +0200 Subject: [PATCH 5/7] Added gui button click logic --- .../java/turniplabs/halplibe/HalpLibe.java | 2 + .../helper/gui/factory/IGuiFactory.java | 5 ++ .../gui/packet/PacketGuiButtonClick.java | 56 +++++++++++++++++++ .../helper/gui/packet/PacketOpenGui.java | 14 ++--- .../helper/gui/registered/RegisteredGui.java | 54 +++++++++++++++--- 5 files changed, 115 insertions(+), 16 deletions(-) create mode 100644 src/main/java/turniplabs/halplibe/helper/gui/packet/PacketGuiButtonClick.java diff --git a/src/main/java/turniplabs/halplibe/HalpLibe.java b/src/main/java/turniplabs/halplibe/HalpLibe.java index f3d1131..1d1bbd3 100644 --- a/src/main/java/turniplabs/halplibe/HalpLibe.java +++ b/src/main/java/turniplabs/halplibe/HalpLibe.java @@ -9,6 +9,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import turniplabs.halplibe.helper.*; +import turniplabs.halplibe.helper.gui.packet.PacketGuiButtonClick; import turniplabs.halplibe.helper.gui.packet.PacketOpenBlockGui; import turniplabs.halplibe.helper.gui.packet.PacketOpenGui; import turniplabs.halplibe.helper.gui.packet.PacketOpenItemGui; @@ -87,6 +88,7 @@ public void onInitialize() { NetworkHelper.register(PacketOpenGui.class, false, true); NetworkHelper.register(PacketOpenItemGui.class, false, true); NetworkHelper.register(PacketOpenBlockGui.class, false, true); + NetworkHelper.register(PacketGuiButtonClick.class, true, false); LOGGER.info("HalpLibe initialized."); } diff --git a/src/main/java/turniplabs/halplibe/helper/gui/factory/IGuiFactory.java b/src/main/java/turniplabs/halplibe/helper/gui/factory/IGuiFactory.java index 289955d..e5f734e 100644 --- a/src/main/java/turniplabs/halplibe/helper/gui/factory/IGuiFactory.java +++ b/src/main/java/turniplabs/halplibe/helper/gui/factory/IGuiFactory.java @@ -2,6 +2,7 @@ import net.minecraft.client.entity.player.EntityPlayerSP; import net.minecraft.client.gui.GuiScreen; +import net.minecraft.core.entity.player.EntityPlayer; import net.minecraft.core.item.ItemStack; import net.minecraft.core.player.inventory.Container; import net.minecraft.server.entity.player.EntityPlayerMP; @@ -18,6 +19,10 @@ public interface IGuiFactory { @Nullable Container createContainer(@NotNull RegisteredGui gui, @NotNull EntityPlayerMP player, @Nullable ItemStack itemStack, int x, int y, int z); + default void onButtonPress(@NotNull RegisteredGui gui, @NotNull EntityPlayer player, int button) { + + } + default @NotNull GuiScreen createGui(@NotNull RegisteredGui gui, @NotNull EntityPlayerSP player, @NotNull PacketOpenGui packet) { if(!gui.isServerSide()) throw new IllegalStateException("Gui is client side!"); diff --git a/src/main/java/turniplabs/halplibe/helper/gui/packet/PacketGuiButtonClick.java b/src/main/java/turniplabs/halplibe/helper/gui/packet/PacketGuiButtonClick.java new file mode 100644 index 0000000..c9639cd --- /dev/null +++ b/src/main/java/turniplabs/halplibe/helper/gui/packet/PacketGuiButtonClick.java @@ -0,0 +1,56 @@ +package turniplabs.halplibe.helper.gui.packet; + +import net.minecraft.core.net.handler.NetHandler; +import net.minecraft.core.net.packet.Packet; +import net.minecraft.server.entity.player.EntityPlayerMP; +import org.apache.commons.lang3.reflect.FieldUtils; +import turniplabs.halplibe.helper.gui.GuiHelper; +import turniplabs.halplibe.helper.gui.registered.RegisteredGui; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class PacketGuiButtonClick extends Packet { + + public String guiNamespace; + public int id; + + public PacketGuiButtonClick(String guiNamespace, int id) { + this.guiNamespace = guiNamespace; + this.id = id; + } + + public PacketGuiButtonClick() { + } + + + @Override + public void readPacketData(DataInputStream input) throws IOException { + this.guiNamespace = input.readUTF(); + this.id = input.readInt(); + } + + @Override + public void writePacketData(DataOutputStream output) throws IOException { + if(guiNamespace == null) throw new IOException("GUI Namespace can't be null!"); + output.writeUTF(guiNamespace); + output.writeInt(id); + } + + @Override + public void processPacket(NetHandler netHandler) { + try { + EntityPlayerMP playerMP = (EntityPlayerMP) FieldUtils.readField(netHandler, "playerEntity", true); + RegisteredGui gui = GuiHelper.getGui(guiNamespace); + gui.getFactory().onButtonPress(gui, playerMP, id); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + @Override + public int getPacketSize() { + return guiNamespace.length() + 4; + } +} diff --git a/src/main/java/turniplabs/halplibe/helper/gui/packet/PacketOpenGui.java b/src/main/java/turniplabs/halplibe/helper/gui/packet/PacketOpenGui.java index f41ea65..6f23a3f 100644 --- a/src/main/java/turniplabs/halplibe/helper/gui/packet/PacketOpenGui.java +++ b/src/main/java/turniplabs/halplibe/helper/gui/packet/PacketOpenGui.java @@ -12,11 +12,11 @@ public class PacketOpenGui extends Packet { - public String namespace; + public String guiNamespace; public int windowId; public PacketOpenGui(@NotNull RegisteredGui gui, int windowId) { - this.namespace = gui.getNamespace(); + this.guiNamespace = gui.getNamespace(); this.windowId = windowId; } @@ -26,24 +26,24 @@ public PacketOpenGui() { @Override public void readPacketData(DataInputStream input) throws IOException { - this.namespace = input.readUTF(); + this.guiNamespace = input.readUTF(); this.windowId = input.readByte(); } @Override public void writePacketData(DataOutputStream output) throws IOException { - if(namespace == null) throw new IOException("Namespace can't be null!"); - output.writeUTF(namespace); + if(guiNamespace == null) throw new IOException("GUI Namespace can't be null!"); + output.writeUTF(guiNamespace); output.writeByte(windowId); } @Override public void processPacket(NetHandler netHandler) { - GuiHelper.getGui(namespace).openPacket(this); + GuiHelper.getGui(guiNamespace).handleOpenPacket(this); } @Override public int getPacketSize() { - return namespace.length() + 1; + return guiNamespace.length() + 1; } } diff --git a/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java b/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java index a406d83..d8c511a 100644 --- a/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java +++ b/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java @@ -1,12 +1,17 @@ package turniplabs.halplibe.helper.gui.registered; import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.player.EntityClientPlayerMP; import net.minecraft.client.entity.player.EntityPlayerSP; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; import net.minecraft.core.block.entity.TileEntity; import net.minecraft.core.entity.player.EntityPlayer; import net.minecraft.core.item.ItemStack; import net.minecraft.core.player.inventory.Container; +import net.minecraft.core.util.helper.Listener; import net.minecraft.server.entity.player.EntityPlayerMP; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import turniplabs.halplibe.HalpLibe; @@ -16,8 +21,11 @@ import turniplabs.halplibe.helper.gui.factory.block.BlockGuiFactory; import turniplabs.halplibe.helper.gui.factory.block.TileGuiFactory; import turniplabs.halplibe.helper.gui.factory.item.ItemGuiFactory; +import turniplabs.halplibe.helper.gui.packet.PacketGuiButtonClick; import turniplabs.halplibe.helper.gui.packet.PacketOpenGui; +import java.util.ArrayList; +import java.util.List; import java.util.Random; import java.util.regex.Pattern; @@ -40,33 +48,33 @@ public RegisteredGui(@NotNull String modId, @NotNull String id, @NotNull IGuiFac if (!ID_PATTERN.matcher(modId + id).matches()) throw new IllegalArgumentException(String.format("Invalid namespace: %s. Must match the following regex '[a-zA-Z0-9_-]+'.", getNamespace())); - if(GuiHelper.REGISTRY.getItem(getNamespace()) != null) + if (GuiHelper.REGISTRY.getItem(getNamespace()) != null) throw new IllegalArgumentException(String.format("Duplicate namespace: %s.", getNamespace())); } public void open(@NotNull EntityPlayer player) { - if(!(factory instanceof GuiFactory)) + if (!(factory instanceof GuiFactory)) throw new IllegalStateException("Gui is not an item gui!"); open(player, null, 0, -100, 0); } public void open(@NotNull EntityPlayer player, @NotNull ItemStack itemStack) { - if(!(factory instanceof ItemGuiFactory)) + if (!(factory instanceof ItemGuiFactory)) throw new IllegalStateException("Gui is not an item gui!"); open(player, itemStack, 0, -100, 0); } public void open(@NotNull EntityPlayer player, int x, int y, int z) { - if(!(factory instanceof BlockGuiFactory)) + if (!(factory instanceof BlockGuiFactory)) throw new IllegalStateException("Gui is not a block gui!"); open(player, null, x, y, z); } public void open(@NotNull EntityPlayer player, TileEntity tile) { - if(!(factory instanceof TileGuiFactory)) + if (!(factory instanceof TileGuiFactory)) throw new IllegalStateException("Gui is not a tile gui!"); open(player, null, tile.x, tile.y, tile.z); @@ -76,12 +84,14 @@ protected void open(@NotNull EntityPlayer player, @Nullable ItemStack itemStack, if (player.world.isClientSide && serverSide) return; if (player instanceof EntityPlayerSP) { - Minecraft.getMinecraft(Minecraft.class).displayGuiScreen(factory.createGui(this, (EntityPlayerSP) player, itemStack, x, y, z)); + EntityPlayerSP playerSP = (EntityPlayerSP) player; + GuiScreen gui = factory.createGui(this, playerSP, itemStack, x, y, z); + Minecraft.getMinecraft(RegisteredGui.class).displayGuiScreen(addButtonListeners(gui, playerSP)); return; } if (player instanceof EntityPlayerMP) { - if(!serverSide) return; + if (!serverSide) return; EntityPlayerMP playerMP = (EntityPlayerMP) player; int windowId = RANDOM.nextInt(100); @@ -100,10 +110,36 @@ protected void open(@NotNull EntityPlayer player, @Nullable ItemStack itemStack, HalpLibe.LOGGER.warn("Tried to open a gui for invalid EntityPlayer: " + player); } - public void openPacket(@NotNull PacketOpenGui packet) { + private GuiScreen addButtonListeners(GuiScreen gui, EntityPlayerSP playerSP) { + List ids = new ArrayList<>(gui.controlList.size()); + for (GuiButton button : gui.controlList) { + if (ids.contains(button.id)) + throw new IllegalStateException(String.format("Found button in gui '%s' with duplicate id: '%s'.", gui, button.id)); + + final Listener oldListener = button.listener; + button.setListener(aButton -> { + if (playerSP instanceof EntityClientPlayerMP) { + EntityClientPlayerMP playerMP = (EntityClientPlayerMP) playerSP; + playerMP.sendQueue.addToSendQueue(new PacketGuiButtonClick(getNamespace(), aButton.id)); + } + + factory.onButtonPress(this, playerSP, aButton.id); + if(oldListener != null) oldListener.listen(aButton); + }); + + ids.add(button.id); + } + + return gui; + } + + @ApiStatus.Internal + public void handleOpenPacket(@NotNull PacketOpenGui packet) { Minecraft mc = Minecraft.getMinecraft(RegisteredGui.class); EntityPlayerSP player = mc.thePlayer; - mc.displayGuiScreen(factory.createGui(this, player, packet)); + GuiScreen gui = factory.createGui(this, player, packet); + + mc.displayGuiScreen(addButtonListeners(gui, player)); player.craftingInventory.windowId = packet.windowId; } From dec317d5f85549e330aae850c59c70e914be70dc Mon Sep 17 00:00:00 2001 From: kill05 Date: Mon, 17 Jun 2024 12:00:20 +0200 Subject: [PATCH 6/7] Fixed button click handler --- .../halplibe/helper/gui/GuiHelper.java | 4 +- .../helper/gui/registered/RegisteredGui.java | 45 +++-------- .../accessors/gui/GuiScreenAccessor.java | 20 +++++ .../mixin/mixins/gui/GuiScreenMixin.java | 74 +++++++++++++++++++ src/main/resources/halplibe.mixins.json | 1 + 5 files changed, 109 insertions(+), 35 deletions(-) create mode 100644 src/main/java/turniplabs/halplibe/mixin/accessors/gui/GuiScreenAccessor.java create mode 100644 src/main/java/turniplabs/halplibe/mixin/mixins/gui/GuiScreenMixin.java diff --git a/src/main/java/turniplabs/halplibe/helper/gui/GuiHelper.java b/src/main/java/turniplabs/halplibe/helper/gui/GuiHelper.java index 4132b1c..0bc79a5 100644 --- a/src/main/java/turniplabs/halplibe/helper/gui/GuiHelper.java +++ b/src/main/java/turniplabs/halplibe/helper/gui/GuiHelper.java @@ -3,6 +3,7 @@ import net.minecraft.core.data.registry.Registry; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import turniplabs.halplibe.HalpLibe; import turniplabs.halplibe.helper.gui.factory.IGuiFactory; import turniplabs.halplibe.helper.gui.registered.RegisteredGui; @@ -29,7 +30,8 @@ public static RegisteredGui getGui(@NotNull String modId, @NotNull String guiId) return REGISTRY.getItem(modId + ":" + guiId); } - public static RegisteredGui getGui(@NotNull String namespace) { + public static RegisteredGui getGui(@Nullable String namespace) { + if(namespace == null) return null; return REGISTRY.getItem(namespace); } diff --git a/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java b/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java index d8c511a..55c5f61 100644 --- a/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java +++ b/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java @@ -1,15 +1,12 @@ package turniplabs.halplibe.helper.gui.registered; import net.minecraft.client.Minecraft; -import net.minecraft.client.entity.player.EntityClientPlayerMP; import net.minecraft.client.entity.player.EntityPlayerSP; -import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; import net.minecraft.core.block.entity.TileEntity; import net.minecraft.core.entity.player.EntityPlayer; import net.minecraft.core.item.ItemStack; import net.minecraft.core.player.inventory.Container; -import net.minecraft.core.util.helper.Listener; import net.minecraft.server.entity.player.EntityPlayerMP; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -21,11 +18,9 @@ import turniplabs.halplibe.helper.gui.factory.block.BlockGuiFactory; import turniplabs.halplibe.helper.gui.factory.block.TileGuiFactory; import turniplabs.halplibe.helper.gui.factory.item.ItemGuiFactory; -import turniplabs.halplibe.helper.gui.packet.PacketGuiButtonClick; import turniplabs.halplibe.helper.gui.packet.PacketOpenGui; +import turniplabs.halplibe.mixin.accessors.gui.GuiScreenAccessor; -import java.util.ArrayList; -import java.util.List; import java.util.Random; import java.util.regex.Pattern; @@ -85,8 +80,7 @@ protected void open(@NotNull EntityPlayer player, @Nullable ItemStack itemStack, if (player instanceof EntityPlayerSP) { EntityPlayerSP playerSP = (EntityPlayerSP) player; - GuiScreen gui = factory.createGui(this, playerSP, itemStack, x, y, z); - Minecraft.getMinecraft(RegisteredGui.class).displayGuiScreen(addButtonListeners(gui, playerSP)); + setupAndOpenGui(factory.createGui(this, playerSP, itemStack, x, y, z)); return; } @@ -110,39 +104,22 @@ protected void open(@NotNull EntityPlayer player, @Nullable ItemStack itemStack, HalpLibe.LOGGER.warn("Tried to open a gui for invalid EntityPlayer: " + player); } - private GuiScreen addButtonListeners(GuiScreen gui, EntityPlayerSP playerSP) { - List ids = new ArrayList<>(gui.controlList.size()); - for (GuiButton button : gui.controlList) { - if (ids.contains(button.id)) - throw new IllegalStateException(String.format("Found button in gui '%s' with duplicate id: '%s'.", gui, button.id)); - - final Listener oldListener = button.listener; - button.setListener(aButton -> { - if (playerSP instanceof EntityClientPlayerMP) { - EntityClientPlayerMP playerMP = (EntityClientPlayerMP) playerSP; - playerMP.sendQueue.addToSendQueue(new PacketGuiButtonClick(getNamespace(), aButton.id)); - } - - factory.onButtonPress(this, playerSP, aButton.id); - if(oldListener != null) oldListener.listen(aButton); - }); - - ids.add(button.id); - } - - return gui; - } - @ApiStatus.Internal public void handleOpenPacket(@NotNull PacketOpenGui packet) { Minecraft mc = Minecraft.getMinecraft(RegisteredGui.class); EntityPlayerSP player = mc.thePlayer; - GuiScreen gui = factory.createGui(this, player, packet); - - mc.displayGuiScreen(addButtonListeners(gui, player)); + setupAndOpenGui(factory.createGui(this, player, packet)); player.craftingInventory.windowId = packet.windowId; } + private void setupAndOpenGui(GuiScreen gui) { + ((GuiScreenAccessor) gui).setRegisteredGui(this); + Minecraft mc = Minecraft.getMinecraft(RegisteredGui.class); + mc.displayGuiScreen(gui); + } + + + public String getModId() { return modId; diff --git a/src/main/java/turniplabs/halplibe/mixin/accessors/gui/GuiScreenAccessor.java b/src/main/java/turniplabs/halplibe/mixin/accessors/gui/GuiScreenAccessor.java new file mode 100644 index 0000000..3ea301e --- /dev/null +++ b/src/main/java/turniplabs/halplibe/mixin/accessors/gui/GuiScreenAccessor.java @@ -0,0 +1,20 @@ +package turniplabs.halplibe.mixin.accessors.gui; + +import turniplabs.halplibe.helper.gui.GuiHelper; +import turniplabs.halplibe.helper.gui.registered.RegisteredGui; + +public interface GuiScreenAccessor { + + void setGuiNamespace(String namespace); + + String getGuiNamespace(); + + default void setRegisteredGui(RegisteredGui gui) { + setGuiNamespace(gui.getNamespace()); + } + + default RegisteredGui getRegisteredGui() { + return GuiHelper.getGui(getGuiNamespace()); + } + +} diff --git a/src/main/java/turniplabs/halplibe/mixin/mixins/gui/GuiScreenMixin.java b/src/main/java/turniplabs/halplibe/mixin/mixins/gui/GuiScreenMixin.java new file mode 100644 index 0000000..2c3493e --- /dev/null +++ b/src/main/java/turniplabs/halplibe/mixin/mixins/gui/GuiScreenMixin.java @@ -0,0 +1,74 @@ +package turniplabs.halplibe.mixin.mixins.gui; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.player.EntityClientPlayerMP; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.core.util.helper.Listener; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +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; +import turniplabs.halplibe.helper.gui.packet.PacketGuiButtonClick; +import turniplabs.halplibe.helper.gui.registered.RegisteredGui; +import turniplabs.halplibe.mixin.accessors.gui.GuiScreenAccessor; + +import java.util.ArrayList; +import java.util.List; + +@SuppressWarnings("AddedMixinMembersNamePattern") +@Mixin( + value = GuiScreen.class, + remap = false +) +public class GuiScreenMixin implements GuiScreenAccessor { + + @Unique + private String guiNamespace; + + @Shadow + public List controlList; + + + @Inject( + method = "init", + at = @At("RETURN") + ) + public void injectInit(CallbackInfo ci) { + Minecraft mc = Minecraft.getMinecraft(GuiScreenMixin.class); + RegisteredGui gui = getRegisteredGui(); + if(gui == null) return; + + List ids = new ArrayList<>(controlList.size()); + for (GuiButton button : controlList) { + if (ids.contains(button.id)) + throw new IllegalStateException(String.format("Found button in gui '%s' with duplicate id: '%s'.", gui, button.id)); + + final Listener oldListener = button.listener; + button.setListener(aButton -> { + if (mc.thePlayer instanceof EntityClientPlayerMP) { + EntityClientPlayerMP playerMP = (EntityClientPlayerMP) mc.thePlayer; + playerMP.sendQueue.addToSendQueue(new PacketGuiButtonClick(getGuiNamespace(), aButton.id)); + } + + gui.getFactory().onButtonPress(gui, mc.thePlayer, aButton.id); + if(oldListener != null) oldListener.listen(aButton); + }); + + ids.add(button.id); + } + } + + @Override + public void setGuiNamespace(String namespace) { + if(guiNamespace != null) throw new IllegalStateException("Gui namespace has already been set!"); + this.guiNamespace = namespace; + } + + @Override + public String getGuiNamespace() { + return guiNamespace; + } +} diff --git a/src/main/resources/halplibe.mixins.json b/src/main/resources/halplibe.mixins.json index 763b684..656f6f9 100644 --- a/src/main/resources/halplibe.mixins.json +++ b/src/main/resources/halplibe.mixins.json @@ -32,6 +32,7 @@ "mixins.MinecraftMixin", "mixins.NetClientHandlerMixin", "mixins.commands.CommandsClientMixin", + "mixins.gui.GuiScreenMixin", "mixins.models.BlockColorDispatcherMixin", "mixins.models.BlockModelDispatcherMixin", "mixins.models.EntityRenderDispatcherMixin", From 77474f7037da7518da037f7cbc7c66a38d31a0d7 Mon Sep 17 00:00:00 2001 From: kill05 Date: Mon, 17 Jun 2024 22:49:50 +0200 Subject: [PATCH 7/7] More fixes to gui buttons --- .../java/turniplabs/halplibe/HalpLibe.java | 2 +- .../gui/GuiScreenAccessor.java | 3 +- .../helper/gui/factory/IGuiFactory.java | 43 ++++++++++++- .../gui/packet/PacketGuiButtonClick.java | 62 +++++++++++++++---- .../helper/gui/packet/PacketOpenGui.java | 9 ++- .../helper/gui/registered/RegisteredGui.java | 2 +- .../mixin/mixins/gui/GuiScreenMixin.java | 47 ++++++-------- .../turniplabs/halplibe/util/PlayerUtils.java | 22 +++++++ 8 files changed, 142 insertions(+), 48 deletions(-) rename src/main/java/turniplabs/halplibe/{mixin/accessors => helper}/gui/GuiScreenAccessor.java (80%) create mode 100644 src/main/java/turniplabs/halplibe/util/PlayerUtils.java diff --git a/src/main/java/turniplabs/halplibe/HalpLibe.java b/src/main/java/turniplabs/halplibe/HalpLibe.java index 1d1bbd3..579676e 100644 --- a/src/main/java/turniplabs/halplibe/HalpLibe.java +++ b/src/main/java/turniplabs/halplibe/HalpLibe.java @@ -88,7 +88,7 @@ public void onInitialize() { NetworkHelper.register(PacketOpenGui.class, false, true); NetworkHelper.register(PacketOpenItemGui.class, false, true); NetworkHelper.register(PacketOpenBlockGui.class, false, true); - NetworkHelper.register(PacketGuiButtonClick.class, true, false); + NetworkHelper.register(PacketGuiButtonClick.class, true, true); LOGGER.info("HalpLibe initialized."); } diff --git a/src/main/java/turniplabs/halplibe/mixin/accessors/gui/GuiScreenAccessor.java b/src/main/java/turniplabs/halplibe/helper/gui/GuiScreenAccessor.java similarity index 80% rename from src/main/java/turniplabs/halplibe/mixin/accessors/gui/GuiScreenAccessor.java rename to src/main/java/turniplabs/halplibe/helper/gui/GuiScreenAccessor.java index 3ea301e..4a2314c 100644 --- a/src/main/java/turniplabs/halplibe/mixin/accessors/gui/GuiScreenAccessor.java +++ b/src/main/java/turniplabs/halplibe/helper/gui/GuiScreenAccessor.java @@ -1,6 +1,5 @@ -package turniplabs.halplibe.mixin.accessors.gui; +package turniplabs.halplibe.helper.gui; -import turniplabs.halplibe.helper.gui.GuiHelper; import turniplabs.halplibe.helper.gui.registered.RegisteredGui; public interface GuiScreenAccessor { diff --git a/src/main/java/turniplabs/halplibe/helper/gui/factory/IGuiFactory.java b/src/main/java/turniplabs/halplibe/helper/gui/factory/IGuiFactory.java index e5f734e..97e95e0 100644 --- a/src/main/java/turniplabs/halplibe/helper/gui/factory/IGuiFactory.java +++ b/src/main/java/turniplabs/halplibe/helper/gui/factory/IGuiFactory.java @@ -6,6 +6,7 @@ import net.minecraft.core.item.ItemStack; import net.minecraft.core.player.inventory.Container; import net.minecraft.server.entity.player.EntityPlayerMP; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import turniplabs.halplibe.helper.gui.packet.PacketOpenBlockGui; @@ -15,14 +16,52 @@ public interface IGuiFactory { + /** + * Called to create a gui screen on a client. + * + * @param gui the registered gui that needs to create a gui + * @param player the player that will see the gui + * @param itemStack an item, in case the gui is an item gui + * @param x x coordinate, in case the gui is a block gui + * @param y y coordinate, in case the gui is a block gui + * @param z z coordinate, in case the gui is a block gui + * @return a new gui + */ + @ApiStatus.Internal @NotNull GuiScreen createGui(@NotNull RegisteredGui gui, @NotNull EntityPlayerSP player, @Nullable ItemStack itemStack, int x, int y, int z); + /** + * Called to create a gui container on a server. + * + * @param gui the registered gui that needs to create a container + * @param player the player that will open the container + * @param itemStack an item, in case the gui is an item gui + * @param x x coordinate, in case the gui is a block gui + * @param y y coordinate, in case the gui is a block gui + * @param z z coordinate, in case the gui is a block gui + * @return a new container + */ + @ApiStatus.Internal @Nullable Container createContainer(@NotNull RegisteredGui gui, @NotNull EntityPlayerMP player, @Nullable ItemStack itemStack, int x, int y, int z); - default void onButtonPress(@NotNull RegisteredGui gui, @NotNull EntityPlayer player, int button) { + /** + * Called when a gui interaction happens.

+ * The player and clicker parameter are not the same when a client acknowledges + * that another player has pressed a button.

+ * As an example, if player1 clicked a button on a server, + * this method will be called on player2's client + * with player2 as the player argument and player1 as the clicker argument + * + * @param gui the registered gui that was clicked + * @param player the player that acknowledges that a player has pressed a button + * @param clicker the player that clicked the button + * @param buttonId the id of the button + */ + default void onButtonClick(@NotNull RegisteredGui gui, @NotNull EntityPlayer player, @NotNull EntityPlayer clicker, int buttonId) { } + @ApiStatus.Internal default @NotNull GuiScreen createGui(@NotNull RegisteredGui gui, @NotNull EntityPlayerSP player, @NotNull PacketOpenGui packet) { if(!gui.isServerSide()) throw new IllegalStateException("Gui is client side!"); @@ -38,6 +77,7 @@ default void onButtonPress(@NotNull RegisteredGui gui, @NotNull EntityPlayer pla return createGui(gui, player, null, 0, -100, 0); } + @ApiStatus.Internal default @NotNull PacketOpenGui createGuiPacket(@NotNull RegisteredGui gui, int windowId, @NotNull EntityPlayerMP player, @Nullable ItemStack itemStack, int x, int y, int z) { if(!gui.isServerSide()) throw new IllegalStateException("Gui is client side!"); @@ -52,6 +92,7 @@ default void onButtonPress(@NotNull RegisteredGui gui, @NotNull EntityPlayer pla return new PacketOpenGui(gui, windowId); } + @ApiStatus.Internal default void throwInvalidException(String message) { throw new IllegalArgumentException(String.format("Invalid arguments for gui factory '%s': %s", getClass(), message)); } diff --git a/src/main/java/turniplabs/halplibe/helper/gui/packet/PacketGuiButtonClick.java b/src/main/java/turniplabs/halplibe/helper/gui/packet/PacketGuiButtonClick.java index c9639cd..f5e6703 100644 --- a/src/main/java/turniplabs/halplibe/helper/gui/packet/PacketGuiButtonClick.java +++ b/src/main/java/turniplabs/halplibe/helper/gui/packet/PacketGuiButtonClick.java @@ -1,11 +1,18 @@ package turniplabs.halplibe.helper.gui.packet; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.player.EntityPlayerSP; +import net.minecraft.client.world.WorldClient; +import net.minecraft.core.entity.Entity; +import net.minecraft.core.entity.player.EntityPlayer; import net.minecraft.core.net.handler.NetHandler; import net.minecraft.core.net.packet.Packet; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.entity.player.EntityPlayerMP; -import org.apache.commons.lang3.reflect.FieldUtils; +import turniplabs.halplibe.HalpLibe; import turniplabs.halplibe.helper.gui.GuiHelper; import turniplabs.halplibe.helper.gui.registered.RegisteredGui; +import turniplabs.halplibe.util.PlayerUtils; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -14,11 +21,17 @@ public class PacketGuiButtonClick extends Packet { public String guiNamespace; - public int id; + public int buttonId; + public int clickerId; - public PacketGuiButtonClick(String guiNamespace, int id) { + public PacketGuiButtonClick(String guiNamespace, int buttonId, int clickerId) { this.guiNamespace = guiNamespace; - this.id = id; + this.buttonId = buttonId; + this.clickerId = clickerId; + } + + public PacketGuiButtonClick(String guiNamespace, int buttonId) { + this(guiNamespace, buttonId, -1); } public PacketGuiButtonClick() { @@ -28,29 +41,52 @@ public PacketGuiButtonClick() { @Override public void readPacketData(DataInputStream input) throws IOException { this.guiNamespace = input.readUTF(); - this.id = input.readInt(); + this.buttonId = input.readInt(); + this.clickerId = input.readInt(); } @Override public void writePacketData(DataOutputStream output) throws IOException { if(guiNamespace == null) throw new IOException("GUI Namespace can't be null!"); output.writeUTF(guiNamespace); - output.writeInt(id); + output.writeInt(buttonId); + output.writeInt(clickerId); } @Override public void processPacket(NetHandler netHandler) { - try { - EntityPlayerMP playerMP = (EntityPlayerMP) FieldUtils.readField(netHandler, "playerEntity", true); - RegisteredGui gui = GuiHelper.getGui(guiNamespace); - gui.getFactory().onButtonPress(gui, playerMP, id); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); + RegisteredGui gui = GuiHelper.getGui(guiNamespace); + if(gui == null) { + HalpLibe.LOGGER.warn("Invalid gui id in packet: " + guiNamespace); + return; } + + EntityPlayer player = PlayerUtils.getPlayer(netHandler); + EntityPlayer clicker = null; + if(player.craftingInventory == null) return; + + if(player instanceof EntityPlayerMP) { + Packet packet = new PacketGuiButtonClick(guiNamespace, buttonId, player.id); + clicker = player; + + for (EntityPlayerMP other : MinecraftServer.getInstance().playerList.playerEntities) { + if(other == player) continue; + if(other.craftingInventory == null || other.craftingInventory.windowId != player.craftingInventory.windowId) continue; + other.playerNetServerHandler.sendPacket(packet); + } + } + + if(player instanceof EntityPlayerSP) { + WorldClient world = (WorldClient) Minecraft.getMinecraft(this).theWorld; + Entity entity = world.getEntityFromId(clickerId); + if(entity instanceof EntityPlayer) clicker = (EntityPlayer) entity; + } + + if(clicker != null) gui.getFactory().onButtonClick(gui, player, clicker, buttonId); } @Override public int getPacketSize() { - return guiNamespace.length() + 4; + return guiNamespace.length() + 4 * 2; } } diff --git a/src/main/java/turniplabs/halplibe/helper/gui/packet/PacketOpenGui.java b/src/main/java/turniplabs/halplibe/helper/gui/packet/PacketOpenGui.java index 6f23a3f..56bd75f 100644 --- a/src/main/java/turniplabs/halplibe/helper/gui/packet/PacketOpenGui.java +++ b/src/main/java/turniplabs/halplibe/helper/gui/packet/PacketOpenGui.java @@ -3,6 +3,7 @@ import net.minecraft.core.net.handler.NetHandler; import net.minecraft.core.net.packet.Packet; import org.jetbrains.annotations.NotNull; +import turniplabs.halplibe.HalpLibe; import turniplabs.halplibe.helper.gui.GuiHelper; import turniplabs.halplibe.helper.gui.registered.RegisteredGui; @@ -39,7 +40,13 @@ public void writePacketData(DataOutputStream output) throws IOException { @Override public void processPacket(NetHandler netHandler) { - GuiHelper.getGui(guiNamespace).handleOpenPacket(this); + RegisteredGui gui = GuiHelper.getGui(guiNamespace); + if(gui == null) { + HalpLibe.LOGGER.warn("Invalid gui id in packet: " + guiNamespace); + return; + } + + gui.handleOpenPacket(this); } @Override diff --git a/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java b/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java index 55c5f61..c7e3081 100644 --- a/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java +++ b/src/main/java/turniplabs/halplibe/helper/gui/registered/RegisteredGui.java @@ -19,7 +19,7 @@ import turniplabs.halplibe.helper.gui.factory.block.TileGuiFactory; import turniplabs.halplibe.helper.gui.factory.item.ItemGuiFactory; import turniplabs.halplibe.helper.gui.packet.PacketOpenGui; -import turniplabs.halplibe.mixin.accessors.gui.GuiScreenAccessor; +import turniplabs.halplibe.helper.gui.GuiScreenAccessor; import java.util.Random; import java.util.regex.Pattern; diff --git a/src/main/java/turniplabs/halplibe/mixin/mixins/gui/GuiScreenMixin.java b/src/main/java/turniplabs/halplibe/mixin/mixins/gui/GuiScreenMixin.java index 2c3493e..a48dfe6 100644 --- a/src/main/java/turniplabs/halplibe/mixin/mixins/gui/GuiScreenMixin.java +++ b/src/main/java/turniplabs/halplibe/mixin/mixins/gui/GuiScreenMixin.java @@ -2,21 +2,20 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.entity.player.EntityClientPlayerMP; +import net.minecraft.client.entity.player.EntityPlayerSP; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; -import net.minecraft.core.util.helper.Listener; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; 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; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import turniplabs.halplibe.helper.gui.GuiScreenAccessor; import turniplabs.halplibe.helper.gui.packet.PacketGuiButtonClick; import turniplabs.halplibe.helper.gui.registered.RegisteredGui; -import turniplabs.halplibe.mixin.accessors.gui.GuiScreenAccessor; -import java.util.ArrayList; -import java.util.List; +import java.util.Iterator; @SuppressWarnings("AddedMixinMembersNamePattern") @Mixin( @@ -28,37 +27,27 @@ public class GuiScreenMixin implements GuiScreenAccessor { @Unique private String guiNamespace; - @Shadow - public List controlList; - - @Inject( - method = "init", - at = @At("RETURN") + method = "mouseClicked", + locals = LocalCapture.CAPTURE_FAILHARD, + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/sound/SoundManager;playSound(Ljava/lang/String;Lnet/minecraft/core/sound/SoundCategory;FF)V", + shift = At.Shift.AFTER + ) ) - public void injectInit(CallbackInfo ci) { - Minecraft mc = Minecraft.getMinecraft(GuiScreenMixin.class); + public void injectMouseClicked(int mouseX, int mouseY, int mouseButton, CallbackInfo ci, Iterator unused, GuiButton button) { RegisteredGui gui = getRegisteredGui(); if(gui == null) return; - List ids = new ArrayList<>(controlList.size()); - for (GuiButton button : controlList) { - if (ids.contains(button.id)) - throw new IllegalStateException(String.format("Found button in gui '%s' with duplicate id: '%s'.", gui, button.id)); - - final Listener oldListener = button.listener; - button.setListener(aButton -> { - if (mc.thePlayer instanceof EntityClientPlayerMP) { - EntityClientPlayerMP playerMP = (EntityClientPlayerMP) mc.thePlayer; - playerMP.sendQueue.addToSendQueue(new PacketGuiButtonClick(getGuiNamespace(), aButton.id)); - } + EntityPlayerSP player = Minecraft.getMinecraft(GuiScreenMixin.class).thePlayer; - gui.getFactory().onButtonPress(gui, mc.thePlayer, aButton.id); - if(oldListener != null) oldListener.listen(aButton); - }); - - ids.add(button.id); + if (player instanceof EntityClientPlayerMP) { + EntityClientPlayerMP playerMP = (EntityClientPlayerMP) player; + playerMP.sendQueue.addToSendQueue(new PacketGuiButtonClick(getGuiNamespace(), button.id)); } + + gui.getFactory().onButtonClick(gui, player, player, button.id); } @Override diff --git a/src/main/java/turniplabs/halplibe/util/PlayerUtils.java b/src/main/java/turniplabs/halplibe/util/PlayerUtils.java new file mode 100644 index 0000000..3fd2f0c --- /dev/null +++ b/src/main/java/turniplabs/halplibe/util/PlayerUtils.java @@ -0,0 +1,22 @@ +package turniplabs.halplibe.util; + +import net.minecraft.client.Minecraft; +import net.minecraft.core.entity.player.EntityPlayer; +import net.minecraft.core.net.handler.NetHandler; +import org.apache.commons.lang3.reflect.FieldUtils; + +public final class PlayerUtils { + + public static EntityPlayer getPlayer(NetHandler handler) { + if(handler.isServerHandler()) { + try { + return (EntityPlayer) FieldUtils.readField(handler, "playerEntity", true); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + return Minecraft.getMinecraft(PlayerUtils.class).thePlayer; + } + +}