From 54aabf557c14fcd2e277ffb58d63bd9b0292a496 Mon Sep 17 00:00:00 2001 From: Cynthia Foxwell Date: Mon, 25 Mar 2024 11:09:52 -0600 Subject: [PATCH] Fix shift clicking server error/desync (fixes GH-6) --- src/main/java/pm/c7/scout/ScoutMixin.java | 2 +- .../mixin/server/DefaultedListMixin.java | 28 +++++++++++++++++++ .../mixin/server/ScreenHandlerMixin.java | 26 +++++++++++++++++ .../pm/c7/scout/server/ScoutUtilServer.java | 25 +++++++++++++++++ 4 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/main/java/pm/c7/scout/mixin/server/DefaultedListMixin.java create mode 100644 src/main/java/pm/c7/scout/mixin/server/ScreenHandlerMixin.java create mode 100644 src/main/java/pm/c7/scout/server/ScoutUtilServer.java diff --git a/src/main/java/pm/c7/scout/ScoutMixin.java b/src/main/java/pm/c7/scout/ScoutMixin.java index e1f198d..9497447 100644 --- a/src/main/java/pm/c7/scout/ScoutMixin.java +++ b/src/main/java/pm/c7/scout/ScoutMixin.java @@ -39,7 +39,7 @@ public class ScoutMixin extends AutoMixin { try { transformers.put(name, (ClassNodeTransformer) Class.forName(type.getClassName()).getDeclaredConstructor().newInstance()); } catch (Exception e) { - LOGGER.error("Transformer class for mixin {} not found", name, e); + LOGGER.error("[Scout] Transformer class for mixin {} not found", name, e); } } return super.shouldAnnotationSkipMixin(name, an); diff --git a/src/main/java/pm/c7/scout/mixin/server/DefaultedListMixin.java b/src/main/java/pm/c7/scout/mixin/server/DefaultedListMixin.java new file mode 100644 index 0000000..73d920c --- /dev/null +++ b/src/main/java/pm/c7/scout/mixin/server/DefaultedListMixin.java @@ -0,0 +1,28 @@ +package pm.c7.scout.mixin.server; + +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; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.util.collection.DefaultedList; +import pm.c7.scout.ScoutUtil; +import pm.c7.scout.server.ScoutUtilServer; + +@Environment(EnvType.SERVER) +@Mixin(DefaultedList.class) +public class DefaultedListMixin { + @Inject(method = "get", at = @At("HEAD"), cancellable = true) + public void scout$fixIndexingSlots(int index, CallbackInfoReturnable cir) { + var currentPlayer = ScoutUtilServer.getCurrentPlayer(); + if (ScoutUtil.isBagSlot(index)) { + if (currentPlayer != null) { + cir.setReturnValue(ScoutUtil.getBagSlot(index, currentPlayer.playerScreenHandler)); + } else { + cir.setReturnValue(null); + } + } + } +} diff --git a/src/main/java/pm/c7/scout/mixin/server/ScreenHandlerMixin.java b/src/main/java/pm/c7/scout/mixin/server/ScreenHandlerMixin.java new file mode 100644 index 0000000..07cde2d --- /dev/null +++ b/src/main/java/pm/c7/scout/mixin/server/ScreenHandlerMixin.java @@ -0,0 +1,26 @@ +package pm.c7.scout.mixin.server; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.screen.ScreenHandler; +import net.minecraft.screen.slot.SlotActionType; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; +import pm.c7.scout.server.ScoutUtilServer; + +@Environment(EnvType.SERVER) +@Mixin(value = ScreenHandler.class) +public abstract class ScreenHandlerMixin { + @Redirect(method = "internalOnSlotClick", at = @At(value = "INVOKE", target = "Lnet/minecraft/screen/ScreenHandler;quickMove(Lnet/minecraft/entity/player/PlayerEntity;I)Lnet/minecraft/item/ItemStack;")) + public ItemStack scout$fixQuickMove(ScreenHandler self, PlayerEntity player, int index, int slotIndex, int button, SlotActionType actionType, PlayerEntity playerAgain) { + ScoutUtilServer.setCurrentPlayer(player); + ItemStack ret = self.quickMove(player, index); + ScoutUtilServer.clearCurrentPlayer(); + + return ret; + } +} diff --git a/src/main/java/pm/c7/scout/server/ScoutUtilServer.java b/src/main/java/pm/c7/scout/server/ScoutUtilServer.java new file mode 100644 index 0000000..7312cb4 --- /dev/null +++ b/src/main/java/pm/c7/scout/server/ScoutUtilServer.java @@ -0,0 +1,25 @@ +package pm.c7.scout.server; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.entity.player.PlayerEntity; +import pm.c7.scout.ScoutUtil; + +public class ScoutUtilServer { + private static PlayerEntity currentPlayer = null; + + public static void setCurrentPlayer(PlayerEntity player) { + if (currentPlayer != null) { + ScoutUtil.LOGGER.warn("[Scout] New player set during existing quick move, expect players getting wrong items!"); + } + currentPlayer = player; + } + + public static void clearCurrentPlayer() { + currentPlayer = null; + } + + public static @Nullable PlayerEntity getCurrentPlayer() { + return currentPlayer; + } +}