diff --git a/src/main/java/dev/dubhe/gugle/carpet/mixin/EntityMixin.java b/src/main/java/dev/dubhe/gugle/carpet/mixin/EntityMixin.java deleted file mode 100644 index ed18783..0000000 --- a/src/main/java/dev/dubhe/gugle/carpet/mixin/EntityMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package dev.dubhe.gugle.carpet.mixin; - -import dev.dubhe.gugle.carpet.GcaSetting; -import net.minecraft.client.player.RemotePlayer; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.player.Player; -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(Entity.class) -public class EntityMixin { - @SuppressWarnings("ConstantValue") - @Inject(method = "interact", at = @At("HEAD"), cancellable = true) - private void interact(Player player, InteractionHand interactionHand, CallbackInfoReturnable cir) { - // 在客户端中,玩家可以与客户端的被交互玩家交互并返回PASS,这时交互玩家手上如果拿着可以使用的物品,则物品会被使用 - // 所以如果判断被交互实体是客户端玩家,返回SUCCESS - if ((Object) this instanceof RemotePlayer && (GcaSetting.openFakePlayerInventory || GcaSetting.openFakePlayerEnderChest)) { - cir.setReturnValue(InteractionResult.SUCCESS); - } - } -} diff --git a/src/main/java/dev/dubhe/gugle/carpet/mixin/PlayerMixin.java b/src/main/java/dev/dubhe/gugle/carpet/mixin/PlayerMixin.java index 5911c67..e712820 100644 --- a/src/main/java/dev/dubhe/gugle/carpet/mixin/PlayerMixin.java +++ b/src/main/java/dev/dubhe/gugle/carpet/mixin/PlayerMixin.java @@ -26,7 +26,7 @@ @Mixin(Player.class) abstract class PlayerMixin { @Unique - Player gca$self = (Player) (Object) this; + private final Player gca$self = (Player) (Object) this; @Inject(method = "tick", at = @At("RETURN")) private void tick(CallbackInfo ci) { @@ -40,16 +40,35 @@ private void tick(CallbackInfo ci) { @WrapOperation(method = "interactOn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;interact(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/InteractionHand;)Lnet/minecraft/world/InteractionResult;")) private InteractionResult interactOn(Entity entity, Player player, InteractionHand hand, Operation original) { + // 此处不能直接使用entity instanceof EntityPlayerMPFake + // 第一次entity instanceof Player是为了排除掉非玩家实体,避免影响非玩家实体的交互逻辑,第二次instanceof在interact方法中,用来判断交互玩家是否为假玩家 + // 在服务端,entity instanceof Player可能是多余的 + // 但是在客户端中,如果直接entity instanceof EntityPlayerMPFake,那么在右键假玩家时,客户端并不知道当前交互的玩家是不是假玩家 + // 因此右键交互时可能会应用玩家手中的物品功能,例如使用熔岩桶右键玩家时可能在假玩家位置放置岩浆,使用风弹右键玩家时可能发射风弹 + // 所以客户端在交互前要先判断一下当前交互的实体是不是玩家,这用来防止意外的使用物品功能 + // 尽管这带来了一些新的问题,例如玩家飞行时不能对着玩家使用烟花,不能对着玩家吃食物,但是这相比意外使用物品是小问题 + if (entity instanceof Player interactPlayer && (GcaSetting.openFakePlayerInventory || GcaSetting.openFakePlayerEnderChest)) { + return interact(interactPlayer, player, hand, original); + } + return original.call(entity, player, hand); + } + + @Unique + private InteractionResult interact(Player entity, Player player, InteractionHand hand, Operation original) { + InteractionResult result; if (entity instanceof EntityPlayerMPFake fakePlayer) { // 打开物品栏 - return this.openInventory(player, fakePlayer); + result = this.openInventory(player, fakePlayer); + } else { + // 怎么判断一个客户端玩家是不是假玩家? + return InteractionResult.SUCCESS; } - return original.call(entity, player, hand); + return result == InteractionResult.PASS ? original.call(entity, player, hand) : result; } @Unique private InteractionResult openInventory(Player player, EntityPlayerMPFake fakePlayer) { - SimpleMenuProvider provider = null; + SimpleMenuProvider provider; if (player.isShiftKeyDown()) { // 打开末影箱 if (GcaSetting.openFakePlayerEnderChest) { @@ -79,9 +98,7 @@ private InteractionResult openInventory(Player player, EntityPlayerMPFake fakePl ), ComponentTranslate.trans("gca.player.inventory", fakePlayer.getDisplayName()) ); - } - - if (provider == null) { + } else { return InteractionResult.PASS; } player.openMenu(provider); diff --git a/src/main/java/dev/dubhe/gugle/carpet/tools/FakePlayerAutoReplenishment.java b/src/main/java/dev/dubhe/gugle/carpet/tools/FakePlayerAutoReplenishment.java index 0719c98..1878d0b 100644 --- a/src/main/java/dev/dubhe/gugle/carpet/tools/FakePlayerAutoReplenishment.java +++ b/src/main/java/dev/dubhe/gugle/carpet/tools/FakePlayerAutoReplenishment.java @@ -4,7 +4,6 @@ import net.minecraft.core.component.DataComponents; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; import net.minecraft.world.item.component.ItemContainerContents; import org.jetbrains.annotations.NotNull; @@ -38,12 +37,13 @@ private static void replenishment(@NotNull ItemStack itemStack, NonNullList