diff --git a/src/main/java/dev/micle/loginprotection/events/OnClientInputEventHandler.java b/src/main/java/dev/micle/loginprotection/events/OnClientInputEventHandler.java index 16da4f1..62a6688 100755 --- a/src/main/java/dev/micle/loginprotection/events/OnClientInputEventHandler.java +++ b/src/main/java/dev/micle/loginprotection/events/OnClientInputEventHandler.java @@ -8,6 +8,10 @@ import dev.micle.loginprotection.proxy.Proxy; import dev.micle.loginprotection.setup.Config; import net.minecraft.client.Minecraft; import net.minecraft.client.Options; +import net.minecraft.client.gui.screens.ChatScreen; +import net.minecraft.client.gui.screens.PauseScreen; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.inventory.InventoryScreen; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.client.event.InputEvent; @@ -47,11 +51,13 @@ public class OnClientInputEventHandler { private static boolean isMoveSprintPressed = false; private static boolean isSneakPressed = false; private static boolean isJumpPressed = false; - private static final Boolean[] isHotbarPressed = new Boolean[9]; + private static final Boolean[] isHotBarPressed = new Boolean[9]; + + private static Screen previousScreen = null; public OnClientInputEventHandler() { - // Initialize isHotbarPressed to false - Arrays.fill(isHotbarPressed, false); + // Initialize isHotBarPressed to false + Arrays.fill(isHotBarPressed, false); } @SubscribeEvent @@ -65,180 +71,250 @@ public class OnClientInputEventHandler { } private static void handle(int action, int key) { + // Initialize variables Minecraft minecraft = Minecraft.getInstance(); - if (LoginProtection.getProxy().getServer() == null || minecraft.screen != null) { + + // Cancel event if not in a game + if (LoginProtection.getProxy().getServer() == null || Proxy.Client.getPlayerState() == null) { return; } - // Check if any significant keys were pressed and save their state + // Check if input is a press or release if (action == GLFW.GLFW_PRESS || action == GLFW.GLFW_RELEASE) { + // Initialize variables Options keyBinds = minecraft.options; boolean isPressed = action == GLFW.GLFW_PRESS; List allowedKeys = (Proxy.Client.getPlayerState().equals(ProtectedPlayer.State.JOINING)) ? (List) Config.Server.LOGIN_KEY_ALLOW_LIST.get() : (List) Config.Server.AFK_KEY_ALLOW_LIST.get(); + // Check if the key is monitored, save it's state, update last input tick and notify server if not allowed if (key == GLFW.GLFW_KEY_ESCAPE) { isPausePressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.PAUSE.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.PAUSE.toString())) { + updateAndNotify(); } } else if (key == GLFW.GLFW_KEY_F3) { isDebugPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.DEBUG.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.DEBUG.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyFullscreen.getKey().getValue()) { isFullscreenPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.FULLSCREEN.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.FULLSCREEN.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyTogglePerspective.getKey().getValue()) { isTogglePerspectivePressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.PERSPECTIVE.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.PERSPECTIVE.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keySmoothCamera.getKey().getValue()) { isSmoothCameraPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.SMOOTH_CAMERA.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.SMOOTH_CAMERA.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyScreenshot.getKey().getValue()) { isScreenshotPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.SCREENSHOT.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.SCREENSHOT.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keySpectatorOutlines.getKey().getValue()) { isSpectatorOutlinesPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.SPECTATOR_OUTLINES.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.SPECTATOR_OUTLINES.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyAdvancements.getKey().getValue()) { isAdvancementsPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.ADVANCEMENTS.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.ADVANCEMENTS.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyPlayerList.getKey().getValue()) { isPlayerListPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.PLAYER_LIST.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.PLAYER_LIST.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyChat.getKey().getValue()) { isChatPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.CHAT.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.CHAT.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyCommand.getKey().getValue()) { isChatCommandPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.CHAT.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.CHAT.toString())) { + updateAndNotify(); } } else if (key == GLFW.GLFW_KEY_ENTER) { isChatEnterPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.CHAT.toString())) { - Proxy.Client.updateLastInputTick(); + // Todo: possibly set isChatPressed and isChatCommandPressed here + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.CHAT.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keySocialInteractions.getKey().getValue()) { isSocialInteractionsPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.SOCIAL_INTERACTIONS.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.SOCIAL_INTERACTIONS.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyLoadHotbarActivator.getKey().getValue()) { isLoadHotbarActivatorPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.LOAD_HOTBAR_ACTIVATOR.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.LOAD_HOTBAR_ACTIVATOR.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keySaveHotbarActivator.getKey().getValue()) { isSaveHotbarActivatorPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.SAVE_HOTBAR_ACTIVATOR.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.SAVE_HOTBAR_ACTIVATOR.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keySwapOffhand.getKey().getValue()) { isSwapOffhandPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.SWAP_ITEM.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.SWAP_ITEM.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyInventory.getKey().getValue()) { isInventoryPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.INVENTORY.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.INVENTORY.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyDrop.getKey().getValue()) { isDropItemPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.DROP_ITEM.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.DROP_ITEM.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyUse.getKey().getValue()) { isUseItemPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.USE_ITEM.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.USE_ITEM.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyPickItem.getKey().getValue()) { isPickBlockPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.PICK_BLOCK.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.PICK_BLOCK.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyAttack.getKey().getValue()) { isAttackPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.ATTACK.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.ATTACK.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyUp.getKey().getValue()) { isMoveUpPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.MOVE.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.MOVE.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyRight.getKey().getValue()) { isMoveRightPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.MOVE.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.MOVE.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyDown.getKey().getValue()) { isMoveDownPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.MOVE.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.MOVE.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyLeft.getKey().getValue()) { isMoveLeftPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.MOVE.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.MOVE.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keySprint.getKey().getValue()) { isMoveSprintPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.MOVE.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.MOVE.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyShift.getKey().getValue()) { isSneakPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.SNEAK.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.SNEAK.toString())) { + updateAndNotify(); } } else if (key == keyBinds.keyJump.getKey().getValue()) { isJumpPressed = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.JUMP.toString())) { - Proxy.Client.updateLastInputTick(); + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.JUMP.toString())) { + updateAndNotify(); } } else { - for (int i = 0; i < isHotbarPressed.length; i++) { + for (int i = 0; i < isHotBarPressed.length; i++) { if (key == keyBinds.keyHotbarSlots[i].getKey().getValue()) { - isHotbarPressed[i] = isPressed; - if (!allowedKeys.contains(Config.Server.KEYS.HOTBAR.toString())) { - Proxy.Client.updateLastInputTick(); + isHotBarPressed[i] = isPressed; + if (!checkIfScreenIsAllowed(allowedKeys, minecraft.screen, isPressed) && + !allowedKeys.contains(Config.Server.KEYS.HOTBAR.toString())) { + updateAndNotify(); } } } } } + } - // Check if any of the pressed keys are not allowed - checkIfInputIsAllowed(); + private static boolean checkIfScreenIsAllowed(List allowedKeys, Screen screen, boolean isActionReleased) { + // Initialize variables + boolean isAllowed; + + // Check if the previous screen or the current screen are significant and their respective keys are allowed + if (previousScreen instanceof PauseScreen || screen instanceof PauseScreen) { + isAllowed = allowedKeys.contains(Config.Server.KEYS.PAUSE.toString()); + } else if (previousScreen instanceof InventoryScreen || screen instanceof InventoryScreen) { + isAllowed = allowedKeys.contains(Config.Server.KEYS.INVENTORY.toString()); + } else if (previousScreen instanceof ChatScreen || screen instanceof ChatScreen) { + isAllowed = allowedKeys.contains(Config.Server.KEYS.CHAT.toString()); + } else { + // Allow any other screen that is not the game itself + isAllowed = screen != null; + } + + // Only update the previous screen when key is released + if (isActionReleased) { + previousScreen = screen; + } + + // Return value + return isAllowed; + } + + private static void updateAndNotify() { + // Update last input tick + Proxy.Client.updateLastInputTick(); + + // Send an input packet if player is joining or is afk + if (Proxy.Client.getPlayerState().equals(ProtectedPlayer.State.JOINING) || + Proxy.Client.getPlayerState().equals(ProtectedPlayer.State.AFK)) { + NetworkManager.getChannel().sendToServer(new InputPacket()); + } } public static void checkIfInputIsAllowed() { + // Get list of allowed keys List allowedKeys = (Proxy.Client.getPlayerState().equals(ProtectedPlayer.State.JOINING)) ? (List) Config.Server.LOGIN_KEY_ALLOW_LIST.get() : (List) Config.Server.AFK_KEY_ALLOW_LIST.get(); + // Update last input tick and notify server if any of the monitored keys are pressed and not allowed if ((isPausePressed && !allowedKeys.contains(Config.Server.KEYS.PAUSE.toString())) || (isDebugPressed && !allowedKeys.contains(Config.Server.KEYS.DEBUG.toString())) || (isFullscreenPressed && !allowedKeys.contains(Config.Server.KEYS.FULLSCREEN.toString())) || @@ -263,14 +339,8 @@ public class OnClientInputEventHandler { !allowedKeys.contains(Config.Server.KEYS.MOVE.toString())) || (isSneakPressed && !allowedKeys.contains(Config.Server.KEYS.SNEAK.toString())) || (isJumpPressed && !allowedKeys.contains(Config.Server.KEYS.JUMP.toString())) || - (Arrays.stream(isHotbarPressed).anyMatch(b -> b) && !allowedKeys.contains(Config.Server.KEYS.HOTBAR.toString()))) { - // Assign new last input tick - Proxy.Client.updateLastInputTick(); - - // If player is not active send an input packet - if (!Proxy.Client.getPlayerState().equals(ProtectedPlayer.State.ACTIVE)) { - NetworkManager.getChannel().sendToServer(new InputPacket()); - } + (Arrays.stream(isHotBarPressed).anyMatch(b -> b) && !allowedKeys.contains(Config.Server.KEYS.HOTBAR.toString()))) { + updateAndNotify(); } } }