From f0656355de6f7d03a958c00322f5df68ff3c633f Mon Sep 17 00:00:00 2001 From: md_5 Date: Wed, 17 Oct 2012 18:32:35 +1100 Subject: [PATCH 01/22] Initial commit. Man the Minecraft protocol is sucky. --- .gitignore | 34 +++ pom.xml | 25 ++ .../md_5/mc/protocol/PacketDefinitions.java | 289 ++++++++++++++++++ 3 files changed, 348 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/net/md_5/mc/protocol/PacketDefinitions.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..433f53cf --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +# Eclipse stuff +/.classpath +/.project +/.settings + +# netbeans +/nbproject +/nbactions.xml +/nb-configuration.xml + +# we use maven! +/build.xml + +# maven +/target +/dependency-reduced-pom.xml + +# vim +.*.sw[a-p] + +# various other potential build files +/build +/bin +/dist +/manifest.mf + +# Mac filesystem dust +/.DS_Store + +# intellij +*.iml +*.ipr +*.iws +.idea/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..57293200 --- /dev/null +++ b/pom.xml @@ -0,0 +1,25 @@ + + 4.0.0 + + net.md-5 + mc-protocol-lib + 1.0-SNAPSHOT + jar + + MinecraftProtocolLib + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + 3.8.1 + test + + + diff --git a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java new file mode 100644 index 00000000..80ce1b55 --- /dev/null +++ b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java @@ -0,0 +1,289 @@ +package net.md_5.mc.protocol; + +import java.io.DataInput; +import java.io.IOException; + +public class PacketDefinitions { + + private static final Instruction[][] opCodes = new Instruction[256][]; + private static final Instruction BYTE = new JumpOpCode(1); + private static final Instruction BOOLEAN = BYTE; + private static final Instruction SHORT = new JumpOpCode(2); + private static final Instruction INT = new JumpOpCode(4); + private static final Instruction FLOAT = INT; + private static final Instruction LONG = new JumpOpCode(8); + private static final Instruction DOUBLE = LONG; + private static final Instruction SHORT_BYTE = new ShortHeader(BYTE); + private static final Instruction BYTE_BYTE = new ByteHeader(BYTE); + private static final Instruction BYTE_INT = new ByteHeader(INT); + private static final Instruction INT_BYTE = new IntHeader(BYTE); + private static final Instruction INT_INT = new IntHeader(INT); + private static final Instruction INT_3 = new IntHeader(new JumpOpCode(3)); + private static final Instruction STRING = new Instruction() { + @Override + void read(DataInput in) throws IOException { + short len = in.readShort(); + skip(in, len * 2); + } + }; + private static final Instruction ITEM = new Instruction() { + @Override + void read(DataInput in) throws IOException { + short type = in.readShort(); + if (type >= 0) { + skip(in, 3); + SHORT_BYTE.read(in); + } + } + }; + private static final Instruction SHORT_ITEM = new ShortHeader(ITEM); + private static final Instruction METADATA = new Instruction() { + @Override + void read(DataInput in) throws IOException { + byte x = in.readByte(); + while (x != 127) { + int type = x >> 5; + switch (type) { + case 0: + BYTE.read(in); + break; + case 1: + SHORT.read(in); + break; + case 2: + INT.read(in); + break; + case 3: + FLOAT.read(in); + break; + case 4: + STRING.read(in); + break; + case 5: + skip(in, 5); // short, byte, short + break; + case 6: + skip(in, 6); // int, int, int + break; + default: + throw new IllegalArgumentException("Unknown metadata type " + type); + } + x = in.readByte(); + } + } + }; + private static final Instruction BULK_CHUNK = new Instruction() { + @Override + void read(DataInput in) throws IOException { + short count = in.readShort(); + INT_BYTE.read(in); + skip(in, count * 12); + } + }; + + static { + opCodes[0x00] = new Instruction[]{INT}; + opCodes[0x01] = new Instruction[]{INT, STRING, BYTE, BYTE, BYTE, BYTE, BYTE}; + opCodes[0x02] = new Instruction[]{BYTE, STRING, STRING, INT}; + opCodes[0x03] = new Instruction[]{STRING}; + opCodes[0x04] = new Instruction[]{LONG}; + opCodes[0x05] = new Instruction[]{INT, SHORT, ITEM}; + opCodes[0x06] = new Instruction[]{INT, INT, INT}; + opCodes[0x07] = new Instruction[]{INT, INT, BOOLEAN}; + opCodes[0x09] = new Instruction[]{INT, BYTE, BYTE, SHORT, STRING}; + opCodes[0x0A] = new Instruction[]{BOOLEAN}; + opCodes[0x0B] = new Instruction[]{DOUBLE, DOUBLE, DOUBLE, DOUBLE, BOOLEAN}; + opCodes[0x0C] = new Instruction[]{FLOAT, FLOAT, BOOLEAN}; + opCodes[0x0D] = new Instruction[]{DOUBLE, DOUBLE, DOUBLE, DOUBLE, FLOAT, FLOAT, BOOLEAN}; + opCodes[0x0E] = new Instruction[]{BYTE, INT, BYTE, INT, BYTE}; + opCodes[0x0F] = new Instruction[]{INT, BYTE, INT, ITEM, BYTE, BYTE, BYTE}; + opCodes[0x10] = new Instruction[]{SHORT}; + opCodes[0x11] = new Instruction[]{INT, BYTE, INT, BYTE, INT}; + opCodes[0x12] = new Instruction[]{INT, BYTE}; + opCodes[0x13] = new Instruction[]{INT, BYTE}; + opCodes[0x14] = new Instruction[]{INT, STRING, INT, INT, INT, BYTE, BYTE, SHORT, METADATA}; + opCodes[0x15] = new Instruction[]{INT, SHORT, BYTE, SHORT, INT, INT, INT, BYTE, BYTE, BYTE}; + opCodes[0x16] = new Instruction[]{INT, INT}; + opCodes[0x17] = new Instruction[]{INT, BYTE, INT, INT, INT, INT, SHORT, SHORT, SHORT}; + opCodes[0x18] = new Instruction[]{INT, BYTE, INT, INT, INT, BYTE, BYTE, BYTE, SHORT, SHORT, SHORT, METADATA}; + opCodes[0x19] = new Instruction[]{INT, STRING, INT, INT, INT, INT}; + opCodes[0x1A] = new Instruction[]{INT, INT, INT, INT, SHORT}; + opCodes[0x1B] = null; // Does not exist + opCodes[0x1C] = new Instruction[]{INT, SHORT, SHORT, SHORT}; + opCodes[0x1D] = new Instruction[]{BYTE_INT}; + opCodes[0x1E] = new Instruction[]{INT}; + opCodes[0x1F] = new Instruction[]{INT, BYTE, BYTE, BYTE}; + opCodes[0x20] = new Instruction[]{INT, BYTE, BYTE}; + opCodes[0x21] = new Instruction[]{INT, BYTE, BYTE, BYTE, BYTE, BYTE}; + opCodes[0x22] = new Instruction[]{INT, INT, INT, INT, BYTE, BYTE}; + opCodes[0x23] = new Instruction[]{INT, BYTE}; + opCodes[0x24] = null; // Does not exist + opCodes[0x25] = null; // Does not exist + opCodes[0x26] = new Instruction[]{INT, BYTE}; + opCodes[0x27] = new Instruction[]{INT, INT}; + opCodes[0x28] = new Instruction[]{INT, METADATA}; + opCodes[0x29] = new Instruction[]{INT, BYTE, BYTE, SHORT}; + opCodes[0x2A] = new Instruction[]{INT, BYTE}; + opCodes[0x2B] = new Instruction[]{FLOAT, SHORT, SHORT}; + // + // + // 0x2C -> 0x32 Do not exist + // + // + opCodes[0x33] = new Instruction[]{INT, INT, BOOLEAN, SHORT, SHORT, INT_BYTE}; + opCodes[0x34] = new Instruction[]{INT, INT, SHORT, INT_INT}; + opCodes[0x35] = new Instruction[]{INT, BYTE, INT, SHORT, BYTE}; + opCodes[0x36] = new Instruction[]{INT, SHORT, INT, BYTE, BYTE, SHORT}; + opCodes[0x37] = new Instruction[]{INT, INT, INT, INT, BYTE}; + opCodes[0x38] = new Instruction[]{BULK_CHUNK}; + opCodes[0x39] = null; // Does not exist + opCodes[0x3A] = null; // Does not exist + opCodes[0x3B] = null; // Does not exist + opCodes[0x3C] = new Instruction[]{DOUBLE, DOUBLE, DOUBLE, FLOAT, INT_3, FLOAT, FLOAT, FLOAT}; + opCodes[0x3D] = new Instruction[]{INT, INT, BYTE, INT, INT}; + opCodes[0x3E] = new Instruction[]{STRING, INT, INT, INT, FLOAT, BYTE}; + // + // + // 0x3F -> 0x45 Do not exist + // + // + opCodes[0x46] = new Instruction[]{BYTE, BYTE}; + opCodes[0x47] = new Instruction[]{INT, BOOLEAN, INT, INT, INT}; + // + // + // 0x4A -> 0x63 Do not exist + // + // + opCodes[0x64] = new Instruction[]{BYTE, BYTE, STRING, BYTE}; + opCodes[0x65] = new Instruction[]{BYTE}; + opCodes[0x66] = new Instruction[]{BYTE, SHORT, BOOLEAN, SHORT, BOOLEAN, ITEM}; + opCodes[0x67] = new Instruction[]{BYTE, SHORT, ITEM}; + opCodes[0x68] = new Instruction[]{BYTE, SHORT_ITEM}; + opCodes[0x69] = new Instruction[]{BYTE, SHORT, SHORT}; + opCodes[0x6A] = new Instruction[]{BYTE, SHORT, BOOLEAN}; + opCodes[0x6B] = new Instruction[]{SHORT, ITEM}; + opCodes[0x6C] = new Instruction[]{BYTE, BYTE}; + // + // + // 0x6D -> 0x81 Do not exist + // + // + opCodes[0x82] = new Instruction[]{INT, SHORT, INT, STRING, STRING, STRING, STRING}; + opCodes[0x83] = new Instruction[]{SHORT, SHORT, BYTE_BYTE}; // TODO: Ubyte? + opCodes[0x84] = new Instruction[]{INT, SHORT, INT, BYTE, SHORT_BYTE}; + // + // + // 0x85 -> 0xC7 Do not exist + // + // + opCodes[0xC8] = new Instruction[]{INT, BYTE}; + opCodes[0xC9] = new Instruction[]{STRING, BOOLEAN, SHORT}; + opCodes[0xCA] = new Instruction[]{BYTE, BYTE, BYTE}; + opCodes[0xCB] = new Instruction[]{STRING}; + opCodes[0xCC] = new Instruction[]{STRING, BYTE, BYTE, BYTE}; + opCodes[0xCD] = new Instruction[]{BYTE}; + // + // + // 0xCE -> 0xF9 Do not exist + // + // + opCodes[0xFA] = new Instruction[]{STRING, SHORT_BYTE}; + opCodes[0xFB] = null; // Does not exist + opCodes[0xFC] = new Instruction[]{SHORT_BYTE, SHORT_BYTE}; + opCodes[0xFD] = new Instruction[]{STRING, SHORT_BYTE, SHORT_BYTE}; + opCodes[0xFE] = new Instruction[]{}; + opCodes[0xFF] = new Instruction[]{STRING}; + } + + public static void readPacket(DataInput in) throws IOException { + int packetId = in.readUnsignedByte(); + Instruction[] instructions = opCodes[packetId]; + if (instructions == null) { + throw new IOException("Unknown packet id " + packetId); + } + + for (Instruction instruction : instructions) { + instruction.read(in); + } + } + + static abstract class Instruction { + + abstract void read(DataInput in) throws IOException; + + final void skip(DataInput in, int len) throws IOException { + int n = 0; + while (n < len) { + n += in.readByte(); + } + } + } + + static class JumpOpCode extends Instruction { + + private final int len; + + public JumpOpCode(int len) { + if (len < 0) { + throw new IndexOutOfBoundsException(); + } + this.len = len; + } + + @Override + void read(DataInput in) throws IOException { + skip(in, len); + } + } + + static class ByteHeader extends Instruction { + + private final Instruction child; + + public ByteHeader(Instruction child) { + this.child = child; + } + + @Override + void read(DataInput in) throws IOException { + byte size = in.readByte(); + for (byte b = 0; b < size; b++) { + child.read(in); + } + } + } + + static class ShortHeader extends Instruction { + + private final Instruction child; + + public ShortHeader(Instruction child) { + this.child = child; + } + + @Override + void read(DataInput in) throws IOException { + short size = in.readShort(); + for (short s = 0; s < size; s++) { + child.read(in); + } + } + } + + static class IntHeader extends Instruction { + + private final Instruction child; + + public IntHeader(Instruction child) { + this.child = child; + } + + @Override + void read(DataInput in) throws IOException { + int size = in.readInt(); + for (int i = 0; i < size; i++) { + child.read(in); + } + } + } +} From c9f78a989cbea1d00ef8f94510ec6e23b296234c Mon Sep 17 00:00:00 2001 From: md_5 Date: Wed, 17 Oct 2012 19:03:30 +1100 Subject: [PATCH 02/22] Fix a few definitions --- .../md_5/mc/protocol/PacketDefinitions.java | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java index 80ce1b55..5777809c 100644 --- a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java +++ b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java @@ -14,10 +14,8 @@ public class PacketDefinitions { private static final Instruction LONG = new JumpOpCode(8); private static final Instruction DOUBLE = LONG; private static final Instruction SHORT_BYTE = new ShortHeader(BYTE); - private static final Instruction BYTE_BYTE = new ByteHeader(BYTE); private static final Instruction BYTE_INT = new ByteHeader(INT); private static final Instruction INT_BYTE = new IntHeader(BYTE); - private static final Instruction INT_INT = new IntHeader(INT); private static final Instruction INT_3 = new IntHeader(new JumpOpCode(3)); private static final Instruction STRING = new Instruction() { @Override @@ -80,6 +78,13 @@ public class PacketDefinitions { skip(in, count * 12); } }; + private static final Instruction UBYTE_BYTE = new Instruction() { + @Override + void read(DataInput in) throws IOException { + int size = in.readUnsignedByte(); + skip(in, size); + } + }; static { opCodes[0x00] = new Instruction[]{INT}; @@ -90,6 +95,7 @@ public class PacketDefinitions { opCodes[0x05] = new Instruction[]{INT, SHORT, ITEM}; opCodes[0x06] = new Instruction[]{INT, INT, INT}; opCodes[0x07] = new Instruction[]{INT, INT, BOOLEAN}; + opCodes[0x08] = new Instruction[]{SHORT, SHORT, FLOAT}; opCodes[0x09] = new Instruction[]{INT, BYTE, BYTE, SHORT, STRING}; opCodes[0x0A] = new Instruction[]{BOOLEAN}; opCodes[0x0B] = new Instruction[]{DOUBLE, DOUBLE, DOUBLE, DOUBLE, BOOLEAN}; @@ -131,7 +137,7 @@ public class PacketDefinitions { // // opCodes[0x33] = new Instruction[]{INT, INT, BOOLEAN, SHORT, SHORT, INT_BYTE}; - opCodes[0x34] = new Instruction[]{INT, INT, SHORT, INT_INT}; + opCodes[0x34] = new Instruction[]{INT, INT, SHORT, INT_BYTE}; opCodes[0x35] = new Instruction[]{INT, BYTE, INT, SHORT, BYTE}; opCodes[0x36] = new Instruction[]{INT, SHORT, INT, BYTE, BYTE, SHORT}; opCodes[0x37] = new Instruction[]{INT, INT, INT, INT, BYTE}; @@ -169,7 +175,7 @@ public class PacketDefinitions { // // opCodes[0x82] = new Instruction[]{INT, SHORT, INT, STRING, STRING, STRING, STRING}; - opCodes[0x83] = new Instruction[]{SHORT, SHORT, BYTE_BYTE}; // TODO: Ubyte? + opCodes[0x83] = new Instruction[]{SHORT, SHORT, UBYTE_BYTE}; opCodes[0x84] = new Instruction[]{INT, SHORT, INT, BYTE, SHORT_BYTE}; // // @@ -201,7 +207,7 @@ public class PacketDefinitions { if (instructions == null) { throw new IOException("Unknown packet id " + packetId); } - + System.out.println(Integer.toHexString(packetId)); for (Instruction instruction : instructions) { instruction.read(in); } @@ -212,9 +218,8 @@ public class PacketDefinitions { abstract void read(DataInput in) throws IOException; final void skip(DataInput in, int len) throws IOException { - int n = 0; - while (n < len) { - n += in.readByte(); + for (int i = 0; i < len; i++) { + in.readByte(); } } } From 83275df93e97fe9810d2c395fe06bcab5b7b0c88 Mon Sep 17 00:00:00 2001 From: md_5 Date: Thu, 18 Oct 2012 10:32:41 +1100 Subject: [PATCH 03/22] Crush packets for speed and add basic toStrings --- .../md_5/mc/protocol/PacketDefinitions.java | 80 ++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java index 5777809c..f34b11c1 100644 --- a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java +++ b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java @@ -2,6 +2,9 @@ package net.md_5.mc.protocol; import java.io.DataInput; import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; public class PacketDefinitions { @@ -23,6 +26,11 @@ public class PacketDefinitions { short len = in.readShort(); skip(in, len * 2); } + + @Override + public String toString() { + return "String"; + } }; private static final Instruction ITEM = new Instruction() { @Override @@ -33,6 +41,11 @@ public class PacketDefinitions { SHORT_BYTE.read(in); } } + + @Override + public String toString() { + return "Item"; + } }; private static final Instruction SHORT_ITEM = new ShortHeader(ITEM); private static final Instruction METADATA = new Instruction() { @@ -69,6 +82,11 @@ public class PacketDefinitions { x = in.readByte(); } } + + @Override + public String toString() { + return "Metadata"; + } }; private static final Instruction BULK_CHUNK = new Instruction() { @Override @@ -77,6 +95,11 @@ public class PacketDefinitions { INT_BYTE.read(in); skip(in, count * 12); } + + @Override + public String toString() { + return "Bulk Chunk"; + } }; private static final Instruction UBYTE_BYTE = new Instruction() { @Override @@ -84,6 +107,11 @@ public class PacketDefinitions { int size = in.readUnsignedByte(); skip(in, size); } + + @Override + public String toString() { + return "Unsigned Byte Byte"; + } }; static { @@ -199,6 +227,33 @@ public class PacketDefinitions { opCodes[0xFD] = new Instruction[]{STRING, SHORT_BYTE, SHORT_BYTE}; opCodes[0xFE] = new Instruction[]{}; opCodes[0xFF] = new Instruction[]{STRING}; + + crushInstructions(); + } + + private static void crushInstructions() { + for (int i = 0; i < opCodes.length; i++) { + Instruction[] instructions = opCodes[i]; + if (instructions != null) { + List crushed = new ArrayList(); + int nextJumpSize = 0; + for (Instruction child : instructions) { + if (child instanceof JumpOpCode) { + nextJumpSize += ((JumpOpCode) child).len; + } else { + if (nextJumpSize != 0) { + crushed.add(new JumpOpCode(nextJumpSize)); + } + crushed.add(child); + nextJumpSize = 0; + } + } + if (nextJumpSize != 0) { + crushed.add(new JumpOpCode(nextJumpSize)); + } + opCodes[i] = crushed.toArray(new Instruction[crushed.size()]); + } + } } public static void readPacket(DataInput in) throws IOException { @@ -207,7 +262,7 @@ public class PacketDefinitions { if (instructions == null) { throw new IOException("Unknown packet id " + packetId); } - System.out.println(Integer.toHexString(packetId)); + for (Instruction instruction : instructions) { instruction.read(in); } @@ -222,6 +277,9 @@ public class PacketDefinitions { in.readByte(); } } + + @Override + public abstract String toString(); } static class JumpOpCode extends Instruction { @@ -239,6 +297,11 @@ public class PacketDefinitions { void read(DataInput in) throws IOException { skip(in, len); } + + @Override + public String toString() { + return "Jump(" + len + ")"; + } } static class ByteHeader extends Instruction { @@ -256,6 +319,11 @@ public class PacketDefinitions { child.read(in); } } + + @Override + public String toString() { + return "ByteHeader(" + child + ")"; + } } static class ShortHeader extends Instruction { @@ -273,6 +341,11 @@ public class PacketDefinitions { child.read(in); } } + + @Override + public String toString() { + return "ShortHeader(" + child + ")"; + } } static class IntHeader extends Instruction { @@ -290,5 +363,10 @@ public class PacketDefinitions { child.read(in); } } + + @Override + public String toString() { + return "IntHeader(" + child + ")"; + } } } From ea5584f28cef2bceb3a93dc39312d69f0cac6afe Mon Sep 17 00:00:00 2001 From: md_5 Date: Thu, 18 Oct 2012 13:50:06 +1100 Subject: [PATCH 04/22] Strings can be treated as short_short --- .../net/md_5/mc/protocol/PacketDefinitions.java | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java index f34b11c1..205fafe0 100644 --- a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java +++ b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java @@ -3,7 +3,6 @@ package net.md_5.mc.protocol; import java.io.DataInput; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; public class PacketDefinitions { @@ -20,18 +19,7 @@ public class PacketDefinitions { private static final Instruction BYTE_INT = new ByteHeader(INT); private static final Instruction INT_BYTE = new IntHeader(BYTE); private static final Instruction INT_3 = new IntHeader(new JumpOpCode(3)); - private static final Instruction STRING = new Instruction() { - @Override - void read(DataInput in) throws IOException { - short len = in.readShort(); - skip(in, len * 2); - } - - @Override - public String toString() { - return "String"; - } - }; + private static final Instruction STRING = new ShortHeader(SHORT); private static final Instruction ITEM = new Instruction() { @Override void read(DataInput in) throws IOException { From ec1829d921e046595537e14ced41bf8d6ed67679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Sundahl?= Date: Thu, 18 Oct 2012 02:42:56 +0200 Subject: [PATCH 05/22] Added the direction byte to 0x0F --- src/main/java/net/md_5/mc/protocol/PacketDefinitions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java index 205fafe0..8ac0176d 100644 --- a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java +++ b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java @@ -118,7 +118,7 @@ public class PacketDefinitions { opCodes[0x0C] = new Instruction[]{FLOAT, FLOAT, BOOLEAN}; opCodes[0x0D] = new Instruction[]{DOUBLE, DOUBLE, DOUBLE, DOUBLE, FLOAT, FLOAT, BOOLEAN}; opCodes[0x0E] = new Instruction[]{BYTE, INT, BYTE, INT, BYTE}; - opCodes[0x0F] = new Instruction[]{INT, BYTE, INT, ITEM, BYTE, BYTE, BYTE}; + opCodes[0x0F] = new Instruction[]{INT, BYTE, INT, BYTE, ITEM, BYTE, BYTE, BYTE}; opCodes[0x10] = new Instruction[]{SHORT}; opCodes[0x11] = new Instruction[]{INT, BYTE, INT, BYTE, INT}; opCodes[0x12] = new Instruction[]{INT, BYTE}; From 5962ebd992e180c8eb8aee495b98b5b462145d2b Mon Sep 17 00:00:00 2001 From: md-5 Date: Fri, 19 Oct 2012 09:51:48 +1200 Subject: [PATCH 06/22] Hopefully fix issue #2 by using an unsigned byte --- src/main/java/net/md_5/mc/protocol/PacketDefinitions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java index 8ac0176d..c3dcd20b 100644 --- a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java +++ b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java @@ -39,7 +39,7 @@ public class PacketDefinitions { private static final Instruction METADATA = new Instruction() { @Override void read(DataInput in) throws IOException { - byte x = in.readByte(); + int x = in.readUnsignedByte(); while (x != 127) { int type = x >> 5; switch (type) { From f38ef71de8a1ea4e84a1226b3e297ede0ce963b7 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 20 Oct 2012 21:37:04 +1100 Subject: [PATCH 07/22] Micro optimize by using ubyte in skips --- pom.xml | 2 +- src/main/java/net/md_5/mc/protocol/PacketDefinitions.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 57293200..9dbf55f2 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ junit junit - 3.8.1 + 4.10 test diff --git a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java index c3dcd20b..d5f230ba 100644 --- a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java +++ b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java @@ -1,6 +1,7 @@ package net.md_5.mc.protocol; import java.io.DataInput; +import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -262,7 +263,7 @@ public class PacketDefinitions { final void skip(DataInput in, int len) throws IOException { for (int i = 0; i < len; i++) { - in.readByte(); + in.readUnsignedByte(); } } From 3b7df920d1b45a6735c282274566fc7b836f553f Mon Sep 17 00:00:00 2001 From: md_5 Date: Mon, 22 Oct 2012 08:43:26 +1100 Subject: [PATCH 08/22] Fix 0x17 --- src/main/java/net/md_5/mc/protocol/PacketDefinitions.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java index d5f230ba..8d9dd144 100644 --- a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java +++ b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java @@ -20,6 +20,7 @@ public class PacketDefinitions { private static final Instruction BYTE_INT = new ByteHeader(INT); private static final Instruction INT_BYTE = new IntHeader(BYTE); private static final Instruction INT_3 = new IntHeader(new JumpOpCode(3)); + private static final Instruction INT_6 = new IntHeader(new JumpOpCode(6)); private static final Instruction STRING = new ShortHeader(SHORT); private static final Instruction ITEM = new Instruction() { @Override @@ -127,7 +128,7 @@ public class PacketDefinitions { opCodes[0x14] = new Instruction[]{INT, STRING, INT, INT, INT, BYTE, BYTE, SHORT, METADATA}; opCodes[0x15] = new Instruction[]{INT, SHORT, BYTE, SHORT, INT, INT, INT, BYTE, BYTE, BYTE}; opCodes[0x16] = new Instruction[]{INT, INT}; - opCodes[0x17] = new Instruction[]{INT, BYTE, INT, INT, INT, INT, SHORT, SHORT, SHORT}; + opCodes[0x17] = new Instruction[]{INT, BYTE, INT, INT, INT, INT_6}; opCodes[0x18] = new Instruction[]{INT, BYTE, INT, INT, INT, BYTE, BYTE, BYTE, SHORT, SHORT, SHORT, METADATA}; opCodes[0x19] = new Instruction[]{INT, STRING, INT, INT, INT, INT}; opCodes[0x1A] = new Instruction[]{INT, INT, INT, INT, SHORT}; From e0b38c9984dadef6c60c93803c9cce48b4618deb Mon Sep 17 00:00:00 2001 From: md_5 Date: Mon, 22 Oct 2012 09:35:43 +1100 Subject: [PATCH 09/22] 0x47 is byte not boolean, shouldn't make a difference --- src/main/java/net/md_5/mc/protocol/PacketDefinitions.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java index 8d9dd144..8d1e003d 100644 --- a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java +++ b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java @@ -1,7 +1,6 @@ package net.md_5.mc.protocol; import java.io.DataInput; -import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -172,7 +171,7 @@ public class PacketDefinitions { // // opCodes[0x46] = new Instruction[]{BYTE, BYTE}; - opCodes[0x47] = new Instruction[]{INT, BOOLEAN, INT, INT, INT}; + opCodes[0x47] = new Instruction[]{INT, BYTE, INT, INT, INT}; // // // 0x4A -> 0x63 Do not exist From 05019bd31ad924db0fa14684b53b8a54ce627ed3 Mon Sep 17 00:00:00 2001 From: md_5 Date: Wed, 24 Oct 2012 07:32:40 +1100 Subject: [PATCH 10/22] Create new OPTIONAL_MOTION instruction and use it in 0x17 --- .../net/md_5/mc/protocol/PacketDefinitions.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java index 8d1e003d..cecb25bb 100644 --- a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java +++ b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java @@ -19,7 +19,6 @@ public class PacketDefinitions { private static final Instruction BYTE_INT = new ByteHeader(INT); private static final Instruction INT_BYTE = new IntHeader(BYTE); private static final Instruction INT_3 = new IntHeader(new JumpOpCode(3)); - private static final Instruction INT_6 = new IntHeader(new JumpOpCode(6)); private static final Instruction STRING = new ShortHeader(SHORT); private static final Instruction ITEM = new Instruction() { @Override @@ -102,6 +101,20 @@ public class PacketDefinitions { return "Unsigned Byte Byte"; } }; + private static final Instruction OPTIONAL_MOTION = new Instruction() { + @Override + void read(DataInput in) throws IOException { + int data = in.readInt(); + if (data > 0) { + skip(in, 6); + } + } + + @Override + public String toString() { + return "Optional Motion"; + } + }; static { opCodes[0x00] = new Instruction[]{INT}; @@ -127,7 +140,7 @@ public class PacketDefinitions { opCodes[0x14] = new Instruction[]{INT, STRING, INT, INT, INT, BYTE, BYTE, SHORT, METADATA}; opCodes[0x15] = new Instruction[]{INT, SHORT, BYTE, SHORT, INT, INT, INT, BYTE, BYTE, BYTE}; opCodes[0x16] = new Instruction[]{INT, INT}; - opCodes[0x17] = new Instruction[]{INT, BYTE, INT, INT, INT, INT_6}; + opCodes[0x17] = new Instruction[]{INT, BYTE, INT, INT, INT, OPTIONAL_MOTION}; opCodes[0x18] = new Instruction[]{INT, BYTE, INT, INT, INT, BYTE, BYTE, BYTE, SHORT, SHORT, SHORT, METADATA}; opCodes[0x19] = new Instruction[]{INT, STRING, INT, INT, INT, INT}; opCodes[0x1A] = new Instruction[]{INT, INT, INT, INT, SHORT}; From 51174c2c9f1b96cd7383618f35114a4f2774cda9 Mon Sep 17 00:00:00 2001 From: md_5 Date: Fri, 26 Oct 2012 16:41:06 +1100 Subject: [PATCH 11/22] Change to Mendax and refactor stuff. --- README.md | 20 + pom.xml | 6 +- .../md_5/mc/protocol/PacketDefinitions.java | 374 ------------------ .../net/md_5/mendax/PacketDefinitions.java | 128 ++++++ .../net/md_5/mendax/datainput/BulkChunk.java | 14 + .../net/md_5/mendax/datainput/ByteHeader.java | 21 + .../datainput/DataInputPacketReader.java | 62 +++ .../md_5/mendax/datainput/Instruction.java | 36 ++ .../net/md_5/mendax/datainput/IntHeader.java | 21 + .../java/net/md_5/mendax/datainput/Item.java | 16 + .../java/net/md_5/mendax/datainput/Jump.java | 21 + .../net/md_5/mendax/datainput/MetaData.java | 41 ++ .../md_5/mendax/datainput/OptionalMotion.java | 15 + .../md_5/mendax/datainput/ShortHeader.java | 21 + .../mendax/datainput/UnsignedByteByte.java | 13 + 15 files changed, 432 insertions(+), 377 deletions(-) create mode 100644 README.md delete mode 100644 src/main/java/net/md_5/mc/protocol/PacketDefinitions.java create mode 100644 src/main/java/net/md_5/mendax/PacketDefinitions.java create mode 100644 src/main/java/net/md_5/mendax/datainput/BulkChunk.java create mode 100644 src/main/java/net/md_5/mendax/datainput/ByteHeader.java create mode 100644 src/main/java/net/md_5/mendax/datainput/DataInputPacketReader.java create mode 100644 src/main/java/net/md_5/mendax/datainput/Instruction.java create mode 100644 src/main/java/net/md_5/mendax/datainput/IntHeader.java create mode 100644 src/main/java/net/md_5/mendax/datainput/Item.java create mode 100644 src/main/java/net/md_5/mendax/datainput/Jump.java create mode 100644 src/main/java/net/md_5/mendax/datainput/MetaData.java create mode 100644 src/main/java/net/md_5/mendax/datainput/OptionalMotion.java create mode 100644 src/main/java/net/md_5/mendax/datainput/ShortHeader.java create mode 100644 src/main/java/net/md_5/mendax/datainput/UnsignedByteByte.java diff --git a/README.md b/README.md new file mode 100644 index 00000000..47845734 --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +Mendax +====== +The Minecraft protocol is a lie! +-------------------------------- +Mendax is a predominantly I Minecraft protocol parser and inspector. It also includes a built in proxy. + +History +------- +MinecraftProtocolLib was designed to be the most efficient way of separating the Minecraft protocol into byte arrays. With other tools like SMProxy by @SirCmpwn and MinerHat by @sk89q becoming obsolete, the decision was made to expand MinecraftProtocolLib into a parser as well. Mendax is that parser. +With no runtime dependencies Mendax is the perfect choice for use in your next Java, Minecraft related project. + +Operation +--------- +Mendax has 2 modes of operation. + +- Parsing Mode - Bytes are read from an InputStream and returned in byte arrays. This mode is the most efficient, however the raw data itself is not very useful +- Inspection Mode - Bytes are read from an InputStream and Packet objects are returned. These packet objects contain all useable information about a packet. In this mode Items, Locations and Compressed Data are expanded into their own fields and data types. + + +>Please note that the above features may not be entirely implemented in the current version of Mendax. Additionally breaking changes may occur without warning, however they should all be easy to update. \ No newline at end of file diff --git a/pom.xml b/pom.xml index 9dbf55f2..698d1020 100644 --- a/pom.xml +++ b/pom.xml @@ -3,11 +3,11 @@ 4.0.0 net.md-5 - mc-protocol-lib - 1.0-SNAPSHOT + mendax + 1.3.2-SNAPSHOT jar - MinecraftProtocolLib + Mendax http://maven.apache.org diff --git a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java b/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java deleted file mode 100644 index cecb25bb..00000000 --- a/src/main/java/net/md_5/mc/protocol/PacketDefinitions.java +++ /dev/null @@ -1,374 +0,0 @@ -package net.md_5.mc.protocol; - -import java.io.DataInput; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -public class PacketDefinitions { - - private static final Instruction[][] opCodes = new Instruction[256][]; - private static final Instruction BYTE = new JumpOpCode(1); - private static final Instruction BOOLEAN = BYTE; - private static final Instruction SHORT = new JumpOpCode(2); - private static final Instruction INT = new JumpOpCode(4); - private static final Instruction FLOAT = INT; - private static final Instruction LONG = new JumpOpCode(8); - private static final Instruction DOUBLE = LONG; - private static final Instruction SHORT_BYTE = new ShortHeader(BYTE); - private static final Instruction BYTE_INT = new ByteHeader(INT); - private static final Instruction INT_BYTE = new IntHeader(BYTE); - private static final Instruction INT_3 = new IntHeader(new JumpOpCode(3)); - private static final Instruction STRING = new ShortHeader(SHORT); - private static final Instruction ITEM = new Instruction() { - @Override - void read(DataInput in) throws IOException { - short type = in.readShort(); - if (type >= 0) { - skip(in, 3); - SHORT_BYTE.read(in); - } - } - - @Override - public String toString() { - return "Item"; - } - }; - private static final Instruction SHORT_ITEM = new ShortHeader(ITEM); - private static final Instruction METADATA = new Instruction() { - @Override - void read(DataInput in) throws IOException { - int x = in.readUnsignedByte(); - while (x != 127) { - int type = x >> 5; - switch (type) { - case 0: - BYTE.read(in); - break; - case 1: - SHORT.read(in); - break; - case 2: - INT.read(in); - break; - case 3: - FLOAT.read(in); - break; - case 4: - STRING.read(in); - break; - case 5: - skip(in, 5); // short, byte, short - break; - case 6: - skip(in, 6); // int, int, int - break; - default: - throw new IllegalArgumentException("Unknown metadata type " + type); - } - x = in.readByte(); - } - } - - @Override - public String toString() { - return "Metadata"; - } - }; - private static final Instruction BULK_CHUNK = new Instruction() { - @Override - void read(DataInput in) throws IOException { - short count = in.readShort(); - INT_BYTE.read(in); - skip(in, count * 12); - } - - @Override - public String toString() { - return "Bulk Chunk"; - } - }; - private static final Instruction UBYTE_BYTE = new Instruction() { - @Override - void read(DataInput in) throws IOException { - int size = in.readUnsignedByte(); - skip(in, size); - } - - @Override - public String toString() { - return "Unsigned Byte Byte"; - } - }; - private static final Instruction OPTIONAL_MOTION = new Instruction() { - @Override - void read(DataInput in) throws IOException { - int data = in.readInt(); - if (data > 0) { - skip(in, 6); - } - } - - @Override - public String toString() { - return "Optional Motion"; - } - }; - - static { - opCodes[0x00] = new Instruction[]{INT}; - opCodes[0x01] = new Instruction[]{INT, STRING, BYTE, BYTE, BYTE, BYTE, BYTE}; - opCodes[0x02] = new Instruction[]{BYTE, STRING, STRING, INT}; - opCodes[0x03] = new Instruction[]{STRING}; - opCodes[0x04] = new Instruction[]{LONG}; - opCodes[0x05] = new Instruction[]{INT, SHORT, ITEM}; - opCodes[0x06] = new Instruction[]{INT, INT, INT}; - opCodes[0x07] = new Instruction[]{INT, INT, BOOLEAN}; - opCodes[0x08] = new Instruction[]{SHORT, SHORT, FLOAT}; - opCodes[0x09] = new Instruction[]{INT, BYTE, BYTE, SHORT, STRING}; - opCodes[0x0A] = new Instruction[]{BOOLEAN}; - opCodes[0x0B] = new Instruction[]{DOUBLE, DOUBLE, DOUBLE, DOUBLE, BOOLEAN}; - opCodes[0x0C] = new Instruction[]{FLOAT, FLOAT, BOOLEAN}; - opCodes[0x0D] = new Instruction[]{DOUBLE, DOUBLE, DOUBLE, DOUBLE, FLOAT, FLOAT, BOOLEAN}; - opCodes[0x0E] = new Instruction[]{BYTE, INT, BYTE, INT, BYTE}; - opCodes[0x0F] = new Instruction[]{INT, BYTE, INT, BYTE, ITEM, BYTE, BYTE, BYTE}; - opCodes[0x10] = new Instruction[]{SHORT}; - opCodes[0x11] = new Instruction[]{INT, BYTE, INT, BYTE, INT}; - opCodes[0x12] = new Instruction[]{INT, BYTE}; - opCodes[0x13] = new Instruction[]{INT, BYTE}; - opCodes[0x14] = new Instruction[]{INT, STRING, INT, INT, INT, BYTE, BYTE, SHORT, METADATA}; - opCodes[0x15] = new Instruction[]{INT, SHORT, BYTE, SHORT, INT, INT, INT, BYTE, BYTE, BYTE}; - opCodes[0x16] = new Instruction[]{INT, INT}; - opCodes[0x17] = new Instruction[]{INT, BYTE, INT, INT, INT, OPTIONAL_MOTION}; - opCodes[0x18] = new Instruction[]{INT, BYTE, INT, INT, INT, BYTE, BYTE, BYTE, SHORT, SHORT, SHORT, METADATA}; - opCodes[0x19] = new Instruction[]{INT, STRING, INT, INT, INT, INT}; - opCodes[0x1A] = new Instruction[]{INT, INT, INT, INT, SHORT}; - opCodes[0x1B] = null; // Does not exist - opCodes[0x1C] = new Instruction[]{INT, SHORT, SHORT, SHORT}; - opCodes[0x1D] = new Instruction[]{BYTE_INT}; - opCodes[0x1E] = new Instruction[]{INT}; - opCodes[0x1F] = new Instruction[]{INT, BYTE, BYTE, BYTE}; - opCodes[0x20] = new Instruction[]{INT, BYTE, BYTE}; - opCodes[0x21] = new Instruction[]{INT, BYTE, BYTE, BYTE, BYTE, BYTE}; - opCodes[0x22] = new Instruction[]{INT, INT, INT, INT, BYTE, BYTE}; - opCodes[0x23] = new Instruction[]{INT, BYTE}; - opCodes[0x24] = null; // Does not exist - opCodes[0x25] = null; // Does not exist - opCodes[0x26] = new Instruction[]{INT, BYTE}; - opCodes[0x27] = new Instruction[]{INT, INT}; - opCodes[0x28] = new Instruction[]{INT, METADATA}; - opCodes[0x29] = new Instruction[]{INT, BYTE, BYTE, SHORT}; - opCodes[0x2A] = new Instruction[]{INT, BYTE}; - opCodes[0x2B] = new Instruction[]{FLOAT, SHORT, SHORT}; - // - // - // 0x2C -> 0x32 Do not exist - // - // - opCodes[0x33] = new Instruction[]{INT, INT, BOOLEAN, SHORT, SHORT, INT_BYTE}; - opCodes[0x34] = new Instruction[]{INT, INT, SHORT, INT_BYTE}; - opCodes[0x35] = new Instruction[]{INT, BYTE, INT, SHORT, BYTE}; - opCodes[0x36] = new Instruction[]{INT, SHORT, INT, BYTE, BYTE, SHORT}; - opCodes[0x37] = new Instruction[]{INT, INT, INT, INT, BYTE}; - opCodes[0x38] = new Instruction[]{BULK_CHUNK}; - opCodes[0x39] = null; // Does not exist - opCodes[0x3A] = null; // Does not exist - opCodes[0x3B] = null; // Does not exist - opCodes[0x3C] = new Instruction[]{DOUBLE, DOUBLE, DOUBLE, FLOAT, INT_3, FLOAT, FLOAT, FLOAT}; - opCodes[0x3D] = new Instruction[]{INT, INT, BYTE, INT, INT}; - opCodes[0x3E] = new Instruction[]{STRING, INT, INT, INT, FLOAT, BYTE}; - // - // - // 0x3F -> 0x45 Do not exist - // - // - opCodes[0x46] = new Instruction[]{BYTE, BYTE}; - opCodes[0x47] = new Instruction[]{INT, BYTE, INT, INT, INT}; - // - // - // 0x4A -> 0x63 Do not exist - // - // - opCodes[0x64] = new Instruction[]{BYTE, BYTE, STRING, BYTE}; - opCodes[0x65] = new Instruction[]{BYTE}; - opCodes[0x66] = new Instruction[]{BYTE, SHORT, BOOLEAN, SHORT, BOOLEAN, ITEM}; - opCodes[0x67] = new Instruction[]{BYTE, SHORT, ITEM}; - opCodes[0x68] = new Instruction[]{BYTE, SHORT_ITEM}; - opCodes[0x69] = new Instruction[]{BYTE, SHORT, SHORT}; - opCodes[0x6A] = new Instruction[]{BYTE, SHORT, BOOLEAN}; - opCodes[0x6B] = new Instruction[]{SHORT, ITEM}; - opCodes[0x6C] = new Instruction[]{BYTE, BYTE}; - // - // - // 0x6D -> 0x81 Do not exist - // - // - opCodes[0x82] = new Instruction[]{INT, SHORT, INT, STRING, STRING, STRING, STRING}; - opCodes[0x83] = new Instruction[]{SHORT, SHORT, UBYTE_BYTE}; - opCodes[0x84] = new Instruction[]{INT, SHORT, INT, BYTE, SHORT_BYTE}; - // - // - // 0x85 -> 0xC7 Do not exist - // - // - opCodes[0xC8] = new Instruction[]{INT, BYTE}; - opCodes[0xC9] = new Instruction[]{STRING, BOOLEAN, SHORT}; - opCodes[0xCA] = new Instruction[]{BYTE, BYTE, BYTE}; - opCodes[0xCB] = new Instruction[]{STRING}; - opCodes[0xCC] = new Instruction[]{STRING, BYTE, BYTE, BYTE}; - opCodes[0xCD] = new Instruction[]{BYTE}; - // - // - // 0xCE -> 0xF9 Do not exist - // - // - opCodes[0xFA] = new Instruction[]{STRING, SHORT_BYTE}; - opCodes[0xFB] = null; // Does not exist - opCodes[0xFC] = new Instruction[]{SHORT_BYTE, SHORT_BYTE}; - opCodes[0xFD] = new Instruction[]{STRING, SHORT_BYTE, SHORT_BYTE}; - opCodes[0xFE] = new Instruction[]{}; - opCodes[0xFF] = new Instruction[]{STRING}; - - crushInstructions(); - } - - private static void crushInstructions() { - for (int i = 0; i < opCodes.length; i++) { - Instruction[] instructions = opCodes[i]; - if (instructions != null) { - List crushed = new ArrayList(); - int nextJumpSize = 0; - for (Instruction child : instructions) { - if (child instanceof JumpOpCode) { - nextJumpSize += ((JumpOpCode) child).len; - } else { - if (nextJumpSize != 0) { - crushed.add(new JumpOpCode(nextJumpSize)); - } - crushed.add(child); - nextJumpSize = 0; - } - } - if (nextJumpSize != 0) { - crushed.add(new JumpOpCode(nextJumpSize)); - } - opCodes[i] = crushed.toArray(new Instruction[crushed.size()]); - } - } - } - - public static void readPacket(DataInput in) throws IOException { - int packetId = in.readUnsignedByte(); - Instruction[] instructions = opCodes[packetId]; - if (instructions == null) { - throw new IOException("Unknown packet id " + packetId); - } - - for (Instruction instruction : instructions) { - instruction.read(in); - } - } - - static abstract class Instruction { - - abstract void read(DataInput in) throws IOException; - - final void skip(DataInput in, int len) throws IOException { - for (int i = 0; i < len; i++) { - in.readUnsignedByte(); - } - } - - @Override - public abstract String toString(); - } - - static class JumpOpCode extends Instruction { - - private final int len; - - public JumpOpCode(int len) { - if (len < 0) { - throw new IndexOutOfBoundsException(); - } - this.len = len; - } - - @Override - void read(DataInput in) throws IOException { - skip(in, len); - } - - @Override - public String toString() { - return "Jump(" + len + ")"; - } - } - - static class ByteHeader extends Instruction { - - private final Instruction child; - - public ByteHeader(Instruction child) { - this.child = child; - } - - @Override - void read(DataInput in) throws IOException { - byte size = in.readByte(); - for (byte b = 0; b < size; b++) { - child.read(in); - } - } - - @Override - public String toString() { - return "ByteHeader(" + child + ")"; - } - } - - static class ShortHeader extends Instruction { - - private final Instruction child; - - public ShortHeader(Instruction child) { - this.child = child; - } - - @Override - void read(DataInput in) throws IOException { - short size = in.readShort(); - for (short s = 0; s < size; s++) { - child.read(in); - } - } - - @Override - public String toString() { - return "ShortHeader(" + child + ")"; - } - } - - static class IntHeader extends Instruction { - - private final Instruction child; - - public IntHeader(Instruction child) { - this.child = child; - } - - @Override - void read(DataInput in) throws IOException { - int size = in.readInt(); - for (int i = 0; i < size; i++) { - child.read(in); - } - } - - @Override - public String toString() { - return "IntHeader(" + child + ")"; - } - } -} diff --git a/src/main/java/net/md_5/mendax/PacketDefinitions.java b/src/main/java/net/md_5/mendax/PacketDefinitions.java new file mode 100644 index 00000000..f584b1f4 --- /dev/null +++ b/src/main/java/net/md_5/mendax/PacketDefinitions.java @@ -0,0 +1,128 @@ +package net.md_5.mendax; + +import static net.md_5.mendax.PacketDefinitions.OpCode.*; + +public class PacketDefinitions { + + public static final OpCode[][] opCodes = new OpCode[256][]; + + public enum OpCode { + + BOOLEAN, BULK_CHUNK, BYTE, BYTE_INT, DOUBLE, FLOAT, INT, INT_3, INT_BYTE, ITEM, LONG, METADATA, OPTIONAL_MOTION, SHORT, SHORT_BYTE, SHORT_ITEM, STRING, UBYTE_BYTE + } + + static { + opCodes[0x00] = new OpCode[]{INT}; + opCodes[0x01] = new OpCode[]{INT, STRING, BYTE, BYTE, BYTE, BYTE, BYTE}; + opCodes[0x02] = new OpCode[]{BYTE, STRING, STRING, INT}; + opCodes[0x03] = new OpCode[]{STRING}; + opCodes[0x04] = new OpCode[]{LONG}; + opCodes[0x05] = new OpCode[]{INT, SHORT, ITEM}; + opCodes[0x06] = new OpCode[]{INT, INT, INT}; + opCodes[0x07] = new OpCode[]{INT, INT, BOOLEAN}; + opCodes[0x08] = new OpCode[]{SHORT, SHORT, FLOAT}; + opCodes[0x09] = new OpCode[]{INT, BYTE, BYTE, SHORT, STRING}; + opCodes[0x0A] = new OpCode[]{BOOLEAN}; + opCodes[0x0B] = new OpCode[]{DOUBLE, DOUBLE, DOUBLE, DOUBLE, BOOLEAN}; + opCodes[0x0C] = new OpCode[]{FLOAT, FLOAT, BOOLEAN}; + opCodes[0x0D] = new OpCode[]{DOUBLE, DOUBLE, DOUBLE, DOUBLE, FLOAT, FLOAT, BOOLEAN}; + opCodes[0x0E] = new OpCode[]{BYTE, INT, BYTE, INT, BYTE}; + opCodes[0x0F] = new OpCode[]{INT, BYTE, INT, BYTE, ITEM, BYTE, BYTE, BYTE}; + opCodes[0x10] = new OpCode[]{SHORT}; + opCodes[0x11] = new OpCode[]{INT, BYTE, INT, BYTE, INT}; + opCodes[0x12] = new OpCode[]{INT, BYTE}; + opCodes[0x13] = new OpCode[]{INT, BYTE}; + opCodes[0x14] = new OpCode[]{INT, STRING, INT, INT, INT, BYTE, BYTE, SHORT, METADATA}; + opCodes[0x15] = new OpCode[]{INT, SHORT, BYTE, SHORT, INT, INT, INT, BYTE, BYTE, BYTE}; + opCodes[0x16] = new OpCode[]{INT, INT}; + opCodes[0x17] = new OpCode[]{INT, BYTE, INT, INT, INT, OPTIONAL_MOTION}; + opCodes[0x18] = new OpCode[]{INT, BYTE, INT, INT, INT, BYTE, BYTE, BYTE, SHORT, SHORT, SHORT, METADATA}; + opCodes[0x19] = new OpCode[]{INT, STRING, INT, INT, INT, INT}; + opCodes[0x1A] = new OpCode[]{INT, INT, INT, INT, SHORT}; + opCodes[0x1B] = null; // Does not exist + opCodes[0x1C] = new OpCode[]{INT, SHORT, SHORT, SHORT}; + opCodes[0x1D] = new OpCode[]{BYTE_INT}; + opCodes[0x1E] = new OpCode[]{INT}; + opCodes[0x1F] = new OpCode[]{INT, BYTE, BYTE, BYTE}; + opCodes[0x20] = new OpCode[]{INT, BYTE, BYTE}; + opCodes[0x21] = new OpCode[]{INT, BYTE, BYTE, BYTE, BYTE, BYTE}; + opCodes[0x22] = new OpCode[]{INT, INT, INT, INT, BYTE, BYTE}; + opCodes[0x23] = new OpCode[]{INT, BYTE}; + opCodes[0x24] = null; // Does not exist + opCodes[0x25] = null; // Does not exist + opCodes[0x26] = new OpCode[]{INT, BYTE}; + opCodes[0x27] = new OpCode[]{INT, INT}; + opCodes[0x28] = new OpCode[]{INT, METADATA}; + opCodes[0x29] = new OpCode[]{INT, BYTE, BYTE, SHORT}; + opCodes[0x2A] = new OpCode[]{INT, BYTE}; + opCodes[0x2B] = new OpCode[]{FLOAT, SHORT, SHORT}; + // + // + // 0x2C -> 0x32 Do not exist + // + // + opCodes[0x33] = new OpCode[]{INT, INT, BOOLEAN, SHORT, SHORT, INT_BYTE}; + opCodes[0x34] = new OpCode[]{INT, INT, SHORT, INT_BYTE}; + opCodes[0x35] = new OpCode[]{INT, BYTE, INT, SHORT, BYTE}; + opCodes[0x36] = new OpCode[]{INT, SHORT, INT, BYTE, BYTE, SHORT}; + opCodes[0x37] = new OpCode[]{INT, INT, INT, INT, BYTE}; + opCodes[0x38] = new OpCode[]{BULK_CHUNK}; + opCodes[0x39] = null; // Does not exist + opCodes[0x3A] = null; // Does not exist + opCodes[0x3B] = null; // Does not exist + opCodes[0x3C] = new OpCode[]{DOUBLE, DOUBLE, DOUBLE, FLOAT, INT_3, FLOAT, FLOAT, FLOAT}; + opCodes[0x3D] = new OpCode[]{INT, INT, BYTE, INT, INT}; + opCodes[0x3E] = new OpCode[]{STRING, INT, INT, INT, FLOAT, BYTE}; + // + // + // 0x3F -> 0x45 Do not exist + // + // + opCodes[0x46] = new OpCode[]{BYTE, BYTE}; + opCodes[0x47] = new OpCode[]{INT, BYTE, INT, INT, INT}; + // + // + // 0x4A -> 0x63 Do not exist + // + // + opCodes[0x64] = new OpCode[]{BYTE, BYTE, STRING, BYTE}; + opCodes[0x65] = new OpCode[]{BYTE}; + opCodes[0x66] = new OpCode[]{BYTE, SHORT, BOOLEAN, SHORT, BOOLEAN, ITEM}; + opCodes[0x67] = new OpCode[]{BYTE, SHORT, ITEM}; + opCodes[0x68] = new OpCode[]{BYTE, SHORT_ITEM}; + opCodes[0x69] = new OpCode[]{BYTE, SHORT, SHORT}; + opCodes[0x6A] = new OpCode[]{BYTE, SHORT, BOOLEAN}; + opCodes[0x6B] = new OpCode[]{SHORT, ITEM}; + opCodes[0x6C] = new OpCode[]{BYTE, BYTE}; + // + // + // 0x6D -> 0x81 Do not exist + // + // + opCodes[0x82] = new OpCode[]{INT, SHORT, INT, STRING, STRING, STRING, STRING}; + opCodes[0x83] = new OpCode[]{SHORT, SHORT, UBYTE_BYTE}; + opCodes[0x84] = new OpCode[]{INT, SHORT, INT, BYTE, SHORT_BYTE}; + // + // + // 0x85 -> 0xC7 Do not exist + // + // + opCodes[0xC8] = new OpCode[]{INT, BYTE}; + opCodes[0xC9] = new OpCode[]{STRING, BOOLEAN, SHORT}; + opCodes[0xCA] = new OpCode[]{BYTE, BYTE, BYTE}; + opCodes[0xCB] = new OpCode[]{STRING}; + opCodes[0xCC] = new OpCode[]{STRING, BYTE, BYTE, BYTE}; + opCodes[0xCD] = new OpCode[]{BYTE}; + // + // + // 0xCE -> 0xF9 Do not exist + // + // + opCodes[0xFA] = new OpCode[]{STRING, SHORT_BYTE}; + opCodes[0xFB] = null; // Does not exist + opCodes[0xFC] = new OpCode[]{SHORT_BYTE, SHORT_BYTE}; + opCodes[0xFD] = new OpCode[]{STRING, SHORT_BYTE, SHORT_BYTE}; + opCodes[0xFE] = new OpCode[]{}; + opCodes[0xFF] = new OpCode[]{STRING}; + } +} diff --git a/src/main/java/net/md_5/mendax/datainput/BulkChunk.java b/src/main/java/net/md_5/mendax/datainput/BulkChunk.java new file mode 100644 index 00000000..13c71e02 --- /dev/null +++ b/src/main/java/net/md_5/mendax/datainput/BulkChunk.java @@ -0,0 +1,14 @@ +package net.md_5.mendax.datainput; + +import java.io.DataInput; +import java.io.IOException; + +public class BulkChunk extends Instruction { + + @Override + void read(DataInput in) throws IOException { + short count = in.readShort(); + INT_BYTE.read(in); + skip(in, count * 12); + } +} diff --git a/src/main/java/net/md_5/mendax/datainput/ByteHeader.java b/src/main/java/net/md_5/mendax/datainput/ByteHeader.java new file mode 100644 index 00000000..c9508e00 --- /dev/null +++ b/src/main/java/net/md_5/mendax/datainput/ByteHeader.java @@ -0,0 +1,21 @@ +package net.md_5.mendax.datainput; + +import java.io.DataInput; +import java.io.IOException; + +class ByteHeader extends Instruction { + + private final Instruction child; + + ByteHeader(Instruction child) { + this.child = child; + } + + @Override + void read(DataInput in) throws IOException { + byte size = in.readByte(); + for (byte b = 0; b < size; b++) { + child.read(in); + } + } +} diff --git a/src/main/java/net/md_5/mendax/datainput/DataInputPacketReader.java b/src/main/java/net/md_5/mendax/datainput/DataInputPacketReader.java new file mode 100644 index 00000000..0bb1b092 --- /dev/null +++ b/src/main/java/net/md_5/mendax/datainput/DataInputPacketReader.java @@ -0,0 +1,62 @@ +package net.md_5.mendax.datainput; + +import java.io.DataInput; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import net.md_5.mendax.PacketDefinitions; +import net.md_5.mendax.PacketDefinitions.OpCode; + +public class DataInputPacketReader { + + private static final Instruction[][] instructions = new Instruction[256][]; + + static { + for (int i = 0; i < instructions.length; i++) { + List output = new ArrayList(); + + OpCode[] enums = PacketDefinitions.opCodes[i]; + if (enums != null) { + for (OpCode struct : enums) { + try { + output.add((Instruction) Instruction.class.getDeclaredField(struct.name()).get(null)); + } catch (Exception ex) { + throw new UnsupportedOperationException("No definition for " + struct.name()); + } + } + + List crushed = new ArrayList(); + int nextJumpSize = 0; + for (Instruction child : output) { + if (child instanceof Jump) { + nextJumpSize += ((Jump) child).len; + } else { + if (nextJumpSize != 0) { + crushed.add(new Jump(nextJumpSize)); + } + crushed.add(child); + nextJumpSize = 0; + } + } + if (nextJumpSize != 0) { + crushed.add(new Jump(nextJumpSize)); + } + + instructions[i] = crushed.toArray(new Instruction[crushed.size()]); + } + } + } + + public static void readPacket(DataInput in) throws IOException { + int packetId = in.readUnsignedByte(); + Instruction[] packetDef = instructions[packetId]; + + if (packetDef == null) { + throw new IOException("Unknown packet id " + packetId); + } + + for (Instruction instruction : packetDef) { + instruction.read(in); + } + } +} diff --git a/src/main/java/net/md_5/mendax/datainput/Instruction.java b/src/main/java/net/md_5/mendax/datainput/Instruction.java new file mode 100644 index 00000000..323ca752 --- /dev/null +++ b/src/main/java/net/md_5/mendax/datainput/Instruction.java @@ -0,0 +1,36 @@ +package net.md_5.mendax.datainput; + +import java.io.DataInput; +import java.io.IOException; + +abstract class Instruction { + + static final Instruction BOOLEAN = new Jump(1); + static final Instruction BULK_CHUNK = new BulkChunk(); + static final Instruction BYTE = new Jump(1); + // BYTE_INT moved down + static final Instruction DOUBLE = new Jump(8); + static final Instruction FLOAT = new Jump(4); + static final Instruction INT = new Jump(4); + static final Instruction INT_3 = new IntHeader(new Jump(3)); + static final Instruction INT_BYTE = new IntHeader(BYTE); + static final Instruction ITEM = new Item(); + static final Instruction LONG = new Jump(8); + static final Instruction METADATA = new MetaData(); + static final Instruction OPTIONAL_MOTION = new OptionalMotion(); + static final Instruction SHORT = new Jump(2); + static final Instruction SHORT_BYTE = new ShortHeader(BYTE); + static final Instruction SHORT_ITEM = new ShortHeader(ITEM); + static final Instruction STRING = new ShortHeader(new Jump(2)); + static final Instruction UBYTE_BYTE = new UnsignedByteByte(); + // Illegal forward references below this line + static final Instruction BYTE_INT = new ByteHeader(INT); + + abstract void read(DataInput in) throws IOException; + + final void skip(DataInput in, int len) throws IOException { + for (int i = 0; i < len; i++) { + in.readUnsignedByte(); + } + } +} diff --git a/src/main/java/net/md_5/mendax/datainput/IntHeader.java b/src/main/java/net/md_5/mendax/datainput/IntHeader.java new file mode 100644 index 00000000..8f90e4c6 --- /dev/null +++ b/src/main/java/net/md_5/mendax/datainput/IntHeader.java @@ -0,0 +1,21 @@ +package net.md_5.mendax.datainput; + +import java.io.DataInput; +import java.io.IOException; + +class IntHeader extends Instruction { + + private final Instruction child; + + IntHeader(Instruction child) { + this.child = child; + } + + @Override + void read(DataInput in) throws IOException { + int size = in.readInt(); + for (int i = 0; i < size; i++) { + child.read(in); + } + } +} diff --git a/src/main/java/net/md_5/mendax/datainput/Item.java b/src/main/java/net/md_5/mendax/datainput/Item.java new file mode 100644 index 00000000..b3e97b18 --- /dev/null +++ b/src/main/java/net/md_5/mendax/datainput/Item.java @@ -0,0 +1,16 @@ +package net.md_5.mendax.datainput; + +import java.io.DataInput; +import java.io.IOException; + +class Item extends Instruction { + + @Override + void read(DataInput in) throws IOException { + short type = in.readShort(); + if (type >= 0) { + skip(in, 3); + SHORT_BYTE.read(in); + } + } +} diff --git a/src/main/java/net/md_5/mendax/datainput/Jump.java b/src/main/java/net/md_5/mendax/datainput/Jump.java new file mode 100644 index 00000000..a9d2b7f3 --- /dev/null +++ b/src/main/java/net/md_5/mendax/datainput/Jump.java @@ -0,0 +1,21 @@ +package net.md_5.mendax.datainput; + +import java.io.DataInput; +import java.io.IOException; + +class Jump extends Instruction { + + final int len; + + Jump(int len) { + if (len < 0) { + throw new IndexOutOfBoundsException(); + } + this.len = len; + } + + @Override + void read(DataInput in) throws IOException { + skip(in, len); + } +} diff --git a/src/main/java/net/md_5/mendax/datainput/MetaData.java b/src/main/java/net/md_5/mendax/datainput/MetaData.java new file mode 100644 index 00000000..02985f40 --- /dev/null +++ b/src/main/java/net/md_5/mendax/datainput/MetaData.java @@ -0,0 +1,41 @@ +package net.md_5.mendax.datainput; + +import java.io.DataInput; +import java.io.IOException; + +class MetaData extends Instruction { + + @Override + void read(DataInput in) throws IOException { + int x = in.readUnsignedByte(); + while (x != 127) { + int type = x >> 5; + switch (type) { + case 0: + BYTE.read(in); + break; + case 1: + SHORT.read(in); + break; + case 2: + INT.read(in); + break; + case 3: + FLOAT.read(in); + break; + case 4: + STRING.read(in); + break; + case 5: + skip(in, 5); // short, byte, short + break; + case 6: + skip(in, 12); // int, int, int + break; + default: + throw new IllegalArgumentException("Unknown metadata type " + type); + } + x = in.readByte(); + } + } +} diff --git a/src/main/java/net/md_5/mendax/datainput/OptionalMotion.java b/src/main/java/net/md_5/mendax/datainput/OptionalMotion.java new file mode 100644 index 00000000..c1181c84 --- /dev/null +++ b/src/main/java/net/md_5/mendax/datainput/OptionalMotion.java @@ -0,0 +1,15 @@ +package net.md_5.mendax.datainput; + +import java.io.DataInput; +import java.io.IOException; + +public class OptionalMotion extends Instruction { + + @Override + void read(DataInput in) throws IOException { + int data = in.readInt(); + if (data > 0) { + skip(in, 6); + } + } +} diff --git a/src/main/java/net/md_5/mendax/datainput/ShortHeader.java b/src/main/java/net/md_5/mendax/datainput/ShortHeader.java new file mode 100644 index 00000000..d77c2657 --- /dev/null +++ b/src/main/java/net/md_5/mendax/datainput/ShortHeader.java @@ -0,0 +1,21 @@ +package net.md_5.mendax.datainput; + +import java.io.DataInput; +import java.io.IOException; + +class ShortHeader extends Instruction { + + private final Instruction child; + + ShortHeader(Instruction child) { + this.child = child; + } + + @Override + void read(DataInput in) throws IOException { + short size = in.readShort(); + for (short s = 0; s < size; s++) { + child.read(in); + } + } +} diff --git a/src/main/java/net/md_5/mendax/datainput/UnsignedByteByte.java b/src/main/java/net/md_5/mendax/datainput/UnsignedByteByte.java new file mode 100644 index 00000000..46a97ec7 --- /dev/null +++ b/src/main/java/net/md_5/mendax/datainput/UnsignedByteByte.java @@ -0,0 +1,13 @@ +package net.md_5.mendax.datainput; + +import java.io.DataInput; +import java.io.IOException; + +public class UnsignedByteByte extends Instruction { + + @Override + void read(DataInput in) throws IOException { + int size = in.readUnsignedByte(); + skip(in, size); + } +} From 52e81deb58023eac81a95d3c8ef2445f2ef8c1e8 Mon Sep 17 00:00:00 2001 From: md_5 Date: Fri, 26 Oct 2012 17:53:07 +1100 Subject: [PATCH 12/22] Update for 1.4. Please note this is really messed and doesn't seem to work. --- pom.xml | 2 +- src/main/java/net/md_5/mendax/PacketDefinitions.java | 12 ++++++------ .../java/net/md_5/mendax/datainput/MetaData.java | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 698d1020..1f5ea188 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.md-5 mendax - 1.3.2-SNAPSHOT + 1.4.2-SNAPSHOT jar Mendax diff --git a/src/main/java/net/md_5/mendax/PacketDefinitions.java b/src/main/java/net/md_5/mendax/PacketDefinitions.java index f584b1f4..b4c42e12 100644 --- a/src/main/java/net/md_5/mendax/PacketDefinitions.java +++ b/src/main/java/net/md_5/mendax/PacketDefinitions.java @@ -16,7 +16,7 @@ public class PacketDefinitions { opCodes[0x01] = new OpCode[]{INT, STRING, BYTE, BYTE, BYTE, BYTE, BYTE}; opCodes[0x02] = new OpCode[]{BYTE, STRING, STRING, INT}; opCodes[0x03] = new OpCode[]{STRING}; - opCodes[0x04] = new OpCode[]{LONG}; + opCodes[0x04] = new OpCode[]{LONG, LONG}; opCodes[0x05] = new OpCode[]{INT, SHORT, ITEM}; opCodes[0x06] = new OpCode[]{INT, INT, INT}; opCodes[0x07] = new OpCode[]{INT, INT, BOOLEAN}; @@ -33,7 +33,7 @@ public class PacketDefinitions { opCodes[0x12] = new OpCode[]{INT, BYTE}; opCodes[0x13] = new OpCode[]{INT, BYTE}; opCodes[0x14] = new OpCode[]{INT, STRING, INT, INT, INT, BYTE, BYTE, SHORT, METADATA}; - opCodes[0x15] = new OpCode[]{INT, SHORT, BYTE, SHORT, INT, INT, INT, BYTE, BYTE, BYTE}; + opCodes[0x15] = new OpCode[]{INT, ITEM, INT, INT, INT, BYTE, BYTE, BYTE}; opCodes[0x16] = new OpCode[]{INT, INT}; opCodes[0x17] = new OpCode[]{INT, BYTE, INT, INT, INT, OPTIONAL_MOTION}; opCodes[0x18] = new OpCode[]{INT, BYTE, INT, INT, INT, BYTE, BYTE, BYTE, SHORT, SHORT, SHORT, METADATA}; @@ -71,7 +71,7 @@ public class PacketDefinitions { opCodes[0x3A] = null; // Does not exist opCodes[0x3B] = null; // Does not exist opCodes[0x3C] = new OpCode[]{DOUBLE, DOUBLE, DOUBLE, FLOAT, INT_3, FLOAT, FLOAT, FLOAT}; - opCodes[0x3D] = new OpCode[]{INT, INT, BYTE, INT, INT}; + opCodes[0x3D] = new OpCode[]{INT, INT, BYTE, INT, INT, BOOLEAN}; opCodes[0x3E] = new OpCode[]{STRING, INT, INT, INT, FLOAT, BYTE}; // // @@ -87,7 +87,7 @@ public class PacketDefinitions { // opCodes[0x64] = new OpCode[]{BYTE, BYTE, STRING, BYTE}; opCodes[0x65] = new OpCode[]{BYTE}; - opCodes[0x66] = new OpCode[]{BYTE, SHORT, BOOLEAN, SHORT, BOOLEAN, ITEM}; + opCodes[0x66] = new OpCode[]{BYTE, SHORT, BYTE, SHORT, BYTE, ITEM}; opCodes[0x67] = new OpCode[]{BYTE, SHORT, ITEM}; opCodes[0x68] = new OpCode[]{BYTE, SHORT_ITEM}; opCodes[0x69] = new OpCode[]{BYTE, SHORT, SHORT}; @@ -111,7 +111,7 @@ public class PacketDefinitions { opCodes[0xC9] = new OpCode[]{STRING, BOOLEAN, SHORT}; opCodes[0xCA] = new OpCode[]{BYTE, BYTE, BYTE}; opCodes[0xCB] = new OpCode[]{STRING}; - opCodes[0xCC] = new OpCode[]{STRING, BYTE, BYTE, BYTE}; + opCodes[0xCC] = new OpCode[]{STRING, BYTE, BYTE, BYTE, BOOLEAN}; opCodes[0xCD] = new OpCode[]{BYTE}; // // @@ -122,7 +122,7 @@ public class PacketDefinitions { opCodes[0xFB] = null; // Does not exist opCodes[0xFC] = new OpCode[]{SHORT_BYTE, SHORT_BYTE}; opCodes[0xFD] = new OpCode[]{STRING, SHORT_BYTE, SHORT_BYTE}; - opCodes[0xFE] = new OpCode[]{}; + opCodes[0xFE] = new OpCode[]{BYTE}; opCodes[0xFF] = new OpCode[]{STRING}; } } diff --git a/src/main/java/net/md_5/mendax/datainput/MetaData.java b/src/main/java/net/md_5/mendax/datainput/MetaData.java index 02985f40..62d84010 100644 --- a/src/main/java/net/md_5/mendax/datainput/MetaData.java +++ b/src/main/java/net/md_5/mendax/datainput/MetaData.java @@ -27,7 +27,9 @@ class MetaData extends Instruction { STRING.read(in); break; case 5: - skip(in, 5); // short, byte, short + if (in.readShort() > 0) { + skip(in, 3); + } break; case 6: skip(in, 12); // int, int, int From 9e4ecf1ad439d4ee9110f81f8091a3789040e68e Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 28 Oct 2012 16:00:28 +1100 Subject: [PATCH 13/22] Is ammar2 a wizard? --- src/main/java/net/md_5/mendax/datainput/MetaData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/md_5/mendax/datainput/MetaData.java b/src/main/java/net/md_5/mendax/datainput/MetaData.java index 62d84010..521c5d56 100644 --- a/src/main/java/net/md_5/mendax/datainput/MetaData.java +++ b/src/main/java/net/md_5/mendax/datainput/MetaData.java @@ -37,7 +37,7 @@ class MetaData extends Instruction { default: throw new IllegalArgumentException("Unknown metadata type " + type); } - x = in.readByte(); + x = in.readUnsignedByte(); } } } From 3c0f9bc3c44a9ce1949ab3c185afb0ecc902552a Mon Sep 17 00:00:00 2001 From: md_5 Date: Mon, 29 Oct 2012 18:36:25 +1100 Subject: [PATCH 14/22] Because server admins are bitchy we need to support 1.3 as well --- src/main/java/net/md_5/mendax/PacketDefinitions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/md_5/mendax/PacketDefinitions.java b/src/main/java/net/md_5/mendax/PacketDefinitions.java index b4c42e12..c382b2a2 100644 --- a/src/main/java/net/md_5/mendax/PacketDefinitions.java +++ b/src/main/java/net/md_5/mendax/PacketDefinitions.java @@ -122,7 +122,7 @@ public class PacketDefinitions { opCodes[0xFB] = null; // Does not exist opCodes[0xFC] = new OpCode[]{SHORT_BYTE, SHORT_BYTE}; opCodes[0xFD] = new OpCode[]{STRING, SHORT_BYTE, SHORT_BYTE}; - opCodes[0xFE] = new OpCode[]{BYTE}; + opCodes[0xFE] = new OpCode[]{}; // Should be byte, screw you too bitchy server admins! opCodes[0xFF] = new OpCode[]{STRING}; } } From 166fc798f15df7713d15bd2f75f6442d6368a829 Mon Sep 17 00:00:00 2001 From: mbax Date: Wed, 14 Nov 2012 15:00:22 -0500 Subject: [PATCH 15/22] Update to 1.4.4 --- src/main/java/net/md_5/mendax/PacketDefinitions.java | 2 +- src/main/java/net/md_5/mendax/datainput/MetaData.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/md_5/mendax/PacketDefinitions.java b/src/main/java/net/md_5/mendax/PacketDefinitions.java index c382b2a2..967628c2 100644 --- a/src/main/java/net/md_5/mendax/PacketDefinitions.java +++ b/src/main/java/net/md_5/mendax/PacketDefinitions.java @@ -100,7 +100,7 @@ public class PacketDefinitions { // // opCodes[0x82] = new OpCode[]{INT, SHORT, INT, STRING, STRING, STRING, STRING}; - opCodes[0x83] = new OpCode[]{SHORT, SHORT, UBYTE_BYTE}; + opCodes[0x83] = new OpCode[]{SHORT, SHORT, SHORT_BYTE}; opCodes[0x84] = new OpCode[]{INT, SHORT, INT, BYTE, SHORT_BYTE}; // // diff --git a/src/main/java/net/md_5/mendax/datainput/MetaData.java b/src/main/java/net/md_5/mendax/datainput/MetaData.java index 521c5d56..c74fa3ff 100644 --- a/src/main/java/net/md_5/mendax/datainput/MetaData.java +++ b/src/main/java/net/md_5/mendax/datainput/MetaData.java @@ -29,6 +29,10 @@ class MetaData extends Instruction { case 5: if (in.readShort() > 0) { skip(in, 3); + short len = in.readShort(); + if (len > 0 ) { + skip(in, len); + } } break; case 6: From b4661a5c5ffdab2969a3e845d7472c75b160488d Mon Sep 17 00:00:00 2001 From: mbax Date: Thu, 15 Nov 2012 16:08:53 -0500 Subject: [PATCH 16/22] Update version number to 1.4.4 - cosmetic change --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1f5ea188..67aec3b5 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.md-5 mendax - 1.4.2-SNAPSHOT + 1.4.4-SNAPSHOT jar Mendax From 1999076429a9c46e6d116f99c2d89a161a0d6a8b Mon Sep 17 00:00:00 2001 From: md_5 Date: Mon, 19 Nov 2012 19:34:08 +1100 Subject: [PATCH 17/22] Fix potential issue with maps and frames. --- src/main/java/net/md_5/mendax/PacketDefinitions.java | 4 ++-- src/main/java/net/md_5/mendax/datainput/Instruction.java | 2 +- src/main/java/net/md_5/mendax/datainput/MetaData.java | 8 +------- .../{UnsignedByteByte.java => UnsignedShortByte.java} | 4 ++-- 4 files changed, 6 insertions(+), 12 deletions(-) rename src/main/java/net/md_5/mendax/datainput/{UnsignedByteByte.java => UnsignedShortByte.java} (66%) diff --git a/src/main/java/net/md_5/mendax/PacketDefinitions.java b/src/main/java/net/md_5/mendax/PacketDefinitions.java index 967628c2..961b3ade 100644 --- a/src/main/java/net/md_5/mendax/PacketDefinitions.java +++ b/src/main/java/net/md_5/mendax/PacketDefinitions.java @@ -8,7 +8,7 @@ public class PacketDefinitions { public enum OpCode { - BOOLEAN, BULK_CHUNK, BYTE, BYTE_INT, DOUBLE, FLOAT, INT, INT_3, INT_BYTE, ITEM, LONG, METADATA, OPTIONAL_MOTION, SHORT, SHORT_BYTE, SHORT_ITEM, STRING, UBYTE_BYTE + BOOLEAN, BULK_CHUNK, BYTE, BYTE_INT, DOUBLE, FLOAT, INT, INT_3, INT_BYTE, ITEM, LONG, METADATA, OPTIONAL_MOTION, SHORT, SHORT_BYTE, SHORT_ITEM, STRING, USHORT_BYTE } static { @@ -100,7 +100,7 @@ public class PacketDefinitions { // // opCodes[0x82] = new OpCode[]{INT, SHORT, INT, STRING, STRING, STRING, STRING}; - opCodes[0x83] = new OpCode[]{SHORT, SHORT, SHORT_BYTE}; + opCodes[0x83] = new OpCode[]{SHORT, SHORT, USHORT_BYTE}; opCodes[0x84] = new OpCode[]{INT, SHORT, INT, BYTE, SHORT_BYTE}; // // diff --git a/src/main/java/net/md_5/mendax/datainput/Instruction.java b/src/main/java/net/md_5/mendax/datainput/Instruction.java index 323ca752..af1485c1 100644 --- a/src/main/java/net/md_5/mendax/datainput/Instruction.java +++ b/src/main/java/net/md_5/mendax/datainput/Instruction.java @@ -22,7 +22,7 @@ abstract class Instruction { static final Instruction SHORT_BYTE = new ShortHeader(BYTE); static final Instruction SHORT_ITEM = new ShortHeader(ITEM); static final Instruction STRING = new ShortHeader(new Jump(2)); - static final Instruction UBYTE_BYTE = new UnsignedByteByte(); + static final Instruction USHORT_BYTE = new UnsignedShortByte(); // Illegal forward references below this line static final Instruction BYTE_INT = new ByteHeader(INT); diff --git a/src/main/java/net/md_5/mendax/datainput/MetaData.java b/src/main/java/net/md_5/mendax/datainput/MetaData.java index c74fa3ff..bc03f4e6 100644 --- a/src/main/java/net/md_5/mendax/datainput/MetaData.java +++ b/src/main/java/net/md_5/mendax/datainput/MetaData.java @@ -27,13 +27,7 @@ class MetaData extends Instruction { STRING.read(in); break; case 5: - if (in.readShort() > 0) { - skip(in, 3); - short len = in.readShort(); - if (len > 0 ) { - skip(in, len); - } - } + ITEM.read(in); break; case 6: skip(in, 12); // int, int, int diff --git a/src/main/java/net/md_5/mendax/datainput/UnsignedByteByte.java b/src/main/java/net/md_5/mendax/datainput/UnsignedShortByte.java similarity index 66% rename from src/main/java/net/md_5/mendax/datainput/UnsignedByteByte.java rename to src/main/java/net/md_5/mendax/datainput/UnsignedShortByte.java index 46a97ec7..ec881294 100644 --- a/src/main/java/net/md_5/mendax/datainput/UnsignedByteByte.java +++ b/src/main/java/net/md_5/mendax/datainput/UnsignedShortByte.java @@ -3,11 +3,11 @@ package net.md_5.mendax.datainput; import java.io.DataInput; import java.io.IOException; -public class UnsignedByteByte extends Instruction { +public class UnsignedShortByte extends Instruction { @Override void read(DataInput in) throws IOException { - int size = in.readUnsignedByte(); + int size = in.readUnsignedShort(); skip(in, size); } } From 2100b6656673412fcedb6f51ac07dde5501c0b7d Mon Sep 17 00:00:00 2001 From: mbax Date: Thu, 13 Dec 2012 16:31:05 -0500 Subject: [PATCH 18/22] Update to protocol version 51 --- pom.xml | 2 +- src/main/java/net/md_5/mendax/PacketDefinitions.java | 2 +- src/main/java/net/md_5/mendax/datainput/BulkChunk.java | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 67aec3b5..f1e17718 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.md-5 mendax - 1.4.4-SNAPSHOT + 1.4.6-SNAPSHOT jar Mendax diff --git a/src/main/java/net/md_5/mendax/PacketDefinitions.java b/src/main/java/net/md_5/mendax/PacketDefinitions.java index 961b3ade..5861fd8b 100644 --- a/src/main/java/net/md_5/mendax/PacketDefinitions.java +++ b/src/main/java/net/md_5/mendax/PacketDefinitions.java @@ -35,7 +35,7 @@ public class PacketDefinitions { opCodes[0x14] = new OpCode[]{INT, STRING, INT, INT, INT, BYTE, BYTE, SHORT, METADATA}; opCodes[0x15] = new OpCode[]{INT, ITEM, INT, INT, INT, BYTE, BYTE, BYTE}; opCodes[0x16] = new OpCode[]{INT, INT}; - opCodes[0x17] = new OpCode[]{INT, BYTE, INT, INT, INT, OPTIONAL_MOTION}; + opCodes[0x17] = new OpCode[]{INT, BYTE, INT, INT, INT, BYTE, BYTE, OPTIONAL_MOTION}; opCodes[0x18] = new OpCode[]{INT, BYTE, INT, INT, INT, BYTE, BYTE, BYTE, SHORT, SHORT, SHORT, METADATA}; opCodes[0x19] = new OpCode[]{INT, STRING, INT, INT, INT, INT}; opCodes[0x1A] = new OpCode[]{INT, INT, INT, INT, SHORT}; diff --git a/src/main/java/net/md_5/mendax/datainput/BulkChunk.java b/src/main/java/net/md_5/mendax/datainput/BulkChunk.java index 13c71e02..4e2de002 100644 --- a/src/main/java/net/md_5/mendax/datainput/BulkChunk.java +++ b/src/main/java/net/md_5/mendax/datainput/BulkChunk.java @@ -8,7 +8,8 @@ public class BulkChunk extends Instruction { @Override void read(DataInput in) throws IOException { short count = in.readShort(); - INT_BYTE.read(in); - skip(in, count * 12); + int size = in.readInt(); + in.readBoolean(); + skip(in, size + count * 12); } } From 2e8c511f01c07d2ade749a1175a6f49866ff0775 Mon Sep 17 00:00:00 2001 From: md_5 Date: Thu, 24 Jan 2013 20:12:22 +1100 Subject: [PATCH 19/22] No packet 15 anymore. --- src/main/java/net/md_5/mendax/PacketDefinitions.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/net/md_5/mendax/PacketDefinitions.java b/src/main/java/net/md_5/mendax/PacketDefinitions.java index 5861fd8b..89cb2739 100644 --- a/src/main/java/net/md_5/mendax/PacketDefinitions.java +++ b/src/main/java/net/md_5/mendax/PacketDefinitions.java @@ -33,7 +33,6 @@ public class PacketDefinitions { opCodes[0x12] = new OpCode[]{INT, BYTE}; opCodes[0x13] = new OpCode[]{INT, BYTE}; opCodes[0x14] = new OpCode[]{INT, STRING, INT, INT, INT, BYTE, BYTE, SHORT, METADATA}; - opCodes[0x15] = new OpCode[]{INT, ITEM, INT, INT, INT, BYTE, BYTE, BYTE}; opCodes[0x16] = new OpCode[]{INT, INT}; opCodes[0x17] = new OpCode[]{INT, BYTE, INT, INT, INT, BYTE, BYTE, OPTIONAL_MOTION}; opCodes[0x18] = new OpCode[]{INT, BYTE, INT, INT, INT, BYTE, BYTE, BYTE, SHORT, SHORT, SHORT, METADATA}; From 12eff818430fdc5cd31852d7f1ea6d7fbb8082f0 Mon Sep 17 00:00:00 2001 From: md_5 Date: Thu, 24 Jan 2013 20:19:45 +1100 Subject: [PATCH 20/22] Actually a boolean, but still 1 byte so only a visual difference. --- src/main/java/net/md_5/mendax/PacketDefinitions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/md_5/mendax/PacketDefinitions.java b/src/main/java/net/md_5/mendax/PacketDefinitions.java index 89cb2739..b17ad6ea 100644 --- a/src/main/java/net/md_5/mendax/PacketDefinitions.java +++ b/src/main/java/net/md_5/mendax/PacketDefinitions.java @@ -86,7 +86,7 @@ public class PacketDefinitions { // opCodes[0x64] = new OpCode[]{BYTE, BYTE, STRING, BYTE}; opCodes[0x65] = new OpCode[]{BYTE}; - opCodes[0x66] = new OpCode[]{BYTE, SHORT, BYTE, SHORT, BYTE, ITEM}; + opCodes[0x66] = new OpCode[]{BYTE, SHORT, BYTE, SHORT, BOOLEAN, ITEM}; opCodes[0x67] = new OpCode[]{BYTE, SHORT, ITEM}; opCodes[0x68] = new OpCode[]{BYTE, SHORT_ITEM}; opCodes[0x69] = new OpCode[]{BYTE, SHORT, SHORT}; From 684600a423cd1247241f00ffc6895aa814193ad3 Mon Sep 17 00:00:00 2001 From: md_5 Date: Thu, 24 Jan 2013 20:27:26 +1100 Subject: [PATCH 21/22] Potentially dramatically reduce CPU usage at the cost of 1 megabytes of ram across the entire Bungee instance. --- src/main/java/net/md_5/mendax/datainput/Instruction.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/md_5/mendax/datainput/Instruction.java b/src/main/java/net/md_5/mendax/datainput/Instruction.java index af1485c1..9c4e1a17 100644 --- a/src/main/java/net/md_5/mendax/datainput/Instruction.java +++ b/src/main/java/net/md_5/mendax/datainput/Instruction.java @@ -25,12 +25,12 @@ abstract class Instruction { static final Instruction USHORT_BYTE = new UnsignedShortByte(); // Illegal forward references below this line static final Instruction BYTE_INT = new ByteHeader(INT); + // Buffer used to read all skips, make sure it is sufficiently large (1mb packet at the moment) + static final byte[] buf = new byte[1 << 20]; abstract void read(DataInput in) throws IOException; final void skip(DataInput in, int len) throws IOException { - for (int i = 0; i < len; i++) { - in.readUnsignedByte(); - } + in.readFully(buf, 0, len); } } From 6bb9a14cd1547684d0cdaa0d14089860d7c1da7c Mon Sep 17 00:00:00 2001 From: md_5 Date: Fri, 1 Feb 2013 21:33:31 +1100 Subject: [PATCH 22/22] Require a buffer to be passed along. --- .../net/md_5/mendax/datainput/BulkChunk.java | 4 ++-- .../net/md_5/mendax/datainput/ByteHeader.java | 4 ++-- .../mendax/datainput/DataInputPacketReader.java | 4 ++-- .../net/md_5/mendax/datainput/Instruction.java | 8 +++----- .../net/md_5/mendax/datainput/IntHeader.java | 4 ++-- .../java/net/md_5/mendax/datainput/Item.java | 6 +++--- .../java/net/md_5/mendax/datainput/Jump.java | 4 ++-- .../java/net/md_5/mendax/datainput/MetaData.java | 16 ++++++++-------- .../md_5/mendax/datainput/OptionalMotion.java | 4 ++-- .../net/md_5/mendax/datainput/ShortHeader.java | 4 ++-- .../md_5/mendax/datainput/UnsignedShortByte.java | 4 ++-- 11 files changed, 30 insertions(+), 32 deletions(-) diff --git a/src/main/java/net/md_5/mendax/datainput/BulkChunk.java b/src/main/java/net/md_5/mendax/datainput/BulkChunk.java index 4e2de002..a3a9d87c 100644 --- a/src/main/java/net/md_5/mendax/datainput/BulkChunk.java +++ b/src/main/java/net/md_5/mendax/datainput/BulkChunk.java @@ -6,10 +6,10 @@ import java.io.IOException; public class BulkChunk extends Instruction { @Override - void read(DataInput in) throws IOException { + void read(DataInput in, byte[] buffer) throws IOException { short count = in.readShort(); int size = in.readInt(); in.readBoolean(); - skip(in, size + count * 12); + skip(in, buffer, size + count * 12); } } diff --git a/src/main/java/net/md_5/mendax/datainput/ByteHeader.java b/src/main/java/net/md_5/mendax/datainput/ByteHeader.java index c9508e00..a67d41c9 100644 --- a/src/main/java/net/md_5/mendax/datainput/ByteHeader.java +++ b/src/main/java/net/md_5/mendax/datainput/ByteHeader.java @@ -12,10 +12,10 @@ class ByteHeader extends Instruction { } @Override - void read(DataInput in) throws IOException { + void read(DataInput in, byte[] buffer) throws IOException { byte size = in.readByte(); for (byte b = 0; b < size; b++) { - child.read(in); + child.read(in, buffer); } } } diff --git a/src/main/java/net/md_5/mendax/datainput/DataInputPacketReader.java b/src/main/java/net/md_5/mendax/datainput/DataInputPacketReader.java index 0bb1b092..b5e9d42b 100644 --- a/src/main/java/net/md_5/mendax/datainput/DataInputPacketReader.java +++ b/src/main/java/net/md_5/mendax/datainput/DataInputPacketReader.java @@ -47,7 +47,7 @@ public class DataInputPacketReader { } } - public static void readPacket(DataInput in) throws IOException { + public static void readPacket(DataInput in, byte[] buffer) throws IOException { int packetId = in.readUnsignedByte(); Instruction[] packetDef = instructions[packetId]; @@ -56,7 +56,7 @@ public class DataInputPacketReader { } for (Instruction instruction : packetDef) { - instruction.read(in); + instruction.read(in, buffer); } } } diff --git a/src/main/java/net/md_5/mendax/datainput/Instruction.java b/src/main/java/net/md_5/mendax/datainput/Instruction.java index 9c4e1a17..c91cd277 100644 --- a/src/main/java/net/md_5/mendax/datainput/Instruction.java +++ b/src/main/java/net/md_5/mendax/datainput/Instruction.java @@ -25,12 +25,10 @@ abstract class Instruction { static final Instruction USHORT_BYTE = new UnsignedShortByte(); // Illegal forward references below this line static final Instruction BYTE_INT = new ByteHeader(INT); - // Buffer used to read all skips, make sure it is sufficiently large (1mb packet at the moment) - static final byte[] buf = new byte[1 << 20]; - abstract void read(DataInput in) throws IOException; + abstract void read(DataInput in, byte[] buffer) throws IOException; - final void skip(DataInput in, int len) throws IOException { - in.readFully(buf, 0, len); + final void skip(DataInput in, byte[] buffer, int len) throws IOException { + in.readFully(buffer, 0, len); } } diff --git a/src/main/java/net/md_5/mendax/datainput/IntHeader.java b/src/main/java/net/md_5/mendax/datainput/IntHeader.java index 8f90e4c6..c113ea7b 100644 --- a/src/main/java/net/md_5/mendax/datainput/IntHeader.java +++ b/src/main/java/net/md_5/mendax/datainput/IntHeader.java @@ -12,10 +12,10 @@ class IntHeader extends Instruction { } @Override - void read(DataInput in) throws IOException { + void read(DataInput in, byte[] buffer) throws IOException { int size = in.readInt(); for (int i = 0; i < size; i++) { - child.read(in); + child.read(in, buffer); } } } diff --git a/src/main/java/net/md_5/mendax/datainput/Item.java b/src/main/java/net/md_5/mendax/datainput/Item.java index b3e97b18..f32cb4f0 100644 --- a/src/main/java/net/md_5/mendax/datainput/Item.java +++ b/src/main/java/net/md_5/mendax/datainput/Item.java @@ -6,11 +6,11 @@ import java.io.IOException; class Item extends Instruction { @Override - void read(DataInput in) throws IOException { + void read(DataInput in, byte[] buffer) throws IOException { short type = in.readShort(); if (type >= 0) { - skip(in, 3); - SHORT_BYTE.read(in); + skip(in, buffer, 3); + SHORT_BYTE.read(in, buffer); } } } diff --git a/src/main/java/net/md_5/mendax/datainput/Jump.java b/src/main/java/net/md_5/mendax/datainput/Jump.java index a9d2b7f3..23c61d3a 100644 --- a/src/main/java/net/md_5/mendax/datainput/Jump.java +++ b/src/main/java/net/md_5/mendax/datainput/Jump.java @@ -15,7 +15,7 @@ class Jump extends Instruction { } @Override - void read(DataInput in) throws IOException { - skip(in, len); + void read(DataInput in, byte[] buffer) throws IOException { + skip(in, buffer, len); } } diff --git a/src/main/java/net/md_5/mendax/datainput/MetaData.java b/src/main/java/net/md_5/mendax/datainput/MetaData.java index bc03f4e6..78eb2c11 100644 --- a/src/main/java/net/md_5/mendax/datainput/MetaData.java +++ b/src/main/java/net/md_5/mendax/datainput/MetaData.java @@ -6,31 +6,31 @@ import java.io.IOException; class MetaData extends Instruction { @Override - void read(DataInput in) throws IOException { + void read(DataInput in, byte[] buffer) throws IOException { int x = in.readUnsignedByte(); while (x != 127) { int type = x >> 5; switch (type) { case 0: - BYTE.read(in); + BYTE.read(in, buffer); break; case 1: - SHORT.read(in); + SHORT.read(in, buffer); break; case 2: - INT.read(in); + INT.read(in, buffer); break; case 3: - FLOAT.read(in); + FLOAT.read(in, buffer); break; case 4: - STRING.read(in); + STRING.read(in, buffer); break; case 5: - ITEM.read(in); + ITEM.read(in, buffer); break; case 6: - skip(in, 12); // int, int, int + skip(in, buffer, 12); // int, int, int break; default: throw new IllegalArgumentException("Unknown metadata type " + type); diff --git a/src/main/java/net/md_5/mendax/datainput/OptionalMotion.java b/src/main/java/net/md_5/mendax/datainput/OptionalMotion.java index c1181c84..4a8f8018 100644 --- a/src/main/java/net/md_5/mendax/datainput/OptionalMotion.java +++ b/src/main/java/net/md_5/mendax/datainput/OptionalMotion.java @@ -6,10 +6,10 @@ import java.io.IOException; public class OptionalMotion extends Instruction { @Override - void read(DataInput in) throws IOException { + void read(DataInput in, byte[] buffer) throws IOException { int data = in.readInt(); if (data > 0) { - skip(in, 6); + skip(in, buffer, 6); } } } diff --git a/src/main/java/net/md_5/mendax/datainput/ShortHeader.java b/src/main/java/net/md_5/mendax/datainput/ShortHeader.java index d77c2657..442a872b 100644 --- a/src/main/java/net/md_5/mendax/datainput/ShortHeader.java +++ b/src/main/java/net/md_5/mendax/datainput/ShortHeader.java @@ -12,10 +12,10 @@ class ShortHeader extends Instruction { } @Override - void read(DataInput in) throws IOException { + void read(DataInput in, byte[] buffer) throws IOException { short size = in.readShort(); for (short s = 0; s < size; s++) { - child.read(in); + child.read(in, buffer); } } } diff --git a/src/main/java/net/md_5/mendax/datainput/UnsignedShortByte.java b/src/main/java/net/md_5/mendax/datainput/UnsignedShortByte.java index ec881294..70b4448f 100644 --- a/src/main/java/net/md_5/mendax/datainput/UnsignedShortByte.java +++ b/src/main/java/net/md_5/mendax/datainput/UnsignedShortByte.java @@ -6,8 +6,8 @@ import java.io.IOException; public class UnsignedShortByte extends Instruction { @Override - void read(DataInput in) throws IOException { + void read(DataInput in, byte[] buffer) throws IOException { int size = in.readUnsignedShort(); - skip(in, size); + skip(in, buffer, size); } }