Asm mixins that "work"
This commit is contained in:
1
extended-mixin-processor/.gitignore
vendored
Normal file
1
extended-mixin-processor/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
dependency-reduced-pom.xml
|
||||
231
extended-mixin-processor/pom.xml
Normal file
231
extended-mixin-processor/pom.xml
Normal file
@@ -0,0 +1,231 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>runelite-parent</artifactId>
|
||||
<groupId>net.runelite</groupId>
|
||||
<version>1.5.24-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>extended-mixin-processor</artifactId>
|
||||
<packaging>maven-plugin</packaging>
|
||||
|
||||
<name>extended-mixin-processor Maven Plugin</name>
|
||||
|
||||
<url>https://www.runelitepl.us</url>
|
||||
|
||||
<prerequisites>
|
||||
<maven>${maven.version}</maven>
|
||||
</prerequisites>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<maven.version>3.3.9</maven.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-plugin-api</artifactId>
|
||||
<version>${maven.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-core</artifactId>
|
||||
<version>${maven.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-artifact</artifactId>
|
||||
<version>${maven.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-compat</artifactId>
|
||||
<version>${maven.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.plugin-tools</groupId>
|
||||
<artifactId>maven-plugin-annotations</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.plugin-testing</groupId>
|
||||
<artifactId>maven-plugin-testing-harness</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>runelite-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite.rs</groupId>
|
||||
<artifactId>runescape-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>client-patch</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>27.1-jre</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/io.sigpipe/jbsdiff -->
|
||||
<dependency>
|
||||
<groupId>io.sigpipe</groupId>
|
||||
<artifactId>jbsdiff</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.javassist/javassist -->
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>3.24.1-GA</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.json-simple</groupId>
|
||||
<artifactId>json-simple</artifactId>
|
||||
<version>1.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.lingala.zip4j</groupId>
|
||||
<artifactId>zip4j</artifactId>
|
||||
<version>1.3.2</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.ow2.asm/asm -->
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm-all</artifactId>
|
||||
<version>6.0_BETA</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
</plugin>
|
||||
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_maven-plugin_packaging -->
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-plugin-plugin</artifactId>
|
||||
<version>3.6.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.22.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-install-plugin</artifactId>
|
||||
<version>2.5.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>2.8.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-invoker-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-plugin-plugin</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<configuration>
|
||||
<!-- <goalPrefix>maven-archetype-plugin</goalPrefix> -->
|
||||
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>mojo-descriptor</id>
|
||||
<goals>
|
||||
<goal>descriptor</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>help-goal</id>
|
||||
<goals>
|
||||
<goal>helpmojo</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<minimizeJar>false</minimizeJar>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor;
|
||||
|
||||
public class MethodGarbageValue
|
||||
{
|
||||
|
||||
private final String type;
|
||||
private final int value;
|
||||
|
||||
public MethodGarbageValue(int value)
|
||||
{
|
||||
if(value <= Byte.MAX_VALUE && value >= Byte.MIN_VALUE)
|
||||
{
|
||||
type = "B";
|
||||
}
|
||||
else if(value <= Short.MAX_VALUE && value >= Short.MIN_VALUE)
|
||||
{
|
||||
type = "S";
|
||||
}
|
||||
else
|
||||
{
|
||||
type = "I";
|
||||
}
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "MethodGarbageValue[type="+getType()+",value="+getValue()+"]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor;
|
||||
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.reflect.ClassPath;
|
||||
import io.sigpipe.jbsdiff.Patch;
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.LoaderClassPath;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import us.runelitepl.mixinprocessor.generators.AnnotationProcessor;
|
||||
import us.runelitepl.mixinprocessor.generators.PatchGenerator;
|
||||
import us.runelitepl.mixinprocessor.generators.StaticGenerator;
|
||||
import us.runelitepl.mixinprocessor.generators.StaticStageTwoGenerator;
|
||||
import us.runelitepl.mixinprocessor.parsers.GamepackDownloader;
|
||||
import us.runelitepl.mixinprocessor.parsers.HooksParser;
|
||||
import us.runelitepl.mixinprocessor.transformers.AsmMethodGarbageTransformer;
|
||||
import us.runelitepl.mixinprocessor.transformers.AsmMethodSignatureTransformer;
|
||||
import us.runelitepl.mixinprocessor.util.JavassistUtils;
|
||||
import us.runelitepl.mixinprocessor.util.RefUtils;
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.apache.maven.plugins.annotations.ResolutionScope;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Goal which touches a timestamp file.
|
||||
*/
|
||||
@Mojo(name = "process-mixins", defaultPhase = LifecyclePhase.PROCESS_CLASSES, requiresDependencyResolution =
|
||||
ResolutionScope.COMPILE)
|
||||
public class MixinProcessorMojo
|
||||
extends AbstractMojo implements Opcodes
|
||||
{
|
||||
private static final String PATCHES_PACKAGE = "us.runelitepl.mixins";
|
||||
/**
|
||||
* Location of the file.
|
||||
*/
|
||||
@Parameter(defaultValue = "${project.build.directory}", property = "outputDir", required = true)
|
||||
private File outputDirectory;
|
||||
|
||||
@Parameter(defaultValue = "${project}", required = true, readonly = true)
|
||||
private MavenProject project;
|
||||
|
||||
@Parameter(property = "process-mixins.hooks", defaultValue = "hooks.json", required = true)
|
||||
private String hooks;
|
||||
|
||||
@Parameter(property = "process-mixins.ops", defaultValue = "gamepack.deob.jar.op.json", required = true)
|
||||
private String ops;
|
||||
|
||||
private static MixinProcessorMojo INST;
|
||||
|
||||
public static ClassPool classPool;
|
||||
|
||||
public static HashMap<String, Long> fieldDecoders = new HashMap<>();
|
||||
|
||||
public static HashMap<String, String> classNames = new HashMap<>();
|
||||
public static HashMap<String, String> methodNames = new HashMap<>();
|
||||
public static HashMap<String, String> fieldNames = new HashMap<>();
|
||||
|
||||
public static HashMap<String, Boolean> isFieldTagged = new HashMap<>();
|
||||
public static HashMap<String, Boolean> isMethodTagged = new HashMap<>();
|
||||
|
||||
public static HashMap<String, MethodGarbageValue> methodGarbageValues = new HashMap<>();
|
||||
|
||||
public static HashMap<String, byte[]> gamepack = new HashMap<>();
|
||||
|
||||
public static final int BUFFER_SIZE = 1024 * 1024 * 4;
|
||||
|
||||
public void execute()
|
||||
throws MojoExecutionException
|
||||
{
|
||||
INST = this;
|
||||
try
|
||||
{
|
||||
List runtimeClasspathElements = project.getRuntimeClasspathElements();
|
||||
URL[] runtimeUrls = new URL[runtimeClasspathElements.size()];
|
||||
for (int i = 0; i < runtimeClasspathElements.size(); i++)
|
||||
{
|
||||
String element = (String) runtimeClasspathElements.get(i);
|
||||
runtimeUrls[i] = new File(element).toURI().toURL();
|
||||
}
|
||||
URLClassLoader classLoader = new URLClassLoader(runtimeUrls,
|
||||
Thread.currentThread().getContextClassLoader());
|
||||
|
||||
File outputFolder = new File(project.getBuild().getOutputDirectory());
|
||||
File projectDir = new File(System.getProperty("user.dir"));
|
||||
|
||||
File hooksFile = new File(projectDir, hooks);
|
||||
File opsFile = new File(projectDir, ops);
|
||||
|
||||
outputFolder.mkdirs();
|
||||
|
||||
GamepackDownloader.downloadGamepack(gamepack);
|
||||
|
||||
ByteArrayOutputStream patchOutputStream = new ByteArrayOutputStream(BUFFER_SIZE); // 4mb
|
||||
|
||||
HooksParser.run(hooksFile, opsFile);
|
||||
|
||||
classPool = new ClassPool();
|
||||
|
||||
classPool.appendClassPath((new LoaderClassPath(classLoader)));
|
||||
|
||||
for (Map.Entry<String, byte[]> entry : gamepack.entrySet())
|
||||
{
|
||||
byte[] b1_;
|
||||
try (InputStream is = getClass().getResourceAsStream("/patch/" + entry.getKey() + ".class.bs"))
|
||||
{
|
||||
if (is == null)
|
||||
{
|
||||
stderr("IS null for %s", entry.getKey());
|
||||
continue;
|
||||
}
|
||||
|
||||
b1_ = ByteStreams.toByteArray(is);
|
||||
}
|
||||
patchOutputStream.reset();
|
||||
Patch.patch(entry.getValue(), b1_, patchOutputStream);
|
||||
entry.setValue(patchOutputStream.toByteArray());
|
||||
|
||||
classPool.makeClass(new ByteArrayInputStream(entry.getValue()));
|
||||
}
|
||||
|
||||
|
||||
HashMap<String, byte[]> finalClasses = new HashMap<>();
|
||||
|
||||
ImmutableSet<ClassPath.ClassInfo> classes =
|
||||
ClassPath.from(classLoader).getTopLevelClassesRecursive(PATCHES_PACKAGE);
|
||||
|
||||
for (ClassPath.ClassInfo clazz : classes)
|
||||
{
|
||||
|
||||
stderr("");
|
||||
stderr("Annotations: %s", clazz.getSimpleName());
|
||||
|
||||
CtClass ctClass = classPool.get(clazz.getName());
|
||||
|
||||
String className = ctClass.getSimpleName();
|
||||
className = RefUtils.getObbedClassName(className);
|
||||
|
||||
byte[] finalCode = JavassistUtils.getClassBytecode(ctClass);
|
||||
|
||||
finalCode = new AnnotationProcessor(className, finalCode).run();
|
||||
|
||||
finalClasses.put(className, finalCode);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, byte[]> entry : finalClasses.entrySet())
|
||||
{
|
||||
String className = entry.getKey();
|
||||
byte[] finalCode = entry.getValue();
|
||||
|
||||
stderr("");
|
||||
stderr("Pass 1: %s", className);
|
||||
finalCode = new AsmMethodSignatureTransformer(className, finalCode).transform();
|
||||
finalCode = new AsmMethodGarbageTransformer(className, finalCode, finalClasses).transform();
|
||||
finalClasses.put(className, finalCode);
|
||||
}
|
||||
|
||||
stderr("");
|
||||
stderr("Pass Statics");
|
||||
|
||||
new StaticGenerator().run(finalClasses.get(RefUtils.STATICS_STRING));
|
||||
|
||||
new StaticStageTwoGenerator(finalClasses).run();
|
||||
|
||||
for (Map.Entry<String, byte[]> entry : finalClasses.entrySet())
|
||||
{
|
||||
String className = entry.getKey();
|
||||
if (className == null)
|
||||
{
|
||||
stderr("Class name null? %s", entry.getValue().length);
|
||||
continue;
|
||||
}
|
||||
if (className.endsWith(RefUtils.STATICS_STRING))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
stderr("");
|
||||
stderr("Pass 2: %s", className);
|
||||
|
||||
byte[] finalCode = entry.getValue();
|
||||
finalCode = new PatchGenerator(className, finalCode).run();
|
||||
|
||||
|
||||
entry.setValue(finalCode);
|
||||
}
|
||||
|
||||
deleteDir(new File(outputFolder, "us/runelitepl/mixins"));
|
||||
|
||||
outputFolder = new File(outputFolder, "extended-mixins");
|
||||
outputFolder.mkdirs();
|
||||
|
||||
for (Map.Entry<String, byte[]> entry : finalClasses.entrySet())
|
||||
{
|
||||
if (entry.getKey().contains(RefUtils.STATICS_STRING))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Files.write(new File(outputFolder, entry.getKey() + ".class").toPath(),
|
||||
entry.getValue());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
throw new MojoExecutionException(ex.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void stderr(String s, Object... format)
|
||||
{
|
||||
getLog().info(String.format(s, format));
|
||||
}
|
||||
|
||||
public static void log(String s, Object... format)
|
||||
{
|
||||
INST.stderr(s, format);
|
||||
}
|
||||
|
||||
static void deleteDir(File file) throws IOException
|
||||
{
|
||||
if (!file.exists())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Files.walk(file.toPath())
|
||||
.sorted(Comparator.reverseOrder())
|
||||
.map(Path::toFile)
|
||||
.forEach(File::delete);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Append
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Inject
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Overwrite
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Prepend
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Provided
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Reobfuscate
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.enums;
|
||||
|
||||
public enum InjectionType
|
||||
{
|
||||
INJECT,
|
||||
APPEND,
|
||||
OVERWRITE,
|
||||
PREPEND,
|
||||
PROVIDED;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.generators;
|
||||
|
||||
import javassist.CannotCompileException;
|
||||
import javassist.CtClass;
|
||||
import us.runelitepl.mixinprocessor.MixinProcessorMojo;
|
||||
import us.runelitepl.mixinprocessor.parsers.FieldAnnotationParser;
|
||||
import us.runelitepl.mixinprocessor.parsers.MethodAnnotationParser;
|
||||
import us.runelitepl.mixinprocessor.util.JavassistUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class AnnotationProcessor
|
||||
{
|
||||
|
||||
private final String className;
|
||||
private final byte[] finalCode;
|
||||
|
||||
public AnnotationProcessor(String className, byte[] finalCode)
|
||||
{
|
||||
this.className = className;
|
||||
this.finalCode = finalCode;
|
||||
}
|
||||
|
||||
public byte[] run() throws IOException, CannotCompileException, ClassNotFoundException
|
||||
{
|
||||
byte[] newCode = finalCode;
|
||||
|
||||
CtClass clazz = MixinProcessorMojo.classPool.makeClass(new ByteArrayInputStream(newCode));
|
||||
new FieldAnnotationParser(clazz).run();
|
||||
new MethodAnnotationParser(clazz).run();
|
||||
newCode = JavassistUtils.getClassBytecode(clazz);
|
||||
|
||||
return newCode;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.generators;
|
||||
|
||||
import us.runelitepl.mixinprocessor.transformers.AnnotationRemoverTransformer;
|
||||
import us.runelitepl.mixinprocessor.transformers.AsmMethodGarbageTransformer;
|
||||
import us.runelitepl.mixinprocessor.transformers.AsmMethodSignatureTransformer;
|
||||
import us.runelitepl.mixinprocessor.transformers.AsmNameTransformer;
|
||||
import us.runelitepl.mixinprocessor.transformers.AsmStaticUsageTransformer;
|
||||
import us.runelitepl.mixinprocessor.transformers.DoNothingTransformer;
|
||||
import us.runelitepl.mixinprocessor.transformers.GetFieldDecoderTransformer;
|
||||
import us.runelitepl.mixinprocessor.transformers.ProvidedRemoverTransformer;
|
||||
|
||||
public class PatchGenerator
|
||||
{
|
||||
|
||||
private final String className;
|
||||
private final byte[] bytecode;
|
||||
|
||||
public PatchGenerator(String className, byte[] bytecode)
|
||||
{
|
||||
this.className = className;
|
||||
this.bytecode = bytecode;
|
||||
}
|
||||
|
||||
public byte[] run()
|
||||
{
|
||||
byte[] newCode = bytecode;
|
||||
|
||||
newCode = new GetFieldDecoderTransformer(className, newCode).transform();
|
||||
// https://asm.ow2.io/javadoc/org/objectweb/asm/commons/Remapper.html
|
||||
// https://asm.ow2.io/javadoc/org/objectweb/asm/commons/ClassRemapper.html
|
||||
newCode = new AsmStaticUsageTransformer(className, newCode).transform();
|
||||
newCode = new AsmNameTransformer(className, newCode).transform();
|
||||
newCode = new ProvidedRemoverTransformer(className, newCode).transform();
|
||||
newCode = new AnnotationRemoverTransformer(className, newCode).transform();
|
||||
|
||||
|
||||
newCode = new DoNothingTransformer(className, newCode).transform();
|
||||
return newCode;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.generators;
|
||||
|
||||
import javassist.CannotCompileException;
|
||||
import javassist.CtClass;
|
||||
import javassist.NotFoundException;
|
||||
import us.runelitepl.mixinprocessor.MixinProcessorMojo;
|
||||
import us.runelitepl.mixinprocessor.util.JavassistUtils;
|
||||
import us.runelitepl.mixinprocessor.util.RefUtils;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class StaticGenerator
|
||||
{
|
||||
|
||||
public static HashMap<String, ArrayList<MethodNode>> staticMethods = new HashMap<>();
|
||||
public static HashMap<String, ArrayList<FieldNode>> staticFields = new HashMap<>();
|
||||
public static Set<String> modifiedClasses = new HashSet<>();
|
||||
|
||||
public void run(byte[] bytecode) throws NotFoundException, IOException, CannotCompileException
|
||||
{
|
||||
ClassReader cr = new ClassReader(bytecode);
|
||||
|
||||
ClassNode node = new ClassNode();
|
||||
cr.accept(node, 0);
|
||||
|
||||
for (Object aaa : node.methods)
|
||||
{
|
||||
MethodNode method = (MethodNode) aaa;
|
||||
|
||||
String methodName = method.name;
|
||||
method.desc = RefUtils.reobMethodDescriptor(method.desc);
|
||||
int access = method.access;
|
||||
if ((access & 8) != 8)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String reobbed = RefUtils.reobMethodName(RefUtils.STATICS_STRING, methodName, method.desc);
|
||||
if(reobbed == null)
|
||||
{
|
||||
MixinProcessorMojo.log("Failed to reob static method: %s %s", methodName, method.desc);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
String[] split = reobbed.split(" ");
|
||||
method.name = split[1];
|
||||
ArrayList<MethodNode> list = staticMethods.getOrDefault(split[0], new ArrayList<>());
|
||||
list.add(method);
|
||||
staticMethods.put(split[0], list);
|
||||
modifiedClasses.add(split[0]);
|
||||
}
|
||||
|
||||
for (Object aaa : node.fields)
|
||||
{
|
||||
FieldNode field = (FieldNode) aaa;
|
||||
|
||||
String fieldName = field.name;
|
||||
field.desc = RefUtils.reobDescriptor(field.desc);
|
||||
int access = field.access;
|
||||
if ((access & 8) != 8)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String reobbed = RefUtils.reobFieldName(RefUtils.STATICS_STRING, fieldName, field.desc);
|
||||
if(reobbed == null)
|
||||
{
|
||||
MixinProcessorMojo.log("Failed to reob static field: %s %s", fieldName, field.desc);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
String[] split = reobbed.split(" ");
|
||||
field.name = split[1];
|
||||
ArrayList<FieldNode> list = staticFields.getOrDefault(split[0], new ArrayList<>());
|
||||
list.add(field);
|
||||
staticFields.put(split[0], list);
|
||||
modifiedClasses.add(split[0]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.generators;
|
||||
|
||||
import org.objectweb.asm.Attribute;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.AnnotationNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
import org.objectweb.asm.tree.TypeAnnotationNode;
|
||||
import us.runelitepl.mixinprocessor.MixinProcessorMojo;
|
||||
import us.runelitepl.mixinprocessor.parsers.MethodReflector;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import static us.runelitepl.mixinprocessor.generators.StaticGenerator.modifiedClasses;
|
||||
import static us.runelitepl.mixinprocessor.generators.StaticGenerator.staticFields;
|
||||
import static us.runelitepl.mixinprocessor.generators.StaticGenerator.staticMethods;
|
||||
|
||||
public class StaticStageTwoGenerator implements Opcodes
|
||||
{
|
||||
|
||||
private HashMap<String, byte[]> classes;
|
||||
|
||||
public StaticStageTwoGenerator(HashMap<String, byte[]> classes)
|
||||
{
|
||||
this.classes = classes;
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
for (String className : modifiedClasses)
|
||||
{
|
||||
byte[] targetBytecode = classes.getOrDefault(className, null);
|
||||
if (targetBytecode == null)
|
||||
{
|
||||
//create new class
|
||||
ClassWriter cw = new ClassWriter(0);
|
||||
FieldVisitor fv;
|
||||
MethodVisitor mv;
|
||||
|
||||
cw.visit(V1_6, ACC_PUBLIC, className, null, "java/lang/Object", null);
|
||||
|
||||
if (staticMethods.get(className) != null)
|
||||
{
|
||||
for (MethodNode method : staticMethods.get(className))
|
||||
{
|
||||
mv = cw.visitMethod(method.access, method.name, method.desc, method.signature,
|
||||
(String[]) method.exceptions.toArray(new String[0]));
|
||||
MethodReflector reflector = new MethodReflector(mv);
|
||||
method.accept(reflector);
|
||||
}
|
||||
}
|
||||
|
||||
if (staticFields.get(className) != null)
|
||||
{
|
||||
for (FieldNode field : staticFields.get(className))
|
||||
{
|
||||
fv = cw.visitField(field.access, field.name, field.desc, field.signature, field.value);
|
||||
int i;
|
||||
int n;
|
||||
AnnotationNode annotation;
|
||||
if (field.visibleAnnotations != null)
|
||||
{
|
||||
i = 0;
|
||||
|
||||
for (n = field.visibleAnnotations.size(); i < n; ++i)
|
||||
{
|
||||
annotation = (AnnotationNode) field.visibleAnnotations.get(i);
|
||||
annotation.accept(fv.visitAnnotation(annotation.desc, true));
|
||||
}
|
||||
}
|
||||
|
||||
if (field.invisibleAnnotations != null)
|
||||
{
|
||||
i = 0;
|
||||
|
||||
for (n = field.invisibleAnnotations.size(); i < n; ++i)
|
||||
{
|
||||
annotation = (AnnotationNode) field.invisibleAnnotations.get(i);
|
||||
annotation.accept(fv.visitAnnotation(annotation.desc, false));
|
||||
}
|
||||
}
|
||||
|
||||
TypeAnnotationNode typeAnnotation;
|
||||
if (field.visibleTypeAnnotations != null)
|
||||
{
|
||||
i = 0;
|
||||
|
||||
for (n = field.visibleTypeAnnotations.size(); i < n; ++i)
|
||||
{
|
||||
typeAnnotation = (TypeAnnotationNode) field.visibleTypeAnnotations.get(i);
|
||||
typeAnnotation.accept(fv
|
||||
.visitTypeAnnotation(typeAnnotation.typeRef, typeAnnotation.typePath,
|
||||
typeAnnotation.desc, true));
|
||||
}
|
||||
}
|
||||
|
||||
if (field.invisibleTypeAnnotations != null)
|
||||
{
|
||||
i = 0;
|
||||
|
||||
for (n = field.invisibleTypeAnnotations.size(); i < n; ++i)
|
||||
{
|
||||
typeAnnotation = (TypeAnnotationNode) field.invisibleTypeAnnotations.get(i);
|
||||
typeAnnotation.accept(fv
|
||||
.visitTypeAnnotation(typeAnnotation.typeRef, typeAnnotation.typePath,
|
||||
typeAnnotation.desc, false));
|
||||
}
|
||||
}
|
||||
|
||||
if (field.attrs != null)
|
||||
{
|
||||
i = 0;
|
||||
|
||||
for (n = field.attrs.size(); i < n; ++i)
|
||||
{
|
||||
fv.visitAttribute((Attribute) field.attrs.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
fv.visitEnd();
|
||||
}
|
||||
}
|
||||
|
||||
cw.visitEnd();
|
||||
|
||||
targetBytecode = cw.toByteArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
ClassReader cr = new ClassReader(targetBytecode);
|
||||
ClassWriter cw = new ClassWriter(cr, 0);
|
||||
ClassVisitor cv = new ClassVisitor(ASM6)
|
||||
{
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
||||
{
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
if (staticMethods.get(className) != null)
|
||||
{
|
||||
for (MethodNode method : staticMethods.get(className))
|
||||
{
|
||||
MethodVisitor mv = visitMethod(method.access, method.name, method.desc,
|
||||
method.signature, (String[]) method.exceptions.toArray(new String[0]));
|
||||
MethodReflector reflector = new MethodReflector(mv);
|
||||
method.accept(reflector);
|
||||
}
|
||||
}
|
||||
|
||||
if (staticFields.get(className) != null)
|
||||
{
|
||||
for (FieldNode field : staticFields.get(className))
|
||||
{
|
||||
FieldVisitor fv = visitField(field.access, field.name, field.desc, field.signature,
|
||||
field.value);
|
||||
int i;
|
||||
int n;
|
||||
AnnotationNode annotation;
|
||||
if (field.visibleAnnotations != null)
|
||||
{
|
||||
i = 0;
|
||||
|
||||
for (n = field.visibleAnnotations.size(); i < n; ++i)
|
||||
{
|
||||
annotation = (AnnotationNode) field.visibleAnnotations.get(i);
|
||||
annotation.accept(fv.visitAnnotation(annotation.desc, true));
|
||||
}
|
||||
}
|
||||
|
||||
if (field.invisibleAnnotations != null)
|
||||
{
|
||||
i = 0;
|
||||
|
||||
for (n = field.invisibleAnnotations.size(); i < n; ++i)
|
||||
{
|
||||
annotation = (AnnotationNode) field.invisibleAnnotations.get(i);
|
||||
annotation.accept(fv.visitAnnotation(annotation.desc, false));
|
||||
}
|
||||
}
|
||||
|
||||
TypeAnnotationNode typeAnnotation;
|
||||
if (field.visibleTypeAnnotations != null)
|
||||
{
|
||||
i = 0;
|
||||
|
||||
for (n = field.visibleTypeAnnotations.size(); i < n; ++i)
|
||||
{
|
||||
typeAnnotation = (TypeAnnotationNode) field.visibleTypeAnnotations.get(i);
|
||||
typeAnnotation.accept(fv
|
||||
.visitTypeAnnotation(typeAnnotation.typeRef, typeAnnotation.typePath,
|
||||
typeAnnotation.desc, true));
|
||||
}
|
||||
}
|
||||
|
||||
if (field.invisibleTypeAnnotations != null)
|
||||
{
|
||||
i = 0;
|
||||
|
||||
for (n = field.invisibleTypeAnnotations.size(); i < n; ++i)
|
||||
{
|
||||
typeAnnotation = (TypeAnnotationNode) field.invisibleTypeAnnotations.get(i);
|
||||
typeAnnotation.accept(fv
|
||||
.visitTypeAnnotation(typeAnnotation.typeRef, typeAnnotation.typePath,
|
||||
typeAnnotation.desc, false));
|
||||
}
|
||||
}
|
||||
|
||||
if (field.attrs != null)
|
||||
{
|
||||
i = 0;
|
||||
|
||||
for (n = field.attrs.size(); i < n; ++i)
|
||||
{
|
||||
fv.visitAttribute((Attribute) field.attrs.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
fv.visitEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
cr.accept(cv, 0);
|
||||
|
||||
targetBytecode = cw.toByteArray();
|
||||
}
|
||||
|
||||
classes.put(className, targetBytecode);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.parsers;
|
||||
|
||||
import javassist.CtClass;
|
||||
import javassist.CtField;
|
||||
import us.runelitepl.mixinprocessor.annotations.Append;
|
||||
import us.runelitepl.mixinprocessor.annotations.Inject;
|
||||
import us.runelitepl.mixinprocessor.annotations.Overwrite;
|
||||
import us.runelitepl.mixinprocessor.annotations.Prepend;
|
||||
import us.runelitepl.mixinprocessor.annotations.Provided;
|
||||
import us.runelitepl.mixinprocessor.annotations.Reobfuscate;
|
||||
import us.runelitepl.mixinprocessor.enums.InjectionType;
|
||||
import us.runelitepl.mixinprocessor.util.RefUtils;
|
||||
|
||||
import static us.runelitepl.mixinprocessor.MixinProcessorMojo.isFieldTagged;
|
||||
|
||||
public class FieldAnnotationParser
|
||||
{
|
||||
|
||||
private CtClass clazz;
|
||||
|
||||
public FieldAnnotationParser(CtClass clazz)
|
||||
{
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public void run() throws ClassNotFoundException
|
||||
{
|
||||
for (CtField field : clazz.getDeclaredFields())
|
||||
{
|
||||
Object[] annotations = field.getAnnotations();
|
||||
|
||||
InjectionType type = null;
|
||||
boolean reobfuscate = false;
|
||||
|
||||
for (Object obj : annotations)
|
||||
{
|
||||
reobfuscate = obj instanceof Reobfuscate || reobfuscate;
|
||||
if (obj instanceof Inject)
|
||||
{
|
||||
type = InjectionType.INJECT;
|
||||
}
|
||||
else if (obj instanceof Append)
|
||||
{
|
||||
type = InjectionType.APPEND;
|
||||
}
|
||||
else if (obj instanceof Overwrite)
|
||||
{
|
||||
type = InjectionType.OVERWRITE;
|
||||
}
|
||||
else if (obj instanceof Prepend)
|
||||
{
|
||||
type = InjectionType.PREPEND;
|
||||
}
|
||||
else if (obj instanceof Provided)
|
||||
{
|
||||
type = InjectionType.PROVIDED;
|
||||
}
|
||||
}
|
||||
|
||||
String fieldOwner = field.getDeclaringClass().getSimpleName();
|
||||
String fieldName = field.getName();
|
||||
String fieldDescriptor = RefUtils.reobDescriptor(field.getSignature());
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
throw new RuntimeException(
|
||||
field.getDeclaringClass().getSimpleName() + "." + field.getName() + " is unannotated" +
|
||||
"!");
|
||||
}
|
||||
|
||||
if (type != InjectionType.PROVIDED && type != InjectionType.INJECT)
|
||||
{
|
||||
throw new RuntimeException(
|
||||
field.getDeclaringClass().getSimpleName() + "." + field.getName() + " has an invalid " +
|
||||
"annotation! @" + type);
|
||||
}
|
||||
|
||||
if (reobfuscate)
|
||||
{
|
||||
isFieldTagged.put(fieldOwner + " " + fieldName + " " + fieldDescriptor, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.parsers;
|
||||
|
||||
import us.runelitepl.mixinprocessor.util.WebUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
public class GamepackDownloader
|
||||
{
|
||||
|
||||
private static final String CONFIG_URL = "http://oldschool.runescape.com/jav_config.ws";
|
||||
private static String codebase;
|
||||
private static String initial_jar;
|
||||
|
||||
public static void downloadGamepack(HashMap<String, byte[]> output) throws IOException
|
||||
{
|
||||
parseConfig();
|
||||
byte[] gamepackJarAry = WebUtils.downloadFile(getGamepackUrl());
|
||||
ZipInputStream zipInputStream = new ZipInputStream(new ByteArrayInputStream(gamepackJarAry));
|
||||
byte[] buffer = new byte[2048];
|
||||
ZipEntry entry;
|
||||
ByteArrayOutputStream fileContent = new ByteArrayOutputStream(1024*1024*4);
|
||||
while ((entry = zipInputStream.getNextEntry()) != null)
|
||||
{
|
||||
if (entry.getName().startsWith("META-INF"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String key = entry.getName().replace(".class", "");
|
||||
int len = 0;
|
||||
while((len = zipInputStream.read(buffer)) > 0)
|
||||
{
|
||||
fileContent.write(buffer, 0, len);
|
||||
}
|
||||
output.put(key, fileContent.toByteArray());
|
||||
fileContent.reset();
|
||||
}
|
||||
zipInputStream.close();
|
||||
}
|
||||
|
||||
private static void parseConfig() throws IOException
|
||||
{
|
||||
String pageText = WebUtils.getUrlContent(CONFIG_URL);
|
||||
for (String line : pageText.split("\n"))
|
||||
{
|
||||
if (line.startsWith("codebase="))
|
||||
{
|
||||
codebase = line.replace("codebase=", "");
|
||||
}
|
||||
else if (line.startsWith("initial_jar="))
|
||||
{
|
||||
initial_jar = line.replace("initial_jar=", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String getGamepackUrl()
|
||||
{
|
||||
return codebase + initial_jar;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.parsers;
|
||||
|
||||
import us.runelitepl.mixinprocessor.MethodGarbageValue;
|
||||
import us.runelitepl.mixinprocessor.MixinProcessorMojo;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Map;
|
||||
|
||||
public class HooksParser
|
||||
{
|
||||
|
||||
public static void run(File hooksFile, File opsFile) throws IOException, ParseException
|
||||
{
|
||||
JSONParser parser = new JSONParser();
|
||||
//region hooksFile
|
||||
String jsonContent = String.join("\n", Files.readAllLines(hooksFile.toPath()));
|
||||
JSONArray array = (JSONArray) parser.parse(jsonContent);
|
||||
|
||||
for (Object object : array)
|
||||
{
|
||||
JSONObject rootObject = (JSONObject) object;
|
||||
String c_obbedName = (String) rootObject.get("name");
|
||||
String c_deobbedName = (String) rootObject.get("class");
|
||||
MixinProcessorMojo.classNames.put(c_deobbedName, c_obbedName);
|
||||
}
|
||||
|
||||
int failedFields = 0;
|
||||
int failedMethods = 0;
|
||||
for (Object object : array)
|
||||
{
|
||||
JSONObject rootObject = (JSONObject) object;
|
||||
|
||||
JSONArray fieldArray = (JSONArray) rootObject.get("fields");
|
||||
for (Object fieldObj : fieldArray)
|
||||
{
|
||||
JSONObject field = (JSONObject) fieldObj;
|
||||
String f_deobbedName = (String) field.get("field");
|
||||
String f_obbedName = (String) field.get("name");
|
||||
String f_descriptor = (String) field.get("descriptor");
|
||||
String f_owner = (String) field.get("owner");
|
||||
long f_decoder = (long) field.getOrDefault("decoder", (long) 1);
|
||||
String f_deobbedOwner = null;
|
||||
if(f_deobbedName.startsWith("__"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (Map.Entry<String, String> entry : MixinProcessorMojo.classNames.entrySet())
|
||||
{
|
||||
if (entry.getValue().equals(f_owner))
|
||||
{
|
||||
f_deobbedOwner = entry.getKey();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (f_deobbedOwner == null)
|
||||
{
|
||||
failedFields++;
|
||||
//stderr("Failed to find deobbed owner for field %s.%s %s", f_owner, f_obbedName, f_descriptor);
|
||||
continue;
|
||||
}
|
||||
MixinProcessorMojo.fieldNames.put(String.format("%s %s %s", f_deobbedOwner, f_deobbedName, f_descriptor),
|
||||
String.format("%s %s", f_owner, f_obbedName));
|
||||
MixinProcessorMojo.fieldDecoders.put(String.format("%s %s", f_deobbedOwner, f_deobbedName),
|
||||
f_decoder);
|
||||
}
|
||||
|
||||
JSONArray methodArray = (JSONArray) rootObject.get("methods");
|
||||
for (Object methodObj : methodArray)
|
||||
{
|
||||
JSONObject method = (JSONObject) methodObj;
|
||||
String m_deobbedName = (String) method.get("method");
|
||||
String m_owner = (String) method.get("owner");
|
||||
String m_deobbedOwner = null;
|
||||
String m_obbedName = (String) method.get("name");
|
||||
String m_descriptor = (String) method.get("descriptor");
|
||||
if(m_deobbedName.startsWith("__"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (Map.Entry<String, String> entry : MixinProcessorMojo.classNames.entrySet())
|
||||
{
|
||||
if (entry.getValue().equals(m_owner))
|
||||
{
|
||||
m_deobbedOwner = entry.getKey();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m_deobbedOwner == null)
|
||||
{
|
||||
failedMethods++;
|
||||
//stderr("Failed to find deobbed owner for method %s.%s %s", m_owner, m_obbedName, m_descriptor);
|
||||
continue;
|
||||
}
|
||||
MixinProcessorMojo.methodNames.put(String.format("%s %s %s", m_deobbedOwner, m_deobbedName, m_descriptor),
|
||||
String.format("%s %s", m_owner, m_obbedName));
|
||||
}
|
||||
}
|
||||
MixinProcessorMojo.log("%d unidentified fields", failedFields);
|
||||
MixinProcessorMojo.log("%d unidentified methods", failedMethods);
|
||||
//endregion
|
||||
|
||||
//region opsFile
|
||||
String opsContent = String.join("\n", Files.readAllLines(opsFile.toPath()));
|
||||
JSONObject opsRoot = (JSONObject) parser.parse(opsContent);
|
||||
opsRoot.forEach((key, value) ->
|
||||
{
|
||||
String k = (String) key;
|
||||
MixinProcessorMojo.methodGarbageValues.put(k, new MethodGarbageValue(Math.toIntExact((Long) value)));
|
||||
});
|
||||
//endregion
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.parsers;
|
||||
|
||||
import javassist.CtClass;
|
||||
import javassist.CtMethod;
|
||||
import us.runelitepl.mixinprocessor.MixinProcessorMojo;
|
||||
import us.runelitepl.mixinprocessor.annotations.Append;
|
||||
import us.runelitepl.mixinprocessor.annotations.Inject;
|
||||
import us.runelitepl.mixinprocessor.annotations.Overwrite;
|
||||
import us.runelitepl.mixinprocessor.annotations.Prepend;
|
||||
import us.runelitepl.mixinprocessor.annotations.Provided;
|
||||
import us.runelitepl.mixinprocessor.annotations.Reobfuscate;
|
||||
import us.runelitepl.mixinprocessor.enums.InjectionType;
|
||||
import us.runelitepl.mixinprocessor.util.RefUtils;
|
||||
|
||||
import static us.runelitepl.mixinprocessor.MixinProcessorMojo.isMethodTagged;
|
||||
|
||||
public class MethodAnnotationParser
|
||||
{
|
||||
|
||||
private final CtClass patch;
|
||||
|
||||
public MethodAnnotationParser(CtClass patch)
|
||||
{
|
||||
this.patch = patch;
|
||||
}
|
||||
|
||||
public void run() throws ClassNotFoundException
|
||||
{
|
||||
for(CtMethod method : patch.getDeclaredMethods())
|
||||
{
|
||||
Object[] annotations = method.getAnnotations();
|
||||
|
||||
boolean reobfuscate = false;
|
||||
InjectionType type = null;
|
||||
|
||||
for (Object obj : annotations)
|
||||
{
|
||||
reobfuscate = obj instanceof Reobfuscate || reobfuscate;
|
||||
if (obj instanceof Inject)
|
||||
{
|
||||
type = InjectionType.INJECT;
|
||||
}
|
||||
else if (obj instanceof Append)
|
||||
{
|
||||
type = InjectionType.APPEND;
|
||||
}
|
||||
else if (obj instanceof Overwrite)
|
||||
{
|
||||
type = InjectionType.OVERWRITE;
|
||||
}
|
||||
else if (obj instanceof Prepend)
|
||||
{
|
||||
type = InjectionType.PREPEND;
|
||||
}
|
||||
else if (obj instanceof Provided)
|
||||
{
|
||||
type = InjectionType.PROVIDED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
throw new RuntimeException(
|
||||
method.getDeclaringClass().getSimpleName() + "." + method.getName() + " is unannotated" +
|
||||
"!");
|
||||
}
|
||||
|
||||
String methodName = method.getName();
|
||||
if (type == InjectionType.PREPEND)
|
||||
{
|
||||
if (!methodName.startsWith("prepend$"))
|
||||
{
|
||||
throw new RuntimeException(
|
||||
method.getDeclaringClass().getSimpleName() + "." + method.getName() + " has a @Prepend " +
|
||||
"annotation without beginning with \"prepend$\"!");
|
||||
}
|
||||
}
|
||||
else if (type == InjectionType.APPEND)
|
||||
{
|
||||
if (!methodName.startsWith("append$"))
|
||||
{
|
||||
throw new RuntimeException(
|
||||
method.getDeclaringClass().getSimpleName() + "." + method.getName() + " has a @Append " +
|
||||
"annotation without beginning with \"append$\"!");
|
||||
}
|
||||
}
|
||||
|
||||
if(reobfuscate)
|
||||
{
|
||||
MixinProcessorMojo.log("Marking: %s %s %s", method.getDeclaringClass().getSimpleName(), methodName,
|
||||
RefUtils.reobMethodDescriptor(method.getSignature()));
|
||||
String r = String.format("%s %s %s", method.getDeclaringClass().getSimpleName(), methodName,
|
||||
RefUtils.reobMethodDescriptor(method.getSignature()));
|
||||
isMethodTagged.put(r, true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.parsers;
|
||||
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.Attribute;
|
||||
import org.objectweb.asm.Handle;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.TypePath;
|
||||
|
||||
public class MethodReflector extends MethodVisitor
|
||||
{
|
||||
|
||||
private MethodVisitor target;
|
||||
|
||||
public MethodReflector(MethodVisitor target)
|
||||
{
|
||||
super(Opcodes.ASM6);
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public void visitCode()
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitCode();
|
||||
}
|
||||
super.visitCode();
|
||||
}
|
||||
|
||||
public void visitEnd()
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitEnd();
|
||||
}
|
||||
super.visitEnd();
|
||||
}
|
||||
|
||||
public void visitParameter(String var1, int var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitParameter(var1, var2);
|
||||
}
|
||||
super.visitParameter(var1, var2);
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitAnnotationDefault()
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitAnnotationDefault();
|
||||
}
|
||||
return super.visitAnnotationDefault();
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitAnnotation(String var1, boolean var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitAnnotation(var1, var2);
|
||||
}
|
||||
return super.visitAnnotation(var1, var2);
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitTypeAnnotation(int var1, TypePath var2, String var3, boolean var4)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitTypeAnnotation(var1, var2, var3, var4);
|
||||
}
|
||||
return super.visitTypeAnnotation(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitParameterAnnotation(int var1, String var2, boolean var3)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitParameterAnnotation(var1, var2, var3);
|
||||
}
|
||||
return super.visitParameterAnnotation(var1, var2, var3);
|
||||
}
|
||||
|
||||
public void visitAttribute(Attribute var1)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitAttribute(var1);
|
||||
}
|
||||
super.visitAttribute(var1);
|
||||
}
|
||||
|
||||
public void visitFrame(int var1, int var2, Object[] var3, int var4, Object[] var5)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitFrame(var1, var2, var3, var4, var5);
|
||||
}
|
||||
super.visitFrame(var1, var2, var3, var4, var5);
|
||||
}
|
||||
|
||||
public void visitInsn(int var1)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitInsn(var1);
|
||||
}
|
||||
super.visitInsn(var1);
|
||||
}
|
||||
|
||||
public void visitIntInsn(int var1, int var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitIntInsn(var1, var2);
|
||||
}
|
||||
super.visitIntInsn(var1, var2);
|
||||
}
|
||||
|
||||
public void visitVarInsn(int var1, int var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitVarInsn(var1, var2);
|
||||
}
|
||||
super.visitVarInsn(var1, var2);
|
||||
}
|
||||
|
||||
public void visitTypeInsn(int var1, String var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitTypeInsn(var1, var2);
|
||||
}
|
||||
super.visitTypeInsn(var1, var2);
|
||||
}
|
||||
|
||||
public void visitFieldInsn(int var1, String var2, String var3, String var4)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitFieldInsn(var1, var2, var3, var4);
|
||||
}
|
||||
super.visitFieldInsn(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public void visitMethodInsn(int var1, String var2, String var3, String var4)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitMethodInsn(var1, var2, var3, var4);
|
||||
}
|
||||
super.visitMethodInsn(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
public void visitMethodInsn(int var1, String var2, String var3, String var4, boolean var5)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitMethodInsn(var1, var2, var3, var4, var5);
|
||||
}
|
||||
super.visitMethodInsn(var1, var2, var3, var4, var5);
|
||||
}
|
||||
|
||||
public void visitInvokeDynamicInsn(String var1, String var2, Handle var3, Object... var4)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitInvokeDynamicInsn(var1, var2, var3, var4);
|
||||
}
|
||||
super.visitInvokeDynamicInsn(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
public void visitJumpInsn(int var1, Label var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitJumpInsn(var1, var2);
|
||||
}
|
||||
super.visitJumpInsn(var1, var2);
|
||||
}
|
||||
|
||||
public void visitLabel(Label var1)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitLabel(var1);
|
||||
}
|
||||
super.visitLabel(var1);
|
||||
}
|
||||
|
||||
public void visitLdcInsn(Object var1)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitLdcInsn(var1);
|
||||
}
|
||||
super.visitLdcInsn(var1);
|
||||
}
|
||||
|
||||
public void visitIincInsn(int var1, int var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitIincInsn(var1, var2);
|
||||
}
|
||||
super.visitIincInsn(var1, var2);
|
||||
}
|
||||
|
||||
public void visitTableSwitchInsn(int var1, int var2, Label var3, Label... var4)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitTableSwitchInsn(var1, var2, var3, var4);
|
||||
}
|
||||
super.visitTableSwitchInsn(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
public void visitLookupSwitchInsn(Label var1, int[] var2, Label[] var3)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitLookupSwitchInsn(var1, var2, var3);
|
||||
}
|
||||
super.visitLookupSwitchInsn(var1, var2, var3);
|
||||
}
|
||||
|
||||
public void visitMultiANewArrayInsn(String var1, int var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitMultiANewArrayInsn(var1, var2);
|
||||
}
|
||||
super.visitMultiANewArrayInsn(var1, var2);
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitInsnAnnotation(int var1, TypePath var2, String var3, boolean var4)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitInsnAnnotation(var1, var2, var3, var4);
|
||||
}
|
||||
return super.visitInsnAnnotation(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
public void visitTryCatchBlock(Label var1, Label var2, Label var3, String var4)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitTryCatchBlock(var1, var2, var3, var4);
|
||||
}
|
||||
super.visitTryCatchBlock(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitTryCatchAnnotation(int var1, TypePath var2, String var3, boolean var4)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitTryCatchAnnotation(var1, var2, var3, var4);
|
||||
}
|
||||
return super.visitTryCatchAnnotation(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
public void visitLocalVariable(String var1, String var2, String var3, Label var4, Label var5, int var6)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitLocalVariable(var1, var2, var3, var4, var5, var6);
|
||||
}
|
||||
super.visitLocalVariable(var1, var2, var3, var4, var5, var6);
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitLocalVariableAnnotation(int var1, TypePath var2, Label[] var3, Label[] var4, int[] var5, String var6, boolean var7)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitLocalVariableAnnotation(var1, var2, var3, var4, var5, var6, var7);
|
||||
}
|
||||
return super.visitLocalVariableAnnotation(var1, var2, var3, var4, var5, var6, var7);
|
||||
}
|
||||
|
||||
public void visitLineNumber(int var1, Label var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitLineNumber(var1, var2);
|
||||
}
|
||||
super.visitLineNumber(var1, var2);
|
||||
}
|
||||
|
||||
public void visitMaxs(int var1, int var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitMaxs(var1, var2);
|
||||
}
|
||||
super.visitMaxs(var1, var2);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.transformers;
|
||||
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
public class AnnotationRemoverTransformer extends AsmBaseTransformer
|
||||
{
|
||||
|
||||
private final String className;
|
||||
private final byte[] bytecode;
|
||||
|
||||
public AnnotationRemoverTransformer(String className, byte[] bytecode)
|
||||
{
|
||||
this.className = className;
|
||||
this.bytecode = bytecode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] transform()
|
||||
{
|
||||
ClassReader cr = new ClassReader(bytecode);
|
||||
ClassWriter cw = new ClassWriter(cr, 0);
|
||||
cr.accept(new ClassVisitor(Opcodes.ASM6, cw)
|
||||
{
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
|
||||
{
|
||||
MethodVisitor visitor = super.visitMethod(access, name, desc, signature, exceptions);
|
||||
MethodVisitor mv = new MethodVisitor(Opcodes.ASM6, visitor)
|
||||
{
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String descriptor, boolean hidden)
|
||||
{
|
||||
if (descriptor.equals(makeAnnotationDescriptor("Reobfuscate")))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return super.visitAnnotation(descriptor, hidden);
|
||||
}
|
||||
};
|
||||
return mv;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value)
|
||||
{
|
||||
FieldVisitor visitor = super.visitField(access, name, descriptor, signature, value);
|
||||
return new FieldVisitor(Opcodes.ASM6, visitor)
|
||||
{
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String descriptor, boolean hidden)
|
||||
{
|
||||
if (descriptor.equals(makeAnnotationDescriptor("Reobfuscate")))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (descriptor.equals(makeAnnotationDescriptor("Provided")))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return super.visitAnnotation(descriptor, hidden);
|
||||
}
|
||||
};
|
||||
}
|
||||
}, 0);
|
||||
return cw.toByteArray();
|
||||
}
|
||||
|
||||
public static String makeAnnotationDescriptor(String s)
|
||||
{
|
||||
return "Lus/runelitepl/mixinprocessor/annotations/" + s + ";";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.transformers;
|
||||
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public abstract class AsmBaseTransformer implements Opcodes
|
||||
{
|
||||
|
||||
protected final ArrayList<String> validMethods = new ArrayList<>();
|
||||
protected final ArrayList<String> validFields = new ArrayList<>();
|
||||
|
||||
protected void buildMethodList(){}
|
||||
|
||||
protected void buildFieldList(){}
|
||||
|
||||
public abstract byte[] transform();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.transformers;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import us.runelitepl.mixinprocessor.MethodGarbageValue;
|
||||
import us.runelitepl.mixinprocessor.MixinProcessorMojo;
|
||||
import us.runelitepl.mixinprocessor.util.RefUtils;
|
||||
|
||||
import java.sql.Ref;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class AsmMethodGarbageTransformer extends AsmBaseTransformer
|
||||
{
|
||||
|
||||
private final String className;
|
||||
private final byte[] bytecode;
|
||||
private HashMap<String, byte[]> classSet;
|
||||
|
||||
public AsmMethodGarbageTransformer(String className, byte[] bytecode, HashMap<String, byte[]> classSet)
|
||||
{
|
||||
this.className = className;
|
||||
this.bytecode = bytecode;
|
||||
this.classSet = classSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] transform()
|
||||
{
|
||||
|
||||
ClassReader cr = new ClassReader(bytecode);
|
||||
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES);
|
||||
|
||||
cr.accept(new ClassVisitor(ASM6, cw)
|
||||
{
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
|
||||
{
|
||||
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
|
||||
return new MethodVisitor(ASM6, mv)
|
||||
{
|
||||
@Override
|
||||
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf)
|
||||
{
|
||||
// get method owner.string(desc)
|
||||
// check if method is annotated with @Reobfuscate
|
||||
// brute force actual descriptor (check with shouldReobMethod(owner, name desc) )
|
||||
// mv.visitLdcInsn(BIPUSH, constant);
|
||||
// call super method with new descriptor
|
||||
|
||||
if(RefUtils.shouldReobMethod(owner, name, desc))
|
||||
{
|
||||
String nc = RefUtils.reobMethodName(owner, name, desc).split(" ")[0];
|
||||
String nn = RefUtils.reobMethodName(owner, name, desc).split(" ")[1];
|
||||
String nd = RefUtils.reobMethodDescriptor(desc);
|
||||
MethodGarbageValue value;
|
||||
if((value = MixinProcessorMojo.methodGarbageValues.getOrDefault(String.format("%s.%s%s",
|
||||
nc, nn, nd), null)) != null)
|
||||
{
|
||||
switch (value.getType())
|
||||
{
|
||||
case "I":
|
||||
super.visitLdcInsn(new Integer(value.getValue()));
|
||||
break;
|
||||
case "S":
|
||||
super.visitIntInsn(SIPUSH, (short) value.getValue());
|
||||
break;
|
||||
case "B":
|
||||
super.visitIntInsn(BIPUSH, (byte) value.getValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.visitMethodInsn(opcode, owner, name, desc, itf);
|
||||
}
|
||||
};
|
||||
}
|
||||
}, 0);
|
||||
|
||||
return cw.toByteArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.transformers;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import us.runelitepl.mixinprocessor.MixinProcessorMojo;
|
||||
import us.runelitepl.mixinprocessor.util.RefUtils;
|
||||
|
||||
public class AsmMethodSignatureTransformer extends AsmBaseTransformer
|
||||
{
|
||||
|
||||
private final String className;
|
||||
private final byte[] bytecode;
|
||||
|
||||
public AsmMethodSignatureTransformer(String className, byte[] bytecode)
|
||||
{
|
||||
this.className = RefUtils.deobClassName(className);
|
||||
this.bytecode = bytecode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] transform()
|
||||
{
|
||||
ClassReader cr = new ClassReader(bytecode);
|
||||
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES);
|
||||
|
||||
cr.accept(new ClassVisitor(ASM6, cw)
|
||||
{
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String sig, String[] exceptions)
|
||||
{
|
||||
MethodVisitor mv = super.visitMethod(access, name, fixMethodDesc(className, name, desc), sig, exceptions);
|
||||
return new MethodVisitor(ASM6, mv)
|
||||
{
|
||||
@Override
|
||||
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf)
|
||||
{
|
||||
super.visitMethodInsn(opcode, owner, name, fixMethodDesc(owner, name, desc), itf);
|
||||
}
|
||||
};
|
||||
}
|
||||
}, 0);
|
||||
|
||||
return cw.toByteArray();
|
||||
}
|
||||
|
||||
private String fixMethodDesc(String className, String name, String desc)
|
||||
{
|
||||
if(className.startsWith(RefUtils.TYPE_PREFIX))
|
||||
{
|
||||
className = className.substring(RefUtils.TYPE_PREFIX.length());
|
||||
}
|
||||
if (RefUtils.shouldReobMethod(className, name, desc))
|
||||
{
|
||||
if (RefUtils.reobMethodName(className, name, desc) == null)
|
||||
{
|
||||
// get correct descriptor
|
||||
String realDesc = null;
|
||||
for (String s : RefUtils.POSSIBLE_GARBAGE_TYPES)
|
||||
{
|
||||
String check = RefUtils.reobMethodName(className, name, RefUtils.appendArgument(desc, s));
|
||||
if (check != null)
|
||||
{
|
||||
realDesc = RefUtils.appendArgument(desc, s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (realDesc == null)
|
||||
{
|
||||
MixinProcessorMojo.log("Failed to find actual method descriptor for %s.%s%s", className,
|
||||
name, desc);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
// fixed = realDesc
|
||||
MixinProcessorMojo.isMethodTagged.put(String.format("%s %s %s", className, name, realDesc), true);
|
||||
return realDesc;
|
||||
}
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.transformers;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.commons.ClassRemapper;
|
||||
import org.objectweb.asm.commons.Remapper;
|
||||
import us.runelitepl.mixinprocessor.MixinProcessorMojo;
|
||||
import us.runelitepl.mixinprocessor.util.RefUtils;
|
||||
|
||||
public class AsmNameTransformer extends AsmBaseTransformer
|
||||
{
|
||||
|
||||
private String className;
|
||||
private byte[] bytecode;
|
||||
|
||||
public AsmNameTransformer(String className, byte[] bytecode)
|
||||
{
|
||||
this.className = className;
|
||||
this.bytecode = bytecode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] transform()
|
||||
{
|
||||
ClassReader cr = new ClassReader(bytecode);
|
||||
ClassWriter cw = new ClassWriter(cr, 0);
|
||||
ClassRemapper remapper = new ClassRemapper(cw, new Remapper()
|
||||
{
|
||||
|
||||
final String TYPE_PREFIX = "us/runelitepl/mixins/";
|
||||
|
||||
@Override
|
||||
public String map(String internalName)
|
||||
{
|
||||
return super.map(internalName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mapDesc(String descriptor)
|
||||
{
|
||||
return RefUtils.reobDescriptor(descriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mapFieldName(String owner, String name, String descriptor)
|
||||
{
|
||||
String oldName = name;
|
||||
String noPackage = owner.replace(TYPE_PREFIX, "");
|
||||
|
||||
descriptor = mapDesc(descriptor);
|
||||
|
||||
owner = RefUtils.reobClassName(owner);
|
||||
if (RefUtils.shouldReobField(noPackage, name, descriptor))
|
||||
{
|
||||
name = RefUtils.reobFieldName(noPackage, name, descriptor);
|
||||
if (name == null)
|
||||
{
|
||||
MixinProcessorMojo.log("Failed to reobfuscate field name %s.%s", noPackage, oldName);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
return super.mapFieldName(owner, name, descriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mapInvokeDynamicMethodName(String name, String descriptor)
|
||||
{
|
||||
throw new UnsupportedOperationException("mapInvokeDynamicMethodName: Not implemented yet," +
|
||||
"\nAsmNameTransformer#mapInvokeDynamicMethodName(" + name + ", " + descriptor + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mapMethodDesc(String descriptor)
|
||||
{
|
||||
return RefUtils.reobMethodDescriptor(descriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mapMethodName(String owner, String name, String descriptor)
|
||||
{
|
||||
String originalClass = owner;
|
||||
if (originalClass.startsWith(TYPE_PREFIX))
|
||||
{
|
||||
originalClass = originalClass.substring(TYPE_PREFIX.length());
|
||||
}
|
||||
owner = RefUtils.reobClassName(owner);
|
||||
if (name.startsWith("protect$"))
|
||||
{
|
||||
name = "1" + name;
|
||||
}
|
||||
// descriptor for reob checking is obfuscated
|
||||
descriptor = mapMethodDesc(descriptor);
|
||||
boolean reob = RefUtils.shouldReobMethod(originalClass, name, descriptor);
|
||||
|
||||
if (reob)
|
||||
{
|
||||
String originalName = name;
|
||||
name = RefUtils.reobMethodName(originalClass, name, descriptor);
|
||||
if (name == null)
|
||||
{
|
||||
MixinProcessorMojo.log("Failed to reobfuscate method: %s.%s%s", originalClass, originalName,
|
||||
descriptor);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//stderr("mapMethodName %s %s %s", owner, name, descriptor);
|
||||
return super.mapMethodName(owner, name, descriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mapPackageName(String name)
|
||||
{
|
||||
throw new UnsupportedOperationException("mapPackageName: Not implemented yet," +
|
||||
"\nAsmNameTransformer#mapPackageName(" + name + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mapSignature(String signature, boolean isTypeSig)
|
||||
{
|
||||
return super.mapSignature(signature, isTypeSig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mapType(String internalName)
|
||||
{
|
||||
internalName = RefUtils.reobClassName(internalName);
|
||||
return super.mapType(internalName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] mapTypes(String[] internalNames)
|
||||
{
|
||||
return super.mapTypes(internalNames);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object mapValue(Object value)
|
||||
{
|
||||
return super.mapValue(value);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
cr.accept(remapper, 0);
|
||||
|
||||
return cw.toByteArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.transformers;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import us.runelitepl.mixinprocessor.MixinProcessorMojo;
|
||||
import us.runelitepl.mixinprocessor.util.RefUtils;
|
||||
|
||||
import static org.objectweb.asm.Opcodes.ASM6;
|
||||
import static org.objectweb.asm.Opcodes.GETSTATIC;
|
||||
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
|
||||
import static org.objectweb.asm.Opcodes.PUTSTATIC;
|
||||
|
||||
public class AsmStaticUsageTransformer extends AsmBaseTransformer
|
||||
{
|
||||
|
||||
private String className;
|
||||
private byte[] bytecode;
|
||||
private final String TYPE_PREFIX = "us/runelitepl/mixins/";
|
||||
|
||||
public AsmStaticUsageTransformer(String className, byte[] bytecode)
|
||||
{
|
||||
this.className = className;
|
||||
this.bytecode = bytecode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] transform()
|
||||
{
|
||||
ClassReader cr = new ClassReader(bytecode);
|
||||
ClassWriter cw = new ClassWriter(cr, 0);
|
||||
ClassVisitor cv = new ClassVisitor(ASM6, cw)
|
||||
{
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions)
|
||||
{
|
||||
MethodVisitor visitor = super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
return new MethodVisitor(ASM6, visitor)
|
||||
{
|
||||
@Override
|
||||
public void visitFieldInsn(int opcode, String owner, String name, String descriptor)
|
||||
{
|
||||
if ((opcode == GETSTATIC || opcode == PUTSTATIC) && owner.endsWith(RefUtils.STATICS_STRING))
|
||||
{
|
||||
String oldName = name;
|
||||
String originalOwner = owner.replace(TYPE_PREFIX, "");
|
||||
String temp = RefUtils.reobFieldNameDangerous(name, RefUtils.reobDescriptor(descriptor));
|
||||
if (temp == null)
|
||||
{
|
||||
MixinProcessorMojo.log("Failed to reobfuscate class name for field %s %s %s", owner,
|
||||
name, descriptor);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
owner = temp.split(" ")[0];
|
||||
if (RefUtils.shouldReobField(originalOwner, name, RefUtils.reobDescriptor(descriptor)))
|
||||
{
|
||||
name = temp.split(" ")[1];
|
||||
}
|
||||
}
|
||||
super.visitFieldInsn(opcode, owner, name, descriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface)
|
||||
{
|
||||
if(opcode == INVOKESTATIC && owner.endsWith(RefUtils.STATICS_STRING))
|
||||
{
|
||||
String originalOwner = owner.replace(TYPE_PREFIX, "");
|
||||
String temp = RefUtils.reobMethodName(RefUtils.STATICS_STRING, name, descriptor);
|
||||
if (temp == null)
|
||||
{
|
||||
MixinProcessorMojo.log("Failed to reobfuscate class name for method %s %s %s", owner,
|
||||
name, descriptor);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
owner = temp.split(" ")[0];
|
||||
if (RefUtils.shouldReobMethod(originalOwner, name, descriptor))
|
||||
{
|
||||
name = temp.split(" ")[1];
|
||||
}
|
||||
}
|
||||
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
cr.accept(cv, 0);
|
||||
|
||||
return cw.toByteArray();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.transformers;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
|
||||
public class DoNothingTransformer extends AsmBaseTransformer
|
||||
{
|
||||
|
||||
private final String className;
|
||||
private final byte[] bytecode;
|
||||
|
||||
public DoNothingTransformer(String className, byte[] bytecode)
|
||||
{
|
||||
this.className = className;
|
||||
this.bytecode = bytecode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] transform()
|
||||
{
|
||||
|
||||
ClassReader cr = new ClassReader(bytecode);
|
||||
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES);
|
||||
|
||||
cr.accept(new ClassVisitor(ASM6, cw)
|
||||
{}, 0);
|
||||
|
||||
return cw.toByteArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.transformers;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import us.runelitepl.mixinprocessor.MixinProcessorMojo;
|
||||
import us.runelitepl.mixinprocessor.util.RefUtils;
|
||||
|
||||
public class GetFieldDecoderTransformer extends AsmBaseTransformer
|
||||
{
|
||||
|
||||
private final String className;
|
||||
private final byte[] classFileBytecode;
|
||||
|
||||
public GetFieldDecoderTransformer(String className, byte[] bytes)
|
||||
{
|
||||
this.className = className;
|
||||
this.classFileBytecode = bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildMethodList()
|
||||
{
|
||||
ClassReader cr = new ClassReader(classFileBytecode);
|
||||
ClassWriter cw = new ClassWriter(cr, 0);
|
||||
cr.accept(new ClassVisitor(Opcodes.ASM6, cw)
|
||||
{
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature,
|
||||
String[] exceptions)
|
||||
{
|
||||
final boolean[] valid = {true};
|
||||
MethodVisitor visitor = super.visitMethod(access, name, desc, signature, exceptions);
|
||||
return new MethodVisitor(Opcodes.ASM6, visitor)
|
||||
{
|
||||
int opcodeCount = 0;
|
||||
|
||||
@Override
|
||||
public void visitEnd()
|
||||
{
|
||||
if (valid[0])
|
||||
{
|
||||
MixinProcessorMojo.log("Valid method: %s %s %s %s", access, name, desc, signature);
|
||||
validMethods.add(access + " " + name + " " + desc + " " + signature);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitVarInsn(int opcode, int var)
|
||||
{
|
||||
if (opcode != Opcodes.ALOAD || var != 0 || opcodeCount != 0)
|
||||
{
|
||||
valid[0] = false;
|
||||
}
|
||||
opcodeCount++;
|
||||
|
||||
super.visitVarInsn(opcode, var);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFieldInsn(int opcode, String owner, String fieldName, String signature)
|
||||
{
|
||||
if (opcode != Opcodes.GETFIELD || opcodeCount != 1)
|
||||
{
|
||||
valid[0] = false;
|
||||
}
|
||||
opcodeCount++;
|
||||
|
||||
super.visitFieldInsn(opcode, owner, fieldName, signature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLdcInsn(Object o)
|
||||
{
|
||||
if (!(o instanceof Integer) && !(o instanceof Long))
|
||||
{
|
||||
valid[0] = false;
|
||||
}
|
||||
if (opcodeCount != 2)
|
||||
{
|
||||
valid[0] = false;
|
||||
}
|
||||
opcodeCount++;
|
||||
super.visitLdcInsn(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInsn(int opcode)
|
||||
{
|
||||
switch (opcode)
|
||||
{
|
||||
case Opcodes.IMUL:
|
||||
if (opcodeCount != 3)
|
||||
{
|
||||
valid[0] = false;
|
||||
}
|
||||
break;
|
||||
case Opcodes.IRETURN:
|
||||
if (opcodeCount != 4)
|
||||
{
|
||||
valid[0] = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
valid[0] = false;
|
||||
break;
|
||||
}
|
||||
opcodeCount++;
|
||||
super.visitInsn(opcode);
|
||||
}
|
||||
};
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
public byte[] transform()
|
||||
{
|
||||
buildMethodList();
|
||||
ClassReader cr = new ClassReader(classFileBytecode);
|
||||
ClassWriter cw = new ClassWriter(cr, 0);
|
||||
cr.accept(new ClassVisitor(Opcodes.ASM6, cw)
|
||||
{
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
|
||||
{
|
||||
MethodVisitor visitor = super.visitMethod(access, name, desc, signature, exceptions);
|
||||
if (!validMethods.contains(access + " " + name + " " + desc + " " + signature))
|
||||
{
|
||||
return visitor;
|
||||
}
|
||||
return new MethodVisitor(Opcodes.ASM6, visitor)
|
||||
{
|
||||
String target = null;
|
||||
|
||||
@Override
|
||||
public void visitFieldInsn(int opcode, String owner, String fieldName, String signature)
|
||||
{
|
||||
target = fieldName;
|
||||
super.visitFieldInsn(opcode, owner, fieldName, signature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitLdcInsn(Object o)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
if (o instanceof Long)
|
||||
{
|
||||
o = MixinProcessorMojo.fieldDecoders.getOrDefault(
|
||||
RefUtils.deobClassName(className) + " " + target, 1L);
|
||||
}
|
||||
else
|
||||
{
|
||||
o = Math.toIntExact(MixinProcessorMojo.fieldDecoders.getOrDefault(RefUtils.deobClassName(className) +
|
||||
" " + target,
|
||||
1L));
|
||||
}
|
||||
}
|
||||
MixinProcessorMojo.log("\tGetFieldDecoderTransformer: %s %s %s %s %s",
|
||||
RefUtils.deobClassName(className), name, target, desc, o);
|
||||
super.visitLdcInsn(o);
|
||||
}
|
||||
};
|
||||
}
|
||||
}, 0);
|
||||
return cw.toByteArray();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.transformers;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.AnnotationNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
import us.runelitepl.mixinprocessor.MixinProcessorMojo;
|
||||
|
||||
public class ProvidedRemoverTransformer extends AsmBaseTransformer
|
||||
{
|
||||
|
||||
private final String className;
|
||||
private final byte[] bytecode;
|
||||
|
||||
public ProvidedRemoverTransformer(String className, byte[] bytecode)
|
||||
{
|
||||
this.className = className;
|
||||
this.bytecode = bytecode;
|
||||
}
|
||||
|
||||
public void buildMethodList()
|
||||
{
|
||||
ClassReader cr = new ClassReader(bytecode);
|
||||
ClassNode node = new ClassNode();
|
||||
cr.accept(node, 0);
|
||||
|
||||
for(Object obj : node.methods)
|
||||
{
|
||||
MethodNode method = (MethodNode) obj;
|
||||
if(method == null)
|
||||
{
|
||||
MixinProcessorMojo.log("ProvidedRemoverTransformer: Method null?");
|
||||
continue;
|
||||
}
|
||||
if(method.visibleAnnotations == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for(Object obj2 : method.visibleAnnotations)
|
||||
{
|
||||
AnnotationNode annot = (AnnotationNode) obj2;
|
||||
if(annot.desc.equals(AnnotationRemoverTransformer.makeAnnotationDescriptor("Provided")))
|
||||
{
|
||||
validMethods.add(method.access + " " + method.desc + " " + method.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] transform()
|
||||
{
|
||||
buildMethodList();
|
||||
ClassReader cr = new ClassReader(bytecode);
|
||||
ClassWriter cw = new ClassWriter(cr, 0);
|
||||
cr.accept(new ClassVisitor(Opcodes.ASM6, cw)
|
||||
{
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature,
|
||||
String[] exceptions)
|
||||
{
|
||||
if(validMethods.contains(access + " " + desc + " " + name))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return super.visitMethod(access, name, desc, signature, exceptions);
|
||||
}
|
||||
}, 0);
|
||||
|
||||
return cw.toByteArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.util;
|
||||
|
||||
import javassist.CannotCompileException;
|
||||
import javassist.CtClass;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class JavassistUtils
|
||||
{
|
||||
|
||||
public static byte[] getClassBytecode(CtClass clazz) throws IOException, CannotCompileException
|
||||
{
|
||||
clazz.stopPruning(true);
|
||||
byte[] retVal = clazz.toBytecode();
|
||||
clazz.defrost();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.util;
|
||||
|
||||
import us.runelitepl.mixinprocessor.MixinProcessorMojo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class RefUtils
|
||||
{
|
||||
|
||||
public static final String TYPE_PREFIX = "us/runelitepl/mixins/";
|
||||
public static final String STATICS_STRING = "_Statics_";
|
||||
public static final String[] POSSIBLE_GARBAGE_TYPES = {"I", "B", "S"};
|
||||
|
||||
public static String deobClassName(String obbed)
|
||||
{
|
||||
for (Map.Entry<String, String> entry : MixinProcessorMojo.classNames.entrySet())
|
||||
{
|
||||
if (entry.getValue().equals(obbed))
|
||||
{
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
return obbed;
|
||||
}
|
||||
|
||||
public static String getObbedClassName(String deob)
|
||||
{
|
||||
return MixinProcessorMojo.classNames.getOrDefault(deob, deob);
|
||||
}
|
||||
|
||||
public static String reobClassName(String deobbed)
|
||||
{
|
||||
String old = deobbed;
|
||||
if (deobbed.contains("/"))
|
||||
{
|
||||
deobbed = deobbed.replaceAll(TYPE_PREFIX, "");
|
||||
deobbed = getObbedClassName(deobbed);
|
||||
if (deobbed == null)
|
||||
{
|
||||
return old;
|
||||
}
|
||||
}
|
||||
return deobbed;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String reobFieldNameDangerous(String deob, String desc)
|
||||
{
|
||||
int i = 0;
|
||||
Map.Entry<String, String> e1 = null;
|
||||
for (Map.Entry<String, String> entry : MixinProcessorMojo.fieldNames.entrySet())
|
||||
{
|
||||
if (entry.getKey().endsWith(deob + " " + desc))
|
||||
{
|
||||
i++;
|
||||
e1 = entry;
|
||||
}
|
||||
}
|
||||
if (i == 1)
|
||||
{
|
||||
return e1.getValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String reobMethodNameDangerous(String deob, String signature)
|
||||
{
|
||||
int i = 0;
|
||||
Map.Entry<String, String> e1 = null;
|
||||
for (Map.Entry<String, String> entry : MixinProcessorMojo.methodNames.entrySet())
|
||||
{
|
||||
if (entry.getKey().endsWith(" " + deob + " " + signature))
|
||||
{
|
||||
i++;
|
||||
e1 = entry;
|
||||
}
|
||||
}
|
||||
if (i == 1)
|
||||
{
|
||||
return e1.getValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String reobFieldName(String owner, String deob, String desc)
|
||||
{
|
||||
if (owner.equals(RefUtils.STATICS_STRING))
|
||||
{
|
||||
return reobFieldNameDangerous(deob, desc);
|
||||
}
|
||||
String asd = MixinProcessorMojo.fieldNames.getOrDefault(owner + " " + deob + " " + desc, null);
|
||||
if (asd == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return asd.split(" ")[1];
|
||||
}
|
||||
|
||||
public static String reobMethodName(String owner, String deob, String signature)
|
||||
{
|
||||
String prefix = "";
|
||||
if(owner.startsWith(RefUtils.TYPE_PREFIX))
|
||||
{
|
||||
owner = owner.substring(RefUtils.TYPE_PREFIX.length());
|
||||
}
|
||||
if (deob.startsWith("prepend$"))
|
||||
{
|
||||
prefix = "prepend$";
|
||||
deob = deob.substring("prepend$".length());
|
||||
}
|
||||
else if (deob.startsWith("append$"))
|
||||
{
|
||||
prefix = "append$";
|
||||
deob = deob.substring("append$".length());
|
||||
}
|
||||
if (owner.equals(RefUtils.STATICS_STRING))
|
||||
{
|
||||
String retVal = reobMethodNameDangerous(deob, signature);
|
||||
if (retVal == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String[] split = retVal.split(" ");
|
||||
split[1] = prefix + split[1];
|
||||
return String.join(" ", split);
|
||||
}
|
||||
String asd = MixinProcessorMojo.methodNames.getOrDefault(owner + " " + deob + " " + signature, null);
|
||||
if (asd == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return prefix + asd.split(" ")[1];
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static boolean shouldReobFieldDangerous(String deob, String desc)
|
||||
{
|
||||
int i = 0;
|
||||
for (Map.Entry<String, Boolean> entry : MixinProcessorMojo.isFieldTagged.entrySet())
|
||||
{
|
||||
if (entry.getKey().endsWith(deob + " " + desc))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (i == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static boolean shouldReobMethodDangerous(String deob, String desc)
|
||||
{
|
||||
int i = 0;
|
||||
for (Map.Entry<String, Boolean> entry : MixinProcessorMojo.isMethodTagged.entrySet())
|
||||
{
|
||||
if (entry.getKey().endsWith(" " + deob + " " + desc))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (i == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean shouldReobField(String owner, String deob, String desc)
|
||||
{
|
||||
if (owner.equals(RefUtils.STATICS_STRING))
|
||||
{
|
||||
return shouldReobFieldDangerous(deob, desc);
|
||||
}
|
||||
return MixinProcessorMojo.isFieldTagged.getOrDefault(owner + " " + deob + " " + desc, false);
|
||||
}
|
||||
|
||||
public static boolean shouldReobMethod(String owner, String deob, String desc)
|
||||
{
|
||||
if(owner.startsWith(RefUtils.TYPE_PREFIX))
|
||||
{
|
||||
owner = owner.substring(RefUtils.TYPE_PREFIX.length());
|
||||
}
|
||||
if (owner.equals(RefUtils.STATICS_STRING))
|
||||
{
|
||||
return shouldReobMethodDangerous(deob, desc);
|
||||
}
|
||||
return MixinProcessorMojo.isMethodTagged.getOrDefault(owner + " " + deob + " " + desc, false);
|
||||
}
|
||||
|
||||
public static String reobDescriptor(String descriptor)
|
||||
{
|
||||
if (!descriptor.startsWith("L"))
|
||||
{
|
||||
return descriptor;
|
||||
}
|
||||
if (!descriptor.contains("us/runelitepl/mixins/"))
|
||||
{
|
||||
return descriptor;
|
||||
}
|
||||
String orig = descriptor;
|
||||
descriptor = descriptor.replace("us/runelitepl/mixins/", "");
|
||||
descriptor = descriptor.substring(1, descriptor.length() - 1);
|
||||
descriptor = getObbedClassName(descriptor);
|
||||
if (descriptor == null)
|
||||
{
|
||||
return orig;
|
||||
}
|
||||
return "L" + descriptor + ";";
|
||||
}
|
||||
|
||||
public static String reobMethodDescriptor(String descriptor)
|
||||
{
|
||||
int strIndex = 0;
|
||||
if (descriptor.charAt(0) != '(')
|
||||
{
|
||||
throw new IllegalArgumentException("sig is not a method signature: " + descriptor);
|
||||
}
|
||||
StringBuilder deobbed = new StringBuilder(1024 * 1024);
|
||||
while (strIndex < descriptor.length())
|
||||
{
|
||||
switch (descriptor.charAt(strIndex))
|
||||
{
|
||||
case '(':
|
||||
case ')':
|
||||
case 'I':
|
||||
case 'B':
|
||||
case 'J':
|
||||
case 'S':
|
||||
case 'D':
|
||||
case 'F':
|
||||
case 'C':
|
||||
case 'Z':
|
||||
case 'V':
|
||||
case '[':
|
||||
deobbed.append(descriptor.charAt(strIndex));
|
||||
strIndex++;
|
||||
break;
|
||||
case 'L':
|
||||
try
|
||||
{
|
||||
String sigPart = descriptor.substring(strIndex, descriptor.indexOf(";", strIndex) + 1);
|
||||
String className = sigPart.substring(1, sigPart.length() - 1);
|
||||
className = className.replace(TYPE_PREFIX, "");
|
||||
String obbedName = MixinProcessorMojo.classNames.getOrDefault(className, null);
|
||||
if (obbedName == null)
|
||||
{
|
||||
obbedName = className;
|
||||
}
|
||||
deobbed.append("L" + obbedName + ";");
|
||||
strIndex += sigPart.length();
|
||||
}
|
||||
catch (StringIndexOutOfBoundsException ex)
|
||||
{
|
||||
System.err.println(
|
||||
"Method signature %s is probably missing a semi-colon".replace("%s", descriptor));
|
||||
throw ex;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("signature is invalid: " + descriptor);
|
||||
}
|
||||
}
|
||||
return deobbed.toString();
|
||||
}
|
||||
|
||||
public static String appendArgument(String desc, String append)
|
||||
{
|
||||
int strIndex = 0;
|
||||
if (desc.charAt(0) != '(')
|
||||
{
|
||||
throw new IllegalArgumentException("sig is not a method signature: " + desc);
|
||||
}
|
||||
StringBuilder deobbed = new StringBuilder(1024 * 1024);
|
||||
while (strIndex < desc.length())
|
||||
{
|
||||
switch (desc.charAt(strIndex))
|
||||
{
|
||||
case ')':
|
||||
deobbed.append(append);
|
||||
deobbed.append(")");
|
||||
strIndex++;
|
||||
break;
|
||||
case '(':
|
||||
case 'I':
|
||||
case 'B':
|
||||
case 'J':
|
||||
case 'S':
|
||||
case 'D':
|
||||
case 'F':
|
||||
case 'C':
|
||||
case 'Z':
|
||||
case 'V':
|
||||
case '[':
|
||||
deobbed.append(desc.charAt(strIndex));
|
||||
strIndex++;
|
||||
break;
|
||||
case 'L':
|
||||
try
|
||||
{
|
||||
String sigPart = desc.substring(strIndex, desc.indexOf(";", strIndex) + 1);
|
||||
deobbed.append(sigPart);
|
||||
strIndex += sigPart.length();
|
||||
}
|
||||
catch (StringIndexOutOfBoundsException ex)
|
||||
{
|
||||
System.err.println(
|
||||
"Method signature %s is probably missing a semi-colon".replace("%s", desc));
|
||||
throw ex;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("signature is invalid: " + desc);
|
||||
}
|
||||
}
|
||||
return deobbed.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class WebUtils
|
||||
{
|
||||
|
||||
public static String getUrlContent(String url) throws IOException
|
||||
{
|
||||
String pageText;
|
||||
URLConnection conn = new URL(url).openConnection();
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)))
|
||||
{
|
||||
pageText = reader.lines().collect(Collectors.joining("\n"));
|
||||
}
|
||||
return pageText;
|
||||
}
|
||||
|
||||
public static byte[] downloadFile(String urlText) throws IOException {
|
||||
URL url = new URL(urlText);
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
|
||||
try (InputStream inputStream = url.openStream()) {
|
||||
int n = 0;
|
||||
byte [] buffer = new byte[ 1024 ];
|
||||
while (-1 != (n = inputStream.read(buffer))) {
|
||||
output.write(buffer, 0, n);
|
||||
}
|
||||
}
|
||||
|
||||
return output.toByteArray();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
864
extended-mixins/gamepack.deob.jar.op.json
Normal file
864
extended-mixins/gamepack.deob.jar.op.json
Normal file
@@ -0,0 +1,864 @@
|
||||
{
|
||||
"aa.aa(IILw;I)V" : -2035282490,
|
||||
"aa.ab(IILjava/util/HashSet;IB)V" : 1,
|
||||
"aa.ae(Lat;Ljd;IIFB)V" : 2,
|
||||
"aa.ah(Ljava/util/HashSet;IIB)V" : 3,
|
||||
"aa.ai(Ljd;I)Lay;" : 868142981,
|
||||
"aa.aq(IIIIII)Ljava/util/List;" : 1174387475,
|
||||
"aa.at(Ljd;IIB)V" : 2,
|
||||
"aa.av(IILjava/util/HashSet;IB)V" : 1,
|
||||
"aa.aw(Ljd;IIIIB)V" : 2,
|
||||
"aa.az(IIIIB)V" : 1,
|
||||
"aa.b(I)V" : -734187576,
|
||||
"aa.c(IILw;[Llv;I)V" : -2131355084,
|
||||
"aa.e(ILar;[Llv;Liz;Liz;I)V" : 16776959,
|
||||
"aa.f(IIIILw;I)V" : 935523592,
|
||||
"aa.g(IIIB)V" : 8,
|
||||
"aa.h(Liz;Ljava/lang/String;Ljava/lang/String;I)Llv;" : -751125902,
|
||||
"aa.h(Ljava/util/HashSet;Ljava/util/List;I)V" : 761583671,
|
||||
"aa.js(Lia;S)V" : 179,
|
||||
"aa.k(IILw;Lar;I)V" : -912761612,
|
||||
"aa.l(Lar;[Llv;Laf;I)V" : -1342196991,
|
||||
"aa.m(I)V" : -1460781870,
|
||||
"aa.n(Liz;B)Z" : -3,
|
||||
"aa.o(Lar;[Llv;Laf;I)V" : 1404817235,
|
||||
"aa.p(Ljy;IIILw;I)V" : 451857695,
|
||||
"aa.q(Ljava/util/List;I)V" : 457654499,
|
||||
"aa.r(IIILjava/util/HashSet;I)V" : 866122217,
|
||||
"aa.t(Ljava/util/HashSet;IIB)V" : 1,
|
||||
"aa.x(Liz;Ljava/lang/String;Ljava/lang/String;I)[Llv;" : -6949303,
|
||||
"aa.y(IILw;Lar;Laf;I)V" : -1385397238,
|
||||
"ab.ar(Ldo;I)V" : -1176858873,
|
||||
"ac.ao(ILcs;ZI)I" : 1813401528,
|
||||
"ac.h(II)V" : 1006232361,
|
||||
"ac.jy([Lia;IIIIIIIB)V" : -1,
|
||||
"ad.hv(IIIIIIII)V" : -430708112,
|
||||
"ad.it(I)V" : -983568512,
|
||||
"ae.t(II)I" : 784278107,
|
||||
"af.a(I)Z" : -2131769709,
|
||||
"af.a(Liz;Liz;I)Z" : -1899763683,
|
||||
"ag.a(Lgx;IB)V" : -1,
|
||||
"ag.ai(ILcs;ZB)I" : -1,
|
||||
"ag.f(III)Lif;" : -435462727,
|
||||
"ag.g(IIII)Z" : 318472532,
|
||||
"ag.h(IIII)[I" : -199162200,
|
||||
"ag.p(I)V" : -1011260827,
|
||||
"ag.x(IIS)Z" : 5119,
|
||||
"ah.kc(Lia;II)Ljava/lang/String;" : -1474185799,
|
||||
"aj.cg(Lgx;ZI)V" : -1515872014,
|
||||
"aj.ch(Lgx;Lgx;IZB)V" : 0,
|
||||
"aj.jw(Lia;III)V" : 572830405,
|
||||
"aj.kk(Lia;I)Ljava/lang/String;" : -96310975,
|
||||
"aj.x(Lge;II)V" : 628965387,
|
||||
"ak.ki(II)V" : -1090851287,
|
||||
"ak.s(Ljava/lang/String;I)Z" : -1560533677,
|
||||
"an.a(Lag;B)V" : -1,
|
||||
"an.at(ILcs;ZI)I" : 1073402399,
|
||||
"an.g(III)Z" : 1060896560,
|
||||
"an.h(III)Lif;" : -175568126,
|
||||
"an.iw(Ljg;IIIS)V" : 1400,
|
||||
"an.m(I)V" : 734935008,
|
||||
"an.s(IIII)Z" : -1346882543,
|
||||
"an.x(IIIB)[I" : 2,
|
||||
"ap.a(I)V" : 75666286,
|
||||
"ap.g(I)I" : 2098880503,
|
||||
"ap.h(I)V" : 1211258439,
|
||||
"aq.a(Lag;B)V" : -1,
|
||||
"aq.g(III)Z" : 1060896560,
|
||||
"aq.h(III)Lif;" : -175568126,
|
||||
"aq.iu(IIIILjava/lang/String;Ljava/lang/String;III)V" : -1659892465,
|
||||
"aq.s(IIII)Z" : -1346882543,
|
||||
"aq.x(IIIB)[I" : 2,
|
||||
"ar.a(IIIIIIIII)V" : -2059524070,
|
||||
"ar.aj(ILcs;ZI)I" : 1205981872,
|
||||
"ar.b(I)V" : -901714140,
|
||||
"ar.e(I)V" : -478549233,
|
||||
"ar.f(I)V" : 452761503,
|
||||
"ar.g(II)I" : 1269863705,
|
||||
"ar.h(I)V" : -1899763684,
|
||||
"ar.m(I)V" : -1516729905,
|
||||
"ar.n(I)V" : -58041941,
|
||||
"ar.p(B)V" : 2,
|
||||
"ar.q(I)V" : -1649013667,
|
||||
"ar.s(III)I" : -1801980882,
|
||||
"ar.s(Lbr;II)V" : 1598019254,
|
||||
"ar.x(I)V" : 1645884426,
|
||||
"as.a(Lgx;I)V" : -1899763684,
|
||||
"as.hn(III)V" : -16711937,
|
||||
"as.s(Lfs;Lgb;I)Lfa;" : 92068864,
|
||||
"as.s(Lgx;I)V" : -1171328621,
|
||||
"at.aw(Lfo;IIB)Lcz;" : -1,
|
||||
"at.hy(III)I" : 1565568466,
|
||||
"at.k(III)Z" : 600452826,
|
||||
"at.o(III)Z" : 915702491,
|
||||
"at.u(B)Z" : 10,
|
||||
"at.y(III)Z" : -1304203093,
|
||||
"av.a(Liz;Ljava/lang/String;ZI)V" : -1168992218,
|
||||
"av.b(I)V" : -317778031,
|
||||
"av.f(IIIIIIIIIII)Ljava/util/List;" : 1272296080,
|
||||
"av.fd(I)V" : -1013343582,
|
||||
"av.g(IIIIIIIII)V" : 1968023039,
|
||||
"av.gn(I)V" : -1529421636,
|
||||
"av.h(IIIILjava/util/HashSet;III)V" : -1503826011,
|
||||
"av.lt(IIIZI)V" : 1023839648,
|
||||
"av.n(III)F" : -2092073595,
|
||||
"av.p(IIIII)Li;" : 54912543,
|
||||
"av.x(IIIIIIIILjava/util/HashSet;Ljava/util/HashSet;IIZI)V" : -350567508,
|
||||
"aw.gf(I)Z" : -25482427,
|
||||
"ax.ge(IIIIS)V" : 254,
|
||||
"ay.a(Lge;I)V" : 413663544,
|
||||
"ay.f(II)V" : -1832203148,
|
||||
"ay.fa(Lia;III)V" : -2035282490,
|
||||
"ay.fb(IB)V" : -1,
|
||||
"ay.s(II)Ljd;" : 256302879,
|
||||
"ay.s(Lin;IIIBZI)V" : 488112187,
|
||||
"az.jl(Lia;IIZI)V" : 321367859,
|
||||
"az.k(IIB)Z" : 1,
|
||||
"az.s(III)I" : -1587813654,
|
||||
"b.s(IB)Ljy;" : 1,
|
||||
"b.x(B)I" : 2,
|
||||
"ba.a(IB)Lcs;" : -1,
|
||||
"ba.a(II)V" : -1476367704,
|
||||
"ba.m([BIIIIIIILen;[Lfk;S)V" : 3138,
|
||||
"ba.q(I)Ldv;" : 270868885,
|
||||
"ba.s(IIIIB)V" : -1,
|
||||
"bb.a(IIILfk;I)Z" : -747978109,
|
||||
"bb.hw(B)V" : 0,
|
||||
"bc.a(I)J" : 1696302624,
|
||||
"bc.aa(Ljava/lang/String;S)V" : 335,
|
||||
"bc.ah(Lkx;B)Z" : 0,
|
||||
"bc.c(Ljava/lang/String;I)V" : 582720271,
|
||||
"bc.f(Lkx;ZB)Z" : 1,
|
||||
"bc.g(Lgx;IB)V" : 0,
|
||||
"bc.im(III)V" : 2028526097,
|
||||
"bc.l(B)Z" : 2,
|
||||
"bc.m(Ljava/lang/String;B)V" : 125,
|
||||
"bc.o(Ljava/lang/String;I)V" : -1157261130,
|
||||
"bc.p(Lkx;I)Z" : -1555038210,
|
||||
"bc.v(I)Z" : -1393904298,
|
||||
"bc.x(I)V" : 1950661086,
|
||||
"bd.ie(II)V" : 181127396,
|
||||
"bd.o(ILcs;ZI)I" : 413151829,
|
||||
"be.iv(IIIII)V" : -325933819,
|
||||
"be.n(Lia;II)V" : 1817349453,
|
||||
"be.s(Ljava/lang/String;B)Ljava/io/File;" : 2,
|
||||
"be.u(ILcs;ZB)I" : 0,
|
||||
"be.x([BB)Lcs;" : 11,
|
||||
"bf.aa(B)V" : 101,
|
||||
"bf.ab(I)V" : 142936820,
|
||||
"bf.ah(S)V" : 200,
|
||||
"bf.ai(Ljava/lang/String;I)V" : -790939352,
|
||||
"bf.al(I)Llh;" : -1432486026,
|
||||
"bf.an(I)V" : -668210151,
|
||||
"bf.aq(B)Ljava/awt/Container;" : 17,
|
||||
"bf.as(ILjava/lang/String;ZI)V" : -1600069416,
|
||||
"bf.b(I)V" : -1709249029,
|
||||
"bf.c(I)Z" : 671133062,
|
||||
"bf.e(I)V" : -721353869,
|
||||
"bf.f(Ljava/lang/Object;I)V" : 721091452,
|
||||
"bf.h(III)V" : -508854098,
|
||||
"bf.k(IIIB)V" : 1,
|
||||
"bf.l(B)V" : 1,
|
||||
"bf.p(B)Lff;" : 1,
|
||||
"bf.t(I)V" : -1101149948,
|
||||
"bf.v(I)V" : 546631502,
|
||||
"bg.a(IS)Ljc;" : 129,
|
||||
"bh.a(Lm;Lm;I)I" : -513481130,
|
||||
"bh.g(I)Lbt;" : -1460580553,
|
||||
"bh.gg(I)V" : 283302901,
|
||||
"bi.e(ILcs;ZI)I" : -1073407294,
|
||||
"bi.gd(I)V" : -2017298644,
|
||||
"bj.a(IB)Z" : 29,
|
||||
"bj.a(Lgx;I)Ljava/lang/Integer;" : 781966774,
|
||||
"bk.gu(Lbq;I)V" : -847852752,
|
||||
"bk.jc(II)Z" : -1251166831,
|
||||
"bk.ku(IIII)Lbk;" : -2131355082,
|
||||
"bl.a(CI)B" : 1789306866,
|
||||
"bl.f(Ljava/lang/Object;ZI)[B" : -1859268163,
|
||||
"bl.g(I)Z" : 459972945,
|
||||
"bl.jv(Lia;I)Lia;" : 388836110,
|
||||
"bl.m(B)V" : -2,
|
||||
"bl.p(B)V" : 3,
|
||||
"bl.x(I)V" : -2005241970,
|
||||
"bl.x(IB)Z" : 0,
|
||||
"bm.a(IIIIB)V" : 0,
|
||||
"bm.s(IB)Lby;" : -2,
|
||||
"bn.g(I)V" : 260585226,
|
||||
"bn.id([Lia;IIIIIIIIB)V" : 8,
|
||||
"bn.io(Ljava/lang/String;Lia;B)Ljava/lang/String;" : 30,
|
||||
"bn.s(ZZI)Llv;" : 1183417792,
|
||||
"bn.x(Lbf;B)V" : 5,
|
||||
"bo.a(IB)Ljf;" : 3,
|
||||
"bo.av(ILcs;ZI)I" : -1854356000,
|
||||
"bo.f(Lge;B)V" : 2,
|
||||
"bo.f(Ljava/awt/event/MouseEvent;I)I" : 578646374,
|
||||
"bo.il(IIIII)V" : 1757949424,
|
||||
"bp.a(I)Z" : -1433048567,
|
||||
"bp.a(II)Lln;" : 302241702,
|
||||
"bq.a(Lin;II)V" : 1001198726,
|
||||
"bq.bd(IIIIIII)V" : 611628477,
|
||||
"bq.bi(II)V" : -1433857362,
|
||||
"bq.bz(IIIIIII)V" : 1567325514,
|
||||
"bq.f(ILcs;ZI)I" : -1899763682,
|
||||
"bq.f(Lbu;Lbu;IZIZI)I" : 1226102711,
|
||||
"bq.h(ILcs;ZB)I" : -1,
|
||||
"br.kv(Ljava/lang/String;ZI)V" : 1790593369,
|
||||
"bs.a(I)V" : -355288644,
|
||||
"bs.av([BB)[B" : 1,
|
||||
"bs.ji(III)V" : 548342891,
|
||||
"bt.at(I)V" : -1263025777,
|
||||
"bt.gi(Lbq;II)V" : -1529490784,
|
||||
"bt.s(I)Lgx;" : 74387722,
|
||||
"bt.s(IIII)I" : -781205087,
|
||||
"bt.v(ILcs;ZB)I" : 1,
|
||||
"bu.a(IIB)I" : 1,
|
||||
"bu.b(I)Z" : -1114257374,
|
||||
"bu.e(I)Z" : -1716454843,
|
||||
"bu.h([BZI)Ljava/lang/Object;" : 738732180,
|
||||
"bu.n(I)Z" : 1001949846,
|
||||
"bu.r(I)Z" : -1318371617,
|
||||
"bu.t(I)Z" : -556326313,
|
||||
"bv.a(I)V" : 1118589205,
|
||||
"bv.is(Ljava/lang/String;Ljava/lang/String;IIIIZI)V" : 936248646,
|
||||
"bw.a(IILfu;Lfk;I)Z" : -1973878234,
|
||||
"bw.a(Lgx;B)V" : 9,
|
||||
"bw.b(IIBI)V" : 1555038206,
|
||||
"bw.e(IIBB)V" : -1,
|
||||
"bw.h(B)V" : 126,
|
||||
"bw.h(I)Z" : -1285553478,
|
||||
"bw.m(B)I" : 1,
|
||||
"bw.p(B)V" : 8,
|
||||
"bw.q(I)Ldv;" : 270868885,
|
||||
"bw.r(I)Z" : -1348553985,
|
||||
"bw.s(B)Z" : 1,
|
||||
"bw.x(B)V" : 100,
|
||||
"bx.q(Lia;I[B[BB)V" : 0,
|
||||
"bx.s(IB)Ljx;" : -2,
|
||||
"by.ad(II)V" : -264070302,
|
||||
"by.ah(IZII)V" : 261286606,
|
||||
"bz.jn([Lia;Lia;ZI)V" : 1459213909,
|
||||
"bz.t(ILcs;ZB)I" : 3,
|
||||
"c.ib(IIIII)V" : 27853463,
|
||||
"c.r(I)V" : 1334087347,
|
||||
"cb.aa(ILcs;ZI)I" : 599221667,
|
||||
"cb.az(ILcs;ZI)I" : -1971585838,
|
||||
"cb.iz(IIIIIIIII)V" : 1136998422,
|
||||
"cf.a([Ljava/lang/String;[SIIB)V" : 82,
|
||||
"cf.q(IIIZII)J" : -184362900,
|
||||
"cf.s(IB)Lia;" : -1,
|
||||
"cg.h(II)I" : 368462775,
|
||||
"cg.n(IIIB)I" : 13,
|
||||
"ch.aw(ILcs;ZB)I" : -1,
|
||||
"ch.s(CII)C" : 1742925831,
|
||||
"ch.x(Ljava/lang/String;B)Ljava/lang/Class;" : 0,
|
||||
"ck.h(B)V" : 1,
|
||||
"ck.s(B)V" : 1,
|
||||
"ck.x(IS)Z" : 2047,
|
||||
"client.ae(I)V" : 839842829,
|
||||
"client.aj(I)V" : -1093400736,
|
||||
"client.au(ZB)V" : -2,
|
||||
"client.av(B)V" : 1,
|
||||
"client.ff(II)V" : -920552638,
|
||||
"client.fi(I)V" : 610258376,
|
||||
"client.fm(I)V" : -465272380,
|
||||
"client.fo(I)V" : -401328439,
|
||||
"client.fu(B)V" : 0,
|
||||
"client.gh(B)V" : 2,
|
||||
"client.gl(I)V" : -265842676,
|
||||
"client.hg(Lck;I)Z" : 16776961,
|
||||
"client.ic(I)Z" : 1896111338,
|
||||
"client.ip(ZB)V" : 15,
|
||||
"client.iy(I)V" : -1774724327,
|
||||
"client.ja(Lia;I)V" : 838714686,
|
||||
"client.ju(I)V" : -756058437,
|
||||
"client.ln(I)Lkx;" : 49412185,
|
||||
"client.r(I)V" : -1611272948,
|
||||
"client.x(CII)I" : 1762474913,
|
||||
"cm.a(IBI)V" : 65534,
|
||||
"cm.hd(IIIIIIII)V" : -759447942,
|
||||
"cm.q(I)Ldv;" : 270868885,
|
||||
"cm.r(I)Z" : -1348553985,
|
||||
"cm.s(IIZI)V" : 1378146881,
|
||||
"co.q(I)Ldv;" : 270868885,
|
||||
"cq.a(III)V" : -1070186518,
|
||||
"cq.b(B)V" : -1,
|
||||
"cq.gr(Ljava/lang/String;ZI)V" : -389570792,
|
||||
"cq.n(B)V" : 9,
|
||||
"cq.p(B)V" : -1,
|
||||
"cq.q(I)V" : 628907907,
|
||||
"cq.s(IB)I" : -1,
|
||||
"cq.x(II)Ljava/lang/String;" : -324172300,
|
||||
"cr.a(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;B)Lbl;" : 1,
|
||||
"cr.s(II)Lbl;" : -1908347194,
|
||||
"ct.a(IIIII)V" : -1426623809,
|
||||
"ct.g(I)V" : 2019467883,
|
||||
"ct.kb(Ljava/lang/String;I)V" : 1782634305,
|
||||
"ct.p(Liz;II)Llv;" : 495439929,
|
||||
"ct.q(I)Ldv;" : 270868885,
|
||||
"ct.s(II)V" : 63583155,
|
||||
"cx.m(B)Lld;" : 3,
|
||||
"cy.hr(IB)V" : 1,
|
||||
"cz.aj(II)V" : 1893251924,
|
||||
"cz.at(I)V" : 1969212074,
|
||||
"cz.au(B)V" : -1,
|
||||
"cz.p([BIILen;[Lfk;I)V" : -402226336,
|
||||
"da.b(CB)Z" : 1,
|
||||
"da.f([BIII)I" : 1742376717,
|
||||
"da.s([BIIB)V" : -1,
|
||||
"da.x(ZI)V" : 495439931,
|
||||
"de.g(CB)C" : 13,
|
||||
"de.g(IIB)Lcs;" : 1,
|
||||
"de.g([BB)V" : 2,
|
||||
"de.x(B)V" : 9,
|
||||
"di.a([Ljava/lang/CharSequence;III)Ljava/lang/String;" : -1699387444,
|
||||
"di.jr(Lia;IB)I" : 17,
|
||||
"di.ko(Lia;IIII)V" : -529963254,
|
||||
"di.y(ILcs;ZI)I" : 1635420646,
|
||||
"dn.a([BI)[B" : -56213800,
|
||||
"dn.g(II)I" : -1564370717,
|
||||
"dn.ka([Lia;II)V" : -958295899,
|
||||
"dn.s(IS)I" : 16382,
|
||||
"dp.a(Ljava/lang/String;Ljava/lang/Throwable;B)V" : -1,
|
||||
"dp.gz(I)V" : 174309589,
|
||||
"ds.a(II[II)Lce;" : -1829245270,
|
||||
"ds.g(I[II)Lce;" : -915277422,
|
||||
"ds.s(II[II)Lce;" : 453356516,
|
||||
"ds.x(I[IB)Lce;" : 0,
|
||||
"du.a(I)I" : 705859952,
|
||||
"du.f(II)Z" : -159952212,
|
||||
"du.g(II)[I" : 1412569886,
|
||||
"du.m(IB)V" : 0,
|
||||
"du.p(I)V" : 674605951,
|
||||
"du.x(II)I" : -1592582549,
|
||||
"dw.b(Len;[Lfk;I)V" : 1851320005,
|
||||
"dw.n(Lbu;B)V" : -1,
|
||||
"dx.a(IIS)I" : 4999,
|
||||
"dx.f(I)V" : -787206662,
|
||||
"dx.g(I)V" : -1550843987,
|
||||
"dx.h([BIIB)V" : 2,
|
||||
"dx.m(B)V" : 3,
|
||||
"dx.p([BIIB)V" : 1,
|
||||
"dy.h(Ljava/lang/CharSequence;IZI)I" : 1182321164,
|
||||
"dz.s(II)Ljh;" : -12306362,
|
||||
"dz.s(II)Ljt;" : -1553990030,
|
||||
"e.a(I[BLfb;B)V" : 0,
|
||||
"e.fv(IB)V" : 6,
|
||||
"e.fz(IIB)V" : 0,
|
||||
"e.ho(ZLge;I)V" : -753481020,
|
||||
"ea.a(Lkl;Lkl;I)I" : 236661620,
|
||||
"ed.a(Lkl;Lkl;I)I" : -1524067389,
|
||||
"ed.gt(Lbq;IIIIII)V" : -845922968,
|
||||
"ee.a(Lkl;Lkl;S)I" : 1500,
|
||||
"ee.fw(B)V" : 5,
|
||||
"ef.g(Ljava/lang/String;ILjava/lang/String;I)Z" : -1896003594,
|
||||
"ef.hc(ZLge;B)V" : 49,
|
||||
"ef.jg([Lia;IB)V" : 25,
|
||||
"ef.x(IZIZI)V" : -1718068584,
|
||||
"eg.a(Lkl;Lkl;I)I" : 843610507,
|
||||
"eg.ac(ILcs;ZB)I" : 127,
|
||||
"eg.s(IB)Ljn;" : 8,
|
||||
"eh.a(II)Lju;" : -686750587,
|
||||
"eh.ft(ZS)V" : 513,
|
||||
"eh.s(II)Lix;" : 449632382,
|
||||
"eh.s(Ljava/io/File;ZI)Z" : 16711935,
|
||||
"ei.jd([Lia;IIIZI)V" : -720054478,
|
||||
"ei.p(II)I" : 1187869470,
|
||||
"ej.a(Lkl;Lkl;I)I" : -1498357881,
|
||||
"ej.gs(Lbw;I)Z" : 2018992164,
|
||||
"ek.s(IIILjy;II)V" : 655507997,
|
||||
"el.a(Lkl;Lkl;I)I" : -1691508553,
|
||||
"el.x(I)V" : -992218542,
|
||||
"em.a(Ljava/io/File;I)V" : -919664594,
|
||||
"em.kl(Lia;IIII)V" : -32275069,
|
||||
"em.s(Ljava/lang/CharSequence;I)Z" : -1575825717,
|
||||
"ep.ab(ILcs;ZI)I" : -1899763684,
|
||||
"ep.b(II)Lei;" : -1071218384,
|
||||
"ep.s(III)V" : -523356652,
|
||||
"eq.a(Lkl;Lkl;B)I" : -2,
|
||||
"er.jo(Lia;IIIIIII)V" : -37715201,
|
||||
"er.m(ILcs;ZB)I" : -1,
|
||||
"es.n([BI)V" : 1477873953,
|
||||
"et.q(CI)Z" : 601159240,
|
||||
"et.x(II)I" : -4454457,
|
||||
"eu.a(Lkl;Lkl;I)I" : -847269360,
|
||||
"eu.s(III)V" : -1808152535,
|
||||
"ev.hi(IIZB)V" : 18,
|
||||
"ey.a(Lkl;Lkl;I)I" : 2046444105,
|
||||
"ey.g(Ljava/lang/String;Ljava/lang/String;ZB)Lda;" : 2,
|
||||
"f.a(Lm;Lm;I)I" : 1846671743,
|
||||
"f.g(ILcs;ZI)I" : 908537385,
|
||||
"f.g(Lgx;II)V" : -1787245950,
|
||||
"f.kp(Ljava/lang/String;ZB)Ljava/lang/String;" : 0,
|
||||
"f.kt(Lia;I)I" : 557758524,
|
||||
"fa.hj(IIII)I" : -127120834,
|
||||
"fa.p(Lkt;Lkt;Lkt;ZB)V" : -1,
|
||||
"fa.x(B)V" : -1,
|
||||
"fb.a(II)[B" : 663352422,
|
||||
"fb.g(I[BIZB)Z" : 15,
|
||||
"fb.s(I[BII)Z" : 345161743,
|
||||
"fc.lh(I)V" : -861855527,
|
||||
"fc.r(ILcs;ZI)I" : 2006195166,
|
||||
"fg.a(B)V" : 2,
|
||||
"fg.a(S)Lfa;" : 10144,
|
||||
"fg.h(Lge;II)Z" : 97676263,
|
||||
"fg.ix(II)Ljava/lang/String;" : 198383047,
|
||||
"fg.s(III)I" : 1327459530,
|
||||
"fh.hs(IIB)V" : 0,
|
||||
"fh.s(II)Ljg;" : 620258019,
|
||||
"fi.a(II)Z" : 1354142902,
|
||||
"fi.a(Lll;B)I" : -1,
|
||||
"fi.f(B)V" : 0,
|
||||
"fi.g(I)I" : -827937127,
|
||||
"fi.k([BIII)V" : -1233693102,
|
||||
"fi.kw(Ljava/lang/String;B)V" : 3,
|
||||
"fi.x(IIIIIIB)I" : 2,
|
||||
"fi.x([BIIB)I" : 1,
|
||||
"fj.a(II)Z" : -1899763683,
|
||||
"fj.a(Ljava/io/File;Ljava/io/File;I)V" : -1114998342,
|
||||
"fj.g(B)I" : 0,
|
||||
"fj.g(IIIIIIB)I" : 79,
|
||||
"fj.h(B)V" : 0,
|
||||
"fj.s(B)I" : 1,
|
||||
"fj.x([BIII)I" : -1210405788,
|
||||
"fk.a(I)V" : -611770194,
|
||||
"fk.g(IIIIZB)V" : 1,
|
||||
"fk.m(IIIIIZB)V" : 1,
|
||||
"fk.p(IIIIZI)V" : -500057817,
|
||||
"fk.s(IIIIZI)V" : 1637050670,
|
||||
"fl.a(II)Lje;" : 1521679245,
|
||||
"fm.ht(IIII)V" : -523356652,
|
||||
"fo.a([BILjava/lang/CharSequence;I)I" : 1159428966,
|
||||
"fo.g([BIIII[Lfk;I)V" : 1327459530,
|
||||
"fp.s(III)I" : 1327459530,
|
||||
"ft.gc(Lbw;ZS)V" : 257,
|
||||
"fu.as(ILcs;ZI)I" : 302016509,
|
||||
"fu.s(Lge;B)V" : 48,
|
||||
"fv.a(Liz;Liz;ZII)V" : -1720129294,
|
||||
"fv.g(IIB)I" : 13,
|
||||
"fw.s(IS)V" : 259,
|
||||
"fx.a(B)Z" : 3,
|
||||
"fx.ar(ILcs;ZI)I" : -31137372,
|
||||
"fx.s([BIIB)V" : 70,
|
||||
"fy.a([BII[BII)I" : 1944979934,
|
||||
"fy.s([BI[BIIB)I" : 20,
|
||||
"fz.q(Llv;I)V" : -1078540656,
|
||||
"g.kx(S)V" : 2502,
|
||||
"gb.a(B)I" : 1,
|
||||
"gb.g(I)V" : 521895284,
|
||||
"gb.s(I)I" : 99718613,
|
||||
"gb.x(I)V" : -155012128,
|
||||
"gc.a(IIII)I" : -1899763684,
|
||||
"gc.c(ILcs;ZB)I" : -1,
|
||||
"gc.h(IIIZIZB)V" : 23,
|
||||
"gc.u(III)I" : 23878205,
|
||||
"ge.a(Liz;IIB)[Lld;" : 23,
|
||||
"ge.jp(I)Z" : -703700792,
|
||||
"ge.jq(II)I" : 1887118654,
|
||||
"ge.jr(I)I" : -1075465045,
|
||||
"ge.jt([BIII)V" : 1292793924,
|
||||
"ge.kj(I)V" : -91714,
|
||||
"gh.l(ILcs;ZB)I" : 76,
|
||||
"gi.p(Ljava/lang/CharSequence;B)I" : 8,
|
||||
"gj.ga(I)V" : -2035282490,
|
||||
"gm.x(Ljava/lang/CharSequence;I)[B" : -1293404993,
|
||||
"gn.a(Lgx;[BI)V" : -858327323,
|
||||
"go.a(IZI)[B" : -1296589171,
|
||||
"gq.a(Ljava/lang/CharSequence;Ljava/lang/CharSequence;IB)I" : 5,
|
||||
"gq.h(IIB)I" : 1,
|
||||
"gq.kr(IIIILld;Lhk;I)V" : -1418612472,
|
||||
"gx.ac(B)I" : 31,
|
||||
"gx.ad(B)I" : -1,
|
||||
"gx.ai([BIII)V" : -594273166,
|
||||
"gx.aj(S)Ljava/lang/String;" : 257,
|
||||
"gx.ak([IIII)V" : -81741600,
|
||||
"gx.al(B)I" : -1,
|
||||
"gx.am([IIIB)V" : 0,
|
||||
"gx.ao(I)I" : -316163985,
|
||||
"gx.ap([II)V" : 1621051798,
|
||||
"gx.aq(I)I" : -442414275,
|
||||
"gx.ar(I)Ljava/lang/String;" : 770756333,
|
||||
"gx.as(I)Ljava/lang/String;" : -721135627,
|
||||
"gx.au(I)Ljava/lang/String;" : 1888102756,
|
||||
"gx.aw(I)I" : -2142523386,
|
||||
"gx.ax([II)V" : -1139374613,
|
||||
"gx.az(I)I" : -1651491166,
|
||||
"gx.b(ZI)V" : 1173873020,
|
||||
"gx.be(S)Z" : 1107,
|
||||
"gx.bu(I)I" : 2024662838,
|
||||
"gx.by(I)I" : 1509644456,
|
||||
"gx.c(II)V" : 1219514079,
|
||||
"gx.ch([BIII)V" : 763323993,
|
||||
"gx.e(Ljava/lang/String;I)V" : 1504225874,
|
||||
"gx.f(IZI)Ljava/lang/String;" : 582940071,
|
||||
"gx.g(I)V" : -134910295,
|
||||
"gx.h(ZI)V" : 1980995418,
|
||||
"gx.l(Ljava/lang/CharSequence;I)V" : 1863463456,
|
||||
"gx.o([BIII)V" : -757753561,
|
||||
"gx.t(Ljava/lang/String;I)V" : -997423168,
|
||||
"gx.v(II)V" : -1392094080,
|
||||
"gy.gq(Lbq;I)V" : 33031345,
|
||||
"gz.ly(I)V" : 1339304,
|
||||
"h.p(Lbu;Lbu;IZI)I" : -1748952325,
|
||||
"h.s(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V" : 763156645,
|
||||
"hb.a(Lhl;[IIIII)V" : 1090105654,
|
||||
"hb.hf(B)V" : -1,
|
||||
"hb.s(Lhl;II)V" : -809158812,
|
||||
"hc.a(Lds;[B[IB)Z" : 2,
|
||||
"hc.gv(III)V" : -543069418,
|
||||
"hc.r(CI)Z" : 1679390240,
|
||||
"hk.a(III)Z" : -1128121077,
|
||||
"hk.as(Ljy;B)Z" : 1,
|
||||
"hk.b(Lia;IIIB)V" : 3,
|
||||
"hl.an(ILcs;ZI)I" : -1910103371,
|
||||
"hl.x(ILcs;ZI)I" : 385664937,
|
||||
"hn.ab(II)V" : -36819028,
|
||||
"hn.ah(II)V" : -1345756874,
|
||||
"hn.ak(Lhl;I)I" : -520794056,
|
||||
"hn.al(II)V" : -598595792,
|
||||
"hn.am(Lhl;I)I" : -1122132199,
|
||||
"hn.an(I)V" : 59932716,
|
||||
"hn.ao(IS)V" : 128,
|
||||
"hn.at(IB)V" : 1,
|
||||
"hn.aw(II)V" : 167541606,
|
||||
"hn.ax(Lhl;I)I" : 657286058,
|
||||
"hn.b(Lhx;ZI)V" : -1551737624,
|
||||
"hn.be(Lhl;[IIII)Z" : 92154578,
|
||||
"hn.bf(B)V" : 1,
|
||||
"hn.bo(Lhl;I)Z" : 1592628248,
|
||||
"hn.g(Lhx;Liz;Lds;II)Z" : 338728781,
|
||||
"hn.k(IIIB)V" : 1,
|
||||
"hn.ls(Lgx;I)V" : -1236370027,
|
||||
"hn.o(III)V" : 522712138,
|
||||
"hn.u(IIII)V" : -1441077132,
|
||||
"hn.y(Lhl;ZB)V" : 1,
|
||||
"i.a(IB)Ljq;" : 13,
|
||||
"i.m(II)I" : 328778210,
|
||||
"ia.a([BI)Ljava/lang/String;" : -353252804,
|
||||
"ia.b(ZB)Lld;" : 7,
|
||||
"ia.e(IB)Lld;" : 16,
|
||||
"ia.f(Lgx;B)V" : 7,
|
||||
"ia.h(Lgx;I)V" : -1234429702,
|
||||
"ia.m(Lgx;B)[I" : -1,
|
||||
"ia.n(I)Lkt;" : 421753985,
|
||||
"ia.o(ILjava/lang/String;I)V" : -1333519203,
|
||||
"ia.p(Lgx;I)[Ljava/lang/Object;" : 542349862,
|
||||
"ia.r(Lju;IZLil;B)Ldv;" : -2,
|
||||
"ia.t(ZI)Lhk;" : -51731421,
|
||||
"ic.b(Liz;IIB)Z" : -1,
|
||||
"if.g([Lbu;II[I[II)V" : 1383511622,
|
||||
"if.s(Lif;I)Z" : 818064734,
|
||||
"ig.hu(Lbj;B)V" : 2,
|
||||
"ii.n(IIIIIZB)Lld;" : 2,
|
||||
"ik.g(Lge;I)V" : 1244850771,
|
||||
"ik.hq(Lfh;I)V" : -1237176758,
|
||||
"il.a([I[IZII)V" : -1797663590,
|
||||
"il.f(I)V" : 684089267,
|
||||
"il.g(IZI)V" : -310896557,
|
||||
"il.h(Lgx;B)V" : 2,
|
||||
"il.he(IIIIII)V" : 1597666720,
|
||||
"il.m(I)Ldk;" : -398095808,
|
||||
"il.p(Lju;ILju;IB)Ldv;" : 0,
|
||||
"il.q(I)I" : -1107905560,
|
||||
"il.s(IZI)V" : 258827147,
|
||||
"in.cl(I)I" : -1072006222,
|
||||
"in.dg(Lfb;I[BZB)V" : 1,
|
||||
"in.dl(B)V" : 0,
|
||||
"in.dn(II)Z" : 1536737195,
|
||||
"in.ds(I[BZZI)V" : 956902428,
|
||||
"in.dt(I)I" : -1062754734,
|
||||
"in.dz(III)V" : -1693261231,
|
||||
"in.q(II)I" : 1178383852,
|
||||
"in.r(IB)V" : 9,
|
||||
"io.p(ILcs;ZB)I" : 1,
|
||||
"ip.hl(ZLge;I)V" : 1467913083,
|
||||
"iq.f(IILld;FI)V" : 704611128,
|
||||
"iq.g(IB)Lld;" : 0,
|
||||
"iq.gb(IIIIZI)V" : 1785115947,
|
||||
"iq.p(Lld;Lld;Llh;B)V" : 1,
|
||||
"iq.s(II)V" : -2029849843,
|
||||
"iq.x(III)V" : -2042722903,
|
||||
"ir.f(I)V" : -2131355084,
|
||||
"iu.ig(Lbw;IIII)V" : -685713479,
|
||||
"iu.kz(IIIILld;Lhk;B)V" : 8,
|
||||
"iv.a(Ljava/lang/CharSequence;I)Ljava/lang/String;" : -1913197059,
|
||||
"iw.fh(IIB)V" : 2,
|
||||
"iy.a(II)Lja;" : 299293337,
|
||||
"iz.a([BB)V" : -1,
|
||||
"iz.ab(Ljava/lang/String;Ljava/lang/String;I)Z" : 1244245246,
|
||||
"iz.b(II)[B" : 987310919,
|
||||
"iz.e(II)[B" : -1294518996,
|
||||
"iz.f(II)Z" : -2035474006,
|
||||
"iz.h(IIB)Z" : 0,
|
||||
"iz.k(I)V" : -1119601835,
|
||||
"iz.m(I)Z" : 35823373,
|
||||
"iz.n(III)[B" : 516194823,
|
||||
"iz.p(II)Z" : 541672068,
|
||||
"iz.t(II)[I" : 431985491,
|
||||
"iz.u(I)V" : -1524099318,
|
||||
"iz.v(I[II)Z" : 227748206,
|
||||
"iz.x(II[II)[B" : -834173405,
|
||||
"j.a(Lag;B)V" : -1,
|
||||
"j.g(CI)C" : -981963683,
|
||||
"j.g(III)Z" : 1060896560,
|
||||
"j.h(III)Lif;" : -175568126,
|
||||
"j.hm(IIIIIIIIIB)V" : 13,
|
||||
"j.iq(II)Ljava/lang/String;" : 1836496129,
|
||||
"j.s(CI)Z" : 197071592,
|
||||
"j.s(IIII)Z" : -1346882543,
|
||||
"ja.g(Lgx;II)V" : 1365905715,
|
||||
"ja.s(Lgx;B)V" : 23,
|
||||
"jc.b(II)Ljc;" : 96183287,
|
||||
"jc.e(ZI)Z" : 1314943295,
|
||||
"jc.f(Ljc;Ljc;I)V" : -1552569050,
|
||||
"jc.g(Lgx;I)V" : -1429982553,
|
||||
"jc.l(ZI)Ldk;" : 1545641841,
|
||||
"jc.m(II)Ldk;" : -573893718,
|
||||
"jc.o(IIS)I" : 3147,
|
||||
"jc.q(IB)Ldv;" : 4,
|
||||
"jc.r(ZB)Ldk;" : 1,
|
||||
"jc.t(ZI)Z" : 564174324,
|
||||
"jc.u(ILjava/lang/String;I)Ljava/lang/String;" : -2051827725,
|
||||
"jc.x(I)V" : 305928935,
|
||||
"jc.x(Lgx;IB)V" : 0,
|
||||
"jc.y(I)I" : 122221946,
|
||||
"jd.f(ZI)Lld;" : 838332995,
|
||||
"jd.h(I)V" : 65279,
|
||||
"jd.n(Ljava/lang/String;B)Ljava/lang/String;" : 6,
|
||||
"jd.p(II)Lld;" : 1990361836,
|
||||
"jd.x(Lgx;II)V" : -2060573893,
|
||||
"je.b(I)Lkt;" : -2064178208,
|
||||
"je.f(B)Lld;" : 68,
|
||||
"je.g(Lgx;IB)V" : -1,
|
||||
"je.h(IB)Ljava/lang/String;" : 1,
|
||||
"je.jx(IIIIII)V" : -508181654,
|
||||
"je.m(CI)Z" : 760945280,
|
||||
"je.m(I)Lld;" : -1778105957,
|
||||
"je.q(I)Lld;" : -827937128,
|
||||
"je.x(I)Lje;" : 943450442,
|
||||
"jf.g(Lgx;II)V" : 214023150,
|
||||
"jf.s(Lgx;B)V" : 3,
|
||||
"jg.ah(ILcs;ZI)I" : 532847216,
|
||||
"jg.b(III)I" : 10887810,
|
||||
"jg.f(Lju;ILju;II)Ldv;" : -40433393,
|
||||
"jg.h(Lgx;IB)V" : 64,
|
||||
"jg.m(B)Ljg;" : 0,
|
||||
"jg.n(ILjava/lang/String;I)Ljava/lang/String;" : -147724755,
|
||||
"jg.p(I)Ldk;" : 1597666720,
|
||||
"jg.q(B)Z" : -2,
|
||||
"jg.s(Ljava/lang/String;ZLjava/lang/String;ZB)V" : -1,
|
||||
"jg.x(Lgx;B)V" : 11,
|
||||
"jh.g(Lgx;I)V" : -667595371,
|
||||
"jh.h(IB)Ldv;" : 41,
|
||||
"jh.x(Lgx;II)V" : -972042923,
|
||||
"jl.a(Lgx;B)V" : 5,
|
||||
"jl.ii(ILjava/lang/String;I)V" : -1675865809,
|
||||
"jl.s(Lgx;II)V" : 572994941,
|
||||
"jn.g(Lgx;I)V" : 96183287,
|
||||
"jn.la(Ljava/lang/String;I)Ljava/lang/String;" : 477812378,
|
||||
"jn.x(Lgx;II)V" : -1850197339,
|
||||
"jo.g(Lgx;II)V" : 723793981,
|
||||
"jo.h(II)V" : -740923085,
|
||||
"jo.x(Lgx;III)V" : 384685616,
|
||||
"jp.g(I)Z" : -498132400,
|
||||
"jp.g(Lgx;II)V" : 424690960,
|
||||
"jp.h(I)Lld;" : -380044805,
|
||||
"jp.hp(ZI)V" : 1068773475,
|
||||
"jp.s(Lgx;B)V" : 9,
|
||||
"jp.x(B)Lld;" : 0,
|
||||
"jq.au(ILcs;ZI)I" : -1963146961,
|
||||
"jq.f(ILjava/lang/String;S)Ljava/lang/String;" : 5007,
|
||||
"jq.h(III)I" : -698436080,
|
||||
"jr.fn(II)V" : -1893789506,
|
||||
"jr.g(Ljava/lang/CharSequence;B)Ljava/lang/String;" : -1,
|
||||
"jr.jt(Lia;Ljc;IIZI)V" : -2033743109,
|
||||
"jt.g(Lgx;I)V" : 721996786,
|
||||
"jt.h(Ljava/lang/CharSequence;II[BII)I" : -1648858462,
|
||||
"jt.k(ILcs;ZB)I" : 6,
|
||||
"jt.x(Lgx;II)V" : 1576334712,
|
||||
"ju.f(Ldv;III)Ldv;" : 132641558,
|
||||
"ju.g(Lgx;II)V" : -613501112,
|
||||
"ju.h(Ldv;II)Ldv;" : -1682213593,
|
||||
"ju.m(Ldv;ILju;II)Ldv;" : 1211273008,
|
||||
"ju.p(Ldv;II)Ldv;" : 172834485,
|
||||
"ju.p(Lge;ILbw;II)V" : -1670832392,
|
||||
"ju.q(Ldv;II)Ldv;" : -1048507799,
|
||||
"ju.s(Lgx;I)V" : -1788727042,
|
||||
"ju.x(B)V" : 0,
|
||||
"jv.g(B)Lfa;" : 7,
|
||||
"jw.a(II)Ljz;" : -1393220766,
|
||||
"jw.g(Lgx;II)V" : 253176345,
|
||||
"jw.h(II)V" : -89150727,
|
||||
"jw.kd(Lbk;ZI)V" : -1454243751,
|
||||
"jw.s(I)V" : 1378135916,
|
||||
"jw.x(Lgx;III)V" : -467387569,
|
||||
"jx.f(B)Ldk;" : 1,
|
||||
"jx.g(Lgx;B)V" : 29,
|
||||
"jx.h(I)Z" : -1555038209,
|
||||
"jx.m(I)Ldk;" : -1339242269,
|
||||
"jx.p(I)Z" : -1362075535,
|
||||
"jx.s(Liz;III)Lld;" : 1385222262,
|
||||
"jx.x(Lgx;IB)V" : 0,
|
||||
"jy.b(II[[IIIILju;II)Ldv;" : 8388609,
|
||||
"jy.e(I)Ljy;" : -1512852885,
|
||||
"jy.f(II)Z" : 282955687,
|
||||
"jy.g(S)V" : 8364,
|
||||
"jy.h(Lgx;II)V" : -1717982543,
|
||||
"jy.l(I)Z" : 150610019,
|
||||
"jy.m(II[[IIIII)Lem;" : -372875047,
|
||||
"jy.n(III)Ldk;" : -884974338,
|
||||
"jy.q(II[[IIIIB)Ldv;" : 25,
|
||||
"jy.r(IIB)I" : -1,
|
||||
"jy.t(ILjava/lang/String;I)Ljava/lang/String;" : -1133392868,
|
||||
"jy.x(Lgx;I)V" : 1763228330,
|
||||
"jz.fs(IIII)V" : -1466898577,
|
||||
"jz.g(Lgx;B)V" : 2,
|
||||
"jz.h(I)Z" : -2131355083,
|
||||
"jz.jp(Lia;B)Z" : -2,
|
||||
"jz.x(Lgx;II)V" : -1511633123,
|
||||
"k.hb(Lbw;IIBI)V" : -1717122274,
|
||||
"k.m(B)V" : 2,
|
||||
"ka.s(I)V" : -2839567,
|
||||
"ka.x(I)V" : -670001098,
|
||||
"kd.aa(Lkx;Lkx;I)Lkn;" : -2059524068,
|
||||
"kd.ab(IB)Lkn;" : -1,
|
||||
"kd.ah(I)V" : 1677000161,
|
||||
"kd.an(Lkn;I)I" : -1066148450,
|
||||
"kd.as(Ljava/util/Comparator;I)V" : 1772662082,
|
||||
"kd.at(Lkn;I)V" : -818755498,
|
||||
"kd.av(Lkn;I)V" : -1176966737,
|
||||
"kd.l(Lkx;B)Z" : 100,
|
||||
"kd.o(Lkx;I)Lkn;" : -1474250075,
|
||||
"kd.v(Lkn;B)V" : 0,
|
||||
"kd.y(Lkx;I)Lkn;" : -10040824,
|
||||
"ke.a([Lkw;I)Ljava/util/HashMap;" : 943906518,
|
||||
"kg.q(IIIIIILen;Lfk;I)V" : 330856458,
|
||||
"kj.m(Ljava/util/Comparator;I)V" : -1871871525,
|
||||
"kj.q(Lkn;Lkn;B)I" : 1,
|
||||
"kl.bg(B)Z" : 1,
|
||||
"km.f(I)V" : 592369164,
|
||||
"km.g(I)V" : 1843719486,
|
||||
"km.gj(II)V" : -1194096980,
|
||||
"km.h(B)Z" : -1,
|
||||
"km.s(I)Z" : -1813992429,
|
||||
"kn.ae(I)Ljava/lang/String;" : 1341360476,
|
||||
"kn.at(I)Ljava/lang/String;" : -1555038208,
|
||||
"kn.av(Lkx;Lkx;I)V" : 275778859,
|
||||
"kn.ih(IIIILjava/lang/String;I)V" : -1657907412,
|
||||
"kn.ik(II)Z" : 271561465,
|
||||
"kp.a(Lgx;Lgs;I)Lgs;" : -692792992,
|
||||
"kr.g(Lkx;ZB)Z" : -1,
|
||||
"kr.kh(Lgx;II)V" : -1134408571,
|
||||
"kr.kn(Lia;I)V" : -2138249594,
|
||||
"kr.n(Lgx;IB)V" : 1,
|
||||
"ks.a(Lks;B)I" : 1,
|
||||
"ku.g(Lgx;II)V" : -1361804166,
|
||||
"kw.fk(I)V" : 1462687380,
|
||||
"kw.fl(IZZZB)Lin;" : 6,
|
||||
"kw.fr(B)V" : 0,
|
||||
"kw.jj(B)V" : 1,
|
||||
"kx.g(Lkx;I)I" : 1091130939,
|
||||
"kx.s(I)Z" : 2085790353,
|
||||
"ky.ck(Lgx;B)V" : 1,
|
||||
"ky.cn(I)V" : 1819322040,
|
||||
"ky.cr(Lgx;I)V" : -2138810208,
|
||||
"ky.cv(Lkm;I)V" : -794082731,
|
||||
"l.go(I)I" : 689623594,
|
||||
"l.lg(I)V" : 212688817,
|
||||
"l.x(IIIII)V" : 1330963020,
|
||||
"lf.a(Liz;I)V" : 216314308,
|
||||
"lg.a(Lkn;Lkn;B)I" : 0,
|
||||
"lh.h(Llh;Llh;I)V" : -1899763684,
|
||||
"lh.x(Llh;Llh;I)V" : 65281,
|
||||
"li.a(Lgx;I)V" : 82212899,
|
||||
"lk.a(Lkn;Lkn;B)I" : 3,
|
||||
"lm.a(I)Lli;" : -1704489684,
|
||||
"lo.ae(ILcs;ZI)I" : 491075880,
|
||||
"lq.a(Liz;Liz;Liz;Lkt;Ljava/util/HashMap;[Llv;B)V" : 2,
|
||||
"lq.aa(IIIIIII)V" : -1022244844,
|
||||
"lq.ab(IIIIB)V" : 15,
|
||||
"lq.ai(IIIB)V" : 4,
|
||||
"lq.aj(III)V" : -1596162919,
|
||||
"lq.an(IB)F" : 0,
|
||||
"lq.ap(II)V" : -368766016,
|
||||
"lq.aq(I)I" : 96183288,
|
||||
"lq.ar(IIII)V" : -1654813278,
|
||||
"lq.as(III)V" : -418862019,
|
||||
"lq.at(I)I" : -1389281243,
|
||||
"lq.au(II)Lag;" : -482362793,
|
||||
"lq.az(B)Lif;" : 0,
|
||||
"lq.b(I)Z" : 1196890805,
|
||||
"lq.bb(S)Lat;" : 3647,
|
||||
"lq.bg(II)Z" : -827937128,
|
||||
"lq.bi(IZI)V" : 1401518352,
|
||||
"lq.bn(ILif;S)Lif;" : 3622,
|
||||
"lq.bo(II)V" : 517430306,
|
||||
"lq.bp(I)Z" : 115992480,
|
||||
"lq.br(IIIIIII)V" : -1670644894,
|
||||
"lq.bv(II)Z" : 2068200578,
|
||||
"lq.bw(B)Lat;" : 0,
|
||||
"lq.bz(IZI)V" : -345932703,
|
||||
"lq.c(IIIIIII)Z" : 977978274,
|
||||
"lq.e(IIIZB)V" : -1,
|
||||
"lq.f(I)V" : -1442221252,
|
||||
"lq.g(IIZIIIII)V" : -311515493,
|
||||
"lq.k(IIIB)V" : -1,
|
||||
"lq.m(IIZI)V" : 443741720,
|
||||
"lq.n(IIIB)Lag;" : 1,
|
||||
"lq.p(I)V" : 946356797,
|
||||
"lq.r(II)V" : -1958030248,
|
||||
"lq.t(I)I" : -1613065466,
|
||||
"lq.v(IIIIII)V" : 1578223622,
|
||||
"lq.x(IIZZI)V" : 703776978,
|
||||
"lq.y(Lag;Lif;Lif;ZI)V" : 559163206,
|
||||
"lr.f([BIIB)Z" : 1,
|
||||
"lw.a(Ljava/lang/String;B)V" : 0,
|
||||
"lw.s(B)I" : 1,
|
||||
"m.s(IIII)Lcs;" : -3560696,
|
||||
"m.x([BIIIIIII[Lfk;S)V" : 254,
|
||||
"m.y(IIIB)I" : 0,
|
||||
"n.a(Lm;Lm;I)I" : 965460013,
|
||||
"n.g(III)Lia;" : -115409750,
|
||||
"n.jk(II)V" : -1949538187,
|
||||
"o.a(Lgx;I)V" : -2015278485,
|
||||
"o.gx(Lbw;III)V" : 16748609,
|
||||
"o.hh(I)V" : 900432092,
|
||||
"o.s(Lgx;I)V" : -1171328621,
|
||||
"p.a(Ljava/util/Comparator;ZB)V" : -1,
|
||||
"p.f([BIIB)Ljava/lang/String;" : 1,
|
||||
"p.gk(ZB)V" : 1,
|
||||
"p.jz(Lia;III)V" : -1232547140,
|
||||
"p.km(IB)V" : 1,
|
||||
"q.a(Lm;Lm;I)I" : 806214979,
|
||||
"r.a(Lm;Lm;I)I" : -587761847,
|
||||
"r.q(I)Ljava/lang/String;" : 1332980896,
|
||||
"s.ac(I)I" : 756871814,
|
||||
"s.fx(B)V" : 1,
|
||||
"s.jh(Lia;III)V" : -718297066,
|
||||
"s.kq(Lia;I)Z" : -1017775700,
|
||||
"t.lf(B)Z" : 0,
|
||||
"v.a(Lag;B)V" : -1,
|
||||
"v.fy(Ljava/lang/String;I)V" : -1100446886,
|
||||
"v.g(III)Z" : 1060896560,
|
||||
"v.gw(B)V" : 9,
|
||||
"v.h(III)Lif;" : -175568126,
|
||||
"v.s(IIII)Z" : -1346882543,
|
||||
"v.s([BIII)Ljava/lang/String;" : -2131355082,
|
||||
"v.x(IIIB)[I" : 2,
|
||||
"w.e(IILgx;II)V" : -1175687218,
|
||||
"w.in(IIIIIIS)V" : 254,
|
||||
"w.m(I)Z" : 665939044,
|
||||
"w.n(IILgx;B)V" : 1,
|
||||
"w.o(III)I" : 174332944,
|
||||
"w.q(Liz;I)V" : -1888528129,
|
||||
"w.r(IILgx;II)V" : -2131355082,
|
||||
"x.g(Ljava/lang/Class;I)La;" : -559220730,
|
||||
"x.s(Ljava/lang/Class;I)Lx;" : -803222413,
|
||||
"y.g(IB)Ly;" : 7,
|
||||
"y.h(Lgx;IIIIIIB)V" : 2,
|
||||
"y.if(B)V" : 10,
|
||||
"y.s(CI)Z" : 1212295357,
|
||||
"y.s(FB)Z" : 0,
|
||||
"y.s(Lge;II)V" : 1027527763,
|
||||
"z.fc(Lju;IIII)V" : 2082929660,
|
||||
"z.jb(IB)V" : 15
|
||||
}
|
||||
32406
extended-mixins/hooks.json
Normal file
32406
extended-mixins/hooks.json
Normal file
File diff suppressed because it is too large
Load Diff
111
extended-mixins/pom.xml
Normal file
111
extended-mixins/pom.xml
Normal file
@@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>runelite-parent</artifactId>
|
||||
<version>1.5.24-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>extended-mixins</artifactId>
|
||||
<name>RuneLite Extended Mixins</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite.rs</groupId>
|
||||
<artifactId>runescape-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
<version>1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<version>1.10.19</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<!-- RuneScape classes do not verify
|
||||
under Java 7+ due to the obfuscation
|
||||
-->
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>extended-mixin-processor</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<configuration>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>reob-classes</id>
|
||||
<phase>process-classes</phase>
|
||||
<configuration>
|
||||
<hooks>${artifactId}/hooks.json</hooks>
|
||||
<ops>${artifactId}/gamepack.deob.jar.op.json</ops>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>process-mixins</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Append
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Inject
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Overwrite
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Prepend
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Provided
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixinprocessor.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Reobfuscate
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixins;
|
||||
|
||||
import net.runelite.api.events.AnimationChanged;
|
||||
import net.runelite.api.events.GraphicChanged;
|
||||
import us.runelitepl.mixinprocessor.annotations.Overwrite;
|
||||
import us.runelitepl.mixinprocessor.annotations.Provided;
|
||||
import us.runelitepl.mixinprocessor.annotations.Reobfuscate;
|
||||
|
||||
public class Actor
|
||||
{
|
||||
|
||||
@Reobfuscate
|
||||
@Provided
|
||||
int sequence;
|
||||
|
||||
@Overwrite
|
||||
public int getAnimation()
|
||||
{
|
||||
return sequence * 42069;
|
||||
}
|
||||
|
||||
@Overwrite
|
||||
public void animationChanged(int n)
|
||||
{
|
||||
AnimationChanged animationChanged = new AnimationChanged();
|
||||
animationChanged.setActor((net.runelite.api.Actor) this);
|
||||
Client.INSTANCE.getCallbacks().post(animationChanged);
|
||||
}
|
||||
|
||||
@Overwrite
|
||||
public void graphicChanged(int n)
|
||||
{
|
||||
GraphicChanged graphicChanged = new GraphicChanged();
|
||||
graphicChanged.setActor((net.runelite.api.Actor)this);
|
||||
Client.INSTANCE.getCallbacks().post(graphicChanged);
|
||||
}
|
||||
|
||||
}
|
||||
543
extended-mixins/src/main/java/us/runelitepl/mixins/Client.java
Normal file
543
extended-mixins/src/main/java/us/runelitepl/mixins/Client.java
Normal file
@@ -0,0 +1,543 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixins;
|
||||
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.Node;
|
||||
import net.runelite.api.hooks.Callbacks;
|
||||
import net.runelite.rs.api.RSCollisionData;
|
||||
import net.runelite.rs.api.RSDeque;
|
||||
import net.runelite.rs.api.RSNode;
|
||||
import us.runelitepl.mixinprocessor.annotations.Inject;
|
||||
import us.runelitepl.mixinprocessor.annotations.Overwrite;
|
||||
import us.runelitepl.mixinprocessor.annotations.Prepend;
|
||||
import us.runelitepl.mixinprocessor.annotations.Provided;
|
||||
import us.runelitepl.mixinprocessor.annotations.Reobfuscate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Client
|
||||
{
|
||||
|
||||
@Provided
|
||||
public static boolean isHidingEntities;
|
||||
|
||||
@Provided
|
||||
public static boolean hideLocalPlayer2D;
|
||||
|
||||
@Provided
|
||||
public static boolean hideLocalPlayer;
|
||||
|
||||
@Provided
|
||||
public static boolean hidePlayers2D;
|
||||
|
||||
@Provided
|
||||
public static boolean hidePlayers;
|
||||
|
||||
@Provided
|
||||
public static boolean hideAttackers;
|
||||
|
||||
@Provided
|
||||
public static boolean hideProjectiles;
|
||||
|
||||
@Provided
|
||||
public static boolean hideNPCs2D;
|
||||
|
||||
@Provided
|
||||
public static boolean hideNPCs;
|
||||
|
||||
@Provided
|
||||
public static boolean hideFriends;
|
||||
|
||||
@Provided
|
||||
public static boolean hideClanMates;
|
||||
|
||||
@Inject
|
||||
public static Client INSTANCE;
|
||||
|
||||
@Inject
|
||||
public static boolean printMenuActions;
|
||||
|
||||
@Provided
|
||||
public static int oldMenuEntryCount;
|
||||
|
||||
@Reobfuscate
|
||||
@Provided
|
||||
static boolean renderSelf;
|
||||
|
||||
@Provided
|
||||
public static final int[] rl$modelViewportXs = new int[0];
|
||||
|
||||
@Provided
|
||||
public static final int[] rl$modelViewportYs = new int[0];
|
||||
|
||||
@Prepend
|
||||
private void prepend$rl$$init()
|
||||
{
|
||||
INSTANCE = this;
|
||||
printMenuActions = false;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void toggleRenderSelf()
|
||||
{
|
||||
renderSelf = !renderSelf;
|
||||
}
|
||||
|
||||
@Provided
|
||||
public int getMenuOptionCount()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public String[] getMenuOptions()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public String[] getMenuTargets()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public int[] getMenuIdentifiers()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public int[] getMenuTypes()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public int[] getMenuActionParams0()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public int[] getMenuActionParams1()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public boolean[] getMenuForceLeftClick()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public void setMenuOptionCount(int i)
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public Callbacks getCallbacks()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public RSCollisionData[] getRsCollisionMaps()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public RSDeque getProjectilesDeque()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Overwrite
|
||||
public List getProjectiles()
|
||||
{
|
||||
List list = new java.util.ArrayList();
|
||||
RSNode head = getProjectilesDeque().getHead();
|
||||
for (Node node = ((Node) head).getNext();
|
||||
node != head;
|
||||
node = node.getNext())
|
||||
{
|
||||
list.add(node);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setPrintMenuActions(boolean b)
|
||||
{
|
||||
printMenuActions = b;
|
||||
}
|
||||
|
||||
@Overwrite
|
||||
public RSCollisionData[] getCollisionMaps()
|
||||
{
|
||||
return getRsCollisionMaps();
|
||||
}
|
||||
|
||||
@Overwrite
|
||||
public void setMenuEntries(MenuEntry[] arrmenuEntry)
|
||||
{
|
||||
int n2 = 0;
|
||||
String[] arrstring = this.getMenuOptions();
|
||||
String[] arrstring2 = this.getMenuTargets();
|
||||
int[] arrn = this.getMenuIdentifiers();
|
||||
int[] arrn2 = this.getMenuTypes();
|
||||
int[] arrn3 = this.getMenuActionParams0();
|
||||
int[] arrn4 = this.getMenuActionParams1();
|
||||
boolean[] arrbl = getMenuForceLeftClick();
|
||||
net.runelite.api.MenuEntry[] arrmenuEntry2 = arrmenuEntry;
|
||||
int n3 = arrmenuEntry2.length;
|
||||
int n4 = 0;
|
||||
do
|
||||
{
|
||||
String string;
|
||||
if (n4 >= n3)
|
||||
{
|
||||
this.setMenuOptionCount(n2);
|
||||
oldMenuEntryCount = n2;
|
||||
return;
|
||||
}
|
||||
net.runelite.api.MenuEntry menuEntry = arrmenuEntry2[n4];
|
||||
int n5 = menuEntry.getType();
|
||||
arrstring[n2] = menuEntry.getOption();
|
||||
arrstring2[n2] = menuEntry.getTarget();
|
||||
arrn[n2] = menuEntry.getIdentifier();
|
||||
arrn2[n2] = n5;
|
||||
arrn3[n2] = menuEntry.getParam0();
|
||||
arrn4[n2] = menuEntry.getParam1();
|
||||
arrbl[n2] = menuEntry.isForceLeftClick();
|
||||
++n2;
|
||||
++n4;
|
||||
}
|
||||
while (true);
|
||||
}
|
||||
|
||||
@Overwrite
|
||||
public static void onMenuOptionsChanged(int n2)
|
||||
{
|
||||
int n3;
|
||||
int n4 = oldMenuEntryCount;
|
||||
oldMenuEntryCount = n3 = INSTANCE.getMenuOptionCount();
|
||||
if (n3 != n4 + 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
net.runelite.api.events.MenuEntryAdded menuEntryAdded =
|
||||
new net.runelite.api.events.MenuEntryAdded(INSTANCE.getMenuOptions()[n3 - 1],
|
||||
INSTANCE.getMenuTargets()[n3 - 1],
|
||||
INSTANCE.getMenuTypes()[n3 - 1],
|
||||
INSTANCE.getMenuIdentifiers()[n3 - 1],
|
||||
INSTANCE.getMenuActionParams0()[n3 - 1],
|
||||
INSTANCE.getMenuActionParams1()[n3 - 1]);
|
||||
INSTANCE.getCallbacks().post(menuEntryAdded);
|
||||
}
|
||||
|
||||
@Overwrite
|
||||
public static void copy$processClientError(String s, Throwable e, byte b)
|
||||
{
|
||||
System.err.println("[RL+] Error thrown: " + s);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@Inject
|
||||
public net.runelite.api.MouseRecorder getMouseRecorder()
|
||||
{
|
||||
return _Statics_.mouseRecorder;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public boolean boundingboxCheck2(net.runelite.api.Model model, int n2, int n3, int n4)
|
||||
{
|
||||
int n5 = INSTANCE.getCameraPitch();
|
||||
int n6 = INSTANCE.getCameraYaw();
|
||||
int n7 = net.runelite.api.Perspective.SINE[n5];
|
||||
int n8 = net.runelite.api.Perspective.COSINE[n5];
|
||||
int n9 = net.runelite.api.Perspective.SINE[n6];
|
||||
int n10 = net.runelite.api.Perspective.COSINE[n6];
|
||||
int n11 = INSTANCE.getCenterX();
|
||||
int n12 = INSTANCE.getCenterY();
|
||||
int n13 = INSTANCE.getViewportMouseX();
|
||||
int n14 = INSTANCE.getViewportMouseY();
|
||||
int n15 = INSTANCE.get3dZoom();
|
||||
int n16 = (n13 - n11) * 50 / n15;
|
||||
int n17 = (n14 - n12) * 50 / n15;
|
||||
int n18 = (n13 - n11) * 10000 / n15;
|
||||
int n19 = (n14 - n12) * 10000 / n15;
|
||||
int n20 = Client.rl$rot1(n17, 50, n8, n7);
|
||||
int n21 = Client.rl$rot2(n17, 50, n8, n7);
|
||||
n17 = n20;
|
||||
n20 = Client.rl$rot1(n19, 10000, n8, n7);
|
||||
int n22 = Client.rl$rot2(n19, 10000, n8, n7);
|
||||
n19 = n20;
|
||||
n20 = Client.rl$rot3(n16, n21, n10, n9);
|
||||
n21 = Client.rl$rot4(n16, n21, n10, n9);
|
||||
n16 = n20;
|
||||
n20 = Client.rl$rot3(n18, n22, n10, n9);
|
||||
n22 = Client.rl$rot4(n18, n22, n10, n9);
|
||||
int n23 = (n20 - n16) / 2;
|
||||
int n24 = (n19 - n17) / 2;
|
||||
int n25 = (n22 - n21) / 2;
|
||||
int n26 = Math.abs(n23);
|
||||
int n27 = Math.abs(n24);
|
||||
int n28 = Math.abs(n25);
|
||||
int n29 = n2 + model.getCenterX();
|
||||
int n30 = n3 + model.getCenterY();
|
||||
int n31 = n4 + model.getCenterZ();
|
||||
int n32 = model.getExtremeX();
|
||||
int n33 = model.getExtremeY();
|
||||
int n34 = model.getExtremeZ();
|
||||
int n35 = (n16 + n20) / 2;
|
||||
int n36 = (n17 + n19) / 2;
|
||||
int n37 = (n22 + n21) / 2;
|
||||
int n38 = n35 - n29;
|
||||
int n39 = n36 - n30;
|
||||
int n40 = n37 - n31;
|
||||
if (Math.abs(n38) > n32 + n26)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (Math.abs(n39) > n33 + n27)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (Math.abs(n40) > n34 + n28)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (Math.abs(n40 * n24 - n39 * n25) > n33 * n28 + n34 * n27)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (Math.abs(n38 * n25 - n40 * n23) > n34 * n26 + n32 * n28)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (Math.abs(n39 * n23 - n38 * n24) <= n33 * n26 + n32 * n27)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Overwrite
|
||||
public void checkClickbox(net.runelite.api.Model model, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9, long l2)
|
||||
{
|
||||
int n10;
|
||||
int n11;
|
||||
int n12;
|
||||
int n13;
|
||||
int n14;
|
||||
net.runelite.rs.api.RSModel rSModel = (net.runelite.rs.api.RSModel) model;
|
||||
boolean bl2 = l2 != 0L && (int) (l2 >>> 16 & 1L) != 1;
|
||||
boolean bl3 = INSTANCE.getViewportContainsMouse();
|
||||
if (!bl2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!bl3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
boolean bl4 = this.boundingboxCheck2(rSModel, n7, n8, n9);
|
||||
if (!bl4)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (rSModel.isClickable())
|
||||
{
|
||||
this.addHashAtMouse(l2);
|
||||
return;
|
||||
}
|
||||
int n15 = rSModel.getVerticesCount();
|
||||
int n16 = rSModel.getTrianglesCount();
|
||||
int[] arrn = rSModel.getVerticesX();
|
||||
int[] arrn2 = rSModel.getVerticesY();
|
||||
int[] arrn3 = rSModel.getVerticesZ();
|
||||
int[] arrn4 = rSModel.getTrianglesX();
|
||||
int[] arrn5 = rSModel.getTrianglesY();
|
||||
int[] arrn6 = rSModel.getTrianglesZ();
|
||||
int[] arrn7 = rSModel.getFaceColors3();
|
||||
int n17 = INSTANCE.get3dZoom();
|
||||
int n18 = INSTANCE.getCenterX();
|
||||
int n19 = INSTANCE.getCenterY();
|
||||
int n20 = 0;
|
||||
int n21 = 0;
|
||||
if (n2 != 0)
|
||||
{
|
||||
n20 = net.runelite.api.Perspective.SINE[n2];
|
||||
n21 = net.runelite.api.Perspective.COSINE[n2];
|
||||
}
|
||||
for (n14 = 0; n14 < n15; ++n14)
|
||||
{
|
||||
n11 = arrn[n14];
|
||||
n13 = arrn2[n14];
|
||||
n12 = arrn3[n14];
|
||||
if (n2 != 0)
|
||||
{
|
||||
n10 = n12 * n20 + n11 * n21 >> 16;
|
||||
n12 = n12 * n21 - n11 * n20 >> 16;
|
||||
n11 = n10;
|
||||
}
|
||||
n10 = (n12 += n9) * n5 + n6 * (n11 += n7) >> 16;
|
||||
n12 = n6 * n12 - n11 * n5 >> 16;
|
||||
n11 = n10;
|
||||
n10 = n4 * (n13 += n8) - n12 * n3 >> 16;
|
||||
if ((n12 = n13 * n3 + n4 * n12 >> 16) >= 50)
|
||||
{
|
||||
Client.rl$modelViewportYs[n14] = n11 * n17 / n12 + n18;
|
||||
Client.rl$modelViewportXs[n14] = n10 * n17 / n12 + n19;
|
||||
continue;
|
||||
}
|
||||
Client.rl$modelViewportYs[n14] = -5000;
|
||||
}
|
||||
n14 = INSTANCE.getViewportMouseX();
|
||||
n11 = INSTANCE.getViewportMouseY();
|
||||
n13 = 0;
|
||||
while (n13 < n16)
|
||||
{
|
||||
if (arrn7[n13] != -2)
|
||||
{
|
||||
int n22;
|
||||
boolean bl5;
|
||||
int n23;
|
||||
n12 = arrn4[n13];
|
||||
n10 = arrn5[n13];
|
||||
int n24 = arrn6[n13];
|
||||
int n25 = rl$modelViewportYs[n12];
|
||||
int n26 = rl$modelViewportYs[n10];
|
||||
int n27 = rl$modelViewportYs[n24];
|
||||
int n28 = rl$modelViewportXs[n12];
|
||||
int n29 = rl$modelViewportXs[n10];
|
||||
int n30 = rl$modelViewportXs[n24];
|
||||
if (n25 != -5000 && n26 != -5000 && n27 != -5000 && (bl5 = (n23 = (n22 = rSModel.isClickable() ? 20
|
||||
: 5) + n11) < n28 && n23 < n29 && n23 < n30 ? false
|
||||
: ((n23 = n11 - n22) > n28 && n23 > n29 && n23 > n30 ? false
|
||||
: ((n23 = n22 + n14) < n25 && n23 < n26 && n23 < n27 ? false
|
||||
: (n23 = n14 - n22) <= n25 || n23 <= n26 || n23 <= n27))))
|
||||
{
|
||||
this.addHashAtMouse(l2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
++n13;
|
||||
}
|
||||
}
|
||||
|
||||
@Provided
|
||||
public boolean getViewportContainsMouse()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public void addHashAtMouse(long l)
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public int getCameraPitch()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public int getCameraYaw()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public int getCenterX()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public int getCenterY()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public int getViewportMouseX()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public int getViewportMouseY()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public int get3dZoom()
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public static int rl$rot1(int a, int b, int c, int d)
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public static int rl$rot2(int a, int b, int c, int d)
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public static int rl$rot3(int a, int b, int c, int d)
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Provided
|
||||
public static int rl$rot4(int a, int b, int c, int d)
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void invokeMenuAction(int actionParam, int widgetId, int opcode, int targetId, String menuOption,
|
||||
String menuTarget, int mouseX, int mouseY)
|
||||
{
|
||||
_Statics_.menuAction(actionParam, widgetId, opcode, targetId, menuOption,
|
||||
menuTarget, mouseX, mouseY);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixins;
|
||||
|
||||
import net.runelite.rs.api.RSMouseRecorder;
|
||||
import us.runelitepl.mixinprocessor.annotations.Inject;
|
||||
import us.runelitepl.mixinprocessor.annotations.Provided;
|
||||
import us.runelitepl.mixinprocessor.annotations.Reobfuscate;
|
||||
|
||||
public class MouseRecorder implements RSMouseRecorder
|
||||
{
|
||||
|
||||
@Provided
|
||||
@Reobfuscate
|
||||
int[] xs;
|
||||
|
||||
@Provided
|
||||
@Reobfuscate
|
||||
int[] ys;
|
||||
|
||||
@Provided
|
||||
@Reobfuscate
|
||||
long[] millis;
|
||||
|
||||
@Provided
|
||||
@Reobfuscate
|
||||
int index;
|
||||
|
||||
@Inject
|
||||
public int[] getXs()
|
||||
{
|
||||
return xs;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public int[] getYs()
|
||||
{
|
||||
return ys;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public long[] getMillis()
|
||||
{
|
||||
return millis;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public int getIndex()
|
||||
{
|
||||
return index * 42069;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixins;
|
||||
|
||||
import net.runelite.api.SkullIcon;
|
||||
import us.runelitepl.mixinprocessor.annotations.Inject;
|
||||
import us.runelitepl.mixinprocessor.annotations.Overwrite;
|
||||
import us.runelitepl.mixinprocessor.annotations.Provided;
|
||||
import us.runelitepl.mixinprocessor.annotations.Reobfuscate;
|
||||
|
||||
public class Player
|
||||
{
|
||||
|
||||
@Reobfuscate
|
||||
@Provided
|
||||
int headIconPk;
|
||||
|
||||
@Reobfuscate
|
||||
@Provided
|
||||
int index;
|
||||
|
||||
@Inject
|
||||
public int getHeadIconPk()
|
||||
{
|
||||
return headIconPk * 42069;
|
||||
}
|
||||
|
||||
@Overwrite
|
||||
public SkullIcon getSkullIcon()
|
||||
{
|
||||
switch(getHeadIconPk())
|
||||
{
|
||||
case 0:
|
||||
return SkullIcon.SKULL;
|
||||
case 1:
|
||||
return SkullIcon.SKULL_FIGHT_PIT;
|
||||
case 8:
|
||||
return SkullIcon.DEAD_MAN_FIVE;
|
||||
case 9:
|
||||
return SkullIcon.DEAD_MAN_FOUR;
|
||||
case 10:
|
||||
return SkullIcon.DEAD_MAN_THREE;
|
||||
case 11:
|
||||
return SkullIcon.DEAD_MAN_TWO;
|
||||
case 12:
|
||||
return SkullIcon.DEAD_MAN_ONE;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
public int getIndex()
|
||||
{
|
||||
return index * 42069;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixins;
|
||||
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.events.ProjectileMoved;
|
||||
import net.runelite.rs.api.RSClient;
|
||||
import us.runelitepl.mixinprocessor.annotations.Inject;
|
||||
import us.runelitepl.mixinprocessor.annotations.Overwrite;
|
||||
import us.runelitepl.mixinprocessor.annotations.Provided;
|
||||
import us.runelitepl.mixinprocessor.annotations.Reobfuscate;
|
||||
|
||||
public class Projectile
|
||||
{
|
||||
|
||||
@Reobfuscate
|
||||
@Provided
|
||||
int targetIndex;
|
||||
|
||||
@Inject
|
||||
public int getTargetId()
|
||||
{
|
||||
return targetIndex * 42069;
|
||||
}
|
||||
|
||||
@Overwrite
|
||||
public void projectileMoved(int x, int y, int z, int n3)
|
||||
{
|
||||
LocalPoint position = new LocalPoint(x, y);
|
||||
ProjectileMoved event = new ProjectileMoved();
|
||||
event.setProjectile((net.runelite.api.Projectile) this);
|
||||
event.setPosition(position);
|
||||
event.setZ(z);
|
||||
((RSClient) Client.INSTANCE).getCallbacks().post(event);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public Actor getInteracting()
|
||||
{
|
||||
final int _targ = this.getTargetId();
|
||||
if (_targ == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (_targ > 0)
|
||||
{
|
||||
return (Actor) ((RSClient) Client.INSTANCE).getCachedNPCs()[_targ - 1];
|
||||
}
|
||||
final int n = -_targ - 1;
|
||||
if (n == ((RSClient) Client.INSTANCE).getLocalInteractingIndex())
|
||||
{
|
||||
return (Actor) ((RSClient) Client.INSTANCE).getLocalPlayer();
|
||||
}
|
||||
return (Actor) ((RSClient) Client.INSTANCE).getCachedPlayers()[n];
|
||||
}
|
||||
|
||||
}
|
||||
104
extended-mixins/src/main/java/us/runelitepl/mixins/Scene.java
Normal file
104
extended-mixins/src/main/java/us/runelitepl/mixins/Scene.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixins;
|
||||
|
||||
import net.runelite.rs.api.RSClient;
|
||||
import net.runelite.rs.api.RSNPC;
|
||||
import net.runelite.rs.api.RSPlayer;
|
||||
import net.runelite.rs.api.RSProjectile;
|
||||
import us.runelitepl.mixinprocessor.annotations.Overwrite;
|
||||
|
||||
public class Scene
|
||||
{
|
||||
|
||||
@Overwrite
|
||||
public static boolean shouldDraw(Object renderable, boolean drawingUI)
|
||||
{
|
||||
|
||||
if (!Client.isHidingEntities)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(renderable instanceof RSPlayer)
|
||||
{
|
||||
RSPlayer p = (RSPlayer) renderable;
|
||||
if(Client.hideClanMates && p.isClanMember())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (renderable instanceof RSPlayer)
|
||||
{
|
||||
boolean local = drawingUI ? Client.hideLocalPlayer2D : Client.hideLocalPlayer;
|
||||
boolean other = drawingUI ? Client.hidePlayers2D : Client.hidePlayers;
|
||||
boolean isLocalPlayer = renderable == ((RSClient)Client.INSTANCE).getLocalPlayer();
|
||||
|
||||
if (isLocalPlayer ? local : other)
|
||||
{
|
||||
RSPlayer player = (RSPlayer) renderable;
|
||||
|
||||
if (!Client.hideAttackers)
|
||||
{
|
||||
if (player.getInteracting() == ((RSClient)Client.INSTANCE).getLocalPlayer())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (player.getName() == null)
|
||||
{
|
||||
// player.isFriend() and player.isClanMember() npe when the player has a null name
|
||||
return false;
|
||||
}
|
||||
|
||||
return (!Client.hideFriends && player.isFriend()) || (!isLocalPlayer && !Client.hideClanMates && player.isClanMember());
|
||||
}
|
||||
}
|
||||
else if (renderable instanceof RSNPC)
|
||||
{
|
||||
RSNPC npc = (RSNPC) renderable;
|
||||
|
||||
if (!Client.hideAttackers)
|
||||
{
|
||||
if (npc.getInteracting() == ((RSClient)Client.INSTANCE).getLocalPlayer())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return drawingUI ? !Client.hideNPCs2D : !Client.hideNPCs;
|
||||
}
|
||||
else if (renderable instanceof RSProjectile)
|
||||
{
|
||||
return !Client.hideProjectiles;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package us.runelitepl.mixins;
|
||||
|
||||
import us.runelitepl.mixinprocessor.annotations.Prepend;
|
||||
import us.runelitepl.mixinprocessor.annotations.Provided;
|
||||
import us.runelitepl.mixinprocessor.annotations.Reobfuscate;
|
||||
|
||||
public class _Statics_
|
||||
{
|
||||
|
||||
@Provided
|
||||
@Reobfuscate
|
||||
static MouseRecorder mouseRecorder;
|
||||
|
||||
@Prepend
|
||||
@Reobfuscate
|
||||
static final void prepend$menuAction(int actionParam, int widgetId, int opcode, int targetId, String menuOption,
|
||||
String menuTarget, int mouseX, int mouseY)
|
||||
{
|
||||
if(Client.printMenuActions)
|
||||
{
|
||||
int printOpcode = opcode;
|
||||
if(opcode >= 2000)
|
||||
{
|
||||
printOpcode -= 2000;
|
||||
}
|
||||
System.out.format("menuAction triggered: '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s'\n", actionParam, widgetId,
|
||||
printOpcode, targetId, menuOption, menuTarget, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
|
||||
@Provided
|
||||
@Reobfuscate
|
||||
static final void menuAction(int actionParam, int widgetId, int opcode, int targetId, String menuOption,
|
||||
String menuTarget, int mouseX, int mouseY)
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
2
pom.xml
2
pom.xml
@@ -115,6 +115,8 @@
|
||||
<module>cache</module>
|
||||
<module>cache-client</module>
|
||||
<module>cache-updater</module>
|
||||
<module>extended-mixin-processor</module>
|
||||
<module>extended-mixins</module>
|
||||
<module>runelite-api</module>
|
||||
<module>runelite-client</module>
|
||||
<module>runelite-mixins</module>
|
||||
|
||||
@@ -1615,5 +1615,9 @@ public interface Client extends GameEngine
|
||||
void toggleRenderSelf();
|
||||
|
||||
void invokeMenuAction(int var1, int var2, int var3, int var4, String var5, String var6, int var7, int var8);
|
||||
|
||||
|
||||
MouseRecorder getMouseRecorder();
|
||||
|
||||
void setPrintMenuActions(boolean b);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.api;
|
||||
|
||||
public interface MouseRecorder
|
||||
{
|
||||
|
||||
int[] getXs();
|
||||
|
||||
int[] getYs();
|
||||
|
||||
long[] getMillis();
|
||||
|
||||
int getIndex();
|
||||
|
||||
}
|
||||
|
||||
@@ -221,6 +221,11 @@
|
||||
<version>1.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>extended-mixins</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
@@ -272,6 +277,11 @@
|
||||
<artifactId>naturalmouse</artifactId>
|
||||
<version>[1.0.0,)</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm-all</artifactId>
|
||||
<version>6.0_BETA</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -315,7 +325,6 @@
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
|
||||
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||
<shadedClassifierName>shaded</shadedClassifierName>
|
||||
|
||||
@@ -118,6 +118,19 @@ class DevToolsPanel extends PluginPanel
|
||||
varInspector.open();
|
||||
}
|
||||
});
|
||||
|
||||
container.add(plugin.getLogMenuActions());
|
||||
plugin.getLogMenuActions().addActionListener((ev) ->
|
||||
{
|
||||
if(plugin.getLogMenuActions().isActive())
|
||||
{
|
||||
client.setPrintMenuActions(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
client.setPrintMenuActions(true);
|
||||
}
|
||||
});
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@ public class DevToolsPlugin extends Plugin
|
||||
private DevToolsButton detachedCamera;
|
||||
private DevToolsButton widgetInspector;
|
||||
private DevToolsButton varInspector;
|
||||
private DevToolsButton logMenuActions;
|
||||
private NavigationButton navButton;
|
||||
|
||||
@Provides
|
||||
@@ -173,6 +174,8 @@ public class DevToolsPlugin extends Plugin
|
||||
overlayManager.add(cameraOverlay);
|
||||
overlayManager.add(worldMapLocationOverlay);
|
||||
overlayManager.add(mapRegionOverlay);
|
||||
|
||||
logMenuActions = new DevToolsButton("Menu Actions");
|
||||
|
||||
final DevToolsPanel panel = injector.getInstance(DevToolsPanel.class);
|
||||
|
||||
|
||||
@@ -32,101 +32,82 @@ import com.google.common.reflect.TypeToken;
|
||||
import com.google.gson.Gson;
|
||||
import io.sigpipe.jbsdiff.InvalidHeaderException;
|
||||
import io.sigpipe.jbsdiff.Patch;
|
||||
|
||||
import java.applet.Applet;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarInputStream;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.logging.Logger;
|
||||
import javassist.ClassPool;
|
||||
import javassist.NotFoundException;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.RuneLite;
|
||||
|
||||
import static net.runelite.client.rs.ClientUpdateCheckMode.AUTO;
|
||||
import static net.runelite.client.rs.ClientUpdateCheckMode.NONE;
|
||||
import static net.runelite.client.rs.ClientUpdateCheckMode.VANILLA;
|
||||
import net.runelite.client.rs.bytecode.ByteCodePatcher;
|
||||
import net.runelite.client.rs.bytecode.ByteCodeUtils;
|
||||
import net.runelite.client.rs.bytecode.Hooks;
|
||||
|
||||
import net.runelite.client.rs.mixins.MixinRunner;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.apache.commons.compress.compressors.CompressorException;
|
||||
import org.xeustechnologies.jcl.JarClassLoader;
|
||||
|
||||
@Slf4j
|
||||
@Singleton
|
||||
public class ClientLoader
|
||||
{
|
||||
public static File hooksFile = new File(RuneLite.RUNELITE_DIR + "/hooks-" + RuneLiteAPI.getVersion() + "-.json");
|
||||
private final ClientConfigLoader clientConfigLoader;
|
||||
private ClientUpdateCheckMode updateCheckMode;
|
||||
private static String[] preotectedStuffs;
|
||||
private static int stepCount;
|
||||
|
||||
@Inject
|
||||
private ClientLoader(
|
||||
@Named("updateCheckMode") final ClientUpdateCheckMode updateCheckMode,
|
||||
final ClientConfigLoader clientConfigLoader)
|
||||
@Named("updateCheckMode") final ClientUpdateCheckMode updateCheckMode,
|
||||
final ClientConfigLoader clientConfigLoader)
|
||||
{
|
||||
this.updateCheckMode = updateCheckMode;
|
||||
this.clientConfigLoader = clientConfigLoader;
|
||||
}
|
||||
|
||||
|
||||
public Applet load()
|
||||
{
|
||||
if (updateCheckMode == NONE)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
File injectedClientFile = ByteCodeUtils.injectedClientFile;
|
||||
File hijackedClientFile = ByteCodeUtils.hijackedClientFile;
|
||||
Manifest manifest = new Manifest();
|
||||
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
|
||||
JarOutputStream target = new JarOutputStream(new FileOutputStream(injectedClientFile), manifest);
|
||||
RSConfig config = clientConfigLoader.fetch();
|
||||
|
||||
|
||||
Map<String, byte[]> zipFile = new HashMap<>();
|
||||
{
|
||||
String codebase = config.getCodeBase();
|
||||
String initialJar = config.getInitialJar();
|
||||
URL url = new URL(codebase + initialJar);
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
|
||||
{
|
||||
JarInputStream jis;
|
||||
|
||||
|
||||
jis = new JarInputStream(response.body().byteStream());
|
||||
|
||||
byte[] tmp = new byte[4096];
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream(756 * 1024);
|
||||
for (; ; )
|
||||
@@ -136,7 +117,7 @@ public class ClientLoader
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
buffer.reset();
|
||||
for (; ; )
|
||||
{
|
||||
@@ -147,12 +128,12 @@ public class ClientLoader
|
||||
}
|
||||
buffer.write(tmp, 0, n);
|
||||
}
|
||||
|
||||
|
||||
zipFile.put(metadata.getName(), buffer.toByteArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (updateCheckMode == AUTO)
|
||||
{
|
||||
Map<String, String> hashes;
|
||||
@@ -162,41 +143,33 @@ public class ClientLoader
|
||||
{
|
||||
}.getType());
|
||||
}
|
||||
|
||||
|
||||
for (Map.Entry<String, String> file : hashes.entrySet())
|
||||
{
|
||||
byte[] bytes = zipFile.get(file.getKey());
|
||||
|
||||
|
||||
String ourHash = null;
|
||||
if (bytes != null)
|
||||
{
|
||||
ourHash = Hashing.sha512().hashBytes(bytes).toString();
|
||||
}
|
||||
|
||||
|
||||
if (!file.getValue().equals(ourHash))
|
||||
{
|
||||
if (hijackedClientFile.exists())
|
||||
{
|
||||
Logger.getAnonymousLogger().warning("[RuneLitePlus] Hash checking / Client patching skipped due to hijacked client.");
|
||||
updateCheckMode = VANILLA;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
log.info("{} had a hash mismatch; falling back to vanilla. {} != {}", file.getKey(), file.getValue(), ourHash);
|
||||
log.info("Client is outdated!");
|
||||
updateCheckMode = VANILLA;
|
||||
break;
|
||||
}
|
||||
log.info("{} had a hash mismatch; falling back to vanilla. {} != {}", file.getKey(),
|
||||
file.getValue(), ourHash);
|
||||
log.info("Client is outdated!");
|
||||
updateCheckMode = VANILLA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (updateCheckMode == AUTO)
|
||||
{
|
||||
ByteArrayOutputStream patchOs = new ByteArrayOutputStream(756 * 1024);
|
||||
int patchCount = 0;
|
||||
|
||||
|
||||
for (Map.Entry<String, byte[]> file : zipFile.entrySet())
|
||||
{
|
||||
byte[] bytes;
|
||||
@@ -206,292 +179,110 @@ public class ClientLoader
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
bytes = ByteStreams.toByteArray(is);
|
||||
}
|
||||
|
||||
|
||||
patchOs.reset();
|
||||
Patch.patch(file.getValue(), bytes, patchOs);
|
||||
file.setValue(patchOs.toByteArray());
|
||||
|
||||
|
||||
++patchCount;
|
||||
|
||||
if (!file.getKey().startsWith("META"))
|
||||
{
|
||||
add(file.getValue(), file.getKey(), target);
|
||||
}
|
||||
}
|
||||
target.close();
|
||||
|
||||
|
||||
log.info("Patched {} classes", patchCount);
|
||||
}
|
||||
if (hooksFile.exists())
|
||||
|
||||
log.info("Patching for RuneLitePlus");
|
||||
|
||||
if (updateCheckMode == AUTO)
|
||||
{
|
||||
ByteCodePatcher.classPool = new ClassPool(true);
|
||||
ByteCodePatcher.classPool.appendClassPath(RuneLite.RUNELITE_DIR + "/injectedClient-" + RuneLiteAPI.getVersion() + "-.jar");
|
||||
Gson gson = new Gson();
|
||||
Hooks hooks = gson.fromJson(new BufferedReader(new FileReader(hooksFile)), Hooks.class);
|
||||
|
||||
if (hooks.clientInstance.equals("") ||
|
||||
hooks.clientClass.equals("") ||
|
||||
hooks.projectileClass.equals("") ||
|
||||
hooks.actorClass.equals("") ||
|
||||
hooks.playerClass.equals(""))
|
||||
|
||||
HashMap<String, byte[]> patches = new HashMap<>();
|
||||
|
||||
for (Map.Entry<String, byte[]> file : zipFile.entrySet())
|
||||
{
|
||||
log.info("[RuneLitePlus] Bad hooks, re-scraping.");
|
||||
stepCount = getStepCount(ByteCodeUtils.injectedClientFile.getPath());
|
||||
ByteCodePatcher.clientInstance = initHookScrape(ByteCodeUtils.injectedClientFile.getPath());
|
||||
ByteCodePatcher.findHooks(injectedClientFile.getPath());
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodePatcher.clientInstance = hooks.clientInstance;
|
||||
ByteCodePatcher.applyHooks(ByteCodeUtils.injectedClientFile, hooks);
|
||||
log.info("[RuneLitePlus] Loaded hooks");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
log.info("[RuneLitePlus] Hooks file not found, scraping hooks.");
|
||||
stepCount = getStepCount(ByteCodeUtils.injectedClientFile.getPath());
|
||||
ByteCodePatcher.clientInstance = initHookScrape(ByteCodeUtils.injectedClientFile.getPath());
|
||||
ByteCodePatcher.hooks.protectedStuff = preotectedStuffs;
|
||||
ByteCodePatcher.findHooks(injectedClientFile.getPath());
|
||||
}
|
||||
|
||||
Map<String, byte[]> zipFile2 = new HashMap<>();
|
||||
JarInputStream jis = new JarInputStream(new FileInputStream(hijackedClientFile));
|
||||
|
||||
byte[] tmp = new byte[4096];
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream(756 * 1024);
|
||||
for (; ; )
|
||||
{
|
||||
JarEntry metadata = jis.getNextJarEntry();
|
||||
if (metadata == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
buffer.reset();
|
||||
for (; ; )
|
||||
{
|
||||
int n = jis.read(tmp);
|
||||
if (n <= -1)
|
||||
byte[] patchClass;
|
||||
try (InputStream is = ClientLoader.class.getResourceAsStream("/extended-mixins/" + file.getKey()))
|
||||
{
|
||||
break;
|
||||
if (is == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
patchClass = ByteStreams.toByteArray(is);
|
||||
}
|
||||
buffer.write(tmp, 0, n);
|
||||
|
||||
patches.put(file.getKey(), patchClass);
|
||||
|
||||
}
|
||||
|
||||
zipFile2.put(metadata.getName(), buffer.toByteArray());
|
||||
|
||||
new MixinRunner(zipFile, patches).run();
|
||||
|
||||
}
|
||||
|
||||
|
||||
for (Map.Entry<String, byte[]> entry : zipFile.entrySet())
|
||||
{
|
||||
if (entry.getKey().contains("class"))
|
||||
{
|
||||
Files.write(new File("H:\\rsclasses\\" + entry.getKey()).toPath(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
String initialClass = config.getInitialClass();
|
||||
|
||||
|
||||
ClassLoader rsClassLoader = new ClassLoader(ClientLoader.class.getClassLoader())
|
||||
{
|
||||
@Override
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException
|
||||
{
|
||||
String path = name.replace('.', '/').concat(".class");
|
||||
byte[] data = zipFile2.get(path);
|
||||
byte[] data = zipFile.get(path);
|
||||
if (data == null)
|
||||
{
|
||||
throw new ClassNotFoundException(name);
|
||||
}
|
||||
|
||||
|
||||
return defineClass(name, data, 0, data.length);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Class<?> clientClass = rsClassLoader.loadClass(initialClass);
|
||||
|
||||
|
||||
Applet rs = (Applet) clientClass.newInstance();
|
||||
rs.setStub(new RSAppletStub(config));
|
||||
return rs;
|
||||
}
|
||||
catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException
|
||||
| CompressorException | InvalidHeaderException | SecurityException e)
|
||||
catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException | CompressorException | InvalidHeaderException | SecurityException | NoSuchMethodException | InvocationTargetException e)
|
||||
{
|
||||
if (e instanceof ClassNotFoundException)
|
||||
{
|
||||
log.error("Unable to load client - class not found. This means you"
|
||||
+ " are not running RuneLite with Maven as the client patch"
|
||||
+ " is not in your classpath.");
|
||||
+ " are not running RuneLite with Maven as the client patch"
|
||||
+ " is not in your classpath.");
|
||||
}
|
||||
|
||||
|
||||
log.error("Error loading RS!", e);
|
||||
return null;
|
||||
}
|
||||
catch (NotFoundException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private void add(byte[] bytes, String entryName, JarOutputStream target) throws IOException
|
||||
{
|
||||
JarEntry entry = new JarEntry(entryName);
|
||||
target.putNextEntry(entry);
|
||||
target.write(bytes);
|
||||
target.closeEntry();
|
||||
}
|
||||
|
||||
private static int getStepCount(String jarFile)
|
||||
{
|
||||
int stepCount = 0;
|
||||
JarClassLoader jcl = new JarClassLoader();
|
||||
BufferedInputStream in = null;
|
||||
try
|
||||
{
|
||||
ClassPool classPool = new ClassPool(true);
|
||||
classPool.appendClassPath(RuneLite.RUNELITE_DIR + "/injectedClient-" + RuneLiteAPI.getVersion() + "-.jar");
|
||||
JarEntry entry = new JarEntry(entryName);
|
||||
target.putNextEntry(entry);
|
||||
target.write(bytes);
|
||||
target.closeEntry();
|
||||
}
|
||||
catch (NotFoundException e)
|
||||
finally
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
jcl.add(new FileInputStream(jarFile));
|
||||
try (JarInputStream in = new JarInputStream(new BufferedInputStream(new FileInputStream(jarFile))))
|
||||
if (in != null)
|
||||
{
|
||||
JarEntry entry;
|
||||
while ((entry = in.getNextJarEntry()) != null)
|
||||
{
|
||||
if (entry.getName().endsWith(".class"))
|
||||
{
|
||||
stepCount++;
|
||||
}
|
||||
}
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return stepCount;
|
||||
}
|
||||
|
||||
private static String initHookScrape(String jarFile)
|
||||
{
|
||||
int currentStep = 0;
|
||||
RuneLite.splashScreen.setMessage("Analyzing injected client");
|
||||
List<String> protectedStuff = new ArrayList<>();
|
||||
String clientInstance = "";
|
||||
JarClassLoader jcl = new JarClassLoader();
|
||||
try
|
||||
{
|
||||
ClassPool classPool = new ClassPool(true);
|
||||
classPool.appendClassPath(RuneLite.RUNELITE_DIR + "/injectedClient-" + RuneLiteAPI.getVersion() + "-.jar");
|
||||
}
|
||||
catch (NotFoundException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
jcl.add(new FileInputStream(jarFile));
|
||||
try (JarInputStream in = new JarInputStream(new BufferedInputStream(new FileInputStream(jarFile))))
|
||||
{
|
||||
JarEntry entry;
|
||||
while ((entry = in.getNextJarEntry()) != null)
|
||||
{
|
||||
if (entry.getName().endsWith(".class"))
|
||||
{
|
||||
File temp = new File(jarFile);
|
||||
ClassLoader cl = ClassLoader.getSystemClassLoader();
|
||||
try
|
||||
{
|
||||
URLClassLoader child = new URLClassLoader(
|
||||
new URL[]{temp.toURI().toURL()},
|
||||
cl
|
||||
);
|
||||
try
|
||||
{
|
||||
Class classToLoad = Class.forName(entry.getName().replace(".class", ""), false, child);
|
||||
RuneLite.splashScreen.setSubMessage(entry.getName());
|
||||
currentStep++;
|
||||
RuneLite.splashScreen.setProgress(currentStep, stepCount);
|
||||
JarClassLoader jcl2 = new JarClassLoader();
|
||||
try
|
||||
{
|
||||
jcl2.add(new FileInputStream(ByteCodeUtils.injectedClientFile));
|
||||
Field[] fields = classToLoad.getDeclaredFields();
|
||||
Method[] methods = classToLoad.getDeclaredMethods();
|
||||
for (Field f : fields)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (f.getName().contains("$"))
|
||||
{
|
||||
log.info(classToLoad.getName() + "." + f.getName());
|
||||
protectedStuff.add(classToLoad.getName() + "." + f.getName());
|
||||
}
|
||||
if (f.getType().getName().equals("client"))
|
||||
{
|
||||
ByteCodePatcher.hooks.clientInstance = classToLoad.getName() + "." + f.getName();
|
||||
clientInstance = classToLoad.getName() + "." + f.getName();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
for (Method m : methods)
|
||||
{
|
||||
RuneLite.splashScreen.setSubMessage("Checked " + m.getName());
|
||||
if (m.getName().contains("$"))
|
||||
{
|
||||
protectedStuff.add(classToLoad.getName() + "." + m.getName());
|
||||
}
|
||||
}
|
||||
RuneLite.splashScreen.setProgress(currentStep, stepCount);
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
RuneLite.splashScreen.setProgress(2, 5);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
log.info("Class not found: " + entry.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (String ignored : protectedStuff)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
preotectedStuffs = new String[i];
|
||||
i = 0;
|
||||
|
||||
for (String o : protectedStuff)
|
||||
{
|
||||
preotectedStuffs[i] = o;
|
||||
i++;
|
||||
}
|
||||
|
||||
return clientInstance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,298 +0,0 @@
|
||||
package net.runelite.client.rs.bytecode;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarInputStream;
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.NotFoundException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.RuneLite;
|
||||
import net.runelite.client.rs.ClientLoader;
|
||||
import net.runelite.client.rs.bytecode.transformers.ActorTransform;
|
||||
import net.runelite.client.rs.bytecode.transformers.ClientTransform;
|
||||
import net.runelite.client.rs.bytecode.transformers.ErrorTransform;
|
||||
import net.runelite.client.rs.bytecode.transformers.PlayerTransform;
|
||||
import net.runelite.client.rs.bytecode.transformers.ProjectileTransform;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import org.xeustechnologies.jcl.JarClassLoader;
|
||||
|
||||
@Slf4j
|
||||
public class ByteCodePatcher
|
||||
{
|
||||
|
||||
public static List<CtClass> modifiedClasses = new ArrayList<>();
|
||||
public static Hooks hooks = new Hooks();
|
||||
public static String clientInstance;
|
||||
private static JarClassLoader jcl = new JarClassLoader();
|
||||
public static ClassPool classPool = null;
|
||||
private static ClassLoader cl = ClassLoader.getSystemClassLoader();
|
||||
private static int classCount = 0;
|
||||
|
||||
public static void applyHooks(File jf, Hooks hooks)
|
||||
{
|
||||
RuneLite.splashScreen.setProgress(0, 5);
|
||||
RuneLite.splashScreen.setMessage("Applying cached bytecode patches...");
|
||||
try
|
||||
{
|
||||
URLClassLoader child = new URLClassLoader(
|
||||
new URL[]{jf.toURI().toURL()},
|
||||
cl
|
||||
);
|
||||
try
|
||||
{
|
||||
RuneLite.splashScreen.setSubMessage("Transforming Client");
|
||||
Class clientClass = Class.forName(hooks.clientClass, false, child);
|
||||
transformClient(clientClass);
|
||||
RuneLite.splashScreen.setProgress(1, 5);
|
||||
|
||||
RuneLite.splashScreen.setSubMessage("Transforming Actor");
|
||||
Class actorClass = Class.forName(hooks.actorClass, false, child);
|
||||
transformActor(actorClass);
|
||||
RuneLite.splashScreen.setProgress(2, 5);
|
||||
|
||||
RuneLite.splashScreen.setSubMessage("Transforming Projectile");
|
||||
Class projectileClass = Class.forName(hooks.projectileClass, false, child);
|
||||
transformProjectile(projectileClass);
|
||||
RuneLite.splashScreen.setProgress(3, 5);
|
||||
|
||||
RuneLite.splashScreen.setSubMessage("Transforming Player");
|
||||
Class playerClass = Class.forName(hooks.playerClass, false, child);
|
||||
transformPlayer(playerClass);
|
||||
RuneLite.splashScreen.setProgress(4, 5);
|
||||
|
||||
// Odds and ends
|
||||
RuneLite.splashScreen.setSubMessage("Transforming Error method");
|
||||
transformStackTrace();
|
||||
RuneLite.splashScreen.setProgress(5, 5);
|
||||
|
||||
RuneLite.splashScreen.setSubMessage("");
|
||||
ByteCodeUtils.updateHijackedJar();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void findHooks(String jf)
|
||||
{
|
||||
RuneLite.splashScreen.setMessage("Hijacking Classes");
|
||||
try
|
||||
{
|
||||
classPool = new ClassPool(true);
|
||||
classPool.appendClassPath(RuneLite.RUNELITE_DIR + "/injectedClient-" + RuneLiteAPI.getVersion() + "-.jar");
|
||||
}
|
||||
catch (NotFoundException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
jcl.add(new FileInputStream(jf));
|
||||
try (JarInputStream in = new JarInputStream(new BufferedInputStream(new FileInputStream(jf))))
|
||||
{
|
||||
JarEntry entry;
|
||||
while ((entry = in.getNextJarEntry()) != null)
|
||||
{
|
||||
if (entry.getName().endsWith(".class"))
|
||||
{
|
||||
classCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
int i = 0;
|
||||
jcl.add(new FileInputStream(jf));
|
||||
try (JarInputStream in = new JarInputStream(new BufferedInputStream(new FileInputStream(jf))))
|
||||
{
|
||||
JarEntry entry;
|
||||
while ((entry = in.getNextJarEntry()) != null)
|
||||
{
|
||||
if (entry.getName().endsWith(".class"))
|
||||
{
|
||||
RuneLite.splashScreen.setProgress(i, classCount);
|
||||
RuneLite.splashScreen.setSubMessage("Checking " + entry.getName());
|
||||
checkClasses(new File(jf), entry);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
try
|
||||
{
|
||||
Writer writer = new FileWriter(ClientLoader.hooksFile);
|
||||
gson.toJson(hooks, writer);
|
||||
writer.flush();
|
||||
writer.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
ByteCodeUtils.updateHijackedJar();
|
||||
}
|
||||
|
||||
private static void checkClasses(File jf, JarEntry entry)
|
||||
{
|
||||
try
|
||||
{
|
||||
URLClassLoader child = new URLClassLoader(
|
||||
new URL[]{jf.toURI().toURL()},
|
||||
cl
|
||||
);
|
||||
try
|
||||
{
|
||||
Class classToLoad = Class.forName(entry.getName().replace(".class", ""), false, child);
|
||||
checkClient(classToLoad);
|
||||
checkActor(classToLoad);
|
||||
checkProjectile(classToLoad);
|
||||
checkPlayer(classToLoad);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// e.printStackTrace();
|
||||
// System.out.println("Class not found: "+entry.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkClient(Class current)
|
||||
{
|
||||
try
|
||||
{
|
||||
Method method = current.getDeclaredMethod("getProjectiles");
|
||||
if (method != null)
|
||||
{
|
||||
hooks.clientClass = current.getName();
|
||||
log.info("[RuneLitePlus] Transforming Client at class: " + current.getName());
|
||||
ClientTransform ct = new ClientTransform();
|
||||
ct.modify(current);
|
||||
}
|
||||
}
|
||||
catch (NoSuchMethodException | NoClassDefFoundError e)
|
||||
{
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void transformClient(Class client)
|
||||
{
|
||||
log.info("[RuneLitePlus] Transforming Client at class: " + client.getName());
|
||||
ClientTransform ct = new ClientTransform();
|
||||
ct.modify(client);
|
||||
}
|
||||
|
||||
private static void checkActor(Class current)
|
||||
{
|
||||
try
|
||||
{
|
||||
Method method = current.getDeclaredMethod("setCombatInfo", new Class[]{int.class, int.class, int.class, int.class, int.class, int.class});
|
||||
if (method != null)
|
||||
{
|
||||
hooks.actorClass = current.getName();
|
||||
log.info("[RuneLitePlus] Transforming Actor at class: " + current.getName());
|
||||
ActorTransform at = new ActorTransform();
|
||||
at.modify(current);
|
||||
}
|
||||
}
|
||||
catch (NoSuchMethodException | NoClassDefFoundError e)
|
||||
{
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void transformActor(Class actor)
|
||||
{
|
||||
log.info("[RuneLitePlus] Transforming Actor at class: " + actor.getName());
|
||||
ActorTransform at = new ActorTransform();
|
||||
at.modify(actor);
|
||||
}
|
||||
|
||||
private static void checkProjectile(Class current)
|
||||
{
|
||||
try
|
||||
{
|
||||
Method method = current.getDeclaredMethod("projectileMoved", new Class[]{int.class, int.class, int.class, int.class});
|
||||
if (method != null)
|
||||
{
|
||||
hooks.projectileClass = current.getName();
|
||||
log.info("[RuneLitePlus] Transforming Projectile at class: " + current.getName());
|
||||
ProjectileTransform pt = new ProjectileTransform();
|
||||
pt.modify(current);
|
||||
}
|
||||
}
|
||||
catch (NoSuchMethodException | NoClassDefFoundError e)
|
||||
{
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void transformProjectile(Class projectile)
|
||||
{
|
||||
log.info("[RuneLitePlus] Transforming Projectile at class: " + projectile.getName());
|
||||
ProjectileTransform pt = new ProjectileTransform();
|
||||
pt.modify(projectile);
|
||||
}
|
||||
|
||||
private static void checkPlayer(Class current)
|
||||
{
|
||||
try
|
||||
{
|
||||
Method method = current.getDeclaredMethod("getSkullIcon");
|
||||
if (method != null)
|
||||
{
|
||||
hooks.playerClass = current.getName();
|
||||
log.info("[RuneLitePlus] Transforming Player at class: " + current.getName());
|
||||
PlayerTransform pt = new PlayerTransform();
|
||||
pt.modify(current);
|
||||
}
|
||||
}
|
||||
catch (NoSuchMethodException | NoClassDefFoundError e)
|
||||
{
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void transformPlayer(Class player)
|
||||
{
|
||||
log.info("[RuneLitePlus] Transforming Player at class: " + player.getName());
|
||||
PlayerTransform pt = new PlayerTransform();
|
||||
pt.modify(player);
|
||||
}
|
||||
|
||||
private static void transformStackTrace()
|
||||
{
|
||||
log.info("[RuneLitePlus] Transforming Stack Trace");
|
||||
ErrorTransform et = new ErrorTransform();
|
||||
et.modify(null);
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
package net.runelite.client.rs.bytecode;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import javassist.CtClass;
|
||||
import net.runelite.client.RuneLite;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
|
||||
public class ByteCodeUtils
|
||||
{
|
||||
//TODO: Write method to delete old revision injected clients.
|
||||
public static File injectedClientFile = new File(RuneLite.RUNELITE_DIR + "/injectedClient-" + RuneLiteAPI.getVersion() + "-.jar");
|
||||
public static File hijackedClientFile = new File(RuneLite.RUNELITE_DIR + "/hijackedClient-" + RuneLiteAPI.getVersion() + "-.jar");
|
||||
|
||||
public static JarOutputStream target;
|
||||
|
||||
static void updateHijackedJar()
|
||||
{
|
||||
Manifest manifest = new Manifest();
|
||||
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
|
||||
try
|
||||
{
|
||||
target = new JarOutputStream(new FileOutputStream(hijackedClientFile), manifest);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
try
|
||||
{
|
||||
JarFile original = new JarFile(injectedClientFile);
|
||||
Enumeration<JarEntry> entries = original.entries();
|
||||
while (entries.hasMoreElements())
|
||||
{
|
||||
JarEntry entry = entries.nextElement();
|
||||
boolean skip = false;
|
||||
for (CtClass ct : ByteCodePatcher.modifiedClasses)
|
||||
{
|
||||
if ((ct.getName() + ".class").equals(entry.getName()))
|
||||
{
|
||||
skip = true;
|
||||
}
|
||||
}
|
||||
if (!skip)
|
||||
{
|
||||
add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
for (CtClass ct : ByteCodePatcher.modifiedClasses)
|
||||
{
|
||||
add(ct);
|
||||
}
|
||||
|
||||
target.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void add(CtClass ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
JarEntry newEntry = new JarEntry(ct.getName() + ".class");
|
||||
target.putNextEntry(newEntry);
|
||||
target.write(ct.toBytecode());
|
||||
target.closeEntry();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void add(JarEntry entry) throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!entry.getName().startsWith("META") && !entry.getName().equals(""))
|
||||
{
|
||||
target.putNextEntry(entry);
|
||||
target.write(getBytesFromZipFile(entry.getName()));
|
||||
target.closeEntry();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] getBytesFromZipFile(String entryName)
|
||||
{
|
||||
ZipFile zipFile;
|
||||
try
|
||||
{
|
||||
zipFile = new ZipFile(injectedClientFile);
|
||||
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
||||
|
||||
while (entries.hasMoreElements())
|
||||
{
|
||||
ZipEntry entry = entries.nextElement();
|
||||
if (entry.getName().equals(entryName))
|
||||
{
|
||||
InputStream stream = zipFile.getInputStream(entry);
|
||||
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
int nRead;
|
||||
byte[] data = new byte[1024];
|
||||
while ((nRead = stream.read(data, 0, data.length)) != -1)
|
||||
{
|
||||
buffer.write(data, 0, nRead);
|
||||
}
|
||||
buffer.flush();
|
||||
return buffer.toByteArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package net.runelite.client.rs.bytecode;
|
||||
|
||||
public class Hooks {
|
||||
|
||||
public String clientInstance = "";
|
||||
public String actorClass = "";
|
||||
public String projectileClass = "";
|
||||
public String playerClass = "";
|
||||
public String[] protectedStuff;
|
||||
public String clientClass = "";
|
||||
|
||||
public Hooks() {
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
package net.runelite.client.rs.bytecode.transformers;
|
||||
|
||||
import javassist.CannotCompileException;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtMethod;
|
||||
import javassist.CtNewMethod;
|
||||
import javassist.NotFoundException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.rs.bytecode.ByteCodePatcher;
|
||||
|
||||
@Slf4j
|
||||
public class ActorTransform implements Transform
|
||||
{
|
||||
private CtClass ct;
|
||||
|
||||
@Override
|
||||
public void modify(Class actor)
|
||||
{
|
||||
try
|
||||
{
|
||||
ct = ByteCodePatcher.classPool.get(actor.getName());
|
||||
|
||||
transformGetAnimation();
|
||||
transformAnimationChanged();
|
||||
transformGraphicChanged();
|
||||
|
||||
ByteCodePatcher.modifiedClasses.add(ct);
|
||||
}
|
||||
catch (CannotCompileException | NotFoundException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void transformGetAnimation() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod protectedAnimation = ct.getDeclaredMethod("1protect$getRsAnimation");
|
||||
ct.removeMethod(protectedAnimation);
|
||||
|
||||
protectedAnimation.setName("getRsAnimation");
|
||||
ct.addMethod(protectedAnimation);
|
||||
|
||||
CtMethod getAnimation = ct.getDeclaredMethod("getAnimation");
|
||||
ct.removeMethod(getAnimation);
|
||||
|
||||
getAnimation = CtNewMethod.make(
|
||||
"public int getAnimation()" +
|
||||
"{" +
|
||||
" return this.getRsAnimation();" +
|
||||
"}", ct);
|
||||
ct.addMethod(getAnimation);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private void transformAnimationChanged() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod getAnimationChanged = ct.getDeclaredMethod("animationChanged", new CtClass[]{CtClass.intType});
|
||||
ct.removeMethod(getAnimationChanged);
|
||||
|
||||
getAnimationChanged = CtNewMethod.make(
|
||||
"public void animationChanged(int n)" +
|
||||
"{" +
|
||||
" net.runelite.api.events.AnimationChanged animationChanged = new net.runelite.api.events.AnimationChanged();" +
|
||||
" animationChanged.setActor((net.runelite.api.Actor) this);" +
|
||||
ByteCodePatcher.clientInstance + ".getCallbacks().post((java.lang.Object)animationChanged);" +
|
||||
"}", ct);
|
||||
ct.addMethod(getAnimationChanged);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
|
||||
private void transformGraphicChanged() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod graphicChanged = ct.getDeclaredMethod("graphicChanged", new CtClass[]{CtClass.intType});
|
||||
ct.removeMethod(graphicChanged);
|
||||
|
||||
graphicChanged = CtNewMethod.make(
|
||||
"public void graphicChanged(int paramInt)" +
|
||||
"{" +
|
||||
" net.runelite.api.events.GraphicChanged localGraphicChanged = new net.runelite.api.events.GraphicChanged();" +
|
||||
" localGraphicChanged.setActor(this);" +
|
||||
ByteCodePatcher.clientInstance + ".getCallbacks().post(localGraphicChanged);" +
|
||||
"}", ct);
|
||||
ct.addMethod(graphicChanged);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,642 +0,0 @@
|
||||
package net.runelite.client.rs.bytecode.transformers;
|
||||
|
||||
import javassist.CannotCompileException;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtMethod;
|
||||
import javassist.CtNewMethod;
|
||||
import javassist.NotFoundException;
|
||||
import javassist.bytecode.AnnotationsAttribute;
|
||||
import javassist.bytecode.ClassFile;
|
||||
import javassist.bytecode.ConstPool;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.rs.bytecode.ByteCodePatcher;
|
||||
|
||||
@Slf4j
|
||||
public class ClientTransform implements Transform
|
||||
{
|
||||
|
||||
private CtClass ct;
|
||||
|
||||
@Override
|
||||
public void modify(Class clazz)
|
||||
{
|
||||
try
|
||||
{
|
||||
ct = ByteCodePatcher.classPool.get(clazz.getName());
|
||||
|
||||
transformProtectedGetMenuOptions();
|
||||
transformProtectedGetMenuTargets();
|
||||
transformProtectedGetMenuIdentifiers();
|
||||
transformProtectedGetMenuTypes();
|
||||
transformProtectedGetMenuActionParams0();
|
||||
transformProtectedGetMenuActionParams1();
|
||||
transformGetMenuEntries();
|
||||
transformSetMenuEntries();
|
||||
transformOnMenuOptionsChanged();
|
||||
transformGetProjectiles();
|
||||
transformGetCollisionMaps();
|
||||
transformDraw2010Menu();
|
||||
transformRenderSelf();
|
||||
transformboundingBoxCheck();
|
||||
transformcheckClickBox();
|
||||
|
||||
ByteCodePatcher.modifiedClasses.add(ct);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void transformProtectedGetMenuOptions() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod protectedGetMenuOptions;
|
||||
|
||||
protectedGetMenuOptions = ct.getDeclaredMethod("1protect$getMenuOptions");
|
||||
ct.removeMethod(protectedGetMenuOptions);
|
||||
|
||||
protectedGetMenuOptions.setName("getMenuOptions");
|
||||
ct.addMethod(protectedGetMenuOptions);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
|
||||
private void transformGetProjectiles() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod getProjectiles;
|
||||
|
||||
CtMethod getProjectilesDeque = ct.getDeclaredMethod("1protect$getProjectilesDeque");
|
||||
ct.removeMethod(getProjectilesDeque);
|
||||
|
||||
getProjectilesDeque.setName("getProjectilesDeque");
|
||||
ct.addMethod(getProjectilesDeque);
|
||||
|
||||
getProjectiles = ct.getDeclaredMethod("getProjectiles");
|
||||
ct.removeMethod(getProjectiles);
|
||||
|
||||
getProjectiles = CtNewMethod.make(
|
||||
"public java.util.List getProjectiles() { " +
|
||||
"java.util.ArrayList localArrayList = new java.util.ArrayList();" +
|
||||
"net.runelite.rs.api.RSDeque localRSDeque = getProjectilesDeque();" +
|
||||
"net.runelite.rs.api.RSNode localRSNode = localRSDeque.getHead();" +
|
||||
"for (net.runelite.api.Node localNode = localRSNode.getNext(); localNode != localRSNode; localNode = localNode.getNext()) {" +
|
||||
"net.runelite.api.Projectile localProjectile = (net.runelite.api.Projectile)localNode;" +
|
||||
"localArrayList.add(localProjectile); }" +
|
||||
"return localArrayList; }", ct);
|
||||
ct.addMethod(getProjectiles);
|
||||
|
||||
ClassFile classFile = ct.getClassFile();
|
||||
ConstPool constPool = classFile.getConstPool();
|
||||
AnnotationsAttribute attr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
|
||||
javassist.bytecode.annotation.Annotation annotation = new javassist.bytecode.annotation.Annotation("Override", constPool);
|
||||
attr.setAnnotation(annotation);
|
||||
getProjectiles.getMethodInfo().addAttribute(attr);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
|
||||
private void transformProtectedGetMenuTargets() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod protectedGetMenuTargets;
|
||||
|
||||
protectedGetMenuTargets = ct.getDeclaredMethod("1protect$getMenuTargets");
|
||||
ct.removeMethod(protectedGetMenuTargets);
|
||||
|
||||
protectedGetMenuTargets.setName("getMenuTargets");
|
||||
ct.addMethod(protectedGetMenuTargets);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
|
||||
private void transformGetCollisionMaps() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod getCollisionMaps;
|
||||
|
||||
CtMethod protectedMaps = ct.getDeclaredMethod("1protect$getRsCollisionMaps");
|
||||
ct.removeMethod(protectedMaps);
|
||||
|
||||
protectedMaps.setName("getRsCollisionMaps");
|
||||
ct.addMethod(protectedMaps);
|
||||
|
||||
getCollisionMaps = ct.getDeclaredMethod("getCollisionMaps");
|
||||
ct.removeMethod(getCollisionMaps);
|
||||
|
||||
getCollisionMaps = CtMethod.make("public net.runelite.rs.api.RSCollisionData[] getCollisionMaps() { return getRsCollisionMaps(); }", ct);
|
||||
ct.addMethod(getCollisionMaps);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
|
||||
private void transformProtectedGetMenuIdentifiers() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod protectedGetMenuIdentifiers;
|
||||
|
||||
protectedGetMenuIdentifiers = ct.getDeclaredMethod("1protect$getMenuIdentifiers");
|
||||
ct.removeMethod(protectedGetMenuIdentifiers);
|
||||
|
||||
protectedGetMenuIdentifiers.setName("getMenuIdentifiers");
|
||||
ct.addMethod(protectedGetMenuIdentifiers);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
|
||||
private void transformProtectedGetMenuTypes() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod protectedGetMenuTypes;
|
||||
protectedGetMenuTypes = ct.getDeclaredMethod("1protect$getMenuTypes");
|
||||
|
||||
// Don't remove as this is referenced elsewhere in client
|
||||
// ct.removeMethod(protectedGetMenuTypes);
|
||||
|
||||
CtMethod newProtectedGetMenuTypes = CtNewMethod.copy(protectedGetMenuTypes, ct, null);
|
||||
newProtectedGetMenuTypes.setName("getMenuTypes");
|
||||
|
||||
ct.addMethod(newProtectedGetMenuTypes);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
|
||||
private void transformProtectedGetMenuActionParams0() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod protectedGetMenuActionParams0;
|
||||
|
||||
protectedGetMenuActionParams0 = ct.getDeclaredMethod("1protect$getMenuActionParams0");
|
||||
ct.removeMethod(protectedGetMenuActionParams0);
|
||||
|
||||
protectedGetMenuActionParams0.setName("getMenuActionParams0");
|
||||
ct.addMethod(protectedGetMenuActionParams0);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
|
||||
private void transformProtectedGetMenuActionParams1() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod protectedGetMenuActionParams1;
|
||||
|
||||
protectedGetMenuActionParams1 = ct.getDeclaredMethod("1protect$getMenuActionParams1");
|
||||
ct.removeMethod(protectedGetMenuActionParams1);
|
||||
protectedGetMenuActionParams1.setName("getMenuActionParams1");
|
||||
ct.addMethod(protectedGetMenuActionParams1);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
|
||||
private void transformGetMenuEntries() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod getMenuEntries;
|
||||
|
||||
getMenuEntries = ct.getDeclaredMethod("getMenuEntries");
|
||||
ct.removeMethod(getMenuEntries);
|
||||
|
||||
getMenuEntries = CtMethod.make(
|
||||
"public net.runelite.api.MenuEntry[] getMenuEntries()" +
|
||||
"{" +
|
||||
" int n2 = this.getMenuOptionCount();" +
|
||||
" String[] arrstring = this.getMenuOptions();" +
|
||||
" String[] arrstring2 = this.getMenuTargets();" +
|
||||
" int[] arrn = this.getMenuIdentifiers();" +
|
||||
" int[] arrn2 = this.getMenuTypes();" +
|
||||
" int[] arrn3 = this.getMenuActionParams0();" +
|
||||
" int[] arrn4 = this.getMenuActionParams1();" +
|
||||
" boolean[] arrbl = this.getMenuForceLeftClick();" +
|
||||
" net.runelite.api.MenuEntry[] arrmenuEntry = new net.runelite.api.MenuEntry[n2];" +
|
||||
" int n3 = 0;" +
|
||||
" while (n3 < n2) " +
|
||||
" {" +
|
||||
" net.runelite.api.MenuEntry menuEntry = arrmenuEntry[n3] = new net.runelite.api.MenuEntry();" +
|
||||
" menuEntry.setOption(arrstring[n3]);" +
|
||||
" menuEntry.setTarget(arrstring2[n3]);" +
|
||||
" menuEntry.setIdentifier(arrn[n3]);" +
|
||||
" menuEntry.setType(arrn2[n3]);" +
|
||||
" menuEntry.setParam0(arrn3[n3]);" +
|
||||
" menuEntry.setParam1(arrn4[n3]);" +
|
||||
" menuEntry.setForceLeftClick(arrbl[n3]);" +
|
||||
" ++n3;" +
|
||||
" }" +
|
||||
" return arrmenuEntry;" +
|
||||
"}", ct);
|
||||
ct.addMethod(getMenuEntries);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
|
||||
private void transformSetMenuEntries() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod setMenuEntries;
|
||||
|
||||
setMenuEntries = ct.getDeclaredMethod("setMenuEntries");
|
||||
ct.removeMethod(setMenuEntries);
|
||||
setMenuEntries = CtNewMethod.make(
|
||||
"public void setMenuEntries(net.runelite.api.MenuEntry[] arrmenuEntry)" +
|
||||
"{" +
|
||||
" int n2 = 0;" +
|
||||
" String[] arrstring = this.getMenuOptions();" +
|
||||
" String[] arrstring2 = this.getMenuTargets();" +
|
||||
" int[] arrn = this.getMenuIdentifiers();" +
|
||||
" int[] arrn2 = this.getMenuTypes();" +
|
||||
" int[] arrn3 = this.getMenuActionParams0();" +
|
||||
" int[] arrn4 = this.getMenuActionParams1();" +
|
||||
" boolean[] arrbl = getMenuForceLeftClick();" +
|
||||
" net.runelite.api.MenuEntry[] arrmenuEntry2 = arrmenuEntry;" +
|
||||
" int n3 = arrmenuEntry2.length;" +
|
||||
" int n4 = 0;" +
|
||||
" do" +
|
||||
" {" +
|
||||
" String string;" +
|
||||
" if (n4 >= n3)" +
|
||||
" {" +
|
||||
" this.setMenuOptionCount(n2);" +
|
||||
" oldMenuEntryCount = n2;" +
|
||||
" return;" +
|
||||
" }" +
|
||||
" net.runelite.api.MenuEntry menuEntry = arrmenuEntry2[n4];" +
|
||||
" int n5 = menuEntry.getType();" +
|
||||
" arrstring[n2] = menuEntry.getOption();" +
|
||||
" arrstring2[n2] = menuEntry.getTarget();" +
|
||||
" arrn[n2] = menuEntry.getIdentifier();" +
|
||||
" arrn2[n2] = n5;" +
|
||||
" arrn3[n2] = menuEntry.getParam0();" +
|
||||
" arrn4[n2] = menuEntry.getParam1();" +
|
||||
" arrbl[n2] = menuEntry.isForceLeftClick();" +
|
||||
" ++n2;" +
|
||||
" ++n4;" +
|
||||
" } while (true);" +
|
||||
"}"
|
||||
, ct);
|
||||
ct.addMethod(setMenuEntries);
|
||||
}
|
||||
|
||||
private void transformOnMenuOptionsChanged() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod onMenuOptionsChanged;
|
||||
|
||||
onMenuOptionsChanged = ct.getDeclaredMethod("onMenuOptionsChanged", new CtClass[]{CtClass.intType});
|
||||
ct.removeMethod(onMenuOptionsChanged);
|
||||
|
||||
onMenuOptionsChanged = CtMethod.make(
|
||||
"public static void onMenuOptionsChanged(int n2)" +
|
||||
"{" +
|
||||
" int n3;" +
|
||||
" int n4 = oldMenuEntryCount;" +
|
||||
" oldMenuEntryCount = n3 = " + ByteCodePatcher.clientInstance + ".getMenuOptionCount();" +
|
||||
" if (n3 != n4 + 1) return;" +
|
||||
" net.runelite.api.events.MenuEntryAdded menuEntryAdded = new net.runelite.api.events.MenuEntryAdded(" +
|
||||
ByteCodePatcher.clientInstance + ".getMenuOptions()[n3 - 1]," +
|
||||
ByteCodePatcher.clientInstance + ".getMenuTargets()[n3 - 1]," +
|
||||
ByteCodePatcher.clientInstance + ".getMenuTypes()[n3 - 1]," +
|
||||
ByteCodePatcher.clientInstance + ".getMenuIdentifiers()[n3 - 1]," +
|
||||
ByteCodePatcher.clientInstance + ".getMenuActionParams0()[n3 - 1]," +
|
||||
ByteCodePatcher.clientInstance + ".getMenuActionParams1()[n3 - 1]);" +
|
||||
ByteCodePatcher.clientInstance + ".getCallbacks().post((Object)menuEntryAdded);" +
|
||||
"}"
|
||||
, ct);
|
||||
|
||||
ct.addMethod(onMenuOptionsChanged);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
|
||||
private void transformRenderSelf() throws CannotCompileException
|
||||
{
|
||||
CtMethod renderSelf;
|
||||
|
||||
renderSelf = CtMethod.make("public void toggleRenderSelf() { jb = !jb; }", ct);
|
||||
|
||||
ClassFile classFile = ct.getClassFile();
|
||||
ConstPool constPool = classFile.getConstPool();
|
||||
AnnotationsAttribute attr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
|
||||
javassist.bytecode.annotation.Annotation annotation = new javassist.bytecode.annotation.Annotation("Export", constPool);
|
||||
attr.setAnnotation(annotation);
|
||||
renderSelf.getMethodInfo().addAttribute(attr);
|
||||
|
||||
ct.addMethod(renderSelf);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
|
||||
private void transformDraw2010Menu() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod draw2010Menu;
|
||||
|
||||
draw2010Menu = ct.getDeclaredMethod("draw2010Menu");
|
||||
ct.removeMethod(draw2010Menu);
|
||||
|
||||
draw2010Menu = CtNewMethod.make(
|
||||
"public void draw2010Menu()" +
|
||||
"{" +
|
||||
" int n2 = this.getMenuX();" +
|
||||
" int n3 = this.getMenuY();" +
|
||||
" int n4 = this.getMenuWidth();" +
|
||||
" int n5 = this.getMenuHeight();" +
|
||||
" this.RasterizerDrawHorizontalLine(n2 + 2, n3, n4 - 4, 7170651);" +
|
||||
" this.RasterizerDrawHorizontalLine(n2 + 2, n3 + n5 - 1, n4 - 4, 7170651);" +
|
||||
" this.RasterizerDrawVerticalLine(n2, n3 + 2, n5 - 4, 7170651);" +
|
||||
" this.RasterizerDrawVerticalLine(n2 + n4 - 1, n3 + 2, n5 - 4, 7170651);" +
|
||||
" this.RasterizerDrawRectangle(n2 + 1, n3 + 5, n4 - 2, n5 - 6, 2827810);" +
|
||||
" this.RasterizerDrawHorizontalLine(n2 + 1, n3 + 17, n4 - 2, 2827810);" +
|
||||
" this.RasterizerDrawCircle(n2 + 2, n3 + n5 - 3, 0, 2827810);" +
|
||||
" this.RasterizerDrawCircle(n2 + n4 - 3, n3 + n5 - 3, 0, 2827810);" +
|
||||
" this.RasterizerDrawGradient(n2 + 2, n3 + 1, n4 - 4, 16, 3288610, 592388);" +
|
||||
" this.RasterizerFillRectangle(n2 + 1, n3 + 1, 2, 4, 2827810);" +
|
||||
" this.RasterizerFillRectangle(n2 + n4 - 3, n3 + 1, 2, 4, 2827810);" +
|
||||
" this.RasterizerDrawHorizontalLine(n2 + 2, n3 + 18, n4 - 4, 5392957);" +
|
||||
" this.RasterizerDrawHorizontalLine(n2 + 3, n3 + n5 - 3, n4 - 6, 5392957);" +
|
||||
" this.RasterizerDrawVerticalLine(n2 + 2, n3 + 18, n5 - 21, 5392957);" +
|
||||
" this.RasterizerDrawVerticalLine(n2 + n4 - 3, n3 + 18, n5 - 21, 5392957);" +
|
||||
" this.RasterizerFillRectangle(n2 + 3, n3 + 19, n4 - 6, n5 - 22, 2828060);" +
|
||||
" this.RasterizerDrawCircle(n2 + 1, n3 + 1, 0, 7170651);" +
|
||||
" this.RasterizerDrawCircle(n2 + n4 - 2, n3 + 1, 0, 7170651);" +
|
||||
" this.RasterizerDrawCircle(n2 + 1, n3 + n5 - 2, 0, 7170651);" +
|
||||
" this.RasterizerDrawCircle(n2 + n4 - 2, n3 + n5 - 2, 0, 7170651);" +
|
||||
" net.runelite.rs.api.RSFont rSFont = this.getFontBold12();" +
|
||||
" rSFont.drawTextLeftAligned(\"Choose Option\", n2 + 3, n3 + 14, 13023381, -1);" +
|
||||
" int n6 = this.getMouseX();" +
|
||||
" int n7 = this.getMouseY();" +
|
||||
" int n8 = this.getMenuOptionCount();" +
|
||||
" String[] arrstring = this.getMenuTargets();" +
|
||||
" String[] arrstring2 = this.getMenuOptions();" +
|
||||
" for (int i = 0; i < n8; ++i)" +
|
||||
" {" +
|
||||
" int n9 = n3 + (n8 - 1 - i) * 15 + 31;" +
|
||||
" String string = arrstring2[i];" +
|
||||
" if (!arrstring[i].isEmpty())" +
|
||||
" {" +
|
||||
" string = string + \" \" + arrstring[i];" +
|
||||
" }" +
|
||||
" rSFont.drawTextLeftAligned(string, n2 + 3, n9, 13023381, -1);" +
|
||||
" if (n6 <= n2 || n6 >= n4 + n2 || n7 <= n9 - 13 || n7 >= n9 + 3)" +
|
||||
" {" +
|
||||
" continue;" +
|
||||
" }" +
|
||||
" this.RasterizerFillRectangleAlpha(n2 + 3, n9 - 12, n4 - 6, 15, 16777215, 80);" +
|
||||
" }" +
|
||||
"}"
|
||||
, ct);
|
||||
ct.addMethod(draw2010Menu);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
|
||||
//TODO: fix not being able to click far away objects towards top of screen only.
|
||||
private void transformboundingBoxCheck() throws CannotCompileException
|
||||
{
|
||||
CtMethod boundingboxCheck2;
|
||||
|
||||
boundingboxCheck2 = CtMethod.make(
|
||||
"public boolean boundingboxCheck2(net.runelite.api.Model model, int n2, int n3, int n4)" +
|
||||
"{" +
|
||||
" int n5 = " + ByteCodePatcher.clientInstance + ".getCameraPitch();" +
|
||||
" int n6 = " + ByteCodePatcher.clientInstance + ".getCameraYaw();" +
|
||||
" int n7 = net.runelite.api.Perspective.SINE[n5];" +
|
||||
" int n8 = net.runelite.api.Perspective.COSINE[n5];" +
|
||||
" int n9 = net.runelite.api.Perspective.SINE[n6];" +
|
||||
" int n10 = net.runelite.api.Perspective.COSINE[n6];" +
|
||||
" int n11 = " + ByteCodePatcher.clientInstance + ".getCenterX();" +
|
||||
" int n12 = " + ByteCodePatcher.clientInstance + ".getCenterY();" +
|
||||
" int n13 = " + ByteCodePatcher.clientInstance + ".getViewportMouseX();" +
|
||||
" int n14 = " + ByteCodePatcher.clientInstance + ".getViewportMouseY();" +
|
||||
" int n15 = " + ByteCodePatcher.clientInstance + ".get3dZoom();" +
|
||||
" int n16 = (n13 - n11) * 50 / n15;" +
|
||||
" int n17 = (n14 - n12) * 50 / n15;" +
|
||||
" int n18 = (n13 - n11) * 10000 / n15;" +
|
||||
" int n19 = (n14 - n12) * 10000 / n15;" +
|
||||
" int n20 = client.rl$rot1(n17, 50, n8, n7);" +
|
||||
" int n21 = client.rl$rot2(n17, 50, n8, n7);" +
|
||||
" n17 = n20;" +
|
||||
" n20 = client.rl$rot1(n19, 10000, n8, n7);" +
|
||||
" int n22 = client.rl$rot2(n19, 10000, n8, n7);" +
|
||||
" n19 = n20;" +
|
||||
" n20 = client.rl$rot3(n16, n21, n10, n9);" +
|
||||
" n21 = client.rl$rot4(n16, n21, n10, n9);" +
|
||||
" n16 = n20;" +
|
||||
" n20 = client.rl$rot3(n18, n22, n10, n9);" +
|
||||
" n22 = client.rl$rot4(n18, n22, n10, n9);" +
|
||||
" int n23 = (n20 - n16) / 2;" +
|
||||
" int n24 = (n19 - n17) / 2;" +
|
||||
" int n25 = (n22 - n21) / 2;" +
|
||||
" int n26 = Math.abs(n23);" +
|
||||
" int n27 = Math.abs(n24);" +
|
||||
" int n28 = Math.abs(n25);" +
|
||||
" int n29 = n2 + model.getCenterX();" +
|
||||
" int n30 = n3 + model.getCenterY();" +
|
||||
" int n31 = n4 + model.getCenterZ();" +
|
||||
" int n32 = model.getExtremeX();" +
|
||||
" int n33 = model.getExtremeY();" +
|
||||
" int n34 = model.getExtremeZ();" +
|
||||
" int n35 = (n16 + n20) / 2;" +
|
||||
" int n36 = (n17 + n19) / 2;" +
|
||||
" int n37 = (n22 + n21) / 2;" +
|
||||
" int n38 = n35 - n29;" +
|
||||
" int n39 = n36 - n30;" +
|
||||
" int n40 = n37 - n31;" +
|
||||
" if (Math.abs(n38) > n32 + n26)" +
|
||||
" {" +
|
||||
" return false;" +
|
||||
" }" +
|
||||
" if (Math.abs(n39) > n33 + n27)" +
|
||||
" {" +
|
||||
" return false;" +
|
||||
" }" +
|
||||
" if (Math.abs(n40) > n34 + n28)" +
|
||||
" {" +
|
||||
" return false;" +
|
||||
" }" +
|
||||
" if (Math.abs(n40 * n24 - n39 * n25) > n33 * n28 + n34 * n27)" +
|
||||
" {" +
|
||||
" return false;" +
|
||||
" }" +
|
||||
" if (Math.abs(n38 * n25 - n40 * n23) > n34 * n26 + n32 * n28)" +
|
||||
" {" +
|
||||
" return false;" +
|
||||
" }" +
|
||||
" if (Math.abs(n39 * n23 - n38 * n24) <= n33 * n26 + n32 * n27)" +
|
||||
" {" +
|
||||
" return true;" +
|
||||
" }" +
|
||||
" return false;" +
|
||||
"}", ct);
|
||||
ct.addMethod(boundingboxCheck2);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
|
||||
private void transformcheckClickBox() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod checkClickBox;
|
||||
|
||||
checkClickBox = ct.getDeclaredMethod("checkClickbox");
|
||||
ct.removeMethod(checkClickBox);
|
||||
|
||||
checkClickBox = CtMethod.make(
|
||||
"public void checkClickbox(net.runelite.api.Model model, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9, long l2) {" +
|
||||
" int n10;" +
|
||||
" int n11;" +
|
||||
" int n12;" +
|
||||
" int n13;" +
|
||||
" int n14;" +
|
||||
" net.runelite.rs.api.RSModel rSModel = (net.runelite.rs.api.RSModel)model;" +
|
||||
" boolean bl2 = l2 != 0L && (int)(l2 >>> 16 & 1L) != 1;" +
|
||||
" boolean bl3 = " + ByteCodePatcher.clientInstance + ".getViewportContainsMouse();" +
|
||||
" if (!bl2)" +
|
||||
" {" +
|
||||
" return;" +
|
||||
" }" +
|
||||
" if (!bl3)" +
|
||||
" {" +
|
||||
" return;" +
|
||||
" }" +
|
||||
" boolean bl4 = this.boundingboxCheck2((net.runelite.api.Model)rSModel, n7, n8, n9);" +
|
||||
" if (!bl4)" +
|
||||
" {" +
|
||||
" return;" +
|
||||
" }" +
|
||||
" if (rSModel.isClickable())" +
|
||||
" {" +
|
||||
" this.addHashAtMouse(l2);" +
|
||||
" return;" +
|
||||
" }" +
|
||||
" int n15 = rSModel.getVerticesCount();" +
|
||||
" int n16 = rSModel.getTrianglesCount();" +
|
||||
" int[] arrn = rSModel.getVerticesX();" +
|
||||
" int[] arrn2 = rSModel.getVerticesY();" +
|
||||
" int[] arrn3 = rSModel.getVerticesZ();" +
|
||||
" int[] arrn4 = rSModel.getTrianglesX();" +
|
||||
" int[] arrn5 = rSModel.getTrianglesY();" +
|
||||
" int[] arrn6 = rSModel.getTrianglesZ();" +
|
||||
" int[] arrn7 = rSModel.getFaceColors3();" +
|
||||
" int n17 = " + ByteCodePatcher.clientInstance + ".get3dZoom();" +
|
||||
" int n18 = " + ByteCodePatcher.clientInstance + ".getCenterX();" +
|
||||
" int n19 = " + ByteCodePatcher.clientInstance + ".getCenterY();" +
|
||||
" int n20 = 0;" +
|
||||
" int n21 = 0;" +
|
||||
" if (n2 != 0)" +
|
||||
" {" +
|
||||
" n20 = net.runelite.api.Perspective.SINE[n2];" +
|
||||
" n21 = net.runelite.api.Perspective.COSINE[n2];" +
|
||||
" }" +
|
||||
" for (n14 = 0; n14 < n15; ++n14)" +
|
||||
" {" +
|
||||
" n11 = arrn[n14];" +
|
||||
" n13 = arrn2[n14];" +
|
||||
" n12 = arrn3[n14];" +
|
||||
" if (n2 != 0)" +
|
||||
" {" +
|
||||
" n10 = n12 * n20 + n11 * n21 >> 16;" +
|
||||
" n12 = n12 * n21 - n11 * n20 >> 16;" +
|
||||
" n11 = n10;" +
|
||||
" }" +
|
||||
" n10 = (n12 += n9) * n5 + n6 * (n11 += n7) >> 16;" +
|
||||
" n12 = n6 * n12 - n11 * n5 >> 16;" +
|
||||
" n11 = n10;" +
|
||||
" n10 = n4 * (n13 += n8) - n12 * n3 >> 16;" +
|
||||
" if ((n12 = n13 * n3 + n4 * n12 >> 16) >= 50)" +
|
||||
" {" +
|
||||
" client.rl$modelViewportYs[n14] = n11 * n17 / n12 + n18;" +
|
||||
" client.rl$modelViewportXs[n14] = n10 * n17 / n12 + n19;" +
|
||||
" continue;" +
|
||||
" }" +
|
||||
" client.rl$modelViewportYs[n14] = -5000;" +
|
||||
" }" +
|
||||
" n14 = " + ByteCodePatcher.clientInstance + ".getViewportMouseX();" +
|
||||
" n11 = " + ByteCodePatcher.clientInstance + ".getViewportMouseY();" +
|
||||
" n13 = 0;" +
|
||||
" while (n13 < n16)" +
|
||||
" {" +
|
||||
" if (arrn7[n13] != -2)" +
|
||||
" {" +
|
||||
" int n22;" +
|
||||
" boolean bl5;" +
|
||||
" int n23;" +
|
||||
" n12 = arrn4[n13];" +
|
||||
" n10 = arrn5[n13];" +
|
||||
" int n24 = arrn6[n13];" +
|
||||
" int n25 = rl$modelViewportYs[n12];" +
|
||||
" int n26 = rl$modelViewportYs[n10];" +
|
||||
" int n27 = rl$modelViewportYs[n24];" +
|
||||
" int n28 = rl$modelViewportXs[n12];" +
|
||||
" int n29 = rl$modelViewportXs[n10];" +
|
||||
" int n30 = rl$modelViewportXs[n24];" +
|
||||
" if (n25 != -5000 && n26 != -5000 && n27 != -5000 && (bl5 = (n23 = (n22 = rSModel.isClickable() ? 20 : 5) + n11) < n28 && n23 < n29 && n23 < n30 ? false : ((n23 = n11 - n22) > n28 && n23 > n29 && n23 > n30 ? false : ((n23 = n22 + n14) < n25 && n23 < n26 && n23 < n27 ? false : (n23 = n14 - n22) <= n25 || n23 <= n26 || n23 <= n27))))" +
|
||||
" {" +
|
||||
" this.addHashAtMouse(l2);" +
|
||||
" return;" +
|
||||
" }" +
|
||||
" }" +
|
||||
" ++n13;" +
|
||||
" }" +
|
||||
"}", ct);
|
||||
ct.addMethod(checkClickBox);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package net.runelite.client.rs.bytecode.transformers;
|
||||
|
||||
import javassist.CannotCompileException;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtMethod;
|
||||
import javassist.NotFoundException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.rs.bytecode.ByteCodePatcher;
|
||||
|
||||
@Slf4j
|
||||
// This prevents the client from sending stack traces to Jagex at all, even classes outside of runelite.
|
||||
public class ErrorTransform implements Transform
|
||||
{
|
||||
private CtClass ct;
|
||||
|
||||
// Where Runelites error interceptor is located, not auto-scraped.
|
||||
private static final String ERROR_INSTANCE_CLASS = "dp";
|
||||
private static final String ERROR_INSTANCE_METHOD = "a";
|
||||
// private static final String ERROR_WARNING = "Tried to send a warning";
|
||||
|
||||
@Override
|
||||
public void modify(Class clazz)
|
||||
{
|
||||
try
|
||||
{
|
||||
ct = ByteCodePatcher.classPool.get(ERROR_INSTANCE_CLASS);
|
||||
transformError();
|
||||
|
||||
ByteCodePatcher.modifiedClasses.add(ct);
|
||||
}
|
||||
catch (CannotCompileException | NotFoundException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void transformError() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod error = ct.getDeclaredMethod(ERROR_INSTANCE_METHOD);
|
||||
ct.removeMethod(error);
|
||||
|
||||
error = CtMethod.make(
|
||||
"public static void a(String string, Throwable throwable, byte by)" +
|
||||
"{" +
|
||||
" throwable.printStackTrace();" +
|
||||
" System.out.println(\"[RuneLitePlus] Prevented preceeding stack trace from being sent to Jagex\");" +
|
||||
"}", ct);
|
||||
ct.addMethod(error);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
package net.runelite.client.rs.bytecode.transformers;
|
||||
|
||||
import javassist.CannotCompileException;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtMethod;
|
||||
import javassist.CtNewMethod;
|
||||
import javassist.NotFoundException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.rs.bytecode.ByteCodePatcher;
|
||||
|
||||
@Slf4j
|
||||
public class PlayerTransform implements Transform
|
||||
{
|
||||
private CtClass ct;
|
||||
|
||||
@Override
|
||||
public void modify(Class player)
|
||||
{
|
||||
try
|
||||
{
|
||||
ct = ByteCodePatcher.classPool.get(player.getName());
|
||||
transformProtectedGetSkullIcon();
|
||||
transformGetSkullIcon();
|
||||
ByteCodePatcher.modifiedClasses.add(ct);
|
||||
}
|
||||
catch (CannotCompileException | NotFoundException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void transformProtectedGetSkullIcon() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod protectedGetSkullIcon;
|
||||
|
||||
protectedGetSkullIcon = ct.getDeclaredMethod("1protect$getRsSkullIcon");
|
||||
ct.removeMethod(protectedGetSkullIcon);
|
||||
protectedGetSkullIcon.setName("getRsSkullIcon");
|
||||
|
||||
ct.addMethod(protectedGetSkullIcon);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
|
||||
private void transformGetSkullIcon() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod getSkullIcon;
|
||||
|
||||
String SkullIcon = "net.runelite.api.SkullIcon";
|
||||
getSkullIcon = ct.getDeclaredMethod("getSkullIcon");
|
||||
ct.removeMethod(getSkullIcon);
|
||||
|
||||
getSkullIcon = CtNewMethod.make(
|
||||
"public " + SkullIcon + " getSkullIcon()" +
|
||||
"{" +
|
||||
"switch (this.getRsSkullIcon())" +
|
||||
"{" +
|
||||
"case 0:" +
|
||||
"return " + SkullIcon + ".SKULL;" +
|
||||
"case 1:" +
|
||||
"return " + SkullIcon + ".SKULL_FIGHT_PIT;" +
|
||||
"case 8:" +
|
||||
"return " + SkullIcon + ".DEAD_MAN_FIVE;" +
|
||||
"case 9:" +
|
||||
"return " + SkullIcon + ".DEAD_MAN_FOUR;" +
|
||||
"case 10:" +
|
||||
"return " + SkullIcon + ".DEAD_MAN_THREE;" +
|
||||
"case 11:" +
|
||||
"return " + SkullIcon + ".DEAD_MAN_TWO;" +
|
||||
"case 12:" +
|
||||
"return " + SkullIcon + ".DEAD_MAN_ONE;" +
|
||||
"}" +
|
||||
"return null;" +
|
||||
"}", ct);
|
||||
ct.addMethod(getSkullIcon);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
package net.runelite.client.rs.bytecode.transformers;
|
||||
|
||||
import javassist.CannotCompileException;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtMethod;
|
||||
import javassist.CtNewMethod;
|
||||
import javassist.NotFoundException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.rs.bytecode.ByteCodePatcher;
|
||||
|
||||
@Slf4j
|
||||
public class ProjectileTransform implements Transform
|
||||
{
|
||||
private CtClass ct;
|
||||
|
||||
// Next variable is manually added, and will break on rev update
|
||||
private static final String interactingIntvalue = "-1655053057";
|
||||
|
||||
@Override
|
||||
public void modify(Class projectile)
|
||||
{
|
||||
try
|
||||
{
|
||||
ct = ByteCodePatcher.classPool.get(projectile.getName());
|
||||
transformGetAnimation();
|
||||
transformInteracting();
|
||||
ByteCodePatcher.modifiedClasses.add(ct);
|
||||
}
|
||||
catch (CannotCompileException | NotFoundException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void transformGetAnimation() throws CannotCompileException, NotFoundException
|
||||
{
|
||||
CtMethod getAnimation;
|
||||
|
||||
getAnimation = ct.getDeclaredMethod("projectileMoved", new CtClass[]{CtClass.intType, CtClass.intType, CtClass.intType, CtClass.intType});
|
||||
ct.removeMethod(getAnimation);
|
||||
|
||||
getAnimation = CtNewMethod.make(
|
||||
"public void projectileMoved(int n, int n2, int n3, int n4)" +
|
||||
"{ " +
|
||||
" int n5 = this.getId();" +
|
||||
" net.runelite.api.coords.LocalPoint localPoint = new net.runelite.api.coords.LocalPoint(n, n2);" +
|
||||
" net.runelite.api.events.ProjectileMoved projectileMoved = new net.runelite.api.events.ProjectileMoved();" +
|
||||
" projectileMoved.setProjectile(this);" +
|
||||
" projectileMoved.setPosition(localPoint);" +
|
||||
" projectileMoved.setZ(n3);" +
|
||||
ByteCodePatcher.clientInstance + ".getCallbacks().post(projectileMoved);" +
|
||||
"}", ct);
|
||||
ct.addMethod(getAnimation);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
|
||||
private void transformInteracting() throws CannotCompileException
|
||||
{
|
||||
CtMethod getRsInteracting;
|
||||
CtMethod getInteracting;
|
||||
|
||||
getRsInteracting = CtNewMethod.make("public int getRsInteracting() { return this.n * " + interactingIntvalue + "; }", ct);
|
||||
ct.addMethod(getRsInteracting);
|
||||
|
||||
getInteracting = CtNewMethod.make(
|
||||
"public net.runelite.api.Actor getInteracting()" +
|
||||
"{" +
|
||||
" int var1 = this.getRsInteracting();" +
|
||||
" if (var1 == 0)" +
|
||||
" {" +
|
||||
" return null;" +
|
||||
" }" +
|
||||
" else" +
|
||||
" {" +
|
||||
" int var2;" +
|
||||
" if (var1 > 0)" +
|
||||
" {" +
|
||||
" var2 = var1 - 1;" +
|
||||
" net.runelite.rs.api.RSNPC[] var4 = " + ByteCodePatcher.clientInstance + ".getCachedNPCs();" +
|
||||
" return var4[var2];" +
|
||||
" }" +
|
||||
" else" +
|
||||
" {" +
|
||||
" var2 = -var1 - 1;" +
|
||||
" if (var2 == " + ByteCodePatcher.clientInstance + ".getLocalInteractingIndex())" +
|
||||
" {" +
|
||||
" return " + ByteCodePatcher.clientInstance + ".getLocalPlayer();" +
|
||||
" }" +
|
||||
" else" +
|
||||
" {" +
|
||||
" net.runelite.rs.api.RSPlayer[] var3 = " + ByteCodePatcher.clientInstance + ".getCachedPlayers();" +
|
||||
" return var3[var2];" +
|
||||
" }" +
|
||||
" }" +
|
||||
" }" +
|
||||
"}", ct);
|
||||
ct.addMethod(getInteracting);
|
||||
|
||||
log.info(
|
||||
"[RuneLitePlus] transformed {} ({}) at class: {}",
|
||||
this.getClass().getSimpleName(),
|
||||
new Object(){}.getClass().getEnclosingMethod().getName(),
|
||||
ct.getName()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package net.runelite.client.rs.bytecode.transformers;
|
||||
|
||||
public interface Transform {
|
||||
|
||||
void modify(Class clazz);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.rs.mixins;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.client.rs.mixins.transformers.*;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.commons.ClassRemapper;
|
||||
import org.objectweb.asm.commons.Remapper;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Map;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class MixinRunner
|
||||
{
|
||||
|
||||
private final Map<String, byte[]> classes;
|
||||
private final Map<String, byte[]> patches;
|
||||
|
||||
public Map<String, byte[]> run()
|
||||
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException
|
||||
{
|
||||
runVisitor(InterfaceTransformer.class);
|
||||
runVisitor(OverwriteTransformer.class);
|
||||
runSanityChecker(OverwriteSanityCheck.class);
|
||||
runVisitor(InjectTransformer.class);
|
||||
runVisitor(AppendTransformer.class); // append has to come before prepend or append does nothing
|
||||
// (test method: Projectile.rl$$init()V )
|
||||
runVisitor(PrependTransformer.class);
|
||||
runRemapper(ProtectTransformer.class);
|
||||
|
||||
recalcMaxes();
|
||||
return classes;
|
||||
}
|
||||
|
||||
private void runRemapper(Class<? extends Remapper> clazz) throws IllegalAccessException, InstantiationException
|
||||
{
|
||||
for (Map.Entry<String, byte[]> entry : classes.entrySet())
|
||||
{
|
||||
if (entry.getKey().contains("META-INF"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Remapper inst = clazz.newInstance();
|
||||
ClassReader cr = new ClassReader(entry.getValue());
|
||||
ClassWriter cw = new ClassWriter(cr, 1);
|
||||
cr.accept(new ClassRemapper(cw, inst), 0);
|
||||
|
||||
entry.setValue(cw.toByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
private void runVisitor(Class<? extends ClassVisitor> clazz)
|
||||
throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException
|
||||
{
|
||||
runVisitor(clazz, 1);
|
||||
}
|
||||
|
||||
private void runVisitor(Class<? extends ClassVisitor> clazz, int flags)
|
||||
throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException
|
||||
{
|
||||
for (Map.Entry<String, byte[]> entry : classes.entrySet())
|
||||
{
|
||||
if (entry.getKey().contains("META-INF"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ClassReader cr = new ClassReader(entry.getValue());
|
||||
ClassWriter cw = new ClassWriter(cr, flags);
|
||||
byte[] patch = patches.getOrDefault(entry.getKey(), null);
|
||||
ClassNode node = new ClassNode();
|
||||
cr.accept(node, 0);
|
||||
ClassVisitor inst = clazz.getConstructor(ClassVisitor.class, byte[].class, ClassNode.class).newInstance(cw,
|
||||
patch, node);
|
||||
cr.accept(inst, 0);
|
||||
|
||||
entry.setValue(cw.toByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
private void runSanityChecker(Class<? extends SanityChecker> clazz)
|
||||
throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException
|
||||
{
|
||||
runSanityChecker(clazz, 1);
|
||||
}
|
||||
|
||||
private void runSanityChecker(Class<? extends SanityChecker> clazz, int flags)
|
||||
throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, InstantiationException
|
||||
{
|
||||
for (Map.Entry<String, byte[]> entry : patches.entrySet())
|
||||
{
|
||||
ClassReader cr = new ClassReader(entry.getValue());
|
||||
ClassWriter cw = new ClassWriter(cr, flags);
|
||||
ClassNode node = new ClassNode();
|
||||
cr.accept(node, 0);
|
||||
SanityChecker inst = clazz.getConstructor(ClassVisitor.class, ClassNode.class).newInstance(cw, node);
|
||||
cr.accept(inst, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void recalcMaxes()
|
||||
throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException
|
||||
{
|
||||
runVisitor(DoNothingTransformer.class, 3);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.rs.mixins.transformers;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.util.RefUtils;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.LabelNode;
|
||||
import org.objectweb.asm.tree.LineNumberNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
@Slf4j
|
||||
public class AppendTransformer extends ClassVisitor implements Opcodes
|
||||
{
|
||||
|
||||
private final byte[] patch;
|
||||
private String className;
|
||||
private ClassNode classNode;
|
||||
|
||||
public AppendTransformer(ClassVisitor classVisitor, byte[] patch, ClassNode node)
|
||||
{
|
||||
super(Opcodes.ASM6, classVisitor);
|
||||
this.patch = patch;
|
||||
this.classNode = node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
||||
{
|
||||
className = name;
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions)
|
||||
{
|
||||
if (patch == null)
|
||||
{
|
||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
}
|
||||
ClassReader cr = new ClassReader(patch);
|
||||
ClassNode patchNode = new ClassNode(Opcodes.ASM6);
|
||||
cr.accept(patchNode, 0);
|
||||
for (Object obj : patchNode.methods)
|
||||
{
|
||||
MethodNode patchMethod = (MethodNode) obj;
|
||||
if ((patchMethod.access == access && patchMethod.name.equals("append$" + name) &&
|
||||
patchMethod.desc.equals(descriptor)) &&
|
||||
RefUtils.checkAnnotation(patchMethod, "Append"))
|
||||
{
|
||||
MethodVisitor mv =
|
||||
new MethodVisitor(Opcodes.ASM6, super.visitMethod(access, name, descriptor, signature,
|
||||
exceptions))
|
||||
{
|
||||
};
|
||||
mv.visitCode();
|
||||
|
||||
for (Object obj2 : classNode.methods)
|
||||
{
|
||||
MethodNode classMethod = (MethodNode) obj2;
|
||||
if (classMethod.access == access && classMethod.name.equals(name) &&
|
||||
classMethod.desc.equals(descriptor))
|
||||
{
|
||||
AbstractInsnNode inode = classMethod.instructions.getLast();
|
||||
|
||||
while(inode instanceof LabelNode || inode instanceof LineNumberNode)
|
||||
{
|
||||
inode = inode.getPrevious();
|
||||
}
|
||||
|
||||
if(RefUtils.isReturn(inode.getOpcode(), true))
|
||||
{
|
||||
log.error("[Append] Can't append to {}.{}, requires typed return opcode", className, name);
|
||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
}
|
||||
|
||||
classMethod.instructions.remove(inode);
|
||||
|
||||
classMethod.accept(new MethodReflector(mv));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
patchMethod.accept(new MethodReflector(mv));
|
||||
|
||||
mv.visitEnd();
|
||||
return mv;
|
||||
}
|
||||
}
|
||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.rs.mixins.transformers;
|
||||
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
public class DoNothingTransformer extends ClassVisitor
|
||||
{
|
||||
public DoNothingTransformer(ClassVisitor parent, byte[] patch, ClassNode node)
|
||||
{
|
||||
super(Opcodes.ASM6, parent);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.rs.mixins.transformers;
|
||||
|
||||
import net.runelite.client.util.RefUtils;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
public class InjectTransformer extends ClassVisitor
|
||||
{
|
||||
|
||||
private final byte[] patch;
|
||||
private ClassNode node;
|
||||
private String className;
|
||||
private boolean patching = false;
|
||||
|
||||
public InjectTransformer(ClassVisitor classVisitor, byte[] patch, ClassNode node)
|
||||
{
|
||||
super(Opcodes.ASM6, classVisitor);
|
||||
this.patch = patch;
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
||||
{
|
||||
className = name;
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions)
|
||||
{
|
||||
if (patch == null || name.startsWith("1protect$"))
|
||||
{
|
||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
}
|
||||
if (name.startsWith("prepend$") || name.startsWith("append$")||
|
||||
(patching && name.startsWith("<")))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
ClassReader cr = new ClassReader(patch);
|
||||
ClassNode patchNode = new ClassNode(Opcodes.ASM6);
|
||||
cr.accept(patchNode, 0);
|
||||
for (Object obj : patchNode.methods)
|
||||
{
|
||||
MethodNode node = (MethodNode) obj;
|
||||
if ((node.access == access && node.name.equals(name) && node.desc.equals(descriptor)) &&
|
||||
RefUtils.checkAnnotation(node, "Inject"))
|
||||
{
|
||||
mv.visitCode();
|
||||
node.accept(new MethodReflector(mv));
|
||||
mv.visitEnd();
|
||||
}
|
||||
}
|
||||
return mv;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd()
|
||||
{
|
||||
|
||||
if (patch == null)
|
||||
{
|
||||
super.visitEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
ClassReader cr = new ClassReader(patch);
|
||||
ClassNode patchNode = new ClassNode(Opcodes.ASM6);
|
||||
cr.accept(patchNode, 0);
|
||||
patching = true;
|
||||
for (Object obj : patchNode.methods)
|
||||
{
|
||||
MethodNode node = (MethodNode) obj;
|
||||
if (RefUtils.checkAnnotation(node, "Inject"))
|
||||
{
|
||||
visitMethod(node.access, node.name, node.desc, node.signature,
|
||||
(String[]) node.exceptions.toArray(new String[0]));
|
||||
}
|
||||
}
|
||||
|
||||
for (Object obj : patchNode.fields)
|
||||
{
|
||||
FieldNode node = (FieldNode) obj;
|
||||
if (RefUtils.checkAnnotation(node, "Inject"))
|
||||
{
|
||||
visitField(node.access, node.name, node.desc, node.signature, node.value);
|
||||
}
|
||||
}
|
||||
patching = false;
|
||||
super.visitEnd();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.rs.mixins.transformers;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Slf4j
|
||||
public class InterfaceTransformer extends ClassVisitor implements Opcodes
|
||||
{
|
||||
|
||||
private final byte[] patch;
|
||||
private ClassNode node;
|
||||
private String className;
|
||||
|
||||
public InterfaceTransformer(ClassVisitor classVisitor, byte[] patch, ClassNode node)
|
||||
{
|
||||
super(Opcodes.ASM6, classVisitor);
|
||||
this.patch = patch;
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
||||
{
|
||||
className = name;
|
||||
if(patch != null)
|
||||
{
|
||||
ClassReader reader = new ClassReader(patch);
|
||||
ClassNode pNode = new ClassNode();
|
||||
reader.accept(pNode, 0);
|
||||
if(pNode.interfaces != null && pNode.interfaces.size() != 0)
|
||||
{
|
||||
if(interfaces == null)
|
||||
{
|
||||
interfaces = (String[]) pNode.interfaces.toArray(new String[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ArrayList<String> list = new ArrayList<>(Arrays.asList(interfaces));
|
||||
pNode.interfaces.forEach((s) -> list.add((String) s));
|
||||
interfaces = list.toArray(new String[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.rs.mixins.transformers;
|
||||
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.Attribute;
|
||||
import org.objectweb.asm.Handle;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.TypePath;
|
||||
|
||||
public class MethodReflector extends MethodVisitor
|
||||
{
|
||||
|
||||
private MethodVisitor target;
|
||||
|
||||
public MethodReflector(MethodVisitor target)
|
||||
{
|
||||
super(Opcodes.ASM6);
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public void visitParameter(String var1, int var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitParameter(var1, var2);
|
||||
}
|
||||
super.visitParameter(var1, var2);
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitAnnotationDefault()
|
||||
{
|
||||
return super.visitAnnotationDefault();
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitAnnotation(String var1, boolean var2)
|
||||
{
|
||||
return super.visitAnnotation(var1, var2);
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitTypeAnnotation(int var1, TypePath var2, String var3, boolean var4)
|
||||
{
|
||||
return super.visitTypeAnnotation(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitParameterAnnotation(int var1, String var2, boolean var3)
|
||||
{
|
||||
return super.visitParameterAnnotation(var1, var2, var3);
|
||||
}
|
||||
|
||||
public void visitAttribute(Attribute var1)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitAttribute(var1);
|
||||
}
|
||||
super.visitAttribute(var1);
|
||||
}
|
||||
|
||||
public void visitFrame(int var1, int var2, Object[] var3, int var4, Object[] var5)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitFrame(var1, var2, var3, var4, var5);
|
||||
}
|
||||
super.visitFrame(var1, var2, var3, var4, var5);
|
||||
}
|
||||
|
||||
public void visitInsn(int var1)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitInsn(var1);
|
||||
}
|
||||
super.visitInsn(var1);
|
||||
}
|
||||
|
||||
public void visitIntInsn(int var1, int var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitIntInsn(var1, var2);
|
||||
}
|
||||
super.visitIntInsn(var1, var2);
|
||||
}
|
||||
|
||||
public void visitVarInsn(int var1, int var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitVarInsn(var1, var2);
|
||||
}
|
||||
super.visitVarInsn(var1, var2);
|
||||
}
|
||||
|
||||
public void visitTypeInsn(int var1, String var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitTypeInsn(var1, var2);
|
||||
}
|
||||
super.visitTypeInsn(var1, var2);
|
||||
}
|
||||
|
||||
public void visitFieldInsn(int var1, String var2, String var3, String var4)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitFieldInsn(var1, var2, var3, var4);
|
||||
}
|
||||
super.visitFieldInsn(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public void visitMethodInsn(int var1, String var2, String var3, String var4)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitMethodInsn(var1, var2, var3, var4);
|
||||
}
|
||||
super.visitMethodInsn(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
public void visitMethodInsn(int var1, String var2, String var3, String var4, boolean var5)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitMethodInsn(var1, var2, var3, var4, var5);
|
||||
}
|
||||
super.visitMethodInsn(var1, var2, var3, var4, var5);
|
||||
}
|
||||
|
||||
public void visitInvokeDynamicInsn(String var1, String var2, Handle var3, Object... var4)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitInvokeDynamicInsn(var1, var2, var3, var4);
|
||||
}
|
||||
super.visitInvokeDynamicInsn(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
public void visitJumpInsn(int var1, Label var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitJumpInsn(var1, var2);
|
||||
}
|
||||
super.visitJumpInsn(var1, var2);
|
||||
}
|
||||
|
||||
public void visitLabel(Label var1)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitLabel(var1);
|
||||
}
|
||||
super.visitLabel(var1);
|
||||
}
|
||||
|
||||
public void visitLdcInsn(Object var1)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitLdcInsn(var1);
|
||||
}
|
||||
super.visitLdcInsn(var1);
|
||||
}
|
||||
|
||||
public void visitIincInsn(int var1, int var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitIincInsn(var1, var2);
|
||||
}
|
||||
super.visitIincInsn(var1, var2);
|
||||
}
|
||||
|
||||
public void visitTableSwitchInsn(int var1, int var2, Label var3, Label... var4)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitTableSwitchInsn(var1, var2, var3, var4);
|
||||
}
|
||||
super.visitTableSwitchInsn(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
public void visitLookupSwitchInsn(Label var1, int[] var2, Label[] var3)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitLookupSwitchInsn(var1, var2, var3);
|
||||
}
|
||||
super.visitLookupSwitchInsn(var1, var2, var3);
|
||||
}
|
||||
|
||||
public void visitMultiANewArrayInsn(String var1, int var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitMultiANewArrayInsn(var1, var2);
|
||||
}
|
||||
super.visitMultiANewArrayInsn(var1, var2);
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitInsnAnnotation(int var1, TypePath var2, String var3, boolean var4)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitInsnAnnotation(var1, var2, var3, var4);
|
||||
}
|
||||
return super.visitInsnAnnotation(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
public void visitTryCatchBlock(Label var1, Label var2, Label var3, String var4)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitTryCatchBlock(var1, var2, var3, var4);
|
||||
}
|
||||
super.visitTryCatchBlock(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitTryCatchAnnotation(int var1, TypePath var2, String var3, boolean var4)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitTryCatchAnnotation(var1, var2, var3, var4);
|
||||
}
|
||||
return super.visitTryCatchAnnotation(var1, var2, var3, var4);
|
||||
}
|
||||
|
||||
public void visitLocalVariable(String var1, String var2, String var3, Label var4, Label var5, int var6)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitLocalVariable(var1, var2, var3, var4, var5, var6);
|
||||
}
|
||||
super.visitLocalVariable(var1, var2, var3, var4, var5, var6);
|
||||
}
|
||||
|
||||
public AnnotationVisitor visitLocalVariableAnnotation(int var1, TypePath var2, Label[] var3, Label[] var4, int[] var5, String var6, boolean var7)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitLocalVariableAnnotation(var1, var2, var3, var4, var5, var6, var7);
|
||||
}
|
||||
return super.visitLocalVariableAnnotation(var1, var2, var3, var4, var5, var6, var7);
|
||||
}
|
||||
|
||||
public void visitLineNumber(int var1, Label var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitLineNumber(var1, var2);
|
||||
}
|
||||
super.visitLineNumber(var1, var2);
|
||||
}
|
||||
|
||||
public void visitMaxs(int var1, int var2)
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
target.visitMaxs(var1, var2);
|
||||
}
|
||||
super.visitMaxs(var1, var2);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.rs.mixins.transformers;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.util.RefUtils;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@Slf4j
|
||||
public class OverwriteSanityCheck extends SanityChecker implements Opcodes
|
||||
{
|
||||
|
||||
private String className;
|
||||
private ClassNode patchNode;
|
||||
public static final ArrayList<String> methodsUsed = new ArrayList<>();
|
||||
|
||||
public OverwriteSanityCheck(ClassVisitor classVisitor, ClassNode node)
|
||||
{
|
||||
super(ASM6, classVisitor);
|
||||
this.className = node.name;
|
||||
this.patchNode = node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions)
|
||||
{
|
||||
String check = String.format("%s %s %s %s", className, name,
|
||||
descriptor, access);
|
||||
|
||||
MethodNode methodNode = null;
|
||||
for (Object obj2 : patchNode.methods)
|
||||
{
|
||||
MethodNode classMethod = (MethodNode) obj2;
|
||||
if (classMethod.access == access && classMethod.name.equals(name) &&
|
||||
classMethod.desc.equals(descriptor))
|
||||
{
|
||||
methodNode = classMethod;
|
||||
}
|
||||
}
|
||||
|
||||
if(methodNode == null)
|
||||
{
|
||||
log.error("[OverwriteSanity] Failed to find original patch method for {}", check);
|
||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
}
|
||||
|
||||
if (!RefUtils.checkAnnotation(methodNode, "Overwrite"))
|
||||
{
|
||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
}
|
||||
|
||||
if (!methodsUsed.contains(check))
|
||||
{
|
||||
throw new RuntimeException("[OverwriteSanity] Overwrite target not found: " + check);
|
||||
}
|
||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.rs.mixins.transformers;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.util.RefUtils;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
@Slf4j
|
||||
public class OverwriteTransformer extends ClassVisitor
|
||||
{
|
||||
|
||||
private final byte[] patch;
|
||||
private ClassNode node;
|
||||
private String className;
|
||||
|
||||
public OverwriteTransformer(ClassVisitor classVisitor, byte[] patch, ClassNode node)
|
||||
{
|
||||
super(Opcodes.ASM6, classVisitor);
|
||||
this.patch = patch;
|
||||
this.node = node;
|
||||
this.className = node.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
||||
{
|
||||
className = name;
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions)
|
||||
{
|
||||
if (patch == null || name.startsWith("1protect$"))
|
||||
{
|
||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
}
|
||||
|
||||
if (name.startsWith("prepend$") || name.startsWith("append$"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ClassReader cr = new ClassReader(patch);
|
||||
ClassNode patchNode = new ClassNode(Opcodes.ASM6);
|
||||
cr.accept(patchNode, 0);
|
||||
|
||||
for (Object obj : patchNode.methods)
|
||||
{
|
||||
MethodNode patchMethod = (MethodNode) obj;
|
||||
|
||||
if (patchMethod.access == access && patchMethod.name.equals(name) && patchMethod.desc.equals(descriptor))
|
||||
{
|
||||
if (RefUtils.checkAnnotation(patchMethod, "Overwrite"))
|
||||
{
|
||||
MethodVisitor mv =
|
||||
new MethodVisitor(Opcodes.ASM6, super.visitMethod(access, name, descriptor, signature,
|
||||
exceptions))
|
||||
{
|
||||
};
|
||||
mv.visitCode();
|
||||
patchMethod.accept(new MethodReflector(mv));
|
||||
mv.visitEnd();
|
||||
String s = String.format("%s %s %s %s", className, patchMethod.name,
|
||||
patchMethod.desc, patchMethod.access);
|
||||
OverwriteSanityCheck.methodsUsed.add(s);
|
||||
return mv;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.rs.mixins.transformers;
|
||||
|
||||
import net.runelite.client.util.RefUtils;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.InsnNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
public class PrependTransformer extends ClassVisitor
|
||||
{
|
||||
|
||||
private final byte[] patch;
|
||||
private String className;
|
||||
private ClassNode classNode;
|
||||
|
||||
public PrependTransformer(ClassVisitor classVisitor, byte[] patch, ClassNode node)
|
||||
{
|
||||
super(Opcodes.ASM6, classVisitor);
|
||||
this.patch = patch;
|
||||
this.classNode = node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces)
|
||||
{
|
||||
className = name;
|
||||
super.visit(version, access, name, signature, superName, interfaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions)
|
||||
{
|
||||
if (patch == null)
|
||||
{
|
||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
}
|
||||
ClassReader cr = new ClassReader(patch);
|
||||
ClassNode patchNode = new ClassNode(Opcodes.ASM6);
|
||||
cr.accept(patchNode, 0);
|
||||
for (Object obj : patchNode.methods)
|
||||
{
|
||||
MethodNode patchMethod = (MethodNode) obj;
|
||||
if ((patchMethod.access == access && patchMethod.name.equals("prepend$" + name) &&
|
||||
patchMethod.desc.equals(descriptor)) &&
|
||||
RefUtils.checkAnnotation(patchMethod, "Prepend"))
|
||||
{
|
||||
MethodVisitor mv =
|
||||
new MethodVisitor(Opcodes.ASM6, super.visitMethod(access, name, descriptor, signature,
|
||||
exceptions))
|
||||
{
|
||||
};
|
||||
mv.visitCode();
|
||||
|
||||
AbstractInsnNode node = patchMethod.instructions.getLast();
|
||||
while (!(node instanceof InsnNode))
|
||||
{
|
||||
node = node.getPrevious();
|
||||
}
|
||||
|
||||
if (RefUtils.isReturn(node.getOpcode()))
|
||||
{
|
||||
patchMethod.instructions.remove(node);
|
||||
}
|
||||
|
||||
patchMethod.accept(new MethodReflector(mv));
|
||||
|
||||
for (Object obj2 : classNode.methods)
|
||||
{
|
||||
MethodNode classMethod = (MethodNode) obj2;
|
||||
if (classMethod.access == access && classMethod.name.equals(name) &&
|
||||
classMethod.desc.equals(descriptor))
|
||||
{
|
||||
classMethod.accept(new MethodReflector(mv));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mv.visitEnd();
|
||||
return mv;
|
||||
}
|
||||
}
|
||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd()
|
||||
{
|
||||
if (patch == null)
|
||||
{
|
||||
super.visitEnd();
|
||||
return;
|
||||
}
|
||||
super.visitEnd();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.rs.mixins.transformers;
|
||||
|
||||
import org.objectweb.asm.commons.Remapper;
|
||||
|
||||
public class ProtectTransformer extends Remapper
|
||||
{
|
||||
|
||||
public String mapFieldName(String owner, String name, String descriptor)
|
||||
{
|
||||
if (name.startsWith("1protect$"))
|
||||
{
|
||||
name = name.substring("1protect$".length());
|
||||
}
|
||||
return super.mapFieldName(owner, name, descriptor);
|
||||
}
|
||||
|
||||
public String mapMethodName(String owner, String name, String descriptor)
|
||||
{
|
||||
if (name.startsWith("1protect$"))
|
||||
{
|
||||
name = name.substring("1protect$".length());
|
||||
}
|
||||
return super.mapMethodName(owner, name, descriptor);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.rs.mixins.transformers;
|
||||
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
public abstract class SanityChecker extends ClassVisitor implements Opcodes
|
||||
{
|
||||
protected SanityChecker(int i, ClassVisitor classVisitor)
|
||||
{
|
||||
super(i, classVisitor);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.util;
|
||||
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.AnnotationNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
public class RefUtils implements Opcodes
|
||||
{
|
||||
|
||||
private static final String TYPE_PREFIX = "us/runelitepl/mixinprocessor/annotations/";
|
||||
|
||||
public static boolean isReturn(int opcode, boolean checkType)
|
||||
{
|
||||
return (opcode == RETURN && !checkType) || opcode == IRETURN || opcode == LRETURN || opcode == DRETURN ||
|
||||
opcode == ARETURN || opcode == FRETURN;
|
||||
}
|
||||
|
||||
public static boolean isReturn(int opcode)
|
||||
{
|
||||
return isReturn(opcode, false);
|
||||
}
|
||||
|
||||
public static boolean checkAnnotation(MethodNode method, String annotation)
|
||||
{
|
||||
if (method.visibleAnnotations != null)
|
||||
{
|
||||
for (Object obj : method.visibleAnnotations)
|
||||
{
|
||||
if (((AnnotationNode) obj).desc.equals(makeAnnotationDesc(annotation)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean checkAnnotation(FieldNode field, String annotation)
|
||||
{
|
||||
if (field.visibleAnnotations != null)
|
||||
{
|
||||
for (Object obj : field.visibleAnnotations)
|
||||
{
|
||||
if (((AnnotationNode) obj).desc.equals(makeAnnotationDesc(annotation)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String makeAnnotationDesc(String annot)
|
||||
{
|
||||
return "L" + TYPE_PREFIX + annot + ";";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -975,5 +975,11 @@ public interface RSClient extends RSGameEngine, Client
|
||||
|
||||
@Import("renderSelf")
|
||||
void toggleRenderSelf();
|
||||
|
||||
@Import("mouseRecorder")
|
||||
RSMouseRecorder getMouseRecorder();
|
||||
|
||||
@Import("printMenuActions")
|
||||
void setPrintMenuActions(boolean b);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ThatGamerBlue <thatgamerblue@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.rs.api;
|
||||
|
||||
import net.runelite.api.MouseRecorder;
|
||||
import net.runelite.mapping.Import;
|
||||
|
||||
public interface RSMouseRecorder extends MouseRecorder
|
||||
{
|
||||
|
||||
@Import("xs")
|
||||
int[] getXs();
|
||||
|
||||
@Import("ys")
|
||||
int[] getYs();
|
||||
|
||||
@Import("millis")
|
||||
long[] getMillis();
|
||||
|
||||
@Import("index")
|
||||
int getIndex();
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user