Rework clanmanmode attack option hiding (#746)

* A whole bunch of refactoring

* Api/mixins/injector additions for hiding attack options

* Rework clanmanmode attack hiding

* Update Client.java
This commit is contained in:
Lucwousin
2019-06-26 01:01:21 +02:00
committed by Kyleeld
parent ae6274a16f
commit 39a4cb2266
118 changed files with 2038 additions and 1955 deletions

View File

@@ -48,6 +48,7 @@ import net.runelite.deob.deobfuscators.arithmetic.DMath;
import net.runelite.injector.raw.ClearColorBuffer;
import net.runelite.injector.raw.DrawAfterWidgets;
import net.runelite.injector.raw.DrawMenu;
import net.runelite.injector.raw.HidePlayerAttacks;
import net.runelite.injector.raw.Occluder;
import net.runelite.injector.raw.RasterizerHook;
import net.runelite.injector.raw.RenderDraw;
@@ -78,6 +79,7 @@ public class Inject
private final ClearColorBuffer clearColorBuffer = new ClearColorBuffer(this);
private final RenderDraw renderDraw = new RenderDraw(this);
private final Occluder occluder = new Occluder(this);
private final HidePlayerAttacks hidePlayerAttacks = new HidePlayerAttacks(this);
// deobfuscated contains exports etc to apply to vanilla
private final ClassGroup deobfuscated, vanilla;
@@ -337,6 +339,7 @@ public class Inject
renderDraw.inject();
drawMenu.inject();
occluder.inject();
hidePlayerAttacks.inject();
}
private java.lang.Class injectInterface(ClassFile cf, ClassFile other)

View File

@@ -91,6 +91,28 @@ public class InjectUtil
public static Field findDeobField(Inject inject, String name) throws InjectionException
{
return findDeobField(inject, name, null);
}
public static Field findDeobField(Inject inject, String name, String hint) throws InjectionException
{
if (hint != null)
{
ClassFile c = inject.getDeobfuscated().findClass(hint);
for (Field f : c.getFields())
{
if (!f.getName().equals(name))
{
continue;
}
String obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations());
ClassFile c2 = inject.toObClass(c);
return c2.findField(obfuscatedName);
}
}
for (ClassFile c : inject.getDeobfuscated().getClasses())
{
for (Field f : c.getFields())

View File

@@ -0,0 +1,131 @@
package net.runelite.injector.raw;
import com.google.common.base.Stopwatch;
import java.util.Iterator;
import net.runelite.asm.Method;
import net.runelite.asm.attributes.code.Instruction;
import net.runelite.asm.attributes.code.Instructions;
import net.runelite.asm.attributes.code.Label;
import net.runelite.asm.attributes.code.instruction.types.ComparisonInstruction;
import net.runelite.asm.attributes.code.instruction.types.JumpingInstruction;
import net.runelite.asm.attributes.code.instructions.ALoad;
import net.runelite.asm.attributes.code.instructions.GetStatic;
import net.runelite.asm.attributes.code.instructions.IfACmpEq;
import net.runelite.asm.attributes.code.instructions.IfACmpNe;
import net.runelite.asm.attributes.code.instructions.IfNe;
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
import net.runelite.asm.pool.Field;
import net.runelite.injector.Inject;
import net.runelite.injector.InjectUtil;
import net.runelite.injector.InjectionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HidePlayerAttacks
{
private final Logger log = LoggerFactory.getLogger(HidePlayerAttacks.class);
private final Inject inject;
public HidePlayerAttacks(Inject inject)
{
this.inject = inject;
}
public void inject() throws InjectionException
{
Stopwatch stopwatch = Stopwatch.createStarted();
final Method addPlayerOptions = InjectUtil.findStaticMethod(inject, "addPlayerToMenu");
final Field AttackOption_hidden = InjectUtil.findDeobField(inject, "AttackOption_hidden", "AttackOption").getPoolField();
final Field attackOption = InjectUtil.findDeobField(inject, "playerAttackOption", "Client").getPoolField();
final net.runelite.asm.pool.Method shouldHideAttackOptionFor = inject.getVanilla().findClass("client").findMethod("shouldHideAttackOptionFor").getPoolMethod();
// GETSTATIC GETSTATIC
// GETSTATIC GETSTATIC
// IFACMPEQ -> label continue IFACMPNE -> label whatever lets carry on
// MORE OBFUSCATION
int injectIdx = -1;
Instruction labelIns = null;
Label label = null;
Instructions ins = addPlayerOptions.getCode().getInstructions();
Iterator<Instruction> iterator = ins.getInstructions().iterator();
while (iterator.hasNext())
{
Instruction i = iterator.next();
if (!(i instanceof GetStatic))
{
continue;
}
Field field = ((GetStatic) i).getField();
if (!field.equals(AttackOption_hidden) && !field.equals(attackOption))
{
continue;
}
i = iterator.next();
if (!(i instanceof GetStatic))
{
continue;
}
field = ((GetStatic) i).getField();
if (!field.equals(AttackOption_hidden) && !field.equals(attackOption))
{
continue;
}
i = iterator.next();
if (!(i instanceof ComparisonInstruction && i instanceof JumpingInstruction))
{
log.info("You're not supposed to see this lol");
continue;
}
if (i instanceof IfACmpEq)
{
injectIdx = ins.getInstructions().indexOf(i) + 1;
label = ((IfACmpEq) i).getJumps().get(0);
}
else if (i instanceof IfACmpNe)
{
injectIdx = ins.getInstructions().indexOf(((IfACmpNe) i).getJumps().get(0)) + 1;
// We're gonna have to inject a extra label
labelIns = iterator.next();
}
break;
}
if (injectIdx <= 0 || label == null && labelIns == null)
{
throw new InjectionException("HidePlayerAttacks failed");
}
// Load the player
ALoad i1 = new ALoad(ins, 0);
// Get the boolean
InvokeStatic i2 = new InvokeStatic(ins, shouldHideAttackOptionFor);
ins.addInstruction(injectIdx, i1);
ins.addInstruction(injectIdx + 1, i2);
if (label == null)
{
label = ins.createLabelFor(labelIns);
ins.rebuildLabels();
injectIdx = ins.getInstructions().indexOf(i2) + 1;
}
// Compare n such
IfNe i3 = new IfNe(ins, label);
ins.addInstruction(injectIdx, i3);
stopwatch.stop();
log.info("HidePlayerAttacks took {}", stopwatch.toString());
}
}