Fix duplicate keybinding handling by patching KeyBinding static handlers (#968)

This commit is contained in:
slprime authored and GitHub committed 2026-07-08 09:19:48 +03:00
1 parent c84ac27a18
commit 4c4716e64f
3 files changed
+103 -3

No files matched your search

@@ -0,0 +1,76 @@
package codechicken.nei.asm;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.List;
import net.minecraft.client.settings.KeyBinding;
import cpw.mods.fml.relauncher.ReflectionHelper;
public final class KeyBindingFixHooks {
private static volatile boolean initialized;
private static Field keybindArrayField;
private static Field pressedField;
private static Field pressTimeField;
private KeyBindingFixHooks() {}
public static void onTickAll(int keyCode) {
if (keyCode == 0) {
return;
}
for (KeyBinding binding : getBindings()) {
if (binding.getKeyCode() == keyCode) {
try {
pressTimeField.setInt(binding, pressTimeField.getInt(binding) + 1);
} catch (Exception ignored) {}
}
}
}
public static void setKeyBindStateAll(int keyCode, boolean pressed) {
if (keyCode == 0) {
return;
}
for (KeyBinding binding : getBindings()) {
if (binding.getKeyCode() == keyCode) {
try {
pressedField.setBoolean(binding, pressed);
} catch (Exception ignored) {}
}
}
}
@SuppressWarnings("unchecked")
private static List<KeyBinding> getBindings() {
init();
try {
return (List<KeyBinding>) keybindArrayField.get(null);
} catch (Exception ignored) {}
return Collections.emptyList();
}
private static synchronized void init() {
if (initialized) {
return;
}
keybindArrayField = ReflectionHelper.findField(KeyBinding.class, "keybindArray", "field_74516_a");
pressedField = ReflectionHelper.findField(KeyBinding.class, "pressed", "field_74513_e");
pressTimeField = ReflectionHelper.findField(KeyBinding.class, "pressTime", "field_151474_i");
initialized = true;
}
}
@@ -56,7 +56,8 @@ public class NEITransformer implements IClassTransformer {
public NEITransformer() {
if (FMLLaunchHandler.side().isClient()) {
// Generates method to set the placed position of a mob spawner for the item callback. More portable than
// Generates method to set the placed position of a mob spawner for the item
// callback. More portable than
// copying vanilla placement code
transformer.add(
new MethodWriter(
@@ -82,7 +83,6 @@ public class NEITransformer implements IClassTransformer {
asmblocks.get("commaFix"),
true));
// fix workbench container losing items on shift click output without room for the full stack
transformer.add(
new MethodTransformer(
new ObfMapping(
@@ -105,6 +105,20 @@ public class NEITransformer implements IClassTransformer {
asmblocks.get("d_glintAlphaFix"),
asmblocks.get("glintAlphaFix")));
if (FMLLaunchHandler.side().isClient()) {
transformer.add(
new MethodWriter(
ACC_PUBLIC | ACC_STATIC,
new ObfMapping("net/minecraft/client/settings/KeyBinding", "func_74507_a", "(I)V"),
asmblocks.get("m_keyBindingOnTickAll")));
transformer.add(
new MethodWriter(
ACC_PUBLIC | ACC_STATIC,
new ObfMapping("net/minecraft/client/settings/KeyBinding", "func_74510_a", "(IZ)V"),
asmblocks.get("m_keyBindingSetStateAll")));
}
String GuiContainer = "net/minecraft/client/gui/inventory/GuiContainer";
// add manager field
transformer.add(
+11 -1
View File
@@ -62,6 +62,17 @@ ICONST_0
ICONST_1 #keep the destination alpha
INVOKESTATIC net/minecraft/client/renderer/OpenGlHelper.func_148821_a (IIII)V
list m_keyBindingOnTickAll
ILOAD 0
INVOKESTATIC codechicken/nei/asm/KeyBindingFixHooks.onTickAll (I)V
RETURN
list m_keyBindingSetStateAll
ILOAD 0
ILOAD 1
INVOKESTATIC codechicken/nei/asm/KeyBindingFixHooks.setKeyBindStateAll (IZ)V
RETURN
#begin GuiContainer patches
@@ -383,4 +394,3 @@ INVOKEVIRTUAL codechicken/nei/guihook/GuiContainerManager.objectUnderMouse (II)Z
IFEQ LCONT
RETURN
LCONT