Add simple support for packet expressions

This commit is contained in:
UnfamiliarLegacy 2024-06-22 01:33:31 +02:00
parent 55cf3cd475
commit 83ce7a0f6b
13 changed files with 445 additions and 82 deletions

View File

@ -299,6 +299,12 @@
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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 {

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -1,6 +1,10 @@
package gearth.protocol.packethandler.shockwave.packets;
public class ShockPacketUnsupported extends UnsupportedOperationException {
public ShockPacketUnsupported() {
super();
}
public ShockPacketUnsupported(String message) {
super(message);
}

View File

@ -0,0 +1,9 @@
package gearth.services.packet_representation;
import gearth.protocol.HPacket;
public interface PacketReplaceWriter {
void write(HPacket temp, String value);
}

View File

@ -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<Matcher, String> replacer) {
private static String replaceAll(String templateText, String regex, Function<Matcher, String> 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()));
}
}

View File

@ -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<String, String> 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

View File

@ -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<HPacket> 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<InjectedPackets> 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");

View File

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