Skip to content

Commit c81b219

Browse files
committedMay 29, 2016
first commit
0 parents  commit c81b219

13 files changed

+741
-0
lines changed
 

‎PacketCallbacks.java

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.matt.packetlistener;
2+
3+
import com.matt.packetlistener.events.PacketEvent;
4+
import net.minecraft.network.Packet;
5+
import net.minecraftforge.common.MinecraftForge;
6+
7+
public class PacketCallbacks {
8+
public static final PacketCallbacks INSTANCE = new PacketCallbacks();
9+
10+
public static boolean onSendingPacket(Packet<?> packet) {
11+
return MinecraftForge.EVENT_BUS.post(new PacketEvent.SentEvent.Pre(packet));
12+
}
13+
14+
public static void onSentPacket(Packet<?> packet) {
15+
MinecraftForge.EVENT_BUS.post(new PacketEvent.SentEvent.Post(packet));
16+
}
17+
18+
public static boolean onPreReceived(Packet<?> packet) {
19+
return MinecraftForge.EVENT_BUS.post(new PacketEvent.ReceivedEvent.Pre(packet));
20+
}
21+
22+
public static void onPostReceived(Packet<?> packet) {
23+
MinecraftForge.EVENT_BUS.post(new PacketEvent.ReceivedEvent.Post(packet));
24+
}
25+
}

‎PacketCoreMod.java

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.matt.packetlistener;
2+
3+
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
4+
import org.apache.logging.log4j.Logger;
5+
6+
import java.util.Map;
7+
8+
@IFMLLoadingPlugin.SortingIndex(1001)
9+
public class PacketCoreMod implements IFMLLoadingPlugin {
10+
public static boolean isObfuscated = false;
11+
public static Logger logger;
12+
13+
@Override
14+
public String[] getASMTransformerClass() {
15+
return new String[] {PacketTransformer.class.getName()};
16+
}
17+
18+
@Override
19+
public String getModContainerClass() {
20+
return "com.matt.packetlistener.PacketCoreModContainer";
21+
}
22+
23+
@Override
24+
public String getSetupClass() {
25+
return null;
26+
}
27+
28+
@Override
29+
public void injectData(Map<String, Object> data) {
30+
isObfuscated = (Boolean) data.get("runtimeDeobfuscationEnabled");
31+
}
32+
33+
@Override
34+
public String getAccessTransformerClass() {
35+
return null;
36+
}
37+
}

‎PacketCoreModContainer.java

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.matt.packetlistener;
2+
3+
import com.google.common.eventbus.EventBus;
4+
import com.matt.autotradermod.AutoTraderMod;
5+
import net.minecraftforge.fml.common.DummyModContainer;
6+
import net.minecraftforge.fml.common.FMLCommonHandler;
7+
import net.minecraftforge.fml.common.LoadController;
8+
import net.minecraftforge.fml.common.ModMetadata;
9+
import org.apache.logging.log4j.LogManager;
10+
11+
import java.util.Arrays;
12+
13+
public class PacketCoreModContainer extends DummyModContainer {
14+
public PacketCoreModContainer() {
15+
super(new ModMetadata());
16+
17+
ModMetadata metaData = super.getMetadata();
18+
metaData.authorList = Arrays.asList("fr1kin");
19+
metaData.description = "CoreMod for listening to packets.";
20+
metaData.modId = "packetlistenercore";
21+
metaData.version = "1.0";
22+
metaData.name = "Packet Listener Core";
23+
}
24+
25+
@Override
26+
public boolean registerBus(EventBus bus, LoadController controller) {
27+
bus.register(this);
28+
PacketCoreMod.logger = LogManager.getLogger(FMLCommonHandler.instance().findContainerFor(this));
29+
return true;
30+
}
31+
}

‎PacketTransformer.java

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.matt.packetlistener;
2+
3+
import com.matt.packetlistener.helper.IAsmTransformer;
4+
import com.matt.packetlistener.patch.PatchNetManager;
5+
import com.matt.packetlistener.patch.PatchNetManagerRun;
6+
import net.minecraft.launchwrapper.IClassTransformer;
7+
import org.objectweb.asm.ClassReader;
8+
import org.objectweb.asm.ClassWriter;
9+
import org.objectweb.asm.tree.*;
10+
11+
import java.util.HashMap;
12+
import java.util.Map;
13+
14+
public class PacketTransformer implements IClassTransformer {
15+
private Map<String, IAsmTransformer> transformingClasses = new HashMap<String, IAsmTransformer>();
16+
17+
public PacketTransformer() {
18+
transformingClasses.put("net.minecraft.network.NetworkManager", new PatchNetManager());
19+
transformingClasses.put("net.minecraft.network.NetworkManager$4", new PatchNetManagerRun());
20+
}
21+
22+
@Override
23+
public byte[] transform(String name, String realName, byte[] bytes) {
24+
if(transformingClasses.containsKey(realName)) {
25+
try {
26+
PacketCoreMod.logger.info("Transforming class " + realName);
27+
28+
ClassNode classNode = new ClassNode();
29+
ClassReader classReader = new ClassReader(bytes);
30+
classReader.accept(classNode, 0);
31+
32+
transformingClasses.get(realName).transform(classNode);
33+
34+
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
35+
classNode.accept(classWriter);
36+
37+
// let gc clean this up
38+
transformingClasses.remove(realName);
39+
40+
return classWriter.toByteArray();
41+
} catch (Exception e) {
42+
e.printStackTrace();
43+
}
44+
}
45+
return bytes;
46+
}
47+
}

‎Proxies.java

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.matt.packetlistener;
2+
3+
import com.matt.packetlistener.helper.AsmClass;
4+
import com.matt.packetlistener.helper.AsmMethod;
5+
import jdk.internal.org.objectweb.asm.Type;
6+
7+
/**
8+
* The truth is I couldn't think of any better name for this file
9+
*/
10+
public class Proxies {
11+
public static final Proxies INSTANCE = new Proxies();
12+
13+
// MC classes and methods
14+
15+
public AsmClass PACKET = new AsmClass()
16+
.setName("net/minecraft/network/Packet")
17+
.setObfuscatedName("fh");
18+
19+
// Hook classes and methods
20+
public AsmMethod ON_SENDING_PACKET = new AsmMethod()
21+
.setName("onSendingPacket")
22+
.setParentClassName(Type.getInternalName(PacketCallbacks.class))
23+
.setArgumentTypes(PACKET)
24+
.setReturnType(boolean.class);
25+
26+
public AsmMethod ON_SENT_PACKET = new AsmMethod()
27+
.setName("onSentPacket")
28+
.setParentClassName(Type.getInternalName(PacketCallbacks.class))
29+
.setArgumentTypes(PACKET)
30+
.setReturnType(void.class);
31+
32+
public AsmMethod ON_PRE_RECEIVED = new AsmMethod()
33+
.setName("onPreReceived")
34+
.setParentClassName(Type.getInternalName(PacketCallbacks.class))
35+
.setArgumentTypes(PACKET)
36+
.setReturnType(boolean.class);
37+
38+
public AsmMethod ON_POST_RECEIVED = new AsmMethod()
39+
.setName("onPostReceived")
40+
.setParentClassName(Type.getInternalName(PacketCallbacks.class))
41+
.setArgumentTypes(PACKET)
42+
.setReturnType(void.class);
43+
}

‎events/PacketEvent.java

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.matt.packetlistener.events;
2+
3+
import net.minecraft.network.Packet;
4+
import net.minecraftforge.fml.common.eventhandler.Cancelable;
5+
import net.minecraftforge.fml.common.eventhandler.Event;
6+
7+
public class PacketEvent extends Event {
8+
private final Packet<?> packet;
9+
10+
public PacketEvent(Packet<?> packetIn) {
11+
packet = packetIn;
12+
}
13+
14+
public Packet<?> getPacket() {
15+
return packet;
16+
}
17+
18+
public static class SentEvent extends PacketEvent {
19+
public SentEvent(Packet<?> packetIn) {
20+
super(packetIn);
21+
}
22+
23+
@Cancelable
24+
public static class Pre extends SentEvent {
25+
public Pre(Packet<?> packetIn) {
26+
super(packetIn);
27+
}
28+
}
29+
30+
public static class Post extends SentEvent {
31+
public Post(Packet<?> packetIn) {
32+
super(packetIn);
33+
}
34+
}
35+
}
36+
37+
public static class ReceivedEvent extends PacketEvent {
38+
public ReceivedEvent(Packet<?> packetIn) {
39+
super(packetIn);
40+
}
41+
42+
@Cancelable
43+
public static class Pre extends ReceivedEvent {
44+
public Pre(Packet<?> packetIn) {
45+
super(packetIn);
46+
}
47+
}
48+
49+
public static class Post extends ReceivedEvent {
50+
public Post(Packet<?> packetIn) {
51+
super(packetIn);
52+
}
53+
}
54+
}
55+
56+
}

‎helper/AsmClass.java

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.matt.packetlistener.helper;
2+
3+
public class AsmClass {
4+
private String name, obName;
5+
6+
public AsmClass() {
7+
name = obName = "";
8+
}
9+
10+
public AsmClass setName(String in) {
11+
name = in;
12+
return this;
13+
}
14+
public String getName() {
15+
return name;
16+
}
17+
18+
public AsmClass setObfuscatedName(String name) {
19+
obName = name;
20+
return this;
21+
}
22+
public String getObfuscatedName() {
23+
return obName;
24+
}
25+
26+
public String getRuntimeName() {
27+
return (!AsmHelper.isMinecraftObfuscated() || name.isEmpty()) ? name : obName;
28+
}
29+
}

‎helper/AsmHelper.java

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package com.matt.packetlistener.helper;
2+
3+
import com.matt.packetlistener.PacketCoreMod;
4+
import org.apache.logging.log4j.Logger;
5+
import org.objectweb.asm.tree.AbstractInsnNode;
6+
7+
import static org.objectweb.asm.Opcodes.*;
8+
9+
public class AsmHelper {
10+
11+
public static Logger log() {
12+
return PacketCoreMod.logger;
13+
}
14+
15+
public static boolean isMinecraftObfuscated() {
16+
return PacketCoreMod.isObfuscated;
17+
}
18+
19+
/**
20+
* Prints all the opcodes from the start of the node to the end of the node
21+
* @param start starting point
22+
*/
23+
public static void outputBytecode(AbstractInsnNode start) {
24+
StringBuilder hexPattern = new StringBuilder(), mask = new StringBuilder(), deciPattern = new StringBuilder();
25+
AbstractInsnNode next = start;
26+
do {
27+
hexPattern.append("0x");
28+
if(next.getOpcode() != F_NEW) {
29+
mask.append("x");
30+
hexPattern.append(Integer.toHexString(next.getOpcode()));
31+
deciPattern.append(String.format("%4d", next.getOpcode()));
32+
} else {
33+
mask.append("?");
34+
hexPattern.append("00");
35+
deciPattern.append("NULL");
36+
}
37+
hexPattern.append("\\");
38+
deciPattern.append(", ");
39+
next = next.getNext();
40+
} while(next != null);
41+
42+
log().info("Pattern (base10): " + deciPattern.toString());
43+
log().info("Pattern (base16): " + hexPattern.toString());
44+
log().info("Mask: " + mask.toString());
45+
}
46+
47+
/**
48+
* Breaks a string of hexadecimal opcodes into a base10 integer array
49+
* @param pattern pattern
50+
* @return Integer array
51+
*/
52+
public static int[] convertPattern(String pattern) {
53+
if(pattern.startsWith("\0"))
54+
pattern = pattern.substring(1);
55+
String[] hex = pattern.split("\0");
56+
int[] buff = new int[hex.length];
57+
int index = 0;
58+
for(String number : hex) {
59+
if(number.startsWith("0x"))
60+
number = number.substring(2);
61+
else if(number.startsWith("x"))
62+
number = number.substring(1);
63+
buff[index++] = Integer.parseInt(number, 16);
64+
}
65+
return buff;
66+
}
67+
68+
/**
69+
* Finds a pattern of opcodes and returns the first node of the matched pattern if found
70+
* @param start starting node
71+
* @param pattern integer array of opcodes
72+
* @param mask same length as the pattern. 'x' indicates the node will be checked, '?' indicates the node will be skipped over (has a bad opcode)
73+
* @return top node of matching pattern or null if nothing is found
74+
*/
75+
public static AbstractInsnNode findPattern(AbstractInsnNode start, int[] pattern, char[] mask) {
76+
if(start != null &&
77+
pattern.length == mask.length) {
78+
int found = 0;
79+
AbstractInsnNode next = start;
80+
do {
81+
switch(mask[found]) {
82+
// Analyze this node
83+
case 'x': {
84+
// Check if node and pattern have same opcode
85+
if(next.getOpcode() == pattern[found]) {
86+
// Increment number of matched opcodes
87+
found++;
88+
} else {
89+
// Go back to the starting node
90+
for(int i = 1; i <= (found - 1); i++) {
91+
next = next.getPrevious();
92+
}
93+
// Reset the number of opcodes found
94+
found = 0;
95+
}
96+
break;
97+
}
98+
// Skips over this node
99+
default:
100+
case '?':
101+
found++;
102+
break;
103+
}
104+
// Check if found entire pattern
105+
if(found >= mask.length) {
106+
// Go back to top node
107+
for(int i = 1; i <= (found - 1); i++)
108+
next = next.getPrevious();
109+
return next;
110+
}
111+
next = next.getNext();
112+
} while(next != null &&
113+
found < mask.length);
114+
}
115+
log().info("Failed to match pattern");
116+
return null;
117+
}
118+
public static AbstractInsnNode findPattern(AbstractInsnNode start, String pattern, String mask) {
119+
return findPattern(start,
120+
convertPattern(pattern),
121+
mask.toCharArray());
122+
}
123+
public static AbstractInsnNode findPattern(AbstractInsnNode start, int[] pattern, String mask) {
124+
return findPattern(start,
125+
pattern,
126+
mask.toCharArray());
127+
}
128+
}

‎helper/AsmMethod.java

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package com.matt.packetlistener.helper;
2+
3+
import org.objectweb.asm.Type;
4+
5+
public class AsmMethod {
6+
private String methodName;
7+
private String methodObfuscatedName;
8+
private String argumentTypes;
9+
private String returnType;
10+
private String parentClassName;
11+
12+
public AsmMethod() {
13+
methodName = methodObfuscatedName = argumentTypes = returnType = "";
14+
}
15+
16+
public AsmMethod setName(String in) {
17+
methodName = in;
18+
return this;
19+
}
20+
public String getName() {
21+
return methodName;
22+
}
23+
24+
public AsmMethod setObfuscatedName(String name) {
25+
methodObfuscatedName = name;
26+
return this;
27+
}
28+
public String getObfuscatedName() {
29+
return methodObfuscatedName;
30+
}
31+
32+
public String getRuntimeName() {
33+
return (!AsmHelper.isMinecraftObfuscated() || methodName.isEmpty()) ? methodName : methodObfuscatedName;
34+
}
35+
36+
public AsmMethod setArgumentTypes(Object... types) {
37+
StringBuilder builder = new StringBuilder();
38+
for(Object var : types) {
39+
builder.append(objectToDescriptor(var));
40+
}
41+
argumentTypes = builder.toString();
42+
return this;
43+
}
44+
public AsmMethod setReturnType(Object type) {
45+
returnType = objectToDescriptor(type);
46+
return this;
47+
}
48+
49+
public String getDescriptor() {
50+
return String.format("(%s)%s", argumentTypes, returnType);
51+
}
52+
53+
public AsmMethod setParentClassName(String parentClassName) {
54+
this.parentClassName = parentClassName;
55+
return this;
56+
}
57+
public String getParentClassName() {
58+
return parentClassName;
59+
}
60+
61+
private String objectToDescriptor(Object obj) {
62+
if (obj instanceof String)
63+
return (String)obj;
64+
else if (obj instanceof AsmClass) {
65+
return String.format("L%s;", ((AsmClass) obj).getRuntimeName());
66+
} else if(obj instanceof Class) {
67+
if(((Class) obj).isPrimitive()) {
68+
return Primitives.primitiveToDescriptor.get(obj).toString();
69+
} else {
70+
// Avoid using non-primitive classes, especially classes in net.minecraft
71+
// Importing them here will cause them to load too early
72+
AsmHelper.log().info("Warning: Non-primitive classes should not be used in TransformerMethod.setArgumentTypes");
73+
return String.format("L%s;", Type.getInternalName((Class) obj));
74+
}
75+
} else return "";
76+
}
77+
}

‎helper/IAsmTransformer.java

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.matt.packetlistener.helper;
2+
3+
import org.objectweb.asm.tree.ClassNode;
4+
5+
public interface IAsmTransformer {
6+
void transform(ClassNode node);
7+
}

‎helper/Primitives.java

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.matt.packetlistener.helper;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
public class Primitives {
7+
public final static Map<Class<?>, Class<?>> primitiveToWrapper = new HashMap<Class<?>, Class<?>>();
8+
public final static Map<Class<?>, Class<?>> wrapperToPrimitive = new HashMap<Class<?>, Class<?>>();
9+
public final static Map<Class<?>, Character> primitiveToDescriptor = new HashMap<Class<?>, Character>();
10+
11+
static {
12+
primitiveToWrapper.put(boolean.class, Boolean.class);
13+
primitiveToWrapper.put(byte.class, Byte.class);
14+
primitiveToWrapper.put(short.class, Short.class);
15+
primitiveToWrapper.put(char.class, Character.class);
16+
primitiveToWrapper.put(int.class, Integer.class);
17+
primitiveToWrapper.put(long.class, Long.class);
18+
primitiveToWrapper.put(float.class, Float.class);
19+
primitiveToWrapper.put(double.class, Double.class);
20+
primitiveToWrapper.put(void.class, Void.class);
21+
22+
wrapperToPrimitive.put(Boolean.class, boolean.class);
23+
wrapperToPrimitive.put(Byte.class, byte.class);
24+
wrapperToPrimitive.put(Short.class, short.class);
25+
wrapperToPrimitive.put(Character.class, char.class);
26+
wrapperToPrimitive.put(Integer.class, int.class);
27+
wrapperToPrimitive.put(Long.class, long.class);
28+
wrapperToPrimitive.put(Float.class, float.class);
29+
wrapperToPrimitive.put(Double.class, double.class);
30+
wrapperToPrimitive.put(Void.class, void.class);
31+
32+
primitiveToDescriptor.put(boolean.class, 'Z');
33+
primitiveToDescriptor.put(byte.class, 'B');
34+
primitiveToDescriptor.put(short.class, 'S');
35+
primitiveToDescriptor.put(char.class, 'C');
36+
primitiveToDescriptor.put(int.class, 'I');
37+
primitiveToDescriptor.put(long.class, 'J');
38+
primitiveToDescriptor.put(float.class, 'F');
39+
primitiveToDescriptor.put(double.class, 'D');
40+
primitiveToDescriptor.put(void.class, 'V');
41+
}
42+
}

‎patch/PatchNetManager.java

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package com.matt.packetlistener.patch;
2+
3+
import com.matt.packetlistener.PacketCoreMod;
4+
import com.matt.packetlistener.Proxies;
5+
import com.matt.packetlistener.helper.AsmHelper;
6+
import com.matt.packetlistener.helper.AsmMethod;
7+
import com.matt.packetlistener.helper.IAsmTransformer;
8+
import org.objectweb.asm.tree.*;
9+
10+
import static org.objectweb.asm.Opcodes.*;
11+
12+
public class PatchNetManager implements IAsmTransformer {
13+
private final AsmMethod DISPATCH_PACKET = new AsmMethod()
14+
.setName("dispatchPacket")
15+
.setObfuscatedName("a")
16+
.setArgumentTypes(Proxies.INSTANCE.PACKET, "[Lio/netty/util/concurrent/GenericFutureListener;")
17+
.setReturnType(void.class);
18+
19+
private final AsmMethod CHANNEL_READ0 = new AsmMethod()
20+
.setName("channelRead0")
21+
.setObfuscatedName("a")
22+
.setArgumentTypes("Lio/netty/channel/ChannelHandlerContext;", Proxies.INSTANCE.PACKET)
23+
.setReturnType(void.class);
24+
25+
public void transform(ClassNode node) {
26+
for(MethodNode method : node.methods) {
27+
if(method.name.equals(DISPATCH_PACKET.getRuntimeName()) &&
28+
method.desc.equals(DISPATCH_PACKET.getDescriptor())) {
29+
PacketCoreMod.logger.info("Patching method dispatchPacket");
30+
patchDispatchPacket(method);
31+
} else if(method.name.equals(CHANNEL_READ0.getRuntimeName()) &&
32+
method.desc.equals(CHANNEL_READ0.getDescriptor())) {
33+
PacketCoreMod.logger.info("Patching method channelRead0");
34+
patchChannelRead0(method);
35+
}
36+
}
37+
}
38+
39+
private final int[] patternPreDispatch = new int[] {
40+
ALOAD, ALOAD, IF_ACMPEQ, ALOAD, INSTANCEOF, IFNE,
41+
0x00, 0x00,
42+
ALOAD, ALOAD, INVOKEVIRTUAL
43+
};
44+
45+
private final int[] patternPostDispatch = new int[] {
46+
POP,
47+
0x00, 0x00,
48+
GOTO,
49+
0x00, 0x00, 0x00,
50+
ALOAD, GETFIELD, INVOKEINTERFACE, NEW, DUP
51+
};
52+
53+
private void patchDispatchPacket(MethodNode method) {
54+
AbstractInsnNode preNode = AsmHelper.findPattern(method.instructions.getFirst(),
55+
patternPreDispatch, "xxxxxx??xxx");
56+
AbstractInsnNode postNode = AsmHelper.findPattern(method.instructions.getFirst(),
57+
patternPostDispatch, "x??x???xxxxx");
58+
59+
if(preNode != null && postNode != null) {
60+
LabelNode endJump = new LabelNode();
61+
62+
InsnList insnPre = new InsnList();
63+
insnPre.add(new VarInsnNode(ALOAD, 1));
64+
insnPre.add(new MethodInsnNode(INVOKESTATIC,
65+
Proxies.INSTANCE.ON_SENDING_PACKET.getParentClassName(),
66+
Proxies.INSTANCE.ON_SENDING_PACKET.getRuntimeName(),
67+
Proxies.INSTANCE.ON_SENDING_PACKET.getDescriptor(),
68+
false
69+
));
70+
insnPre.add(new JumpInsnNode(IFNE, endJump));
71+
72+
InsnList insnPost = new InsnList();
73+
insnPost.add(new VarInsnNode(ALOAD, 1));
74+
insnPost.add(new MethodInsnNode(INVOKESTATIC,
75+
Proxies.INSTANCE.ON_SENT_PACKET.getParentClassName(),
76+
Proxies.INSTANCE.ON_SENT_PACKET.getRuntimeName(),
77+
Proxies.INSTANCE.ON_SENT_PACKET.getDescriptor(),
78+
false
79+
));
80+
insnPost.add(endJump);
81+
82+
method.instructions.insertBefore(preNode, insnPre);
83+
method.instructions.insert(postNode, insnPost);
84+
} else {
85+
PacketCoreMod.logger.error("Failed to find nodes for dispatch packet");
86+
}
87+
}
88+
89+
private final int[] patternPreSend = new int[] {
90+
ALOAD, ALOAD, GETFIELD, INVOKEINTERFACE
91+
};
92+
93+
private final int[] patternPostSend = new int[] {
94+
INVOKEINTERFACE,
95+
0x00, 0x00,
96+
GOTO,
97+
};
98+
99+
private void patchChannelRead0(MethodNode method) {
100+
AbstractInsnNode preNode = AsmHelper.findPattern(method.instructions.getFirst(),
101+
patternPreSend, "xxxx");
102+
AbstractInsnNode postNode = AsmHelper.findPattern(method.instructions.getFirst(),
103+
patternPostSend, "x??x");
104+
if(preNode != null && postNode != null) {
105+
LabelNode endJump = new LabelNode();
106+
107+
InsnList insnPre = new InsnList();
108+
insnPre.add(new VarInsnNode(ALOAD, 2));
109+
insnPre.add(new MethodInsnNode(INVOKESTATIC,
110+
Proxies.INSTANCE.ON_PRE_RECEIVED.getParentClassName(),
111+
Proxies.INSTANCE.ON_PRE_RECEIVED.getRuntimeName(),
112+
Proxies.INSTANCE.ON_PRE_RECEIVED.getDescriptor(),
113+
false
114+
));
115+
insnPre.add(new JumpInsnNode(IFNE, endJump));
116+
117+
InsnList insnPost = new InsnList();
118+
insnPost.add(new VarInsnNode(ALOAD, 2));
119+
insnPost.add(new MethodInsnNode(INVOKESTATIC,
120+
Proxies.INSTANCE.ON_POST_RECEIVED.getParentClassName(),
121+
Proxies.INSTANCE.ON_POST_RECEIVED.getRuntimeName(),
122+
Proxies.INSTANCE.ON_POST_RECEIVED.getDescriptor(),
123+
false
124+
));
125+
insnPost.add(endJump);
126+
127+
method.instructions.insertBefore(preNode, insnPre);
128+
method.instructions.insert(postNode, insnPost);
129+
}
130+
}
131+
}

‎patch/PatchNetManagerRun.java

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package com.matt.packetlistener.patch;
2+
3+
import com.matt.packetlistener.PacketCoreMod;
4+
import com.matt.packetlistener.Proxies;
5+
import com.matt.packetlistener.helper.AsmClass;
6+
import com.matt.packetlistener.helper.AsmHelper;
7+
import com.matt.packetlistener.helper.AsmMethod;
8+
import com.matt.packetlistener.helper.IAsmTransformer;
9+
import org.objectweb.asm.tree.*;
10+
11+
import static org.objectweb.asm.Opcodes.*;
12+
13+
public class PatchNetManagerRun implements IAsmTransformer {
14+
private final AsmClass NETWORK_MANAGER$4 = new AsmClass()
15+
.setName("net/minecraft/network/NetworkManager$4")
16+
.setObfuscatedName("em$4");
17+
18+
private final AsmMethod RUN = new AsmMethod()
19+
.setName("run")
20+
.setObfuscatedName("run")
21+
.setArgumentTypes()
22+
.setReturnType(void.class);
23+
24+
@Override
25+
public void transform(ClassNode node) {
26+
for(MethodNode method : node.methods) {
27+
if(method.name.equals(RUN.getRuntimeName()) &&
28+
method.desc.equals(RUN.getDescriptor())) {
29+
PacketCoreMod.logger.info("Patching method NetworkManager$4.run");
30+
patchRun(method);
31+
}
32+
}
33+
}
34+
35+
private final int[] patternPreDispatch = new int[] {
36+
ALOAD, GETFIELD, ALOAD, GETFIELD, IF_ACMPEQ
37+
};
38+
39+
private final int[] patternPostDispatch = new int[] {
40+
RETURN
41+
};
42+
43+
private void patchRun(MethodNode method) {
44+
AbstractInsnNode preNode = AsmHelper.findPattern(method.instructions.getFirst(),
45+
patternPreDispatch, "xxxxx");
46+
AbstractInsnNode postNode = AsmHelper.findPattern(method.instructions.getFirst(),
47+
patternPostDispatch, "x");
48+
49+
if(preNode != null && postNode != null) {
50+
LabelNode endJump = new LabelNode();
51+
52+
InsnList insnPre = new InsnList();
53+
insnPre.add(new VarInsnNode(ALOAD, 0));
54+
insnPre.add(new FieldInsnNode(GETFIELD,
55+
NETWORK_MANAGER$4.getRuntimeName(),
56+
"val$inPacket",
57+
String.format("L%s;", Proxies.INSTANCE.PACKET.getRuntimeName())
58+
));
59+
insnPre.add(new MethodInsnNode(INVOKESTATIC,
60+
Proxies.INSTANCE.ON_SENDING_PACKET.getParentClassName(),
61+
Proxies.INSTANCE.ON_SENDING_PACKET.getRuntimeName(),
62+
Proxies.INSTANCE.ON_SENDING_PACKET.getDescriptor(),
63+
false
64+
));
65+
insnPre.add(new JumpInsnNode(IFNE, endJump));
66+
67+
InsnList insnPost = new InsnList();
68+
insnPost.add(new VarInsnNode(ALOAD, 0));
69+
insnPost.add(new FieldInsnNode(GETFIELD,
70+
NETWORK_MANAGER$4.getRuntimeName(),
71+
"val$inPacket",
72+
String.format("L%s;", Proxies.INSTANCE.PACKET.getRuntimeName())
73+
));
74+
insnPost.add(new MethodInsnNode(INVOKESTATIC,
75+
Proxies.INSTANCE.ON_SENT_PACKET.getParentClassName(),
76+
Proxies.INSTANCE.ON_SENT_PACKET.getRuntimeName(),
77+
Proxies.INSTANCE.ON_SENT_PACKET.getDescriptor(),
78+
false
79+
));
80+
insnPost.add(endJump);
81+
82+
method.instructions.insertBefore(preNode, insnPre);
83+
method.instructions.insertBefore(postNode, insnPost);
84+
} else {
85+
PacketCoreMod.logger.error("Failed to find nodes for dispatch packet");
86+
}
87+
}
88+
}

0 commit comments

Comments
 (0)
Please sign in to comment.