From 83ce7a0f6bdaa9cb45263f6420e06ba9d8826cc6 Mon Sep 17 00:00:00 2001
From: UnfamiliarLegacy <74633542+UnfamiliarLegacy@users.noreply.github.com>
Date: Sat, 22 Jun 2024 01:33:31 +0200
Subject: [PATCH] Add simple support for packet expressions
---
G-Earth/pom.xml | 6 +
.../main/java/gearth/protocol/HPacket.java | 14 ++-
.../java/gearth/protocol/HPacketFormat.java | 50 ++++++++
.../shockwave/ShockwavePacketHandler.java | 1 -
.../shockwave/packets/ShockPacket.java | 111 ++++++++++++++----
.../packets/ShockPacketIncoming.java | 64 ++++++++++
.../packets/ShockPacketOutgoing.java | 62 ++++++++++
.../packets/ShockPacketUnsupported.java | 4 +
.../PacketReplaceWriter.java | 9 ++
.../PacketStringUtils.java | 111 ++++++++++++------
.../subforms/injection/InjectedPackets.java | 15 ++-
.../injection/InjectionController.java | 27 +++--
.../src/test/java/TestPacketStringUtils.java | 53 +++++++++
13 files changed, 445 insertions(+), 82 deletions(-)
create mode 100644 G-Earth/src/main/java/gearth/protocol/HPacketFormat.java
create mode 100644 G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacketIncoming.java
create mode 100644 G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacketOutgoing.java
create mode 100644 G-Earth/src/main/java/gearth/services/packet_representation/PacketReplaceWriter.java
create mode 100644 G-Earth/src/test/java/TestPacketStringUtils.java
diff --git a/G-Earth/pom.xml b/G-Earth/pom.xml
index cd15f4c..7e199a3 100644
--- a/G-Earth/pom.xml
+++ b/G-Earth/pom.xml
@@ -299,6 +299,12 @@
logback-classic
${logback.version}
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ 5.10.2
+ test
+
diff --git a/G-Earth/src/main/java/gearth/protocol/HPacket.java b/G-Earth/src/main/java/gearth/protocol/HPacket.java
index bfe448f..7d5a8ca 100644
--- a/G-Earth/src/main/java/gearth/protocol/HPacket.java
+++ b/G-Earth/src/main/java/gearth/protocol/HPacket.java
@@ -27,14 +27,19 @@ public class HPacket implements StringifyAble {
public HPacket(byte[] packet) {
packetInBytes = packet.clone();
}
+
public HPacket(HPacket packet) {
packetInBytes = packet.packetInBytes.clone();
isEdited = packet.isEdited;
}
public HPacket(String packet) {
+ this(packet, HPacketFormat.EVA_WIRE);
+ }
+
+ public HPacket(String packet, HPacketFormat format) {
try {
- HPacket packetFromString = PacketStringUtils.fromString(packet);
+ HPacket packetFromString = PacketStringUtils.fromString(packet, format);
packetInBytes = packetFromString.packetInBytes;
identifier = packetFromString.identifier;
identifierDirection = packetFromString.identifierDirection;
@@ -45,7 +50,7 @@ public class HPacket implements StringifyAble {
public HPacket(int header) {
packetInBytes = new byte[]{0,0,0,2,0,0};
- replaceShort(4, (short)header);
+ replacePacketId((short)header);
isEdited = false;
}
@@ -132,7 +137,7 @@ public class HPacket implements StringifyAble {
}
boolean wasEdited = isEdited;
- replaceShort(4, (short)(packetInfo.getHeaderId()));
+ replacePacketId((short)(packetInfo.getHeaderId()));
identifier = null;
isEdited = wasEdited;
@@ -329,6 +334,9 @@ public class HPacket implements StringifyAble {
return (readByte(index) != 0);
}
+ protected void replacePacketId(short headerId) {
+ replaceShort(4, headerId);
+ }
public HPacket replaceBoolean(int index, boolean b) {
isEdited = true;
diff --git a/G-Earth/src/main/java/gearth/protocol/HPacketFormat.java b/G-Earth/src/main/java/gearth/protocol/HPacketFormat.java
new file mode 100644
index 0000000..37bcf99
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/protocol/HPacketFormat.java
@@ -0,0 +1,50 @@
+package gearth.protocol;
+
+import gearth.protocol.packethandler.shockwave.packets.ShockPacketIncoming;
+import gearth.protocol.packethandler.shockwave.packets.ShockPacketOutgoing;
+
+public enum HPacketFormat {
+
+ EVA_WIRE,
+ WEDGIE_INCOMING,
+ WEDGIE_OUTGOING;
+
+ public HPacket createPacket(String data) {
+ switch (this) {
+ case EVA_WIRE:
+ return new HPacket(data);
+ case WEDGIE_INCOMING:
+ return new ShockPacketIncoming(data);
+ case WEDGIE_OUTGOING:
+ return new ShockPacketOutgoing(data);
+ default:
+ throw new IllegalStateException("Unexpected value: " + this);
+ }
+ }
+
+ public HPacket createPacket(int headerId) {
+ switch (this) {
+ case EVA_WIRE:
+ return new HPacket(headerId);
+ case WEDGIE_INCOMING:
+ return new ShockPacketIncoming(headerId);
+ case WEDGIE_OUTGOING:
+ return new ShockPacketOutgoing(headerId);
+ default:
+ throw new IllegalStateException("Unexpected value: " + this);
+ }
+ }
+
+ public HPacket createPacket(byte[] packet) {
+ switch (this) {
+ case EVA_WIRE:
+ return new HPacket(packet);
+ case WEDGIE_INCOMING:
+ return new ShockPacketIncoming(packet);
+ case WEDGIE_OUTGOING:
+ return new ShockPacketOutgoing(packet);
+ default:
+ throw new IllegalStateException("Unexpected value: " + this);
+ }
+ }
+}
diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/ShockwavePacketHandler.java b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/ShockwavePacketHandler.java
index 4571ddb..111e279 100644
--- a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/ShockwavePacketHandler.java
+++ b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/ShockwavePacketHandler.java
@@ -15,7 +15,6 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
public abstract class ShockwavePacketHandler extends PacketHandler {
diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacket.java b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacket.java
index 63a338f..eabb424 100644
--- a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacket.java
+++ b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacket.java
@@ -3,10 +3,12 @@ package gearth.protocol.packethandler.shockwave.packets;
import gearth.encoding.Base64Encoding;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
+import gearth.protocol.HPacketFormat;
import gearth.services.packet_info.PacketInfoManager;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
+import java.security.InvalidParameterException;
public class ShockPacket extends HPacket {
public ShockPacket(byte[] packet) {
@@ -19,8 +21,8 @@ public class ShockPacket extends HPacket {
readIndex = 2;
}
- public ShockPacket(String packet) {
- super(packet);
+ public ShockPacket(String packet, HPacketFormat format) {
+ super(packet, format);
readIndex = 2;
}
@@ -29,6 +31,89 @@ public class ShockPacket extends HPacket {
readIndex = 2;
}
+ @Override
+ public HPacket appendBoolean(boolean b) {
+ throw new ShockPacketUnsupported();
+ }
+
+ @Override
+ public HPacket appendByte(byte b) {
+ return super.appendByte(b);
+ }
+
+ @Override
+ public HPacket appendBytes(byte[] bytes) {
+ return super.appendBytes(bytes);
+ }
+
+ @Override
+ public HPacket appendInt(int i) {
+ throw new ShockPacketUnsupported();
+ }
+
+ @Override
+ public HPacket appendUShort(int ushort) {
+ throw new ShockPacketUnsupported();
+ }
+
+ @Override
+ public HPacket appendShort(short s) {
+ throw new ShockPacketUnsupported();
+ }
+
+ @Override
+ public HPacket appendLong(long l) {
+ throw new ShockPacketUnsupported();
+ }
+
+ @Override
+ public HPacket appendDouble(double d) {
+ throw new ShockPacketUnsupported();
+ }
+
+ @Override
+ public HPacket appendFloat(float f) {
+ throw new ShockPacketUnsupported();
+ }
+
+ @Override
+ public HPacket appendString(String s, Charset charset) {
+ throw new ShockPacketUnsupported();
+ }
+
+ @Override
+ public HPacket appendString(String s) {
+ throw new ShockPacketUnsupported();
+ }
+
+ @Override
+ public HPacket appendLongString(String s, Charset charset) {
+ throw new ShockPacketUnsupported();
+ }
+
+ @Override
+ public HPacket appendLongString(String s) {
+ throw new ShockPacketUnsupported();
+ }
+
+ @Override
+ public HPacket appendObjects(Object... objects) {
+ throw new ShockPacketUnsupported();
+ }
+
+ @Override
+ public HPacket appendObject(Object o) throws InvalidParameterException {
+ throw new ShockPacketUnsupported();
+ }
+
+ @Override
+ protected void replacePacketId(short headerId) {
+ final byte[] header = Base64Encoding.encode(headerId, 2);
+
+ this.packetInBytes[0] = header[0];
+ this.packetInBytes[1] = header[1];
+ }
+
@Override
public int headerId() {
final String header = new String(this.readBytes(2, 0), StandardCharsets.ISO_8859_1);
@@ -42,28 +127,6 @@ public class ShockPacket extends HPacket {
return this.packetInBytes.length;
}
- @Override
- public HPacket appendUShort(int ushort) {
- isEdited = true;
- appendBytes(Base64Encoding.encode(ushort, 2));
- return this;
- }
-
- @Override
- public HPacket appendString(String s) {
- return appendString(s, StandardCharsets.ISO_8859_1);
- }
-
- @Override
- public HPacket appendString(String s, Charset charset) {
- isEdited = true;
-
- final byte[] data = s.getBytes(charset);
- appendUShort(data.length);
- appendBytes(data);
- return this;
- }
-
@Override
public HPacket copy() {
return new ShockPacket(this);
diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacketIncoming.java b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacketIncoming.java
new file mode 100644
index 0000000..66c95ec
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacketIncoming.java
@@ -0,0 +1,64 @@
+package gearth.protocol.packethandler.shockwave.packets;
+
+import gearth.encoding.Base64Encoding;
+import gearth.encoding.VL64Encoding;
+import gearth.protocol.HPacket;
+import gearth.protocol.HPacketFormat;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+// Server to Client
+public class ShockPacketIncoming extends ShockPacket {
+ public ShockPacketIncoming(byte[] packet) {
+ super(packet);
+ }
+
+ public ShockPacketIncoming(HPacket packet) {
+ super(packet);
+ }
+
+ public ShockPacketIncoming(String packet) {
+ super(packet, HPacketFormat.WEDGIE_INCOMING);
+ }
+
+ public ShockPacketIncoming(int header) {
+ super(header);
+ }
+
+ @Override
+ public HPacket appendBoolean(boolean b) {
+ isEdited = true;
+ appendBytes(VL64Encoding.encode(b ? 1 : 0));
+ return this;
+ }
+
+ @Override
+ public HPacket appendUShort(int ushort) {
+ isEdited = true;
+ appendBytes(VL64Encoding.encode(ushort));
+ return this;
+ }
+
+ @Override
+ public HPacket appendInt(int value) {
+ isEdited = true;
+ appendBytes(VL64Encoding.encode(value));
+ return this;
+ }
+
+ @Override
+ public HPacket appendString(String s) {
+ return appendString(s, StandardCharsets.ISO_8859_1);
+ }
+
+ @Override
+ public HPacket appendString(String s, Charset charset) {
+ isEdited = true;
+
+ final byte[] data = s.getBytes(charset);
+ appendBytes(data);
+ appendByte((byte) 2);
+ return this;
+ }
+}
diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacketOutgoing.java b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacketOutgoing.java
new file mode 100644
index 0000000..c44e25b
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacketOutgoing.java
@@ -0,0 +1,62 @@
+package gearth.protocol.packethandler.shockwave.packets;
+
+import gearth.encoding.Base64Encoding;
+import gearth.encoding.VL64Encoding;
+import gearth.protocol.HPacket;
+import gearth.protocol.HPacketFormat;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+// Client to Server
+public class ShockPacketOutgoing extends ShockPacket {
+ public ShockPacketOutgoing(byte[] packet) {
+ super(packet);
+ }
+
+ public ShockPacketOutgoing(HPacket packet) {
+ super(packet);
+ }
+
+ public ShockPacketOutgoing(String packet) {
+ super(packet, HPacketFormat.WEDGIE_OUTGOING);
+ }
+
+ public ShockPacketOutgoing(int header) {
+ super(header);
+ }
+
+ @Override
+ public HPacket appendBoolean(boolean b) {
+ return appendInt(b ? 1 : 0);
+ }
+
+ @Override
+ public HPacket appendUShort(int ushort) {
+ isEdited = true;
+ appendBytes(Base64Encoding.encode(ushort, 2));
+ return this;
+ }
+
+ @Override
+ public HPacket appendInt(int value) {
+ isEdited = true;
+ appendBytes(VL64Encoding.encode(value));
+ return this;
+ }
+
+ @Override
+ public HPacket appendString(String s) {
+ return appendString(s, StandardCharsets.ISO_8859_1);
+ }
+
+ @Override
+ public HPacket appendString(String s, Charset charset) {
+ isEdited = true;
+
+ final byte[] data = s.getBytes(charset);
+ appendUShort(data.length);
+ appendBytes(data);
+ return this;
+ }
+}
diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacketUnsupported.java b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacketUnsupported.java
index b5c00b8..7d67f2b 100644
--- a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacketUnsupported.java
+++ b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacketUnsupported.java
@@ -1,6 +1,10 @@
package gearth.protocol.packethandler.shockwave.packets;
public class ShockPacketUnsupported extends UnsupportedOperationException {
+ public ShockPacketUnsupported() {
+ super();
+ }
+
public ShockPacketUnsupported(String message) {
super(message);
}
diff --git a/G-Earth/src/main/java/gearth/services/packet_representation/PacketReplaceWriter.java b/G-Earth/src/main/java/gearth/services/packet_representation/PacketReplaceWriter.java
new file mode 100644
index 0000000..8cef45d
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/services/packet_representation/PacketReplaceWriter.java
@@ -0,0 +1,9 @@
+package gearth.services.packet_representation;
+
+import gearth.protocol.HPacket;
+
+public interface PacketReplaceWriter {
+
+ void write(HPacket temp, String value);
+
+}
diff --git a/G-Earth/src/main/java/gearth/services/packet_representation/PacketStringUtils.java b/G-Earth/src/main/java/gearth/services/packet_representation/PacketStringUtils.java
index 9fa001f..d93871a 100644
--- a/G-Earth/src/main/java/gearth/services/packet_representation/PacketStringUtils.java
+++ b/G-Earth/src/main/java/gearth/services/packet_representation/PacketStringUtils.java
@@ -1,6 +1,9 @@
package gearth.services.packet_representation;
+import gearth.encoding.Base64Encoding;
+import gearth.encoding.VL64Encoding;
import gearth.protocol.HMessage;
+import gearth.protocol.HPacketFormat;
import gearth.services.packet_info.PacketInfo;
import gearth.services.packet_representation.prediction.StructurePredictor;
import gearth.protocol.HPacket;
@@ -14,8 +17,7 @@ import java.util.regex.Pattern;
// for all the logistics behind bytes-string conversion
public class PacketStringUtils {
- private static String replaceAll(String templateText, String regex,
- Function replacer) {
+ private static String replaceAll(String templateText, String regex, Function replacer) {
Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
Matcher matcher = pattern.matcher(templateText);
StringBuffer result = new StringBuffer();
@@ -29,35 +31,67 @@ public class PacketStringUtils {
return result.toString();
}
+ private static String replaceWithFormat(HPacketFormat format, String templateText, String regex, PacketReplaceWriter writer) {
+ return replaceAll(templateText, regex, m -> {
+ // Create temp packet.
+ final HPacket temp = format.createPacket(0);
+ final int sizeBefore = temp.getBytesLength();
+ // Write the value to the temp packet.
+ writer.write(temp, m.group(1));
+
+ // Calculate the size of the value.
+ final int sizeAfter = temp.getBytesLength();
+ final int size = sizeAfter - sizeBefore;
+
+ // Return the value in the format.
+ return toString(temp.readBytes(size));
+ });
+ }
+
+ @Deprecated
public static HPacket fromString(String packet) throws InvalidPacketException {
+ return fromString(packet, HPacketFormat.EVA_WIRE);
+ }
+
+ public static HPacket fromString(String packet, HPacketFormat format) throws InvalidPacketException {
boolean fixLengthLater = false;
- if (packet.startsWith("{h:")) {
- fixLengthLater = true;
+
+ if (format != HPacketFormat.EVA_WIRE) {
+ packet = replaceWithFormat(format, packet, "\\{s:(-?[0-9]+)}", (temp, value) -> temp.appendUShort(Short.parseShort(value)));
+ packet = replaceWithFormat(format, packet, "\\{i:(-?[0-9]+)}", (temp, value) -> temp.appendInt(Integer.parseInt(value)));
+ packet = replaceWithFormat(format, packet, "\\{b:([Ff]alse|[Tt]rue)}", (temp, value) -> temp.appendBoolean(value.equalsIgnoreCase("true")));
+
+ packet = replaceAll(packet, "\\{b:([0-9]{1,3})}", m -> "[" + Integer.parseInt(m.group(1)) + "]");
+ packet = replaceAll(packet, "\\{h:(-?[0-9]+)}", m -> toString(Base64Encoding.encode(Short.parseShort(m.group(1)), 2)));
+ } else {
+ if (packet.startsWith("{h:")) {
+ fixLengthLater = true;
+ }
+
+ // note: in String expressions {s:"string"}, character " needs to be backslashed -> \" if used in string
+ packet = replaceAll(packet, "\\{i:(-?[0-9]+)}",
+ m -> toString(ByteBuffer.allocate(4).putInt(Integer.parseInt(m.group(1))).array()));
+
+ packet = replaceAll(packet, "\\{l:(-?[0-9]+)}",
+ m -> toString(ByteBuffer.allocate(8).putLong(Long.parseLong(m.group(1))).array()));
+
+ packet = replaceAll(packet, "\\{d:(-?[0-9]*\\.[0-9]*)}",
+ m -> toString(ByteBuffer.allocate(8).putDouble(Double.parseDouble(m.group(1))).array()));
+
+ packet = replaceAll(packet, "\\{u:([0-9]+)}",
+ m -> "[" + (Integer.parseInt(m.group(1))/256) + "][" + (Integer.parseInt(m.group(1)) % 256) + "]");
+
+ packet = replaceAll(packet, "\\{h:(-?[0-9]+)}",
+ m -> toString(ByteBuffer.allocate(2).putShort(Short.parseShort(m.group(1))).array()));
+
+ packet = replaceAll(packet, "\\{b:([Ff]alse|[Tt]rue)}",
+ m -> m.group(1).toLowerCase().equals("true") ? "[1]" : "[0]");
+
+ packet = replaceAll(packet, "\\{b:([0-9]{1,3})}",
+ m -> "[" + Integer.parseInt(m.group(1)) + "]");
}
- // note: in String expressions {s:"string"}, character " needs to be backslashed -> \" if used in string
- packet = replaceAll(packet, "\\{i:(-?[0-9]+)}",
- m -> toString(ByteBuffer.allocate(4).putInt(Integer.parseInt(m.group(1))).array()));
-
- packet = replaceAll(packet, "\\{l:(-?[0-9]+)}",
- m -> toString(ByteBuffer.allocate(8).putLong(Long.parseLong(m.group(1))).array()));
-
- packet = replaceAll(packet, "\\{d:(-?[0-9]*\\.[0-9]*)}",
- m -> toString(ByteBuffer.allocate(8).putDouble(Double.parseDouble(m.group(1))).array()));
-
- packet = replaceAll(packet, "\\{u:([0-9]+)}",
- m -> "[" + (Integer.parseInt(m.group(1))/256) + "][" + (Integer.parseInt(m.group(1)) % 256) + "]");
-
- packet = replaceAll(packet, "\\{h:(-?[0-9]+)}",
- m -> toString(ByteBuffer.allocate(2).putShort(Short.parseShort(m.group(1))).array()));
-
- packet = replaceAll(packet, "\\{b:([Ff]alse|[Tt]rue)}",
- m -> m.group(1).toLowerCase().equals("true") ? "[1]" : "[0]");
-
- packet = replaceAll(packet, "\\{b:([0-9]{1,3})}",
- m -> "[" + Integer.parseInt(m.group(1)) + "]");
-
// results in regex stackoverflow for long strings
// packet = replaceAll(packet, "\\{s:\"(([^\"]|(\\\\\"))*)\"}",
// m -> {
@@ -127,12 +161,16 @@ public class PacketStringUtils {
actualString.append(match);
String latin = new String(actualString.toString().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
- HPacket temp = new HPacket(0);
- temp.appendString(latin, StandardCharsets.ISO_8859_1);
+ HPacket temp = format.createPacket(0);
- packet = packet.substring(0, start) +
- toString(temp.readBytes(latin.length() + 2, 6)) +
- packet.substring(end + 2);
+ int sizeBefore = temp.getBytesLength();
+ temp.appendString(latin, StandardCharsets.ISO_8859_1);
+ int sizeAfter = temp.getBytesLength();
+ int size = sizeAfter - sizeBefore;
+
+ packet = packet.substring(0, start)
+ + toString(temp.readBytes(size))
+ + packet.substring(end + 2);
}
String[] identifier = {null};
@@ -162,14 +200,14 @@ public class PacketStringUtils {
}
byte[] packetInBytes = packet.getBytes(StandardCharsets.ISO_8859_1);
- if (fixLengthLater) {
+ if (fixLengthLater && format == HPacketFormat.EVA_WIRE) {
byte[] combined = new byte[4 + packetInBytes.length];
System.arraycopy(packetInBytes,0, combined, 4, packetInBytes.length);
packetInBytes = combined;
}
- HPacket hPacket = new HPacket(packetInBytes);
- if (fixLengthLater) {
+ HPacket hPacket = format.createPacket(packetInBytes);
+ if (fixLengthLater && format == HPacketFormat.EVA_WIRE) {
hPacket.fixLength();
}
if (identifier[0] != null) {
@@ -179,6 +217,7 @@ public class PacketStringUtils {
}
return hPacket;
}
+
public static String toString(byte[] packet) {
StringBuilder teststring = new StringBuilder();
for (byte x : packet) {
@@ -292,6 +331,10 @@ public class PacketStringUtils {
HPacket p3 = fromString("{h:2266}{s:\"¥\"}{i:0}{i:0}");
System.out.println(p3);
+
+ // IPAKQA
+ System.out.println(VL64Encoding.decode("K".getBytes()));
+ //System.out.println(VL64Encoding.decode("K".getBytes()));
}
}
diff --git a/G-Earth/src/main/java/gearth/ui/subforms/injection/InjectedPackets.java b/G-Earth/src/main/java/gearth/ui/subforms/injection/InjectedPackets.java
index 94318f2..1e95560 100644
--- a/G-Earth/src/main/java/gearth/ui/subforms/injection/InjectedPackets.java
+++ b/G-Earth/src/main/java/gearth/ui/subforms/injection/InjectedPackets.java
@@ -3,8 +3,7 @@ package gearth.ui.subforms.injection;
import gearth.misc.StringifyAble;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
-import gearth.protocol.connection.HClient;
-import gearth.protocol.packethandler.shockwave.packets.ShockPacket;
+import gearth.protocol.HPacketFormat;
import gearth.services.packet_info.PacketInfo;
import gearth.services.packet_info.PacketInfoManager;
import gearth.ui.translations.LanguageBundle;
@@ -16,17 +15,17 @@ import java.util.Optional;
public class InjectedPackets implements StringifyAble {
- private HClient client;
+ private HPacketFormat packetFormat;
private String packetsAsString;
private String description;
- public InjectedPackets(String packetsAsString, int amountPackets, PacketInfoManager packetInfoManager, HMessage.Direction direction, HClient client) {
+ public InjectedPackets(String packetsAsString, int amountPackets, PacketInfoManager packetInfoManager, HMessage.Direction direction, HPacketFormat packetFormat) {
String description;
if (amountPackets > 1) {
description = String.format("(%s: %d, %s: %d)", LanguageBundle.get("tab.injection.description.packets"), amountPackets, LanguageBundle.get("tab.injection.description.length"), packetsAsString.length());
}
else { // assume 1 packet
- HPacket packet = client == HClient.SHOCKWAVE ? new ShockPacket(packetsAsString) : new HPacket(packetsAsString);
+ HPacket packet = packetFormat.createPacket(packetsAsString);
String identifier = null;
if (!packet.isPacketComplete()) {
identifier = packet.packetIncompleteIdentifier();
@@ -48,7 +47,7 @@ public class InjectedPackets implements StringifyAble {
}
}
- this.client = client;
+ this.packetFormat = packetFormat;
this.description = description;
this.packetsAsString = packetsAsString;
}
@@ -68,9 +67,9 @@ public class InjectedPackets implements StringifyAble {
@Override
public String stringify() {
Map info = new HashMap<>();
+ info.put("packetFormat", packetFormat.toString());
info.put("packetsAsString", packetsAsString);
info.put("description", description);
- info.put("clientType", client.toString());
return new JSONObject(info).toString();
}
@@ -78,9 +77,9 @@ public class InjectedPackets implements StringifyAble {
@Override
public void constructFromString(String str) {
JSONObject jsonObject = new JSONObject(str);
+ this.packetFormat = jsonObject.has("packetFormat") ? HPacketFormat.valueOf(jsonObject.getString("packetFormat")) : HPacketFormat.EVA_WIRE;
this.packetsAsString = jsonObject.getString("packetsAsString");
this.description = jsonObject.getString("description");
- this.client = jsonObject.has("clientType") ? HClient.valueOf(jsonObject.getString("clientType")) : null;
}
@Override
diff --git a/G-Earth/src/main/java/gearth/ui/subforms/injection/InjectionController.java b/G-Earth/src/main/java/gearth/ui/subforms/injection/InjectionController.java
index b500f7c..55d6d87 100644
--- a/G-Earth/src/main/java/gearth/ui/subforms/injection/InjectionController.java
+++ b/G-Earth/src/main/java/gearth/ui/subforms/injection/InjectionController.java
@@ -4,6 +4,7 @@ import gearth.misc.Cacher;
import gearth.protocol.HConnection;
import gearth.protocol.HMessage;
import gearth.protocol.HPacket;
+import gearth.protocol.HPacketFormat;
import gearth.protocol.connection.HClient;
import gearth.protocol.packethandler.shockwave.packets.ShockPacket;
import gearth.ui.SubForm;
@@ -93,7 +94,7 @@ public class InjectionController extends SubForm {
return unmatchedBrace;
}
- private static HPacket[] parsePackets(HClient client, String fullText) {
+ private static HPacket[] parsePackets(HPacketFormat format, String fullText) {
LinkedList packets = new LinkedList<>();
String[] lines = fullText.split("\n");
@@ -102,9 +103,7 @@ public class InjectionController extends SubForm {
while (isPacketIncomplete(line) && i < lines.length - 1)
line += '\n' + lines[++i];
- packets.add(client == HClient.SHOCKWAVE
- ? new ShockPacket(line)
- : new HPacket(line));
+ packets.add(format.createPacket(line));
}
return packets.toArray(new HPacket[0]);
}
@@ -117,7 +116,9 @@ public class InjectionController extends SubForm {
lbl_corruption.getStyleClass().clear();
lbl_corruption.getStyleClass().add("not-corrupted-label");
- HPacket[] packets = parsePackets(getHConnection().getClientType(), inputPacket.getText());
+ // For Shockwave parse with either WEDGIE_INCOMING or WEDGIE_OUTGOING, both will validate the same expression.
+ HPacketFormat format = getHConnection().getClientType() == HClient.FLASH ? HPacketFormat.EVA_WIRE : HPacketFormat.WEDGIE_INCOMING;
+ HPacket[] packets = parsePackets(format, inputPacket.getText());
if (packets.length == 0) {
dirty = true;
@@ -202,27 +203,29 @@ public class InjectionController extends SubForm {
}
public void sendToServer_clicked(ActionEvent actionEvent) {
- HPacket[] packets = parsePackets(getHConnection().getClientType(), inputPacket.getText());
+ HPacketFormat format = getHConnection().getClientType() == HClient.FLASH ? HPacketFormat.EVA_WIRE : HPacketFormat.WEDGIE_OUTGOING;
+ HPacket[] packets = parsePackets(format, inputPacket.getText());
for (HPacket packet : packets) {
getHConnection().sendToServer(packet);
writeToLog(Color.BLUE, String.format("SS -> %s: %d", LanguageBundle.get("tab.injection.log.packetwithid"), packet.headerId()));
}
- addToHistory(packets, inputPacket.getText(), HMessage.Direction.TOSERVER);
+ addToHistory(format, packets, inputPacket.getText(), HMessage.Direction.TOSERVER);
}
public void sendToClient_clicked(ActionEvent actionEvent) {
- HPacket[] packets = parsePackets(getHConnection().getClientType(), inputPacket.getText());
+ HPacketFormat format = getHConnection().getClientType() == HClient.FLASH ? HPacketFormat.EVA_WIRE : HPacketFormat.WEDGIE_INCOMING;
+ HPacket[] packets = parsePackets(format, inputPacket.getText());
for (HPacket packet : packets) {
getHConnection().sendToClient(packet);
writeToLog(Color.RED, String.format("CS -> %s: %d", LanguageBundle.get("tab.injection.log.packetwithid"), packet.headerId()));
}
- addToHistory(packets, inputPacket.getText(), HMessage.Direction.TOCLIENT);
+ addToHistory(format, packets, inputPacket.getText(), HMessage.Direction.TOCLIENT);
}
- private void addToHistory(HPacket[] packets, String packetsAsString, HMessage.Direction direction) {
- InjectedPackets injectedPackets = new InjectedPackets(packetsAsString, packets.length, getHConnection().getPacketInfoManager(), direction, getHConnection().getClientType());
+ private void addToHistory(HPacketFormat format, HPacket[] packets, String packetsAsString, HMessage.Direction direction) {
+ InjectedPackets injectedPackets = new InjectedPackets(packetsAsString, packets.length, getHConnection().getPacketInfoManager(), direction, format);
List newHistory = new ArrayList<>();
newHistory.add(injectedPackets);
@@ -276,7 +279,7 @@ public class InjectionController extends SubForm {
}
public static void main(String[] args) {
- HPacket[] packets = parsePackets(HClient.FLASH, "{l}{h:3}{i:967585}{i:9589}{s:\"furni_inscriptionfuckfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss\"}{s:\"sirjonasxx-II\"}{s:\"\"}{i:188}{i:0}{i:0}{b:false}");
+ HPacket[] packets = parsePackets(HPacketFormat.EVA_WIRE, "{l}{h:3}{i:967585}{i:9589}{s:\"furni_inscriptionfuckfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionfurni_inscriptionsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss\"}{s:\"sirjonasxx-II\"}{s:\"\"}{i:188}{i:0}{i:0}{b:false}");
System.out.println(new HPacket("{l}{h:2550}{s:\"ClientPerf\"\"ormance\\\"}\"}{s:\"23\"}{s:\"fps\"}{s:\"Avatars: 1, Objects: 0\"}{i:76970180}").toExpression());
System.out.println("hi");
diff --git a/G-Earth/src/test/java/TestPacketStringUtils.java b/G-Earth/src/test/java/TestPacketStringUtils.java
new file mode 100644
index 0000000..be693e0
--- /dev/null
+++ b/G-Earth/src/test/java/TestPacketStringUtils.java
@@ -0,0 +1,53 @@
+import gearth.protocol.HPacketFormat;
+import gearth.services.packet_representation.InvalidPacketException;
+import gearth.services.packet_representation.PacketStringUtils;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class TestPacketStringUtils {
+
+ // Important to test:
+ // - bool
+ // - byte
+ // - int
+ // - str
+
+ @Test
+ public void testShockwaveIncoming() throws InvalidPacketException {
+ checkSame("@t@FHoi123");
+ checkSame("AK@J@F");
+ checkSame("@XHaaaaaaaaa[2]");
+ checkSame("C\\HSGHDance Clubs & Pubs[2]HRLKSAIThe bobba Duck Pub[2]HRLSGthe_dirty_duck_pub[2]SAHhh_room_pub[2]HIRNIThe Chromide Club[2]IRLSGthe_chromide_club[2]RNHhh_room_disco[2]HI");
+ }
+
+ @Test
+ public void testShockwaveIncomingExpressions() throws InvalidPacketException {
+ checkExpression(HPacketFormat.WEDGIE_INCOMING, "{h:24}{i:0}{s:\"aaaaaaaaa\"}", "@XHaaaaaaaaa[2]");
+ checkExpression(HPacketFormat.WEDGIE_INCOMING, "{h:34}{i:1}{i:4}{i:3}{i:5}{s:\"0.0\"}{i:2}{i:2}{s:\"/flatctrl 4/\"}", "@bIPAKQA0.0[2]JJ/flatctrl 4/[2]"); // STATUS
+ checkExpression(HPacketFormat.WEDGIE_INCOMING, "{h:220}{i:0}" +
+ "{i:31}{i:0}{s:\"Dance Clubs & Pubs\"}{i:0}{i:50}{i:3}" +
+ "{i:7}{i:1}{s:\"The bobba Duck Pub\"}{i:0}{i:50}{i:31}{s:\"the_dirty_duck_pub\"}{i:7}{i:0}{s:\"hh_room_pub\"}{i:0}{b:true}" +
+ "{i:58}{i:1}{s:\"The Chromide Club\"}{i:1}{i:50}{i:31}{s:\"the_chromide_club\"}{i:58}{i:0}{s:\"hh_room_disco\"}{i:0}{b:true}",
+ "C\\HSGHDance Clubs & Pubs[2]HRLKSAIThe bobba Duck Pub[2]HRLSGthe_dirty_duck_pub[2]SAHhh_room_pub[2]HIRNIThe Chromide Club[2]IRLSGthe_chromide_club[2]RNHhh_room_disco[2]HI"); // NAVNODEINFO
+ }
+
+ @Test
+ public void testShockwaveOutgoingExpressions() throws InvalidPacketException {
+ checkExpression(HPacketFormat.WEDGIE_OUTGOING, "{h:18}{b:false}", "@RH"); // GETFVRF
+ checkExpression(HPacketFormat.WEDGIE_OUTGOING, "{h:52}{s:\"Hoi123\"}", "@t@FHoi123"); // CHAT
+ checkExpression(HPacketFormat.WEDGIE_OUTGOING, "{h:75}{s:10}{s:6}", "AK@J@F"); // MOVE
+ }
+
+ private void checkSame(String expected) throws InvalidPacketException {
+ // Should be the same for all formats
+ for (HPacketFormat value : HPacketFormat.values()) {
+ assertEquals(expected, PacketStringUtils.fromString(expected, value).toString());
+ }
+ }
+
+ private void checkExpression(HPacketFormat format, String expression, String expected) throws InvalidPacketException {
+ assertEquals(expected, PacketStringUtils.fromString(expression, format).toString());
+ }
+
+}