key remapper: consume key typed events for remapped keys

Since all of the keys we remap to (f/arrow/escape keys) do not have
associated characters, consume key typed events for the characters
associated to the original key press event.

This fixes entering bank pins with fkey remapping on both entering your
pin and changing your inventory tab, due to the client processing the
tab change on key press (which is remapped) and the bank plugin
processing the pin input on key typed.
This commit is contained in:
Adam
2020-05-02 20:31:03 -04:00
parent c7a155d09c
commit 26ffd1be33
2 changed files with 91 additions and 51 deletions

View File

@@ -28,7 +28,9 @@ package net.runelite.client.plugins.keyremapping;
import com.google.common.base.Strings;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.GameState;
@@ -51,10 +53,16 @@ class KeyRemappingListener implements KeyListener
private ClientThread clientThread;
private final Map<Integer, Integer> modified = new HashMap<>();
private final Set<Character> blockedChars = new HashSet<>();
@Override
public void keyTyped(KeyEvent e)
{
char keyChar = e.getKeyChar();
if (keyChar != KeyEvent.CHAR_UNDEFINED && blockedChars.contains(keyChar))
{
e.consume();
}
}
@Override
@@ -67,27 +75,25 @@ class KeyRemappingListener implements KeyListener
if (!plugin.isTyping())
{
int mappedKeyCode = KeyEvent.VK_UNDEFINED;
if (config.cameraRemap())
{
if (config.up().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_UP);
e.setKeyCode(KeyEvent.VK_UP);
mappedKeyCode = KeyEvent.VK_UP;
}
else if (config.down().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_DOWN);
e.setKeyCode(KeyEvent.VK_DOWN);
mappedKeyCode = KeyEvent.VK_DOWN;
}
else if (config.left().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_LEFT);
e.setKeyCode(KeyEvent.VK_LEFT);
mappedKeyCode = KeyEvent.VK_LEFT;
}
else if (config.right().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_RIGHT);
e.setKeyCode(KeyEvent.VK_RIGHT);
mappedKeyCode = KeyEvent.VK_RIGHT;
}
}
@@ -98,68 +104,70 @@ class KeyRemappingListener implements KeyListener
{
if (config.f1().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F1);
e.setKeyCode(KeyEvent.VK_F1);
mappedKeyCode = KeyEvent.VK_F1;
}
else if (config.f2().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F2);
e.setKeyCode(KeyEvent.VK_F2);
mappedKeyCode = KeyEvent.VK_F2;
}
else if (config.f3().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F3);
e.setKeyCode(KeyEvent.VK_F3);
mappedKeyCode = KeyEvent.VK_F3;
}
else if (config.f4().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F4);
e.setKeyCode(KeyEvent.VK_F4);
mappedKeyCode = KeyEvent.VK_F4;
}
else if (config.f5().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F5);
e.setKeyCode(KeyEvent.VK_F5);
mappedKeyCode = KeyEvent.VK_F5;
}
else if (config.f6().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F6);
e.setKeyCode(KeyEvent.VK_F6);
mappedKeyCode = KeyEvent.VK_F6;
}
else if (config.f7().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F7);
e.setKeyCode(KeyEvent.VK_F7);
mappedKeyCode = KeyEvent.VK_F7;
}
else if (config.f8().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F8);
e.setKeyCode(KeyEvent.VK_F8);
mappedKeyCode = KeyEvent.VK_F8;
}
else if (config.f9().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F9);
e.setKeyCode(KeyEvent.VK_F9);
mappedKeyCode = KeyEvent.VK_F9;
}
else if (config.f10().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F10);
e.setKeyCode(KeyEvent.VK_F10);
mappedKeyCode = KeyEvent.VK_F10;
}
else if (config.f11().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F11);
e.setKeyCode(KeyEvent.VK_F11);
mappedKeyCode = KeyEvent.VK_F11;
}
else if (config.f12().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_F12);
e.setKeyCode(KeyEvent.VK_F12);
mappedKeyCode = KeyEvent.VK_F12;
}
else if (config.esc().matches(e))
{
modified.put(e.getKeyCode(), KeyEvent.VK_ESCAPE);
e.setKeyCode(KeyEvent.VK_ESCAPE);
mappedKeyCode = KeyEvent.VK_ESCAPE;
}
}
if (mappedKeyCode != KeyEvent.VK_UNDEFINED)
{
final char keyChar = e.getKeyChar();
modified.put(e.getKeyCode(), mappedKeyCode);
e.setKeyCode(mappedKeyCode);
// arrow keys and fkeys do not have a character
e.setKeyChar(KeyEvent.CHAR_UNDEFINED);
if (keyChar != KeyEvent.CHAR_UNDEFINED)
{
// If this key event has a valid key char then a key typed event may be received next,
// we must block it
blockedChars.add(keyChar);
}
}
@@ -209,6 +217,12 @@ class KeyRemappingListener implements KeyListener
@Override
public void keyReleased(KeyEvent e)
{
final char keyChar = e.getKeyChar();
if (keyChar != KeyEvent.CHAR_UNDEFINED)
{
blockedChars.remove(keyChar);
}
if (client.getGameState() == GameState.LOGIN_SCREEN)
{
return;
@@ -218,23 +232,25 @@ class KeyRemappingListener implements KeyListener
{
modified.remove(e.getKeyCode());
int mappedKeyCode = KeyEvent.VK_UNDEFINED;
if (config.cameraRemap())
{
if (config.up().matches(e))
{
e.setKeyCode(KeyEvent.VK_UP);
mappedKeyCode = KeyEvent.VK_UP;
}
else if (config.down().matches(e))
{
e.setKeyCode(KeyEvent.VK_DOWN);
mappedKeyCode = KeyEvent.VK_DOWN;
}
else if (config.left().matches(e))
{
e.setKeyCode(KeyEvent.VK_LEFT);
mappedKeyCode = KeyEvent.VK_LEFT;
}
else if (config.right().matches(e))
{
e.setKeyCode(KeyEvent.VK_RIGHT);
mappedKeyCode = KeyEvent.VK_RIGHT;
}
}
@@ -242,57 +258,63 @@ class KeyRemappingListener implements KeyListener
{
if (config.f1().matches(e))
{
e.setKeyCode(KeyEvent.VK_F1);
mappedKeyCode = KeyEvent.VK_F1;
}
else if (config.f2().matches(e))
{
e.setKeyCode(KeyEvent.VK_F2);
mappedKeyCode = KeyEvent.VK_F2;
}
else if (config.f3().matches(e))
{
e.setKeyCode(KeyEvent.VK_F3);
mappedKeyCode = KeyEvent.VK_F3;
}
else if (config.f4().matches(e))
{
e.setKeyCode(KeyEvent.VK_F4);
mappedKeyCode = KeyEvent.VK_F4;
}
else if (config.f5().matches(e))
{
e.setKeyCode(KeyEvent.VK_F5);
mappedKeyCode = KeyEvent.VK_F5;
}
else if (config.f6().matches(e))
{
e.setKeyCode(KeyEvent.VK_F6);
mappedKeyCode = KeyEvent.VK_F6;
}
else if (config.f7().matches(e))
{
e.setKeyCode(KeyEvent.VK_F7);
mappedKeyCode = KeyEvent.VK_F7;
}
else if (config.f8().matches(e))
{
e.setKeyCode(KeyEvent.VK_F8);
mappedKeyCode = KeyEvent.VK_F8;
}
else if (config.f9().matches(e))
{
e.setKeyCode(KeyEvent.VK_F9);
mappedKeyCode = KeyEvent.VK_F9;
}
else if (config.f10().matches(e))
{
e.setKeyCode(KeyEvent.VK_F10);
mappedKeyCode = KeyEvent.VK_F10;
}
else if (config.f11().matches(e))
{
e.setKeyCode(KeyEvent.VK_F11);
mappedKeyCode = KeyEvent.VK_F11;
}
else if (config.f12().matches(e))
{
e.setKeyCode(KeyEvent.VK_F12);
mappedKeyCode = KeyEvent.VK_F12;
}
else if (config.esc().matches(e))
{
e.setKeyCode(KeyEvent.VK_ESCAPE);
mappedKeyCode = KeyEvent.VK_ESCAPE;
}
}
if (mappedKeyCode != KeyEvent.VK_UNDEFINED)
{
e.setKeyCode(mappedKeyCode);
e.setKeyChar(KeyEvent.CHAR_UNDEFINED);
}
}
else
{
@@ -302,6 +324,7 @@ class KeyRemappingListener implements KeyListener
{
modified.remove(e.getKeyCode());
e.setKeyCode(m);
e.setKeyChar(KeyEvent.CHAR_UNDEFINED);
}
}
}

View File

@@ -36,6 +36,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -77,11 +78,26 @@ public class KeyRemappingListenerTest
when(keyRemappingConfig.right()).thenReturn(new ModifierlessKeybind(KeyEvent.VK_D, 0));
when(keyRemappingPlugin.chatboxFocused()).thenReturn(true);
KeyEvent event = mock(KeyEvent.class);
when(event.getKeyChar()).thenReturn('d');
when(event.getKeyCode()).thenReturn(KeyEvent.VK_D);
when(event.getExtendedKeyCode()).thenReturn(KeyEvent.VK_D); // for keybind matches()
keyRemappingListener.keyPressed(event);
verify(event).setKeyCode(KeyEvent.VK_RIGHT);
verify(event).setKeyChar(KeyEvent.CHAR_UNDEFINED);
// now the key listener has remapped d->right, it should consume the key type
// event for d
event = mock(KeyEvent.class);
when(event.getKeyChar()).thenReturn('d');
lenient().when(event.getKeyCode()).thenReturn(KeyEvent.VK_UNDEFINED);
keyRemappingListener.keyTyped(event);
verify(event).consume();
// with the plugin now in typing mode, previously pressed and remapped keys should still be mapped
// on key release regardless
@@ -90,5 +106,6 @@ public class KeyRemappingListenerTest
when(event.getKeyCode()).thenReturn(KeyEvent.VK_D);
keyRemappingListener.keyReleased(event);
verify(event).setKeyCode(KeyEvent.VK_RIGHT);
verify(event).setKeyChar(KeyEvent.CHAR_UNDEFINED);
}
}