diff --git a/src/main/java/folk/sisby/inventory_tabs/mixin/MixinKeyBinding.java b/src/main/java/folk/sisby/inventory_tabs/mixin/MixinKeyBinding.java index bb261fb..04ebb50 100644 --- a/src/main/java/folk/sisby/inventory_tabs/mixin/MixinKeyBinding.java +++ b/src/main/java/folk/sisby/inventory_tabs/mixin/MixinKeyBinding.java @@ -1,11 +1,10 @@ package folk.sisby.inventory_tabs.mixin; import java.util.Map; -import java.util.Objects; -import com.llamalad7.mixinextras.sugar.Local; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; import folk.sisby.inventory_tabs.InventoryTabs; -import folk.sisby.inventory_tabs.duck.InventoryTabsScreen; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -14,42 +13,45 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import net.minecraft.client.MinecraftClient; import net.minecraft.client.option.KeyBinding; import net.minecraft.client.util.InputUtil; @Mixin(KeyBinding.class) -public abstract class MixinKeyBinding { - @Shadow @Final private static Map KEY_TO_BINDINGS; - +public class MixinKeyBinding { @Shadow private int timesPressed; - + @Shadow private InputUtil.Key boundKey; + + @Shadow @Final private static Map KEYS_BY_ID; + @Unique private static final Multimap KEYS_TO_BINDINGS = ArrayListMultimap.create(); + + @Inject(method = "(Ljava/lang/String;Lnet/minecraft/client/util/InputUtil$Type;ILjava/lang/String;)V", at = @At("TAIL")) + private void saveConflictedBinds(String translationKey, InputUtil.Type type, int code, String category, CallbackInfo ci) { + KEYS_TO_BINDINGS.put(boundKey, (KeyBinding) (Object) this); + } + @Inject(method = "onKeyPressed", at = @At("HEAD"), cancellable = true) - private static void onKeyPressed(InputUtil.Key key, CallbackInfo ci) { - MixinKeyBinding alternative = (MixinKeyBinding) (Object) findAlternative(key, KEY_TO_BINDINGS.get(key), InventoryTabs.NEXT_TAB); - if(alternative != null) { - alternative.timesPressed++; - ci.cancel(); + private static void allowTabConflictedOnKeyPressed(InputUtil.Key key, CallbackInfo ci) { + if (!key.equals(((MixinKeyBinding) (Object) InventoryTabs.NEXT_TAB).boundKey)) return; + for (KeyBinding bind : KEYS_TO_BINDINGS.get(key)) { + ((MixinKeyBinding) (Object) bind).timesPressed++; } + ci.cancel(); } - - @Inject(method = "setKeyPressed", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/option/KeyBinding;setPressed(Z)V"), cancellable = true) - private static void keyPressed(InputUtil.Key key, boolean pressed, CallbackInfo ci, @Local KeyBinding KeyBind) { - KeyBinding alternative = findAlternative(key, KeyBind, InventoryTabs.NEXT_TAB); - if(alternative != null) { - alternative.setPressed(pressed); - ci.cancel(); + + @Inject(method = "setKeyPressed", at = @At("HEAD"), cancellable = true) + private static void allowTabConflictedSetKeyPressed(InputUtil.Key key, boolean pressed$, CallbackInfo ci) { + if (!key.equals(((MixinKeyBinding) (Object) InventoryTabs.NEXT_TAB).boundKey)) return; + for (KeyBinding bind : KEYS_TO_BINDINGS.get(key)) { + bind.setPressed(pressed$); } + ci.cancel(); } - - @Unique private static KeyBinding findAlternative(InputUtil.Key key, KeyBinding binding, KeyBinding alternativeTo) { - if(binding == alternativeTo && (!(MinecraftClient.getInstance().currentScreen instanceof InventoryTabsScreen its) || !its.inventoryTabs$allowTabs())) { - for(Map.Entry entry : KEY_TO_BINDINGS.entrySet()) { - if(Objects.equals(entry.getKey(), key) && entry.getValue() != alternativeTo) { - return entry.getValue(); - } - } + + @Inject(method = "updateKeysByCode", at = @At("HEAD")) + private static void updateConflictedBinds(CallbackInfo ci) { + KEYS_TO_BINDINGS.clear(); + for (KeyBinding bind : KEYS_BY_ID.values()) { + KEYS_TO_BINDINGS.put(((MixinKeyBinding) (Object) bind).boundKey, bind); } - return null; } }