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()); + } + +}