From 5d63904075724db4dc17f1685443fd77230a4677 Mon Sep 17 00:00:00 2001 From: Graham Date: Sat, 19 Oct 2019 11:43:12 +0100 Subject: [PATCH] Increase the size of the client's main packet buffer --- .../java/dev/openrs2/bundler/Bundler.java | 2 + .../transform/BufferSizeTransformer.java | 93 +++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 bundler/src/main/java/dev/openrs2/bundler/transform/BufferSizeTransformer.java diff --git a/bundler/src/main/java/dev/openrs2/bundler/Bundler.java b/bundler/src/main/java/dev/openrs2/bundler/Bundler.java index 6464a05e09..94e61d8f27 100644 --- a/bundler/src/main/java/dev/openrs2/bundler/Bundler.java +++ b/bundler/src/main/java/dev/openrs2/bundler/Bundler.java @@ -2,6 +2,7 @@ package dev.openrs2.bundler; import com.google.common.collect.ImmutableList; import dev.openrs2.asm.transform.Transformer; +import dev.openrs2.bundler.transform.BufferSizeTransformer; import dev.openrs2.bundler.transform.CachePathTransformer; import dev.openrs2.bundler.transform.HostCheckTransformer; import dev.openrs2.bundler.transform.LoadLibraryTransformer; @@ -10,6 +11,7 @@ import dev.openrs2.bundler.transform.RightClickTransformer; public final class Bundler { public static final ImmutableList TRANSFORMERS = ImmutableList.of( + new BufferSizeTransformer(), new CachePathTransformer(), new HostCheckTransformer(), new MacResizeTransformer(), diff --git a/bundler/src/main/java/dev/openrs2/bundler/transform/BufferSizeTransformer.java b/bundler/src/main/java/dev/openrs2/bundler/transform/BufferSizeTransformer.java new file mode 100644 index 0000000000..65b415000e --- /dev/null +++ b/bundler/src/main/java/dev/openrs2/bundler/transform/BufferSizeTransformer.java @@ -0,0 +1,93 @@ +package dev.openrs2.bundler.transform; + +import java.util.Optional; + +import dev.openrs2.asm.InsnMatcher; +import dev.openrs2.asm.InsnNodeUtils; +import dev.openrs2.asm.MemberRef; +import dev.openrs2.asm.classpath.ClassPath; +import dev.openrs2.asm.classpath.Library; +import dev.openrs2.asm.transform.Transformer; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldInsnNode; +import org.objectweb.asm.tree.LdcInsnNode; +import org.objectweb.asm.tree.MethodNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class BufferSizeTransformer extends Transformer { + private static final Logger logger = LoggerFactory.getLogger(BufferSizeTransformer.class); + + private static final InsnMatcher GPP1_POS_MATCHER = InsnMatcher.compile("LDC (INVOKESPECIAL | INVOKEVIRTUAL) GETSTATIC"); + private static final InsnMatcher NEW_BUFFER_MATCHER = InsnMatcher.compile("NEW DUP (SIPUSH | LDC) INVOKESPECIAL PUTSTATIC"); + + private static Optional findBuffer(MethodNode method) { + return GPP1_POS_MATCHER.match(method) + .filter(match -> { + var ldc = (LdcInsnNode) match.get(0); + return ldc.cst.equals("gpp1 pos:"); + }) + .map(match -> { + var getstatic = (FieldInsnNode) match.get(2); + return new MemberRef(getstatic.owner, getstatic.name, getstatic.desc); + }) + .findAny(); + } + + private MemberRef buffer; + private int buffersResized; + + @Override + protected void preTransform(ClassPath classPath) { + buffer = null; + buffersResized = 0; + + for (var library : classPath.getLibraries()) { + for (var clazz : library) { + for (var method : clazz.methods) { + if ((method.access & (Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT)) != 0) { + continue; + } + + var buffer = findBuffer(method); + if (buffer.isEmpty()) { + continue; + } + + this.buffer = buffer.orElseThrow(); + logger.info("Identified buffer: {}", this.buffer); + break; + } + } + } + } + + @Override + protected boolean transformCode(ClassPath classPath, Library library, ClassNode clazz, MethodNode method) { + if (buffer == null) { + return false; + } + + NEW_BUFFER_MATCHER.match(method).forEach(match -> { + var putstatic = (FieldInsnNode) match.get(4); + if (!putstatic.owner.equals(buffer.getOwner())) { + return; + } else if (!putstatic.name.equals(buffer.getName())) { + return; + } else if (!putstatic.desc.equals(buffer.getDesc())) { + return; + } + + method.instructions.set(match.get(2), InsnNodeUtils.createIntConstant(65535)); + buffersResized++; + }); + + return false; + } + + @Override + protected void postTransform(ClassPath classPath) { + logger.info("Resized {} buffers to 65535 bytes", buffersResized); + } +}