Fix drawMenu raw injector and add test
(change in compiled class is naming drawLoggedIn)
This commit is contained in:
@@ -14,7 +14,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "com.openosrs"
|
group = "com.openosrs"
|
||||||
version = "1.0.1"
|
version = "1.0.2"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import com.openosrs.injector.injectors.MixinInjector;
|
|||||||
import com.openosrs.injector.injectors.RSApiInjector;
|
import com.openosrs.injector.injectors.RSApiInjector;
|
||||||
import com.openosrs.injector.injectors.raw.ClearColorBuffer;
|
import com.openosrs.injector.injectors.raw.ClearColorBuffer;
|
||||||
import com.openosrs.injector.injectors.raw.DrawAfterWidgets;
|
import com.openosrs.injector.injectors.raw.DrawAfterWidgets;
|
||||||
|
import com.openosrs.injector.injectors.raw.DrawMenu;
|
||||||
import com.openosrs.injector.injectors.raw.HidePlayerAttacks;
|
import com.openosrs.injector.injectors.raw.HidePlayerAttacks;
|
||||||
import com.openosrs.injector.injectors.raw.Occluder;
|
import com.openosrs.injector.injectors.raw.Occluder;
|
||||||
import com.openosrs.injector.injectors.raw.RasterizerAlpha;
|
import com.openosrs.injector.injectors.raw.RasterizerAlpha;
|
||||||
@@ -72,7 +73,7 @@ public class Injection extends InjectData implements InjectTaskHandler
|
|||||||
|
|
||||||
inject(new Occluder(this));
|
inject(new Occluder(this));
|
||||||
|
|
||||||
// inject(new DrawMenu(this));
|
inject(new DrawMenu(this));
|
||||||
|
|
||||||
inject(new HidePlayerAttacks(this));
|
inject(new HidePlayerAttacks(this));
|
||||||
|
|
||||||
|
|||||||
@@ -5,198 +5,127 @@
|
|||||||
* This code is licensed under GPL3, see the complete license in
|
* This code is licensed under GPL3, see the complete license in
|
||||||
* the LICENSE file in the root directory of this source tree.
|
* the LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
//package com.openosrs.injector.injectors.raw;
|
package com.openosrs.injector.injectors.raw;
|
||||||
|
|
||||||
//import com.openosrs.injector.InjectUtil;
|
import com.openosrs.injector.InjectUtil;
|
||||||
//import com.openosrs.injector.Injexception;
|
import com.openosrs.injector.Injexception;
|
||||||
//import com.openosrs.injector.injection.InjectData;
|
import com.openosrs.injector.injection.InjectData;
|
||||||
//import static com.openosrs.injector.injection.InjectData.HOOKS;
|
import static com.openosrs.injector.injection.InjectData.HOOKS;
|
||||||
//import com.openosrs.injector.injectors.AbstractInjector;
|
import com.openosrs.injector.injectors.AbstractInjector;
|
||||||
//import java.util.List;
|
import java.util.List;
|
||||||
//import java.util.ListIterator;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
//import net.runelite.asm.ClassFile;
|
import net.runelite.asm.Method;
|
||||||
//import net.runelite.asm.ClassGroup;
|
import net.runelite.asm.attributes.code.Instruction;
|
||||||
//import net.runelite.asm.Method;
|
import net.runelite.asm.attributes.code.Instructions;
|
||||||
//import net.runelite.asm.Type;
|
import net.runelite.asm.attributes.code.Label;
|
||||||
//import net.runelite.asm.attributes.code.Instruction;
|
import net.runelite.asm.attributes.code.instructions.GetStatic;
|
||||||
//import net.runelite.asm.attributes.code.Instructions;
|
import net.runelite.asm.attributes.code.instructions.IfEq;
|
||||||
//import net.runelite.asm.attributes.code.Label;
|
import net.runelite.asm.attributes.code.instructions.IfNe;
|
||||||
//import net.runelite.asm.attributes.code.instruction.types.JumpingInstruction;
|
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
||||||
//import net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction;
|
import net.runelite.asm.execution.Execution;
|
||||||
//import net.runelite.asm.attributes.code.instructions.GetStatic;
|
import net.runelite.asm.execution.InstructionContext;
|
||||||
//import net.runelite.asm.attributes.code.instructions.IStore;
|
import net.runelite.asm.execution.MethodContext;
|
||||||
//import net.runelite.asm.attributes.code.instructions.IfEq;
|
import net.runelite.asm.pool.Class;
|
||||||
//import net.runelite.asm.attributes.code.instructions.IfNe;
|
import net.runelite.asm.pool.Field;
|
||||||
//import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
import net.runelite.asm.signature.Signature;
|
||||||
//import net.runelite.asm.execution.Execution;
|
|
||||||
//import net.runelite.asm.execution.InstructionContext;
|
|
||||||
//import net.runelite.asm.pool.Class;
|
|
||||||
//import net.runelite.asm.pool.Field;
|
|
||||||
//import net.runelite.asm.signature.Signature;
|
|
||||||
|
|
||||||
//public class DrawMenu extends AbstractInjector
|
public class DrawMenu extends AbstractInjector
|
||||||
//{
|
{
|
||||||
//private static final net.runelite.asm.pool.Method HOOK = new net.runelite.asm.pool.Method(
|
private static final net.runelite.asm.pool.Method DRAWMENU = new net.runelite.asm.pool.Method(
|
||||||
//new Class(HOOKS),
|
new Class(HOOKS),
|
||||||
//"drawMenu",
|
"drawMenu",
|
||||||
//new Signature("()Z")
|
new Signature("()Z")
|
||||||
//);
|
);
|
||||||
//private static final int MENU_COLOR = 0x5d5447;
|
|
||||||
|
|
||||||
//public DrawMenu(InjectData inject)
|
public DrawMenu(InjectData inject)
|
||||||
//{
|
{
|
||||||
//super(inject);
|
super(inject);
|
||||||
//}
|
}
|
||||||
|
|
||||||
//public void inject() throws Injexception
|
public void inject() throws Injexception
|
||||||
//{
|
{
|
||||||
///*
|
/*
|
||||||
//* Label Getstatic client.isMenuOpen
|
* The drawMenu method can be inlined, so we need this raw injector to find where to inject.
|
||||||
//* Ifne -> Label Drawmenu
|
*
|
||||||
//* Jump -> Label Drawtext
|
* Originally I wanted to make sure we don't skip the method where client gets told not to draw
|
||||||
//*
|
* the widgets behind the menu. This would be useless though, as the client redraws the widgets
|
||||||
//* Label drawtext
|
* no matter what. It would also be such a insignificant performance boost it doesn't seem worth
|
||||||
//* Ldc xxx
|
* the extra headache to me.
|
||||||
//* Getstatic client. something with viewport size?
|
*
|
||||||
//* Imul
|
* --- what the code looks like completely uninlined ---
|
||||||
//* Iconst_m1
|
* if (!isMenuOpen) {
|
||||||
//* Ifne -> Label after draw menu <- info we need
|
* if (viewportX != -1) {
|
||||||
//* Getstatic / LDC (same getstatic and LDC before)
|
* drawTopLeftText(viewportX, viewportY);
|
||||||
//* Getstatic / LDC
|
* }
|
||||||
//*/
|
* } else {
|
||||||
//final ClassFile deobClient = inject.getDeobfuscated().findClass("Client");
|
* drawMenu();
|
||||||
//final ClassGroup vanilla = inject.getVanilla();
|
* }
|
||||||
|
*
|
||||||
|
* if (gameDrawingMode == 3) {
|
||||||
|
* ...
|
||||||
|
* --------
|
||||||
|
*/
|
||||||
|
|
||||||
//final Field isMenuOpen = inject.toVanilla(deobClient.findField("isMenuOpen")).getPoolField();
|
final Method drawLoggedIn = InjectUtil.findMethod(inject, "drawLoggedIn", "Client", null, true, false);
|
||||||
//final Method drawLoggedIn = inject.toVanilla(deobClient.findMethod("drawLoggedIn"));
|
final Field gameDrawMode = InjectUtil.findField(inject, "gameDrawingMode", "Client").getPoolField();
|
||||||
|
final Field isMenuOpen = InjectUtil.findField(inject, "isMenuOpen", "Client").getPoolField();
|
||||||
|
|
||||||
//final Instructions inst = drawLoggedIn.getCode().getInstructions();
|
final Execution execution = new Execution(inject.getVanilla());
|
||||||
|
execution.noInvoke = true;
|
||||||
|
execution.addMethod(drawLoggedIn);
|
||||||
|
|
||||||
//boolean foundCol = false, foundEnd = false;
|
AtomicReference<MethodContext> mcRef = new AtomicReference<>(null);
|
||||||
//int injIdx = -1;
|
|
||||||
//final ListIterator<Instruction> it = inst.listIterator();
|
|
||||||
//while (it.hasNext())
|
|
||||||
//{
|
|
||||||
//Instruction i = it.next();
|
|
||||||
//if (!foundCol &&
|
|
||||||
//(i instanceof PushConstantInstruction) &&
|
|
||||||
//((PushConstantInstruction) i).getConstant().equals(MENU_COLOR))
|
|
||||||
//{
|
|
||||||
//foundCol = true;
|
|
||||||
//injIdx = it.nextIndex();
|
|
||||||
//}
|
|
||||||
//else if (!foundEnd &&
|
|
||||||
//(i instanceof PushConstantInstruction) &&
|
|
||||||
//((PushConstantInstruction) i).getConstant().equals(0))
|
|
||||||
//{
|
|
||||||
//i = it.next();
|
|
||||||
//if (!(i instanceof IStore))
|
|
||||||
//{
|
|
||||||
//continue;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//int varIdx = ((IStore) i).getVariableIndex();
|
execution.addMethodContextVisitor(mcRef::set);
|
||||||
//i = it.next();
|
execution.run();
|
||||||
|
|
||||||
//if (!(i instanceof JumpingInstruction))
|
Instruction injectInvokeAfter = null;
|
||||||
//{
|
Label labelToJumpTo = null;
|
||||||
//continue;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//List<Label> jumps = ((JumpingInstruction) i).getJumps();
|
MethodContext mc = mcRef.get();
|
||||||
//if (jumps.size() > 1)
|
for (InstructionContext ic : mc.getInstructionContexts())
|
||||||
//{
|
{
|
||||||
//continue;
|
Instruction instruction = ic.getInstruction();
|
||||||
//}
|
if (!(instruction instanceof GetStatic))
|
||||||
//
|
continue;
|
||||||
//Instruction afterLabel = inst.
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
if (((GetStatic) instruction).getField().equals(isMenuOpen))
|
||||||
|
{
|
||||||
|
InstructionContext isMenuOpenPopper = ic.getPushes().get(0).getPopped().get(0);
|
||||||
|
Instruction isMenuOpenPopI = isMenuOpenPopper.getInstruction();
|
||||||
|
|
||||||
//final Execution ex = new Execution(vanilla);
|
// Unless there's a isMenuOpen in drawLoggedIn I missed (or something new got inlined (and I missed that)) this should never happen
|
||||||
//// Static step makes static methods not count as methods
|
assert isMenuOpenPopI instanceof IfEq || isMenuOpenPopI instanceof IfNe : "isMenuOpen was popped by a " + isMenuOpenPopI + "?";
|
||||||
//ex.staticStep = true;
|
|
||||||
//ex.noExceptions = true;
|
|
||||||
//ex.addMethod(drawLoggedIn);
|
|
||||||
|
|
||||||
//final Instruction
|
// If the popper is a IfNe the label it's pointing to is the drawMenu one and topLeft is directly after it
|
||||||
//ex.addExecutionVisitor((InstructionContext ic) ->
|
// else it's the other way around, obviously
|
||||||
//{
|
if (isMenuOpenPopI instanceof IfNe)
|
||||||
//Instruction i = ic.getInstruction();
|
injectInvokeAfter = ((IfNe) isMenuOpenPopI).getTo();
|
||||||
//if (i instanceof PushConstantInstruction)
|
else
|
||||||
//{
|
injectInvokeAfter = isMenuOpenPopI;
|
||||||
//if (((PushConstantInstruction) i).getConstant().equals(MENU_COLOR))
|
}
|
||||||
//{
|
else if (((GetStatic) instruction).getField().equals(gameDrawMode))
|
||||||
//injIdx
|
{
|
||||||
//}
|
List<Instruction> instrL = instruction.getInstructions().getInstructions();
|
||||||
//}
|
for (int i = instrL.indexOf(instruction); !(instruction instanceof Label); i--)
|
||||||
//});
|
instruction = instrL.get(i);
|
||||||
//ex.run();
|
|
||||||
|
|
||||||
//final Instructions ins = drawLoggedIn.getCode().getInstructions();
|
labelToJumpTo = (Label) instruction;
|
||||||
//ListIterator<Instruction> it = ins.getInstructions().listIterator();
|
}
|
||||||
//int injectIndex = -1;
|
|
||||||
//Label after = null;
|
|
||||||
//boolean foundBefore = false;
|
|
||||||
//boolean foundAfter = false;
|
|
||||||
|
|
||||||
//while (it.hasNext())
|
if (injectInvokeAfter != null && labelToJumpTo != null)
|
||||||
//{
|
break;
|
||||||
//Instruction i = it.next();
|
}
|
||||||
|
|
||||||
//if (!(i instanceof GetStatic) && !(i instanceof InvokeStatic))
|
if (injectInvokeAfter == null || labelToJumpTo == null)
|
||||||
//{
|
throw new Injexception("Couldn't find the right location for DrawMenu to inject");
|
||||||
//continue;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//if (!foundBefore && i instanceof GetStatic)
|
final Instructions instrs = mc.getMethod().getCode().getInstructions();
|
||||||
//{
|
int idx = instrs.getInstructions().indexOf(injectInvokeAfter);
|
||||||
//if (!((GetStatic) i).getField().equals(isMenuOpen))
|
|
||||||
//{
|
|
||||||
//continue;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//i = it.next();
|
instrs.addInstruction(++idx, new InvokeStatic(instrs, DRAWMENU));
|
||||||
//if (!(i instanceof IfEq) && !(i instanceof IfNe))
|
instrs.addInstruction(++idx, new IfNe(instrs, labelToJumpTo));
|
||||||
//{
|
|
||||||
//continue;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//if (i instanceof IfEq)
|
log.info("DrawMenu injected a method call at index {} in method {}. With a comparison jumping to {}", idx, drawLoggedIn, labelToJumpTo);
|
||||||
//{
|
}
|
||||||
//injectIndex = it.nextIndex();
|
}
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
//injectIndex = ins.getInstructions().indexOf(((IfNe) i).getJumps().get(0)) + 1;
|
|
||||||
//}
|
|
||||||
//foundBefore = true;
|
|
||||||
//}
|
|
||||||
//else if (!foundAfter && i instanceof InvokeStatic
|
|
||||||
//&& ((InvokeStatic) i).getMethod().equals("topLeftText"))
|
|
||||||
//{
|
|
||||||
//i = it.next();
|
|
||||||
//assert i instanceof JumpingInstruction;
|
|
||||||
//after = ((JumpingInstruction) i).getJumps().get(0);
|
|
||||||
//foundAfter = true;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//if (foundBefore && foundAfter)
|
|
||||||
//{
|
|
||||||
//break;
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
|
|
||||||
//if (!foundBefore || !foundAfter || injectIndex == -1)
|
|
||||||
//{
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//ins.addInstruction(injectIndex, new IfNe(ins, after));
|
|
||||||
//ins.addInstruction(injectIndex, new InvokeStatic(ins, HOOK));
|
|
||||||
//log.info("Injected drawmenu hook in {} at index {}", "", injectIndex);
|
|
||||||
|
|
||||||
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Lucas <https://github.com/Lucwousin>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is licensed under GPL3, see the complete license in
|
||||||
|
* the LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
package com.openosrs.injector.injectors.raw;
|
||||||
|
|
||||||
|
import com.google.common.io.ByteStreams;
|
||||||
|
import com.openosrs.injector.TestInjection;
|
||||||
|
import com.openosrs.injector.injection.InjectData;
|
||||||
|
import com.openosrs.injector.rsapi.RSApi;
|
||||||
|
import net.runelite.asm.ClassFile;
|
||||||
|
import net.runelite.asm.ClassGroup;
|
||||||
|
import net.runelite.deob.util.JarUtil;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class DrawMenuTest
|
||||||
|
{
|
||||||
|
@Test
|
||||||
|
public void test160() throws Exception
|
||||||
|
{
|
||||||
|
// 160 has both drawMenu and drawTopLeftText inlined
|
||||||
|
ClassFile deobClient = JarUtil.loadClass(ByteStreams.toByteArray(getClass().getResourceAsStream("/drawafterwidgets/Client_deob160.class")));
|
||||||
|
ClassFile obClient = JarUtil.loadClass(ByteStreams.toByteArray(getClass().getResourceAsStream("/drawafterwidgets/Client_ob160.class")));
|
||||||
|
|
||||||
|
ClassGroup van = new ClassGroup();
|
||||||
|
van.addClass(obClient);
|
||||||
|
ClassGroup deob = new ClassGroup();
|
||||||
|
deob.addClass(deobClient);
|
||||||
|
|
||||||
|
InjectData inject = new TestInjection(van, deob, new ClassGroup(), new RSApi());
|
||||||
|
|
||||||
|
new DrawMenu(inject).inject();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test180() throws Exception
|
||||||
|
{
|
||||||
|
// 180 has only drawMenu inlined
|
||||||
|
ClassFile deobClient = JarUtil.loadClass(ByteStreams.toByteArray(getClass().getResourceAsStream("/drawafterwidgets/Client_deob180.class")));
|
||||||
|
ClassFile obClient = JarUtil.loadClass(ByteStreams.toByteArray(getClass().getResourceAsStream("/drawafterwidgets/Client_ob180.class")));
|
||||||
|
|
||||||
|
ClassGroup van = new ClassGroup();
|
||||||
|
van.addClass(obClient);
|
||||||
|
ClassGroup deob = new ClassGroup();
|
||||||
|
deob.addClass(deobClient);
|
||||||
|
|
||||||
|
InjectData inject = new TestInjection(van, deob, new ClassGroup(), new RSApi());
|
||||||
|
|
||||||
|
new DrawMenu(inject).inject();
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
Reference in New Issue
Block a user