Skip to content

Commit aa029a8

Browse files
committed
Initial commit
0 parents  commit aa029a8

File tree

16 files changed

+563
-0
lines changed

16 files changed

+563
-0
lines changed

.gitignore

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Vim
2+
.*swp
3+
*~
4+
5+
# IntelliJ
6+
out/
7+
*.iml
8+
.idea/
9+
10+
# Gradle
11+
build/
12+
.gradle/
13+
14+
# Test Server stuff
15+
testenv/
16+

LICENSE

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Copyright 2017 MiniDigger,Yamakaja
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4+
5+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6+
7+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

agent/build.gradle

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
apply plugin: 'java'
2+
3+
dependencies {
4+
compile "org.ow2.asm:asm-all:5.2"
5+
}
6+
7+
repositories {
8+
mavenCentral()
9+
}
10+
11+
jar {
12+
from {
13+
configurations.compile.collect {
14+
it.isDirectory() ? it : zipTree(it)
15+
}
16+
}
17+
18+
manifest {
19+
attributes(
20+
"Agent-Class": "me.yamakaja.runtimetransformer.agent.Agent",
21+
"Can-Retransform-Classes": "true",
22+
"Can-Redefine-Classes": "true"
23+
)
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package me.yamakaja.runtimetransformer.agent;
2+
3+
import java.lang.instrument.Instrumentation;
4+
import java.lang.instrument.UnmodifiableClassException;
5+
import java.util.regex.Matcher;
6+
import java.util.regex.Pattern;
7+
8+
/**
9+
* Created by Yamakaja on 19.05.17.
10+
*/
11+
public class Agent {
12+
13+
private static Pattern pattern = Pattern.compile("net\\.minecraft\\.server\\.(v[\\d_R]*)\\.EntityLiving");
14+
15+
public static void agentmain(String agentArgument, Instrumentation instrumentation) {
16+
17+
instrumentation.addTransformer(new EntityClassFileTransformer(), true);
18+
19+
String version = null;
20+
Class<?> resultClass = null;
21+
22+
for (Class<?> clazz : instrumentation.getAllLoadedClasses()) {
23+
if (pattern.matcher(clazz.getName()).matches()) {
24+
Matcher matcher = pattern.matcher(clazz.getName());
25+
matcher.find();
26+
version = matcher.group(1);
27+
resultClass = clazz;
28+
break;
29+
}
30+
}
31+
32+
if (version == null) {
33+
throw new RuntimeException("No version of EntityLiving could be found!");
34+
}
35+
36+
System.out.println("Determined version: " + version);
37+
38+
try {
39+
instrumentation.retransformClasses(resultClass);
40+
} catch (UnmodifiableClassException e) {
41+
e.printStackTrace();
42+
}
43+
44+
}
45+
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package me.yamakaja.runtimetransformer.agent;
2+
3+
import org.objectweb.asm.ClassReader;
4+
import org.objectweb.asm.ClassVisitor;
5+
import org.objectweb.asm.ClassWriter;
6+
import org.objectweb.asm.Opcodes;
7+
8+
import java.lang.instrument.ClassFileTransformer;
9+
import java.security.ProtectionDomain;
10+
import java.util.regex.Pattern;
11+
12+
/**
13+
* Created by Yamakaja on 18.05.17.
14+
*/
15+
public class EntityClassFileTransformer implements ClassFileTransformer {
16+
17+
private Pattern pattern = Pattern.compile("net/minecraft/server/(v[\\d_R]*)/EntityLiving");
18+
19+
@Override
20+
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) {
21+
boolean visitingEntityLiving = pattern.matcher(className).matches();
22+
if (!visitingEntityLiving)
23+
return classfileBuffer;
24+
25+
System.out.println("Transforming EntityLiving!");
26+
27+
ClassWriter writer;
28+
try {
29+
ClassReader reader = new ClassReader(classfileBuffer);
30+
31+
writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
32+
ClassVisitor visitor = new EntityClassVisitor(Opcodes.ASM5, writer);
33+
34+
reader.accept(visitor, 0);
35+
36+
} catch (Throwable e) {
37+
e.printStackTrace();
38+
throw new RuntimeException(e);
39+
}
40+
41+
return writer.toByteArray();
42+
}
43+
44+
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package me.yamakaja.runtimetransformer.agent;
2+
3+
import org.objectweb.asm.MethodVisitor;
4+
import org.objectweb.asm.Opcodes;
5+
6+
/**
7+
* Created by Yamakaja on 18.05.17.
8+
*/
9+
public class EntityClassMethodVisitor extends MethodVisitor {
10+
11+
private String version;
12+
public float test;
13+
14+
public EntityClassMethodVisitor(int api, MethodVisitor mv, String version) {
15+
super(api, mv);
16+
this.version = version;
17+
}
18+
19+
@Override
20+
public void visitCode() {
21+
super.visitCode();
22+
23+
mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder");
24+
mv.visitInsn(Opcodes.DUP);
25+
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V", false);
26+
27+
mv.visitVarInsn(Opcodes.ALOAD, 0);
28+
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "net/minecraft/server/" + version + "/Entity", "getName", "()Ljava/lang/String;", false);
29+
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
30+
31+
mv.visitLdcInsn(": Health set to: ");
32+
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
33+
34+
mv.visitVarInsn(Opcodes.FLOAD, 1);
35+
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(F)Ljava/lang/StringBuilder;", false);
36+
37+
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
38+
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/bukkit/Bukkit", "broadcastMessage", "(Ljava/lang/String;)I", false);
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package me.yamakaja.runtimetransformer.agent;
2+
3+
import org.objectweb.asm.ClassVisitor;
4+
import org.objectweb.asm.MethodVisitor;
5+
import org.objectweb.asm.Opcodes;
6+
7+
import java.util.regex.Matcher;
8+
import java.util.regex.Pattern;
9+
10+
/**
11+
* Created by Yamakaja on 18.05.17.
12+
*/
13+
public class EntityClassVisitor extends ClassVisitor {
14+
15+
private String className;
16+
17+
private Pattern pattern = Pattern.compile("net/minecraft/server/(v[\\d_R]*)/EntityLiving");
18+
19+
public EntityClassVisitor(int api, ClassVisitor cv) {
20+
super(api, cv);
21+
}
22+
23+
@Override
24+
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
25+
super.visit(version, access, name, signature, superName, interfaces);
26+
this.className = name;
27+
}
28+
29+
@Override
30+
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
31+
if (name.endsWith("setHealth")) {
32+
Matcher matcher = this.pattern.matcher(className);
33+
matcher.find();
34+
return new EntityClassMethodVisitor(Opcodes.ASM5, super.visitMethod(access, name, desc, signature, exceptions), matcher.group(1));
35+
}
36+
return super.visitMethod(access, name, desc, signature, exceptions);
37+
}
38+
}

build.gradle

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
group 'me.yamakaja.runtimetransformer'
2+
version '1.0-SNAPSHOT'
3+
4+
repositories {
5+
mavenCentral()
6+
}
7+
8+
task installAgent(type: Copy) {
9+
from("$rootDir/agent/build/libs/agent.jar")
10+
into "$rootDir/testenv"
11+
}
12+
13+
task install(type: Copy) {
14+
from("$rootDir/plugin/build/libs/plugin.jar")
15+
into "$rootDir/testenv/plugins"
16+
installAgent.execute()
17+
}

gradle/wrapper/gradle-wrapper.jar

52.9 KB
Binary file not shown.
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#Fri May 19 11:22:50 CEST 2017
2+
distributionBase=GRADLE_USER_HOME
3+
distributionPath=wrapper/dists
4+
zipStoreBase=GRADLE_USER_HOME
5+
zipStorePath=wrapper/dists
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip

0 commit comments

Comments
 (0)