From 01120044571361f8db883adc2ee110276c4aca41 Mon Sep 17 00:00:00 2001 From: samo_lego <34912839+samolego@users.noreply.github.com> Date: Sat, 28 Mar 2020 20:11:38 +0100 Subject: [PATCH] Finally! Better inventory protection. --- gradle.properties | 8 +-- .../org/samo_lego/simpleauth/SimpleAuth.java | 2 + .../simpleauth/commands/LoginCommand.java | 17 +++-- .../simpleauth/event/AuthEventHandler.java | 15 +++-- .../event/item/TakeItemCallback.java | 20 ++++++ .../simpleauth/mixin/MixinPlayerEntity.java | 55 --------------- .../mixin/MixinPlayerInventory.java | 67 ------------------- .../mixin/MixinServerPlayNetworkHandler.java | 21 +++++- .../mixin/MixinServerPlayerEntity.java | 40 ----------- .../samo_lego/simpleauth/mixin/MixinSlot.java | 34 ++++++++++ .../simpleauth/utils/AuthConfig.java | 2 + src/main/resources/mixins.simpleauth.json | 3 +- 12 files changed, 106 insertions(+), 178 deletions(-) create mode 100644 src/main/java/org/samo_lego/simpleauth/event/item/TakeItemCallback.java delete mode 100644 src/main/java/org/samo_lego/simpleauth/mixin/MixinPlayerInventory.java delete mode 100644 src/main/java/org/samo_lego/simpleauth/mixin/MixinServerPlayerEntity.java create mode 100644 src/main/java/org/samo_lego/simpleauth/mixin/MixinSlot.java diff --git a/gradle.properties b/gradle.properties index 6d32782..7602f10 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,12 +2,12 @@ org.gradle.jvmargs=-Xmx1G # Fabric properties -minecraft_version=20w11a -yarn_mappings=20w11a+build.6 -loader_version=0.7.8+build.187 +minecraft_version=20w13a +yarn_mappings=20w13a+build.5 +loader_version=0.7.8+build.189 #Fabric api -fabric_version=0.5.3+build.308-1.16 +fabric_version=0.5.6+build.313-1.16 # Mod Properties mod_version = 1.2.0 diff --git a/src/main/java/org/samo_lego/simpleauth/SimpleAuth.java b/src/main/java/org/samo_lego/simpleauth/SimpleAuth.java index 5e8f9d9..f2db7a1 100644 --- a/src/main/java/org/samo_lego/simpleauth/SimpleAuth.java +++ b/src/main/java/org/samo_lego/simpleauth/SimpleAuth.java @@ -19,6 +19,7 @@ import org.samo_lego.simpleauth.event.entity.player.ChatCallback; import org.samo_lego.simpleauth.event.entity.player.PlayerJoinServerCallback; import org.samo_lego.simpleauth.event.entity.player.PlayerMoveCallback; import org.samo_lego.simpleauth.event.item.DropItemCallback; +import org.samo_lego.simpleauth.event.item.TakeItemCallback; import org.samo_lego.simpleauth.utils.AuthConfig; import java.io.File; @@ -73,6 +74,7 @@ public class SimpleAuth implements DedicatedServerModInitializer { // Registering the events PlayerJoinServerCallback.EVENT.register(AuthEventHandler::onPlayerJoin); DropItemCallback.EVENT.register(AuthEventHandler::onDropItem); + TakeItemCallback.EVENT.register(AuthEventHandler::onTakeItem); ChatCallback.EVENT.register(AuthEventHandler::onPlayerChat); PlayerMoveCallback.EVENT.register(AuthEventHandler::onPlayerMove); // From Fabric API diff --git a/src/main/java/org/samo_lego/simpleauth/commands/LoginCommand.java b/src/main/java/org/samo_lego/simpleauth/commands/LoginCommand.java index 81c0c59..6b1b588 100644 --- a/src/main/java/org/samo_lego/simpleauth/commands/LoginCommand.java +++ b/src/main/java/org/samo_lego/simpleauth/commands/LoginCommand.java @@ -42,9 +42,10 @@ public class LoginCommand { player.sendMessage(alreadyAuthenticated); return 0; } - else if(SimpleAuth.deauthenticatedUsers.get(player) >= maxLoginTries && maxLoginTries != -1) + else if(SimpleAuth.deauthenticatedUsers.get(player) >= maxLoginTries && maxLoginTries != -1) { player.networkHandler.disconnect(loginTriesExceeded); - + return 0; + } else if(SimpleAuth.config.main.enableGlobalPassword) { if (AuthHelper.checkPass("globalPass", pass.toCharArray())) { SimpleAuth.authenticatePlayer(player, successfullyAuthenticated); @@ -55,11 +56,19 @@ public class LoginCommand { SimpleAuth.authenticatePlayer(player, successfullyAuthenticated); return 1; } - else if(maxLoginTries == 1) + // Kicking the player out + else if(maxLoginTries == 1) { player.networkHandler.disconnect(wrongPassword); + return 0; + } + // Sending wrong pass message player.sendMessage(wrongPassword); - SimpleAuth.deauthenticatedUsers.replace(player, SimpleAuth.deauthenticatedUsers.get(player) + 1); + // ++ the login tries + SimpleAuth.deauthenticatedUsers.replace( + player, + SimpleAuth.deauthenticatedUsers.getOrDefault(player, 0) + 1 + ); return 0; } diff --git a/src/main/java/org/samo_lego/simpleauth/event/AuthEventHandler.java b/src/main/java/org/samo_lego/simpleauth/event/AuthEventHandler.java index 141c0f3..f7ae060 100644 --- a/src/main/java/org/samo_lego/simpleauth/event/AuthEventHandler.java +++ b/src/main/java/org/samo_lego/simpleauth/event/AuthEventHandler.java @@ -31,10 +31,7 @@ public class AuthEventHandler { public static void onPlayerJoin(ServerPlayerEntity player) { // Marking player as not authenticated, (re)setting login tries to zero SimpleAuth.deauthenticatedUsers.put(player, 0); - /*CompoundTag loginTries = new CompoundTag(); - loginTries.putInt("loginTries", 0); - player.saveToTag(loginTries); - player.writeCustomDataToTag(loginTries);*/ + // Player not authenticated // If clause actually not needed, since we add player to deauthenticated hashset above if (!SimpleAuth.isAuthenticated(player)) { @@ -68,6 +65,7 @@ public class AuthEventHandler { } return ActionResult.PASS; } + // Player movement public static ActionResult onPlayerMove(PlayerEntity player) { if(!SimpleAuth.isAuthenticated((ServerPlayerEntity) player) && !SimpleAuth.config.main.allowMovement) { @@ -111,6 +109,15 @@ public class AuthEventHandler { } return ActionResult.PASS; } + // Changing inventory (item moving etc.) + public static ActionResult onTakeItem(PlayerEntity player) { + if(!SimpleAuth.isAuthenticated((ServerPlayerEntity) player) && !SimpleAuth.config.main.allowItemMoving) { + player.sendMessage(notAuthenticated()); + return ActionResult.FAIL; + } + + return ActionResult.PASS; + } // Attacking an entity public static ActionResult onAttackEntity(PlayerEntity player) { if(!SimpleAuth.isAuthenticated((ServerPlayerEntity) player) && !SimpleAuth.config.main.allowEntityPunch) { diff --git a/src/main/java/org/samo_lego/simpleauth/event/item/TakeItemCallback.java b/src/main/java/org/samo_lego/simpleauth/event/item/TakeItemCallback.java new file mode 100644 index 0000000..9b2aa43 --- /dev/null +++ b/src/main/java/org/samo_lego/simpleauth/event/item/TakeItemCallback.java @@ -0,0 +1,20 @@ +package org.samo_lego.simpleauth.event.item; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.ActionResult; + +public interface TakeItemCallback { + Event EVENT = EventFactory.createArrayBacked(TakeItemCallback.class, listeners -> (player) -> { + for (TakeItemCallback event : listeners) { + ActionResult result = event.onTakeItem(player); + if (result != ActionResult.PASS) { + return result; + } + } + return ActionResult.PASS; + }); + + ActionResult onTakeItem(PlayerEntity player); +} diff --git a/src/main/java/org/samo_lego/simpleauth/mixin/MixinPlayerEntity.java b/src/main/java/org/samo_lego/simpleauth/mixin/MixinPlayerEntity.java index 7bce6d0..476d431 100644 --- a/src/main/java/org/samo_lego/simpleauth/mixin/MixinPlayerEntity.java +++ b/src/main/java/org/samo_lego/simpleauth/mixin/MixinPlayerEntity.java @@ -1,61 +1,20 @@ package org.samo_lego.simpleauth.mixin; -import net.minecraft.entity.Entity; -import net.minecraft.entity.ItemEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; -import net.minecraft.network.packet.s2c.play.EntityPositionS2CPacket; -import net.minecraft.network.packet.s2c.play.PlayerPositionLookS2CPacket; -import net.minecraft.network.packet.s2c.play.PlayerSpawnPositionS2CPacket; import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import org.samo_lego.simpleauth.event.entity.player.PlayerMoveCallback; import org.samo_lego.simpleauth.event.item.DropItemCallback; -import org.spongepowered.asm.mixin.Final; 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; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(PlayerEntity.class) public abstract class MixinPlayerEntity { - - // Thanks to PR https://github.com/FabricMC/fabric/pull/260 and AbusedLib https://github.com/abused/AbusedLib - @Inject(method = "dropItem(Lnet/minecraft/item/ItemStack;ZZ)Lnet/minecraft/entity/ItemEntity;", at = @At("HEAD"), cancellable = true) - private void dropItem(ItemStack stack, boolean throwRandomly, boolean retainOwnership, CallbackInfoReturnable cir) { - // Defining player - ServerPlayerEntity player = (ServerPlayerEntity) (Object) this; - - // Getting action result from auth event handler - ActionResult result = DropItemCallback.EVENT.invoker().onDropItem(player); - - if (result == ActionResult.FAIL) { - // Canceling the item drop, as well as giving the items back to player (and updating inv with packet) - player.inventory.insertStack(stack); - player.networkHandler.sendPacket( - new ScreenHandlerSlotUpdateS2CPacket( - -2, - player.inventory.selectedSlot, - player.inventory.getInvStack(player.inventory.selectedSlot)) - ); - // Packet for mouse-dropping inventory update - player.currentScreenHandler.sendContentUpdates(); - //player.networkHandler.sendPacket(new ScreenHandlerSlotUpdateS2CPacket(-1, -1, player.inventory.getCursorStack())); - cir.cancel(); - } - } - // Player item dropping @Inject(method = "dropSelectedItem(Z)Z", at = @At("HEAD"), cancellable = true) private void dropSelectedItem(boolean dropEntireStack, CallbackInfoReturnable cir) { - //Testing purposes - todo - doesn't delete armor, but allows mouse dropping ServerPlayerEntity player = (ServerPlayerEntity) (Object) this; ActionResult result = DropItemCallback.EVENT.invoker().onDropItem(player); @@ -71,18 +30,4 @@ public abstract class MixinPlayerEntity { cir.setReturnValue(false); } } - - // Player movement - @Inject(method = "travel(Lnet/minecraft/util/math/Vec3d;)V", at = @At("HEAD"), cancellable = true) - private void travel(Vec3d movementInput, CallbackInfo ci) { - ServerPlayerEntity player = (ServerPlayerEntity) (Object) this; - - ActionResult result = PlayerMoveCallback.EVENT.invoker().onPlayerMove(player); - - if (result == ActionResult.FAIL) { - // A bit ugly, I know. (we need to update player position) - player.teleport(player.getX(), player.getY(), player.getZ()); - ci.cancel(); - } - } } \ No newline at end of file diff --git a/src/main/java/org/samo_lego/simpleauth/mixin/MixinPlayerInventory.java b/src/main/java/org/samo_lego/simpleauth/mixin/MixinPlayerInventory.java deleted file mode 100644 index 4efb393..0000000 --- a/src/main/java/org/samo_lego/simpleauth/mixin/MixinPlayerInventory.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.samo_lego.simpleauth.mixin; - -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.inventory.Inventories; -import net.minecraft.item.ItemStack; -import net.minecraft.server.network.ServerPlayerEntity; -import org.samo_lego.simpleauth.SimpleAuth; -import org.spongepowered.asm.mixin.Final; -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; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -import java.util.List; - -@Mixin(PlayerInventory.class) -public abstract class MixinPlayerInventory { - - @Final - @Shadow - public PlayerEntity player; - - @Inject(method="setInvStack(ILnet/minecraft/item/ItemStack;)V", at = @At(value = "HEAD"), cancellable = true) - private void setInvStack(int slot, ItemStack stack, CallbackInfo ci) { - /*ServerPlayerEntity player = (ServerPlayerEntity) this.player; - ActionResult result = DropItemCallback.EVENT.invoker().onDropItem(player); - - if (result == ActionResult.FAIL) { - player.inventory - player.networkHandler.sendPacket( - new ScreenHandlerSlotUpdateS2CPacket( - -2, - player.inventory.selectedSlot, - player.inventory.getInvStack(player.inventory.selectedSlot)) - ); - // Packet for mouse-dropping inventory update - player.currentScreenHandler.sendContentUpdates(); - ci.cancel(); - }*/ - System.out.println("Setting inv stack: " + slot + "(slot) " + stack.getCount()+ "(amount)" + stack.getItem().getTranslationKey() + "(item)"); - } - - // Thank you Giselbaer for the help provided! - @Inject(method = "takeInvStack(II)Lnet/minecraft/item/ItemStack;", at = @At(value = "RETURN"), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true) - private void takeInvStack(int slot, int amount, CallbackInfoReturnable cir, List list) { - - if(!SimpleAuth.isAuthenticated((ServerPlayerEntity) player)) { - // Getting back the default item count - int initialCount = player.inventory.getInvStack(slot).getCount() + amount; - // Getting itemstack that would be returned - ItemStack stack = list != null && !list.get(slot).isEmpty() ? Inventories.splitStack(list, slot, amount) : ItemStack.EMPTY; - System.out.println("takeInvStack: " + slot + "(slot) " + amount + "(amount)" + stack.getItem().getTranslationKey() + "(item)"); - - // Setting stack value back to default (before it was taken or dropped) - stack.setCount(initialCount); - - // Setting the stack back to inventory - player.inventory.setInvStack(slot, stack); - - cir.setReturnValue(stack); - } - } -} diff --git a/src/main/java/org/samo_lego/simpleauth/mixin/MixinServerPlayNetworkHandler.java b/src/main/java/org/samo_lego/simpleauth/mixin/MixinServerPlayNetworkHandler.java index f1f826f..5fca44f 100644 --- a/src/main/java/org/samo_lego/simpleauth/mixin/MixinServerPlayNetworkHandler.java +++ b/src/main/java/org/samo_lego/simpleauth/mixin/MixinServerPlayNetworkHandler.java @@ -4,7 +4,6 @@ import net.minecraft.network.packet.c2s.play.*; import net.minecraft.server.network.ServerPlayNetworkHandler; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.ActionResult; -import org.samo_lego.simpleauth.SimpleAuth; import org.samo_lego.simpleauth.event.entity.player.ChatCallback; import org.samo_lego.simpleauth.event.entity.player.PlayerMoveCallback; import org.spongepowered.asm.mixin.Mixin; @@ -34,5 +33,23 @@ public abstract class MixinServerPlayNetworkHandler { ci.cancel(); } } - // onClickWindow, onPickFromInventory todo*/ + // onClickWindow, onPickFromInventory todo + @Inject( + method="onPlayerMove(Lnet/minecraft/network/packet/c2s/play/PlayerMoveC2SPacket;)V", + at = @At( + value = "INVOKE", + // Thanks to Liach for helping me out! + target = "net/minecraft/network/NetworkThreadUtils.forceMainThread(Lnet/minecraft/network/Packet;Lnet/minecraft/network/listener/PacketListener;Lnet/minecraft/server/world/ServerWorld;)V", + shift = At.Shift.AFTER + ), + cancellable = true + ) + private void onPlayerMove(PlayerMoveC2SPacket playerMoveC2SPacket_1, CallbackInfo ci) { + ActionResult result = PlayerMoveCallback.EVENT.invoker().onPlayerMove(player); + if (result == ActionResult.FAIL) { + // A bit ugly, I know. (we need to update player position) + player.teleport(player.getX(), player.getY(), player.getZ()); + ci.cancel(); + } + } } diff --git a/src/main/java/org/samo_lego/simpleauth/mixin/MixinServerPlayerEntity.java b/src/main/java/org/samo_lego/simpleauth/mixin/MixinServerPlayerEntity.java deleted file mode 100644 index 20e4279..0000000 --- a/src/main/java/org/samo_lego/simpleauth/mixin/MixinServerPlayerEntity.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.samo_lego.simpleauth.mixin; - -import net.minecraft.item.ItemStack; -import net.minecraft.screen.ScreenHandler; -import net.minecraft.server.network.ServerPlayerEntity; -import org.samo_lego.simpleauth.SimpleAuth; -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.CallbackInfo; - -@Mixin(ServerPlayerEntity.class) -public abstract class MixinServerPlayerEntity { - - @Inject(method = "onSlotUpdate(Lnet/minecraft/screen/ScreenHandler;ILnet/minecraft/item/ItemStack;)V", at = @At("HEAD"), cancellable = true) - private void onSlotUpdate(ScreenHandler handler, int slotId, ItemStack stack, CallbackInfo ci) { - ServerPlayerEntity player = (ServerPlayerEntity) (Object) this; - - /*ActionResult result = DropItemCallback.EVENT.invoker().onDropItem(player); - - if (result == ActionResult.FAIL) { - // Canceling the item drop, as well as giving the items back to player (and updating inv with packet) - player.inventory.insertStack(stack); - player.networkHandler.sendPacket( - new ScreenHandlerSlotUpdateS2CPacket( - -2, - player.inventory.selectedSlot, - player.inventory.getInvStack(player.inventory.selectedSlot)) - ); - // Packet for mouse-dropping inventory update - player.currentScreenHandler.sendContentUpdates(); - }*/ - //player.networkHandler.sendPacket(new ScreenHandlerSlotUpdateS2CPacket(-1, -1, player.inventory.getCursorStack())); - if(!SimpleAuth.isAuthenticated(player)) { - System.out.println("onSlotUpdate: " + stack.getItem().getTranslationKey()); - //player.inventory.setInvStack(slotId, stack); - //ci.cancel(); - } - } -} \ No newline at end of file diff --git a/src/main/java/org/samo_lego/simpleauth/mixin/MixinSlot.java b/src/main/java/org/samo_lego/simpleauth/mixin/MixinSlot.java new file mode 100644 index 0000000..cf74da1 --- /dev/null +++ b/src/main/java/org/samo_lego/simpleauth/mixin/MixinSlot.java @@ -0,0 +1,34 @@ +package org.samo_lego.simpleauth.mixin; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket; +import net.minecraft.screen.slot.Slot; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.ActionResult; +import org.samo_lego.simpleauth.event.item.TakeItemCallback; +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(Slot.class) +public abstract class MixinSlot { + // Denying item moving etc. + @Inject(method = "canTakeItems(Lnet/minecraft/entity/player/PlayerEntity;)Z", at = @At(value = "HEAD"), cancellable = true) + private void canTakeItems(PlayerEntity playerEntity, CallbackInfoReturnable cir) { + ServerPlayerEntity player = (ServerPlayerEntity) playerEntity; + ActionResult result = TakeItemCallback.EVENT.invoker().onTakeItem(player); + + if (result == ActionResult.FAIL) { + // Canceling the item taking + player.networkHandler.sendPacket( + new ScreenHandlerSlotUpdateS2CPacket( + -2, + player.inventory.selectedSlot, + player.inventory.getInvStack(player.inventory.selectedSlot)) + ); + player.networkHandler.sendPacket(new ScreenHandlerSlotUpdateS2CPacket(-1, -1, player.inventory.getCursorStack())); + cir.setReturnValue(false); + } + } +} diff --git a/src/main/java/org/samo_lego/simpleauth/utils/AuthConfig.java b/src/main/java/org/samo_lego/simpleauth/utils/AuthConfig.java index 759a29d..1107cdc 100644 --- a/src/main/java/org/samo_lego/simpleauth/utils/AuthConfig.java +++ b/src/main/java/org/samo_lego/simpleauth/utils/AuthConfig.java @@ -40,6 +40,8 @@ public class AuthConfig { public boolean allowBlockPunch = false; // Allows dropping items from inventory public boolean allowItemDrop = false; + // Allows moving item through inventory + public boolean allowItemMoving = false; // Allows item "use" - right click function (e.g. using a bow) public boolean allowItemUse = false; // Allows attacking mobs diff --git a/src/main/resources/mixins.simpleauth.json b/src/main/resources/mixins.simpleauth.json index 8d0e0ca..db96661 100644 --- a/src/main/resources/mixins.simpleauth.json +++ b/src/main/resources/mixins.simpleauth.json @@ -8,8 +8,7 @@ "MixinServerPlayNetworkHandler", "MixinPlayerManager", "MixinPlayerEntity", - "MixinServerPlayerEntity", - "MixinPlayerInventory" + "MixinSlot" ], "injectors": { "defaultRequire": 1