From 19ca5a2b73297bbe11a0387cf0831b9f74d6b80f Mon Sep 17 00:00:00 2001 From: ch-yx Date: Tue, 17 Oct 2023 01:02:58 +0800 Subject: [PATCH 01/16] temp step --- .../java/carpet/script/api/Inventories.java | 21 +++++++++++++++++++ .../java/carpet/script/value/ScreenValue.java | 21 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/main/java/carpet/script/api/Inventories.java b/src/main/java/carpet/script/api/Inventories.java index be4e42a32..aed3a5a2a 100644 --- a/src/main/java/carpet/script/api/Inventories.java +++ b/src/main/java/carpet/script/api/Inventories.java @@ -475,6 +475,27 @@ else if (owner instanceof LivingEntity livingEntity) return new ScreenValue(player, type, name, function, c); }); + expression.addContextFunction("get_current_screen", -1, (c, t, lv) -> + { + if (lv.size() < 1) + { + throw new InternalExpressionException("'get_current_screen' requires at least 1 argument"); + } + Value playerValue = lv.get(0); + ServerPlayer player = EntityValue.getPlayerByValue(((CarpetContext) c).server(), playerValue); + if (player == null) + { + throw new InternalExpressionException("'get_current_screen' requires a valid online player as the first argument."); + } + FunctionValue function = null; + if (lv.size() > 1) + { + function = FunctionArgument.findIn(c, expression.module, lv, 1, true, false).function; + } + + return new ScreenValue(player, function, c); + }); + expression.addContextFunction("close_screen", 1, (c, t, lv) -> { Value value = lv.get(0); diff --git a/src/main/java/carpet/script/value/ScreenValue.java b/src/main/java/carpet/script/value/ScreenValue.java index 9ec9ccd79..b8357a815 100644 --- a/src/main/java/carpet/script/value/ScreenValue.java +++ b/src/main/java/carpet/script/value/ScreenValue.java @@ -17,6 +17,7 @@ import java.util.OptionalInt; import net.minecraft.commands.CommandSourceStack; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; @@ -130,6 +131,26 @@ public ScreenValue(ServerPlayer player, String type, Component name, @Nullable F this.inventory = new ScreenHandlerInventory(this.screenHandler); } + public ScreenValue(ServerPlayer player, @Nullable FunctionValue callback, Context c) + { + this.screenHandler = player.containerMenu; + + this.name = Component.literal("seems that the game forgot that");//should i make something like a weak map to remember it? + this.typestring = player.hasContainerOpen()? ValueConversions.simplify(BuiltInRegistries.MENU.getKey(screenHandler.getType())):"inventory"; + + if (callback != null) + { + callback.checkArgs(4); + } + this.callback = callback; + this.hostname = c.host.getName(); + this.scriptServer = (CarpetScriptServer) c.host.scriptServer(); + this.player = player; + + addListenerCallback(screenHandler); + this.inventory = new ScreenHandlerInventory(this.screenHandler); + } + private MenuProvider createScreenHandlerFactory() { if (!screenHandlerFactories.containsKey(this.typestring)) From 2ca7f374313cad2c53d741f47709c92d3af69802 Mon Sep 17 00:00:00 2001 From: ch-yx Date: Tue, 17 Oct 2023 22:36:43 +0800 Subject: [PATCH 02/16] event --- .../carpet/mixins/ServerPlayer_scarpetEventMixin.java | 10 ++++++++++ src/main/java/carpet/script/CarpetEventServer.java | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java b/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java index afba6cde3..b0971cffa 100644 --- a/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java +++ b/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java @@ -2,6 +2,7 @@ import carpet.fakes.EntityInterface; import carpet.fakes.ServerPlayerInterface; +import carpet.script.CarpetEventServer; import carpet.script.EntityEventsGroup; import com.mojang.authlib.GameProfile; import net.minecraft.core.BlockPos; @@ -10,6 +11,7 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.stats.Stat; import net.minecraft.world.InteractionHand; +import net.minecraft.world.MenuProvider; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; @@ -45,6 +47,14 @@ public ServerPlayer_scarpetEventMixin(Level level, BlockPos blockPos, float f, G @Shadow public boolean wonGame; + @Inject(method = "openMenu", at = @At("RETURN")) + private void grabStat(MenuProvider menuProvider, CallbackInfoReturnable cir) + { + if (cir.getReturnValue().isPresent()) { + CarpetEventServer.Event.PLAYER_OPEN_SCREEN.onPlayerEvent((ServerPlayer)(Object)this); + }; + } + @Redirect(method = "completeUsingItem", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;completeUsingItem()V" diff --git a/src/main/java/carpet/script/CarpetEventServer.java b/src/main/java/carpet/script/CarpetEventServer.java index c749b47be..57ed360bf 100644 --- a/src/main/java/carpet/script/CarpetEventServer.java +++ b/src/main/java/carpet/script/CarpetEventServer.java @@ -853,6 +853,17 @@ public void onSlotSwitch(ServerPlayer player, int from, int to) ), player::createCommandSourceStack); } }; + public static final Event PLAYER_OPEN_SCREEN = new Event("player_open_screen", 1, false) + { + @Override + public boolean onPlayerEvent(ServerPlayer player) + { + return handler.call(() -> + Arrays.asList( + new EntityValue(player) + ), player::createCommandSourceStack); + } + }; public static final Event PLAYER_SWAPS_HANDS = new Event("player_swaps_hands", 1, false) { @Override From 414a8a57c98b1e47b46a2c4fb882d23934eb8176 Mon Sep 17 00:00:00 2001 From: ch-yx Date: Wed, 18 Oct 2023 03:52:58 +0800 Subject: [PATCH 03/16] reslove replaceitem s comment --- .../java/carpet/mixins/ServerPlayer_scarpetEventMixin.java | 6 +++--- src/main/java/carpet/script/value/ScreenValue.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java b/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java index b0971cffa..4cbf71b4a 100644 --- a/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java +++ b/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java @@ -2,7 +2,6 @@ import carpet.fakes.EntityInterface; import carpet.fakes.ServerPlayerInterface; -import carpet.script.CarpetEventServer; import carpet.script.EntityEventsGroup; import com.mojang.authlib.GameProfile; import net.minecraft.core.BlockPos; @@ -29,6 +28,7 @@ import static carpet.script.CarpetEventServer.Event.PLAYER_CHANGES_DIMENSION; import static carpet.script.CarpetEventServer.Event.PLAYER_DIES; import static carpet.script.CarpetEventServer.Event.PLAYER_FINISHED_USING_ITEM; +import static carpet.script.CarpetEventServer.Event.PLAYER_OPEN_SCREEN; import static carpet.script.CarpetEventServer.Event.STATISTICS; @Mixin(ServerPlayer.class) @@ -48,10 +48,10 @@ public ServerPlayer_scarpetEventMixin(Level level, BlockPos blockPos, float f, G @Shadow public boolean wonGame; @Inject(method = "openMenu", at = @At("RETURN")) - private void grabStat(MenuProvider menuProvider, CallbackInfoReturnable cir) + private void onOpenScreen(MenuProvider menuProvider, CallbackInfoReturnable cir) { if (cir.getReturnValue().isPresent()) { - CarpetEventServer.Event.PLAYER_OPEN_SCREEN.onPlayerEvent((ServerPlayer)(Object)this); + PLAYER_OPEN_SCREEN.onPlayerEvent((ServerPlayer)(Object)this); }; } diff --git a/src/main/java/carpet/script/value/ScreenValue.java b/src/main/java/carpet/script/value/ScreenValue.java index b8357a815..bb654e57f 100644 --- a/src/main/java/carpet/script/value/ScreenValue.java +++ b/src/main/java/carpet/script/value/ScreenValue.java @@ -135,7 +135,7 @@ public ScreenValue(ServerPlayer player, @Nullable FunctionValue callback, Contex { this.screenHandler = player.containerMenu; - this.name = Component.literal("seems that the game forgot that");//should i make something like a weak map to remember it? + this.name = null; //seems that the game forgot that. should i make something like a weak map to remember it? this.typestring = player.hasContainerOpen()? ValueConversions.simplify(BuiltInRegistries.MENU.getKey(screenHandler.getType())):"inventory"; if (callback != null) From fdc59330ed509191d9fcca46cc11c71dbd2d8bd5 Mon Sep 17 00:00:00 2001 From: ch-yx Date: Wed, 18 Oct 2023 22:18:18 +0800 Subject: [PATCH 04/16] let opening inv fires the event too --- ...erverGamePacketListenerImpl_scarpetEventsMixin.java | 10 ++++++++++ .../carpet/mixins/ServerPlayer_scarpetEventMixin.java | 2 +- src/main/java/carpet/script/value/ScreenValue.java | 6 +++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetEventsMixin.java b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetEventsMixin.java index 550116357..fe2f1d0eb 100644 --- a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetEventsMixin.java +++ b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetEventsMixin.java @@ -28,6 +28,7 @@ import static carpet.script.CarpetEventServer.Event.PLAYER_COMMAND; import static carpet.script.CarpetEventServer.Event.PLAYER_USES_ITEM; import static carpet.script.CarpetEventServer.Event.PLAYER_WAKES_UP; +import static carpet.script.CarpetEventServer.Event.PLAYER_OPEN_SCREEN; import net.minecraft.network.protocol.game.ServerboundContainerButtonClickPacket; import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket; @@ -235,6 +236,15 @@ private void onElytraEngage(ServerboundPlayerCommandPacket clientCommandC2SPacke PLAYER_DEPLOYS_ELYTRA.onPlayerEvent(player); } + @Inject(method = "handlePlayerCommand", at = @At("RETURN"))//"at return" so that the screen can be get by scarpet. + private void onOpenScreen(ServerboundPlayerCommandPacket clientCommandC2SPacket_1, CallbackInfo ci) + { + // doesn't feel efficient..... is "At jump" stable to be use? + if (clientCommandC2SPacket_1.getAction()==net.minecraft.network.protocol.game.ServerboundPlayerCommandPacket.Action.OPEN_INVENTORY) { + PLAYER_OPEN_SCREEN.onPlayerEvent(player); + } + } + @Inject(method = "handleContainerButtonClick", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;resetLastActionTime()V")) private void onItemBeingPickedFromInventory(ServerboundContainerButtonClickPacket packet, CallbackInfo ci) { diff --git a/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java b/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java index 4cbf71b4a..adb9d133e 100644 --- a/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java +++ b/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java @@ -47,7 +47,7 @@ public ServerPlayer_scarpetEventMixin(Level level, BlockPos blockPos, float f, G @Shadow public boolean wonGame; - @Inject(method = "openMenu", at = @At("RETURN")) + @Inject(method = "openMenu", at = @At("RETURN"))//"at return" so that the screen can be get by scarpet. private void onOpenScreen(MenuProvider menuProvider, CallbackInfoReturnable cir) { if (cir.getReturnValue().isPresent()) { diff --git a/src/main/java/carpet/script/value/ScreenValue.java b/src/main/java/carpet/script/value/ScreenValue.java index bb654e57f..20a00e7e1 100644 --- a/src/main/java/carpet/script/value/ScreenValue.java +++ b/src/main/java/carpet/script/value/ScreenValue.java @@ -136,7 +136,7 @@ public ScreenValue(ServerPlayer player, @Nullable FunctionValue callback, Contex this.screenHandler = player.containerMenu; this.name = null; //seems that the game forgot that. should i make something like a weak map to remember it? - this.typestring = player.hasContainerOpen()? ValueConversions.simplify(BuiltInRegistries.MENU.getKey(screenHandler.getType())):"inventory"; + this.typestring = playerScreenTypeName(player); if (callback != null) { @@ -151,6 +151,10 @@ public ScreenValue(ServerPlayer player, @Nullable FunctionValue callback, Contex this.inventory = new ScreenHandlerInventory(this.screenHandler); } + public String playerScreenTypeName(ServerPlayer player) { + return player.hasContainerOpen()? ValueConversions.simplify(BuiltInRegistries.MENU.getKey(screenHandler.getType())):"inventory"; + } + private MenuProvider createScreenHandlerFactory() { if (!screenHandlerFactories.containsKey(this.typestring)) From aae79894f9e53ed95baf515f29c82f7cd21513bd Mon Sep 17 00:00:00 2001 From: ch-yx Date: Thu, 19 Oct 2023 00:54:52 +0800 Subject: [PATCH 05/16] add a type there.... --- src/main/java/carpet/script/CarpetEventServer.java | 4 +++- src/main/java/carpet/script/value/ScreenValue.java | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/carpet/script/CarpetEventServer.java b/src/main/java/carpet/script/CarpetEventServer.java index 57ed360bf..55a551ed8 100644 --- a/src/main/java/carpet/script/CarpetEventServer.java +++ b/src/main/java/carpet/script/CarpetEventServer.java @@ -13,6 +13,7 @@ import carpet.script.value.ListValue; import carpet.script.value.NBTSerializableValue; import carpet.script.value.NumericValue; +import carpet.script.value.ScreenValue; import carpet.script.value.StringValue; import carpet.script.value.Value; import carpet.script.value.ValueConversions; @@ -853,7 +854,7 @@ public void onSlotSwitch(ServerPlayer player, int from, int to) ), player::createCommandSourceStack); } }; - public static final Event PLAYER_OPEN_SCREEN = new Event("player_open_screen", 1, false) + public static final Event PLAYER_OPEN_SCREEN = new Event("player_open_screen", 2, false) { @Override public boolean onPlayerEvent(ServerPlayer player) @@ -861,6 +862,7 @@ public boolean onPlayerEvent(ServerPlayer player) return handler.call(() -> Arrays.asList( new EntityValue(player) + , StringValue.of(ScreenValue.playerScreenTypeName(player)) ), player::createCommandSourceStack); } }; diff --git a/src/main/java/carpet/script/value/ScreenValue.java b/src/main/java/carpet/script/value/ScreenValue.java index 20a00e7e1..a2c8dc2dd 100644 --- a/src/main/java/carpet/script/value/ScreenValue.java +++ b/src/main/java/carpet/script/value/ScreenValue.java @@ -151,8 +151,8 @@ public ScreenValue(ServerPlayer player, @Nullable FunctionValue callback, Contex this.inventory = new ScreenHandlerInventory(this.screenHandler); } - public String playerScreenTypeName(ServerPlayer player) { - return player.hasContainerOpen()? ValueConversions.simplify(BuiltInRegistries.MENU.getKey(screenHandler.getType())):"inventory"; + public static String playerScreenTypeName(ServerPlayer player) { + return player.hasContainerOpen()? ValueConversions.simplify(BuiltInRegistries.MENU.getKey(player.containerMenu.getType())):"inventory"; } private MenuProvider createScreenHandlerFactory() From a72e8e864daf7905dc8eea6c34df5b6f09ac2c35 Mon Sep 17 00:00:00 2001 From: ch-yx Date: Thu, 19 Oct 2023 00:58:32 +0800 Subject: [PATCH 06/16] not good... --- ...erverGamePacketListenerImpl_scarpetEventsMixin.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetEventsMixin.java b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetEventsMixin.java index fe2f1d0eb..550116357 100644 --- a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetEventsMixin.java +++ b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetEventsMixin.java @@ -28,7 +28,6 @@ import static carpet.script.CarpetEventServer.Event.PLAYER_COMMAND; import static carpet.script.CarpetEventServer.Event.PLAYER_USES_ITEM; import static carpet.script.CarpetEventServer.Event.PLAYER_WAKES_UP; -import static carpet.script.CarpetEventServer.Event.PLAYER_OPEN_SCREEN; import net.minecraft.network.protocol.game.ServerboundContainerButtonClickPacket; import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket; @@ -236,15 +235,6 @@ private void onElytraEngage(ServerboundPlayerCommandPacket clientCommandC2SPacke PLAYER_DEPLOYS_ELYTRA.onPlayerEvent(player); } - @Inject(method = "handlePlayerCommand", at = @At("RETURN"))//"at return" so that the screen can be get by scarpet. - private void onOpenScreen(ServerboundPlayerCommandPacket clientCommandC2SPacket_1, CallbackInfo ci) - { - // doesn't feel efficient..... is "At jump" stable to be use? - if (clientCommandC2SPacket_1.getAction()==net.minecraft.network.protocol.game.ServerboundPlayerCommandPacket.Action.OPEN_INVENTORY) { - PLAYER_OPEN_SCREEN.onPlayerEvent(player); - } - } - @Inject(method = "handleContainerButtonClick", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;resetLastActionTime()V")) private void onItemBeingPickedFromInventory(ServerboundContainerButtonClickPacket packet, CallbackInfo ci) { From a7c3a2c7ccb6e35f91c99ba2c29f87fe2ee90717 Mon Sep 17 00:00:00 2001 From: ch-yx Date: Fri, 20 Oct 2023 03:09:10 +0800 Subject: [PATCH 07/16] for special cases... --- src/main/java/carpet/script/value/ScreenValue.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/carpet/script/value/ScreenValue.java b/src/main/java/carpet/script/value/ScreenValue.java index a2c8dc2dd..940b54521 100644 --- a/src/main/java/carpet/script/value/ScreenValue.java +++ b/src/main/java/carpet/script/value/ScreenValue.java @@ -152,7 +152,14 @@ public ScreenValue(ServerPlayer player, @Nullable FunctionValue callback, Contex } public static String playerScreenTypeName(ServerPlayer player) { - return player.hasContainerOpen()? ValueConversions.simplify(BuiltInRegistries.MENU.getKey(player.containerMenu.getType())):"inventory"; + if (!player.hasContainerOpen()) { + return "inventory"; + } + try { + return ValueConversions.simplify(BuiltInRegistries.MENU.getKey(player.containerMenu.getType())); + } catch (java.lang.UnsupportedOperationException e) { + return "unknown"; + } } private MenuProvider createScreenHandlerFactory() From 9632ccd0238fb697fdfe9affef86bd309102b310 Mon Sep 17 00:00:00 2001 From: ch-yx Date: Sun, 22 Oct 2023 04:04:03 +0800 Subject: [PATCH 08/16] why not give it a try? --- .../java/carpet/mixins/ServerPlayer_scarpetEventMixin.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java b/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java index adb9d133e..879b6b0d9 100644 --- a/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java +++ b/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java @@ -54,6 +54,11 @@ private void onOpenScreen(MenuProvider menuProvider, CallbackInfoReturnable Date: Mon, 23 Oct 2023 15:57:45 +0800 Subject: [PATCH 09/16] reduce some unnecessary code --- .../java/carpet/mixins/ServerPlayer_scarpetEventMixin.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java b/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java index 879b6b0d9..675b4ea77 100644 --- a/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java +++ b/src/main/java/carpet/mixins/ServerPlayer_scarpetEventMixin.java @@ -10,7 +10,6 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.stats.Stat; import net.minecraft.world.InteractionHand; -import net.minecraft.world.MenuProvider; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; @@ -48,7 +47,7 @@ public ServerPlayer_scarpetEventMixin(Level level, BlockPos blockPos, float f, G @Shadow public boolean wonGame; @Inject(method = "openMenu", at = @At("RETURN"))//"at return" so that the screen can be get by scarpet. - private void onOpenScreen(MenuProvider menuProvider, CallbackInfoReturnable cir) + private void onOpenScreen(CallbackInfoReturnable cir) { if (cir.getReturnValue().isPresent()) { PLAYER_OPEN_SCREEN.onPlayerEvent((ServerPlayer)(Object)this); From 3c35adffcd2bffd8f76ae464c59d3f432a11768b Mon Sep 17 00:00:00 2001 From: ch-yx Date: Wed, 1 Nov 2023 05:47:38 +0800 Subject: [PATCH 10/16] try to support crafter try to support crafter --- ...cketListenerImpl_scarpetCrafterScreen.java | 30 +++++++++++++++++++ .../java/carpet/script/value/ScreenValue.java | 13 ++++++++ src/main/resources/carpet.mixins.json | 1 + 3 files changed, 44 insertions(+) create mode 100644 src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetCrafterScreen.java diff --git a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetCrafterScreen.java b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetCrafterScreen.java new file mode 100644 index 000000000..3e6ee79e6 --- /dev/null +++ b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetCrafterScreen.java @@ -0,0 +1,30 @@ +package carpet.mixins; + +import net.minecraft.network.protocol.game.ServerboundContainerSlotStateChangedPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.world.inventory.CrafterMenu; +import net.minecraft.world.level.block.entity.CrafterBlockEntity; + +import org.spongepowered.asm.mixin.Mixin; +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; + +@Mixin(ServerGamePacketListenerImpl.class) +public abstract class ServerGamePacketListenerImpl_scarpetCrafterScreen +{ + + @Shadow + public ServerPlayer player; + + @Inject(method = "handleContainerSlotStateChanged", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/CrafterMenu;getContainer()Lnet/minecraft/world/Container;")) + + private void injected(ServerboundContainerSlotStateChangedPacket serverboundContainerSlotStateChangedPacket,CallbackInfo ci) { + CrafterMenu cm =(CrafterMenu)this.player.containerMenu; + if(!(cm.getContainer() instanceof CrafterBlockEntity)){ + cm.setSlotState(serverboundContainerSlotStateChangedPacket.slotId(), serverboundContainerSlotStateChangedPacket.newState()); + }; + } +} diff --git a/src/main/java/carpet/script/value/ScreenValue.java b/src/main/java/carpet/script/value/ScreenValue.java index 940b54521..9da862144 100644 --- a/src/main/java/carpet/script/value/ScreenValue.java +++ b/src/main/java/carpet/script/value/ScreenValue.java @@ -40,6 +40,7 @@ import net.minecraft.world.inventory.ClickType; import net.minecraft.world.inventory.ContainerListener; import net.minecraft.world.inventory.CraftingMenu; +import net.minecraft.world.inventory.CrafterMenu; import net.minecraft.world.inventory.DataSlot; import net.minecraft.world.inventory.EnchantmentMenu; import net.minecraft.world.inventory.FurnaceMenu; @@ -102,6 +103,7 @@ public class ScreenValue extends Value screenHandlerFactories.put("smithing", SmithingMenu::new); screenHandlerFactories.put("smoker", SmokerMenu::new); screenHandlerFactories.put("stonecutter", StonecutterMenu::new); + screenHandlerFactories.put("crafter_3x3", (x,y)->{var m =new CrafterMenu(x,y);m.addSlotListener(m);return m;}); } @@ -348,6 +350,17 @@ private DataSlot getProperty(String propertyName) case "enchantment_level_3" -> getPropertyForType(EnchantmentMenu.class, "enchantment", 9, propertyName); case "banner_pattern" -> getPropertyForType(LoomMenu.class, "loom", 0, propertyName); case "stonecutter_recipe" -> getPropertyForType(StonecutterMenu.class, "stonecutter", 0, propertyName); + case "crafter_slot_disable_0" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 0, propertyName); + case "crafter_slot_disable_1" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 1, propertyName); + case "crafter_slot_disable_2" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 2, propertyName); + case "crafter_slot_disable_3" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 3, propertyName); + case "crafter_slot_disable_4" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 4, propertyName); + case "crafter_slot_disable_5" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 5, propertyName); + case "crafter_slot_disable_6" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 6, propertyName); + case "crafter_slot_disable_7" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 7, propertyName); + case "crafter_slot_disable_8" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 8, propertyName); + case "crafter_enable" -> getPropertyForType(CrafterMenu.class, "crafter_3x3", 9, propertyName); + default -> throw new InternalExpressionException("Invalid screen property: " + propertyName); }; diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index a68896207..de4a31484 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -54,6 +54,7 @@ "Villager_aiMixin", "Player_fakePlayersMixin", "ServerGamePacketListenerImpl_coreMixin", + "ServerGamePacketListenerImpl_scarpetCrafterScreen", "MinecraftServer_scarpetMixin", "ExperienceOrb_xpNoCooldownMixin", "Player_xpNoCooldownMixin", From f45cd0d9a3422d3b0376421b7e405f6ce9bee901 Mon Sep 17 00:00:00 2001 From: ch-yx Date: Sun, 10 Dec 2023 05:05:31 +0800 Subject: [PATCH 11/16] small tweak --- ...ServerGamePacketListenerImpl_scarpetCrafterScreen.java | 4 +++- src/main/java/carpet/script/value/ScreenValue.java | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetCrafterScreen.java b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetCrafterScreen.java index 3e6ee79e6..78a69c3d4 100644 --- a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetCrafterScreen.java +++ b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetCrafterScreen.java @@ -12,6 +12,8 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import carpet.script.value.ScreenValue.CarpetCrafterMenu; + @Mixin(ServerGamePacketListenerImpl.class) public abstract class ServerGamePacketListenerImpl_scarpetCrafterScreen { @@ -23,7 +25,7 @@ public abstract class ServerGamePacketListenerImpl_scarpetCrafterScreen private void injected(ServerboundContainerSlotStateChangedPacket serverboundContainerSlotStateChangedPacket,CallbackInfo ci) { CrafterMenu cm =(CrafterMenu)this.player.containerMenu; - if(!(cm.getContainer() instanceof CrafterBlockEntity)){ + if(cm instanceof CarpetCrafterMenu && !(cm.getContainer() instanceof CrafterBlockEntity)){ cm.setSlotState(serverboundContainerSlotStateChangedPacket.slotId(), serverboundContainerSlotStateChangedPacket.newState()); }; } diff --git a/src/main/java/carpet/script/value/ScreenValue.java b/src/main/java/carpet/script/value/ScreenValue.java index efe9e0d8d..2370f25a9 100644 --- a/src/main/java/carpet/script/value/ScreenValue.java +++ b/src/main/java/carpet/script/value/ScreenValue.java @@ -103,10 +103,16 @@ public class ScreenValue extends Value screenHandlerFactories.put("smithing", SmithingMenu::new); screenHandlerFactories.put("smoker", SmokerMenu::new); screenHandlerFactories.put("stonecutter", StonecutterMenu::new); - screenHandlerFactories.put("crafter_3x3", (x,y)->{var m =new CrafterMenu(x,y);m.addSlotListener(m);return m;}); + screenHandlerFactories.put("crafter_3x3", CarpetCrafterMenu::new); } + public static class CarpetCrafterMenu extends CrafterMenu{ + public CarpetCrafterMenu(int i, Inventory inventory) { + super(i, inventory); + addSlotListener(this); + } + } protected interface ScarpetScreenHandlerFactory { AbstractContainerMenu create(int syncId, Inventory playerInventory); From 3de14edff03cc17499da074ef8706c6635b62ad9 Mon Sep 17 00:00:00 2001 From: ch-yx Date: Sun, 10 Dec 2023 05:36:34 +0800 Subject: [PATCH 12/16] return "horse" when it is horse... --- src/main/java/carpet/script/value/ScreenValue.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/carpet/script/value/ScreenValue.java b/src/main/java/carpet/script/value/ScreenValue.java index 2370f25a9..7effef214 100644 --- a/src/main/java/carpet/script/value/ScreenValue.java +++ b/src/main/java/carpet/script/value/ScreenValue.java @@ -46,6 +46,7 @@ import net.minecraft.world.inventory.FurnaceMenu; import net.minecraft.world.inventory.GrindstoneMenu; import net.minecraft.world.inventory.HopperMenu; +import net.minecraft.world.inventory.HorseInventoryMenu; import net.minecraft.world.inventory.LecternMenu; import net.minecraft.world.inventory.LoomMenu; import net.minecraft.world.inventory.MerchantMenu; @@ -166,6 +167,9 @@ public static String playerScreenTypeName(ServerPlayer player) { try { return ValueConversions.simplify(BuiltInRegistries.MENU.getKey(player.containerMenu.getType())); } catch (java.lang.UnsupportedOperationException e) { + if (player.containerMenu instanceof HorseInventoryMenu) { + return "horse"; + } return "unknown"; } } From 9d1b12e283cd8ef4a0110851d4759bc6e9e3e7d8 Mon Sep 17 00:00:00 2001 From: ch-yx Date: Wed, 27 Dec 2023 05:46:41 +0800 Subject: [PATCH 13/16] small change....:thinking: --- .../ServerGamePacketListenerImpl_scarpetCrafterScreen.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetCrafterScreen.java b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetCrafterScreen.java index 78a69c3d4..0373948c8 100644 --- a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetCrafterScreen.java +++ b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetCrafterScreen.java @@ -3,7 +3,6 @@ import net.minecraft.network.protocol.game.ServerboundContainerSlotStateChangedPacket; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.network.ServerGamePacketListenerImpl; -import net.minecraft.world.inventory.CrafterMenu; import net.minecraft.world.level.block.entity.CrafterBlockEntity; import org.spongepowered.asm.mixin.Mixin; @@ -22,10 +21,8 @@ public abstract class ServerGamePacketListenerImpl_scarpetCrafterScreen public ServerPlayer player; @Inject(method = "handleContainerSlotStateChanged", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/CrafterMenu;getContainer()Lnet/minecraft/world/Container;")) - private void injected(ServerboundContainerSlotStateChangedPacket serverboundContainerSlotStateChangedPacket,CallbackInfo ci) { - CrafterMenu cm =(CrafterMenu)this.player.containerMenu; - if(cm instanceof CarpetCrafterMenu && !(cm.getContainer() instanceof CrafterBlockEntity)){ + if(player.containerMenu instanceof CarpetCrafterMenu cm && !(cm.getContainer() instanceof CrafterBlockEntity)){ cm.setSlotState(serverboundContainerSlotStateChangedPacket.slotId(), serverboundContainerSlotStateChangedPacket.newState()); }; } From dbb30fe11e5ae739b0801f33c187706962c1f12c Mon Sep 17 00:00:00 2001 From: ch-yx Date: Wed, 27 Dec 2023 06:13:32 +0800 Subject: [PATCH 14/16] Still slightly different from the real thing. --- src/main/java/carpet/script/value/ScreenValue.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/carpet/script/value/ScreenValue.java b/src/main/java/carpet/script/value/ScreenValue.java index 7effef214..747619f4b 100644 --- a/src/main/java/carpet/script/value/ScreenValue.java +++ b/src/main/java/carpet/script/value/ScreenValue.java @@ -113,6 +113,7 @@ public CarpetCrafterMenu(int i, Inventory inventory) { super(i, inventory); addSlotListener(this); } + //public void setSlotState(int i, boolean bl) {} //Still slightly different from the real thing. } protected interface ScarpetScreenHandlerFactory { From 0faf2bd3cff1919f6d9bd7644bfa6cbc1798e21a Mon Sep 17 00:00:00 2001 From: ch-yx Date: Sat, 30 Dec 2023 03:29:23 +0800 Subject: [PATCH 15/16] make it more similar to the real one.... --- src/main/java/carpet/script/value/ScreenValue.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/carpet/script/value/ScreenValue.java b/src/main/java/carpet/script/value/ScreenValue.java index 747619f4b..bbc661b22 100644 --- a/src/main/java/carpet/script/value/ScreenValue.java +++ b/src/main/java/carpet/script/value/ScreenValue.java @@ -9,6 +9,8 @@ import carpet.script.exception.ThrowStatement; import carpet.script.exception.Throwables; import carpet.script.external.Vanilla; +import carpet.script.value.ScreenValue.ScarpetScreenHandlerFactory; +import carpet.script.value.ScreenValue.ScreenHandlerInventory; import java.util.Arrays; import java.util.HashMap; @@ -109,11 +111,19 @@ public class ScreenValue extends Value public static class CarpetCrafterMenu extends CrafterMenu{ + private boolean suppress = false; public CarpetCrafterMenu(int i, Inventory inventory) { super(i, inventory); addSlotListener(this); } - //public void setSlotState(int i, boolean bl) {} //Still slightly different from the real thing. + public void broadcastChanges(){ + if(!suppress)super.broadcastChanges(); + } + public void setSlotState(int i, boolean bl) { + suppress = true; + super.setSlotState(i, bl); + suppress = false; + } //Do I really need to go to this point to make them similar? } protected interface ScarpetScreenHandlerFactory { From 5951a5efd45012c6f57d8ef18315d7227e6d05b7 Mon Sep 17 00:00:00 2001 From: ch-yx Date: Sat, 30 Dec 2023 04:35:55 +0800 Subject: [PATCH 16/16] small rename --- ...ServerGamePacketListenerImpl_scarpetCrafterScreen.java | 4 ++-- src/main/java/carpet/script/value/ScreenValue.java | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetCrafterScreen.java b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetCrafterScreen.java index 0373948c8..110d4cfb2 100644 --- a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetCrafterScreen.java +++ b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetCrafterScreen.java @@ -11,7 +11,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import carpet.script.value.ScreenValue.CarpetCrafterMenu; +import carpet.script.value.ScreenValue.ScarpetCrafterMenu; @Mixin(ServerGamePacketListenerImpl.class) public abstract class ServerGamePacketListenerImpl_scarpetCrafterScreen @@ -22,7 +22,7 @@ public abstract class ServerGamePacketListenerImpl_scarpetCrafterScreen @Inject(method = "handleContainerSlotStateChanged", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/CrafterMenu;getContainer()Lnet/minecraft/world/Container;")) private void injected(ServerboundContainerSlotStateChangedPacket serverboundContainerSlotStateChangedPacket,CallbackInfo ci) { - if(player.containerMenu instanceof CarpetCrafterMenu cm && !(cm.getContainer() instanceof CrafterBlockEntity)){ + if(player.containerMenu instanceof ScarpetCrafterMenu cm && !(cm.getContainer() instanceof CrafterBlockEntity)){ cm.setSlotState(serverboundContainerSlotStateChangedPacket.slotId(), serverboundContainerSlotStateChangedPacket.newState()); }; } diff --git a/src/main/java/carpet/script/value/ScreenValue.java b/src/main/java/carpet/script/value/ScreenValue.java index bbc661b22..fcb971e69 100644 --- a/src/main/java/carpet/script/value/ScreenValue.java +++ b/src/main/java/carpet/script/value/ScreenValue.java @@ -106,15 +106,15 @@ public class ScreenValue extends Value screenHandlerFactories.put("smithing", SmithingMenu::new); screenHandlerFactories.put("smoker", SmokerMenu::new); screenHandlerFactories.put("stonecutter", StonecutterMenu::new); - screenHandlerFactories.put("crafter_3x3", CarpetCrafterMenu::new); + screenHandlerFactories.put("crafter_3x3", ScarpetCrafterMenu::new); } - public static class CarpetCrafterMenu extends CrafterMenu{ + public static class ScarpetCrafterMenu extends CrafterMenu{ private boolean suppress = false; - public CarpetCrafterMenu(int i, Inventory inventory) { + public ScarpetCrafterMenu(int i, Inventory inventory) { super(i, inventory); - addSlotListener(this); + addSlotListener(this);// this line it to make the result item can be generated in the output slot. } public void broadcastChanges(){ if(!suppress)super.broadcastChanges();