aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/mixins
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/mixins')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/mixins/init/BeforeForLoopInjectionPoint.java59
-rw-r--r--src/main/java/at/hannibal2/skyhanni/mixins/init/SkyhanniMixinPlugin.java3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinGuiChat.java62
3 files changed, 83 insertions, 41 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/init/BeforeForLoopInjectionPoint.java b/src/main/java/at/hannibal2/skyhanni/mixins/init/BeforeForLoopInjectionPoint.java
new file mode 100644
index 000000000..5316a8258
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/mixins/init/BeforeForLoopInjectionPoint.java
@@ -0,0 +1,59 @@
+package at.hannibal2.skyhanni.mixins.init;
+
+import org.spongepowered.asm.lib.Opcodes;
+import org.spongepowered.asm.lib.tree.AbstractInsnNode;
+import org.spongepowered.asm.lib.tree.InsnList;
+import org.spongepowered.asm.lib.tree.VarInsnNode;
+import org.spongepowered.asm.mixin.injection.InjectionPoint;
+import org.spongepowered.asm.mixin.injection.struct.InjectionPointData;
+
+import java.util.Collection;
+
+/**
+ * Inject just before a for loop which iterates over a local variable containing an array.
+ *
+ * <pre>{@code
+ * String [] s = new String[10];
+ *
+ * // <-- Injection point here
+ * for (String e : s) {
+ *
+ * }
+ * }
+ * </pre>
+ * Does not work for more complex instructions which call functions or do other operations inside of the for loop header.
+ * Does not work for {@link java.util.Iterator iterators}.
+ *
+ * <p>Set the lvIndex arg to specify which lvIndex to search for when selecting the loop.</p>
+ *
+ *
+ * <pre>{@code
+ * @Inject(method = "...", at = @At(value = "SKYHANNI_FORLOOP_LOCAL_VAR", args = "lvIndex=1"))
+ * }</pre>
+ */
+@InjectionPoint.AtCode("SKYHANNI_FORLOOP_LOCAL_VAR")
+public class BeforeForLoopInjectionPoint extends InjectionPoint {
+ private final int lvIndex;
+
+ public BeforeForLoopInjectionPoint(InjectionPointData data) {
+ lvIndex = data.get("lvIndex", -1);
+ }
+
+ @Override
+ public boolean find(String s, InsnList insnList, Collection<AbstractInsnNode> collection) {
+ for (AbstractInsnNode p = insnList.getFirst(); p != null; p = p.getNext()) {
+ if (p.getOpcode() != Opcodes.ARRAYLENGTH) {
+ continue;
+ }
+ AbstractInsnNode loadLoopVar = p.getPrevious();
+ if (loadLoopVar == null || loadLoopVar.getOpcode() != Opcodes.ALOAD) continue;
+ AbstractInsnNode storeLoopVar = loadLoopVar.getPrevious();
+ if (storeLoopVar == null || storeLoopVar.getOpcode() != Opcodes.ASTORE) continue;
+ AbstractInsnNode loadLoopArg = storeLoopVar.getPrevious();
+ if (loadLoopArg == null || loadLoopArg.getOpcode() != Opcodes.ALOAD) continue;
+ if (lvIndex != -1 && ((VarInsnNode) loadLoopArg).var != lvIndex) continue;
+ collection.add(loadLoopArg);
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/init/SkyhanniMixinPlugin.java b/src/main/java/at/hannibal2/skyhanni/mixins/init/SkyhanniMixinPlugin.java
index 1f1b0e1fe..9dd4cc6f8 100644
--- a/src/main/java/at/hannibal2/skyhanni/mixins/init/SkyhanniMixinPlugin.java
+++ b/src/main/java/at/hannibal2/skyhanni/mixins/init/SkyhanniMixinPlugin.java
@@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.mixins.init;
import org.spongepowered.asm.lib.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
+import org.spongepowered.asm.mixin.injection.InjectionPoint;
import java.io.IOException;
import java.net.MalformedURLException;
@@ -21,7 +22,7 @@ import java.util.zip.ZipInputStream;
public class SkyhanniMixinPlugin implements IMixinConfigPlugin {
@Override
public void onLoad(String mixinPackage) {
-
+ InjectionPoint.register(BeforeForLoopInjectionPoint.class);
}
@Override
diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinGuiChat.java b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinGuiChat.java
index 97ef80364..ff744b7d0 100644
--- a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinGuiChat.java
+++ b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinGuiChat.java
@@ -1,24 +1,22 @@
package at.hannibal2.skyhanni.mixins.transformers;
import at.hannibal2.skyhanni.events.ChatHoverEvent;
-import at.hannibal2.skyhanni.features.commands.tabcomplete.TabComplete;
+import at.hannibal2.skyhanni.events.TabCompletionEvent;
import at.hannibal2.skyhanni.mixins.hooks.GuiChatHook;
-import com.google.common.collect.Lists;
import net.minecraft.client.gui.GuiChat;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.util.ChatComponentText;
-import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
-import org.apache.commons.lang3.StringUtils;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
+import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
-import java.util.List;
+import java.util.Arrays;
@Mixin(GuiChat.class)
public class MixinGuiChat {
@@ -26,41 +24,25 @@ public class MixinGuiChat {
@Shadow
protected GuiTextField inputField;
- @Shadow
- private boolean waitingOnAutocomplete;
-
- @Shadow
- private boolean playerNamesFound;
-
- @Shadow
- private List<String> foundPlayerNames = Lists.newArrayList();
-
- @Inject(method = "onAutocompleteResponse", at = @At(value = "HEAD"), cancellable = true)
- private void renderItemOverlayPost(String[] originalArray, CallbackInfo ci) {
-
- if (this.waitingOnAutocomplete) {
- String[] result = TabComplete.handleTabComplete(this.inputField.getText(), originalArray);
- if (result == null) return;
- ci.cancel();
-
- this.playerNamesFound = false;
- this.foundPlayerNames.clear();
- for (String s : result) {
- if (!s.isEmpty()) {
- this.foundPlayerNames.add(s);
- }
- }
-
- String s1 = this.inputField.getText().substring(this.inputField.func_146197_a(-1, this.inputField.getCursorPosition(), false));
- String s2 = StringUtils.getCommonPrefix(result);
- s2 = EnumChatFormatting.getTextWithoutFormattingCodes(s2);
- if (!s2.isEmpty() && !s1.equalsIgnoreCase(s2)) {
- this.inputField.deleteFromCursor(this.inputField.func_146197_a(-1, this.inputField.getCursorPosition(), false) - this.inputField.getCursorPosition());
- this.inputField.writeText(s2);
- } else if (!this.foundPlayerNames.isEmpty()) {
- this.playerNamesFound = true;
- }
- }
+ @ModifyVariable(
+ method = "onAutocompleteResponse",
+ at = @At(
+ value = "SKYHANNI_FORLOOP_LOCAL_VAR",
+ shift = At.Shift.BEFORE,
+ args = "lvIndex=1"
+ ),
+ index = 1,
+ argsOnly = true
+ )
+ private String[] renderItemOverlayPost(String[] originalArray) {
+ String inputFieldText = this.inputField.getText();
+ String beforeCursor = inputFieldText.substring(0, this.inputField.getCursorPosition());
+ TabCompletionEvent tabCompletionEvent = new TabCompletionEvent(beforeCursor, inputFieldText, Arrays.asList(originalArray));
+ tabCompletionEvent.postAndCatch();
+ String[] newSuggestions = tabCompletionEvent.intoSuggestionArray();
+ if (newSuggestions == null)
+ newSuggestions = originalArray;
+ return newSuggestions;
}
@Inject(method = "drawScreen", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiChat;handleComponentHover(Lnet/minecraft/util/IChatComponent;II)V"), locals = LocalCapture.CAPTURE_FAILHARD)