Fix shift clicking server error/desync (fixes GH-6)

This commit is contained in:
Cynthia Foxwell 2024-03-25 11:09:52 -06:00
parent 845257d5d2
commit 54aabf557c
4 changed files with 80 additions and 1 deletions

View file

@ -39,7 +39,7 @@ public class ScoutMixin extends AutoMixin {
try { try {
transformers.put(name, (ClassNodeTransformer) Class.forName(type.getClassName()).getDeclaredConstructor().newInstance()); transformers.put(name, (ClassNodeTransformer) Class.forName(type.getClassName()).getDeclaredConstructor().newInstance());
} catch (Exception e) { } 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); return super.shouldAnnotationSkipMixin(name, an);

View file

@ -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<Object> cir) {
var currentPlayer = ScoutUtilServer.getCurrentPlayer();
if (ScoutUtil.isBagSlot(index)) {
if (currentPlayer != null) {
cir.setReturnValue(ScoutUtil.getBagSlot(index, currentPlayer.playerScreenHandler));
} else {
cir.setReturnValue(null);
}
}
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}