In Forge 1.13.2 there's no current keyboard press logic, and in 1.14 there's some weirdness with multiple dispatching of keyboard presses.
Additionally I want long press support to open the config menu.
package com.irtimaled.bbor.client;
import com.irtimaled.bbor.client.events.*;
+import com.irtimaled.bbor.client.gui.SettingsScreen;
+import com.irtimaled.bbor.client.keyboard.KeyListener;
import com.irtimaled.bbor.common.BoundingBoxType;
import com.irtimaled.bbor.common.CommonProxy;
import com.irtimaled.bbor.common.EventBus;
import com.irtimaled.bbor.config.ConfigManager;
import com.irtimaled.bbor.config.Setting;
import net.minecraft.client.Minecraft;
-import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.NetworkManager;
import net.minecraft.util.math.BlockPos;
import static com.irtimaled.bbor.client.Constants.CHUNK_SIZE;
public class ClientProxy extends CommonProxy {
- public static final String KeyCategory = "Bounding Box Outline Reloaded";
- public static KeyBinding ActiveHotKey = new KeyBinding("Toggle On/Off", 0x42, KeyCategory);
- public static KeyBinding OuterBoxOnlyHotKey = new KeyBinding("Toggle Display Outer Box Only", 0x4f, KeyCategory);
+ public static final String Name = "Bounding Box Outline Reloaded";
public static boolean active;
+ static {
+ KeyListener.register("Toggle Active", 0x42, Name)
+ .onKeyPressHandler(ClientProxy::toggleActive)
+ .onLongKeyPressHandler(60, SettingsScreen::show);
+ KeyListener.register("Toggle Outer Box Only", 0x4f, Name)
+ .onKeyPressHandler(ClientProxy::toggleOuterBoxesOnly);
+ }
+
+ public static void toggleActive() {
+ active = !active;
+ if (active)
+ PlayerData.setActiveY();
+ }
+
+ private static void toggleOuterBoxesOnly() {
+ Setting<Boolean> outerBoxesOnly = ConfigManager.outerBoxesOnly;
+ outerBoxesOnly.set(!outerBoxesOnly.get());
+ }
+
private ClientRenderer renderer;
@Override
public void init() {
super.init();
EventBus.subscribe(Render.class, e -> render(e.getPartialTicks()));
- EventBus.subscribe(KeyPressed.class, e -> keyPressed());
EventBus.subscribe(ConnectedToRemoteServer.class, e -> connectedToServer(e.getNetworkManager()));
EventBus.subscribe(DisconnectedFromRemoteServer.class, e -> disconnectedFromServer());
EventBus.subscribe(InitializeClientReceived.class, e -> setWorldData(e.getSeed(), e.getSpawnX(), e.getSpawnZ()));
EventBus.subscribe(RemoveBoundingBoxReceived.class, e -> removeBoundingBox(e.getDimensionType(), e.getKey()));
renderer = new ClientRenderer(this::getCache);
+ KeyListener.init();
}
private void render(float partialTicks) {
}
}
- public static void toggleActive() {
- active = !active;
- if (active)
- PlayerData.setActiveY();
- }
-
- private void keyPressed() {
- if (ActiveHotKey.isPressed()) {
- toggleActive();
- } else if (OuterBoxOnlyHotKey.isPressed()) {
- Setting<Boolean> outerBoxesOnly = ConfigManager.outerBoxesOnly;
- outerBoxesOnly.set(!outerBoxesOnly.get());
- }
- }
-
private void connectedToServer(NetworkManager networkManager) {
SocketAddress remoteAddress = networkManager.getRemoteAddress();
if (remoteAddress instanceof InetSocketAddress) {
+++ /dev/null
-package com.irtimaled.bbor.client.events;
-
-public class KeyPressed {
-}
}
protected void initGui() {
- this.title = "Bounding Box Outline Reloaded";
+ this.title = ClientProxy.Name;
this.controls = new HashSet<>();
this.addTabs("General", "Structures", "Villages");
--- /dev/null
+package com.irtimaled.bbor.client.keyboard;
+
+import net.minecraft.client.settings.KeyBinding;
+import net.minecraft.client.util.InputMappings;
+
+public class Key extends KeyBinding {
+ private InputMappings.Input input;
+ private KeyHandler onKeyPress;
+ private KeyHandler onLongKeyPress;
+ private int longPressDuration;
+
+ Key(String description, int keyCode, String category) {
+ super(description, keyCode, category);
+ }
+
+ public Key onKeyPressHandler(KeyHandler onKeyPress) {
+ this.onKeyPress = onKeyPress;
+ return this;
+ }
+
+ public Key onLongKeyPressHandler(int duration, KeyHandler onLongKeyPress) {
+ this.longPressDuration = duration;
+ this.onLongKeyPress = onLongKeyPress;
+ return this;
+ }
+
+ InputMappings.Input getInput() {
+ if (input == null)
+ return getDefault();
+ return input;
+ }
+
+ @Override
+ public void bind(InputMappings.Input input) {
+ this.input = input;
+ super.bind(input);
+ }
+
+
+ private int pressDuration = 0;
+
+ @Override
+ public boolean isPressed() {
+ return pressDuration == 1;
+ }
+
+ void release() {
+ if (onKeyPress != null && (onLongKeyPress == null || pressDuration < longPressDuration)) {
+ onKeyPress.handle();
+ }
+
+ pressDuration = 0;
+ }
+
+ void repeat() {
+ if (onLongKeyPress == null) return;
+
+ if (pressDuration <= longPressDuration) {
+ pressDuration++;
+ }
+
+ if (pressDuration == longPressDuration) {
+ onLongKeyPress.handle();
+ }
+ }
+
+ void press() {
+ pressDuration++;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client.keyboard;
+
+@FunctionalInterface
+public interface KeyHandler {
+ void handle();
+}
--- /dev/null
+package com.irtimaled.bbor.client.keyboard;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.settings.KeyBinding;
+import net.minecraft.client.util.InputMappings;
+import org.lwjgl.glfw.GLFW;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class KeyListener {
+ private static final Minecraft minecraft = Minecraft.getInstance();
+ private static long mainWindowHandle;
+ private static Set<Key> keys = new HashSet<>();
+
+ public static void init() {
+ mainWindowHandle = minecraft.mainWindow.getHandle();
+ GLFW.glfwSetKeyCallback(mainWindowHandle, KeyListener::onKeyEvent);
+ }
+
+ public static Key register(String description, int keyCode, String category) {
+ Key key = new Key(description, keyCode, category);
+ keys.add(key);
+ return key;
+ }
+
+ private static void onKeyEvent(long windowHandle, int keyCode, int scanCode, int action, int modifiers) {
+ if (windowHandle == mainWindowHandle && minecraft.currentScreen == null && keyCode != -1) {
+ InputMappings.Input input = InputMappings.getInputByCode(keyCode, scanCode);
+ for (Key key : keys) {
+ if (key.getInput() == input) {
+ switch (action) {
+ case GLFW.GLFW_PRESS:
+ key.press();
+ break;
+ case GLFW.GLFW_REPEAT:
+ key.repeat();
+ break;
+ case GLFW.GLFW_RELEASE:
+ key.release();
+ return;
+ }
+ if (minecraft.currentScreen != null)
+ key.release();
+ return;
+ }
+ }
+ }
+ minecraft.keyboardListener.onKeyEvent(windowHandle, keyCode, scanCode, action, modifiers);
+ }
+
+ public static KeyBinding[] keyBindings() {
+ return keys.stream().toArray(KeyBinding[]::new);
+ }
+}
package com.irtimaled.bbor.mixin.client;
import com.irtimaled.bbor.client.ClientProxy;
-import com.irtimaled.bbor.client.events.KeyPressed;
-import com.irtimaled.bbor.common.EventBus;
import com.irtimaled.bbor.config.ConfigManager;
import net.minecraft.client.Minecraft;
+import net.minecraft.client.main.GameConfiguration;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@Mixin(Minecraft.class)
public class MixinMinecraft {
- @Inject(method = "init", at = @At("RETURN"))
- private void init(CallbackInfo ci) {
- ConfigManager.loadConfig(((Minecraft) (Object) this).gameDir);
- new ClientProxy().init();
+ private ClientProxy clientProxy;
+
+ @Inject(method = "<init>", at = @At("RETURN"))
+ private void constructor(GameConfiguration configuration, CallbackInfo ci) {
+ ConfigManager.loadConfig(configuration.folderInfo.gameDir);
+ clientProxy = new ClientProxy();
}
- @Inject(method = "processKeyBinds", at = @At("HEAD"))
- public void processKeyBinds(CallbackInfo ci) {
- EventBus.publish(new KeyPressed());
+ @Inject(method = "init", at = @At("RETURN"))
+ private void init(CallbackInfo ci) {
+ clientProxy.init();
}
}
package com.irtimaled.bbor.mixin.client.settings;
-import com.irtimaled.bbor.client.ClientProxy;
+import com.irtimaled.bbor.client.keyboard.KeyListener;
import net.minecraft.client.GameSettings;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.KeyBinding;
}
private KeyBinding[] getKeysAll() {
- return ArrayUtils.addAll(keyBindings, ClientProxy.ActiveHotKey, ClientProxy.OuterBoxOnlyHotKey);
+ return ArrayUtils.addAll(keyBindings, KeyListener.keyBindings());
}
@Inject(method = "<init>(Lnet/minecraft/client/Minecraft;Ljava/io/File;)V", at = @At("RETURN"))
private static Map<String, Integer> CATEGORY_ORDER;
static {
- CATEGORY_ORDER.put(ClientProxy.KeyCategory, 0);
+ CATEGORY_ORDER.put(ClientProxy.Name, 0);
}
}