added LAN packets to client

This commit is contained in:
LAX1DUDE 2022-08-13 20:23:11 -07:00
parent 7e3aee8699
commit dac0a9480d
13 changed files with 561 additions and 0 deletions

View File

@ -0,0 +1,32 @@
package net.lax1dude.eaglercraft.sp.relay.pkt;
public class ICEServerSet {
public static enum RelayType {
STUN, TURN;
}
public static class RelayServer {
public final RelayType type;
public final String address;
public final String username;
public final String password;
protected RelayServer(RelayType type, String address, String username, String password) {
this.type = type;
this.address = address;
this.username = username;
this.password = password;
}
protected RelayServer(RelayType type, String address) {
this.type = type;
this.address = address;
this.username = null;
this.password = null;
}
}
}

View File

@ -0,0 +1,144 @@
package net.lax1dude.eaglercraft.sp.relay.pkt;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
public class IPacket {
private static final Map<Integer,Class<? extends IPacket>> definedPacketClasses = new HashMap();
private static final Map<Class<? extends IPacket>,Integer> definedPacketIds = new HashMap();
private static void register(int id, Class<? extends IPacket> clazz) {
definedPacketClasses.put(id, clazz);
definedPacketIds.put(clazz, id);
}
static {
register(0x00, IPacket00Handshake.class);
register(0x01, IPacket01ICEServers.class);
register(0x02, IPacket02NewClient.class);
register(0x03, IPacket03ICECandidate.class);
register(0x04, IPacket04Description.class);
register(0x05, IPacket05ClientSuccess.class);
register(0x06, IPacket06ClientFailure.class);
register(0x07, IPacket07LocalWorlds.class);
register(0x69, IPacket69Pong.class);
register(0xFE, IPacketFEDisconnectClient.class);
register(0xFF, IPacketFFErrorCode.class);
}
public static IPacket readPacket(DataInputStream input) throws IOException {
int i = input.read();
try {
Class<? extends IPacket> clazz = definedPacketClasses.get(i);
if(clazz == null) {
throw new IOException("Unknown packet type: " + i);
}
IPacket pkt = clazz.newInstance();
pkt.read(input);
return pkt;
} catch (InstantiationException | IllegalAccessException e) {
throw new IOException("Unknown packet type: " + i);
}
}
public static byte[] writePacket(IPacket packet) throws IOException {
Integer i = definedPacketIds.get(packet.getClass());
if(i != null) {
int len = packet.packetLength();
ByteArrayOutputStream bao = len == -1 ? new ByteArrayOutputStream() :
new ByteArrayOutputStream(len + 1);
bao.write(i);
packet.write(new DataOutputStream(bao));
byte[] ret = bao.toByteArray();
if(len != -1 && ret.length != len + 1) {
System.err.println("writePacket buffer for packet " + packet.getClass().getSimpleName() + " " +
(len + 1 < ret.length ? "overflowed" : "underflowed") + " by " + (len + 1 < ret.length ?
ret.length - len - 1 : len + 1 - ret.length) + " bytes");
}
return ret;
}else {
throw new IOException("Unknown packet type: " + packet.getClass().getSimpleName());
}
}
public void read(DataInputStream input) throws IOException {
}
public void write(DataOutputStream output) throws IOException {
}
public int packetLength() {
return -1;
}
public static String readASCII(InputStream is, int len) throws IOException {
char[] ret = new char[len];
for(int i = 0; i < len; ++i) {
int j = is.read();
if(j < 0) {
return null;
}
ret[i] = (char)is.read();
}
return new String(ret);
}
public static void writeASCII(OutputStream is, String txt) throws IOException {
for(int i = 0, l = txt.length(); i < l; ++i) {
is.write((int)txt.charAt(i));
}
}
public static String readASCII8(InputStream is) throws IOException {
int i = is.read();
if(i < 0) {
return null;
}else {
return readASCII(is, i);
}
}
public static void writeASCII8(OutputStream is, String txt) throws IOException {
if(txt == null) {
is.write(0);
}else {
int l = txt.length();
is.write(l);
for(int i = 0; i < l; ++i) {
is.write((int)txt.charAt(i));
}
}
}
public static String readASCII16(InputStream is) throws IOException {
int hi = is.read();
int lo = is.read();
if(hi < 0 || lo < 0) {
return null;
}else {
return readASCII(is, (hi << 8) | lo);
}
}
public static void writeASCII16(OutputStream is, String txt) throws IOException {
if(txt == null) {
is.write(0);
is.write(0);
}else {
int l = txt.length();
is.write((l >> 8) & 0xFF);
is.write(l & 0xFF);
for(int i = 0; i < l; ++i) {
is.write((int)txt.charAt(i));
}
}
}
}

View File

@ -0,0 +1,41 @@
package net.lax1dude.eaglercraft.sp.relay.pkt;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class IPacket00Handshake extends IPacket {
public int connectionType = 0;
public int connectionVersion = 1;
public String connectionCode = null;
public IPacket00Handshake() {
}
public IPacket00Handshake(int connectionType, int connectionVersion,
String connectionCode) {
this.connectionType = connectionType;
this.connectionVersion = connectionVersion;
this.connectionCode = connectionCode;
}
@Override
public void read(DataInputStream input) throws IOException {
connectionType = input.read();
connectionVersion = input.read();
connectionCode = IPacket.readASCII8(input);
}
@Override
public void write(DataOutputStream output) throws IOException {
output.write(connectionType);
IPacket.writeASCII8(output, connectionCode);
}
@Override
public int packetLength() {
return 1 + 1 + (connectionCode != null ? 1 + connectionCode.length() : 0);
}
}

View File

@ -0,0 +1,40 @@
package net.lax1dude.eaglercraft.sp.relay.pkt;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
public class IPacket01ICEServers extends IPacket {
public final Collection<ICEServerSet.RelayServer> servers;
public IPacket01ICEServers() {
servers = new ArrayList();
}
public void read(DataInputStream input) throws IOException {
servers.clear();
int l = input.readUnsignedShort();
for(int i = 0; i < l; ++i) {
char type = (char)input.read();
if(type == 'S') {
servers.add(new ICEServerSet.RelayServer(
ICEServerSet.RelayType.STUN,
readASCII16(input),
null, null
));
}else if(type == 'T') {
servers.add(new ICEServerSet.RelayServer(
ICEServerSet.RelayType.TURN,
readASCII16(input),
readASCII8(input),
readASCII8(input)
));
}else {
throw new IOException("Unknown/Unsupported Relay Type: '" + type + "'");
}
}
}
}

View File

@ -0,0 +1,17 @@
package net.lax1dude.eaglercraft.sp.relay.pkt;
import java.io.DataInputStream;
import java.io.IOException;
public class IPacket02NewClient extends IPacket {
public String clientId;
public IPacket02NewClient(String clientId) {
}
public void read(DataInputStream input) throws IOException {
clientId = readASCII8(input);
}
}

View File

@ -0,0 +1,34 @@
package net.lax1dude.eaglercraft.sp.relay.pkt;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class IPacket03ICECandidate extends IPacket {
public String peerId;
public String candidate;
public IPacket03ICECandidate(String peerId, String desc) {
this.peerId = peerId;
this.candidate = desc;
}
public IPacket03ICECandidate() {
}
public void read(DataInputStream input) throws IOException {
peerId = readASCII8(input);
candidate = readASCII16(input);
}
public void write(DataOutputStream output) throws IOException {
writeASCII8(output, peerId);
writeASCII16(output, candidate);
}
public int packetLength() {
return 1 + peerId.length() + 2 + candidate.length();
}
}

View File

@ -0,0 +1,34 @@
package net.lax1dude.eaglercraft.sp.relay.pkt;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class IPacket04Description extends IPacket {
public String peerId;
public String description;
public IPacket04Description(String peerId, String desc) {
this.peerId = peerId;
this.description = desc;
}
public IPacket04Description() {
}
public void read(DataInputStream input) throws IOException {
peerId = readASCII8(input);
description = readASCII16(input);
}
public void write(DataOutputStream output) throws IOException {
writeASCII8(output, peerId);
writeASCII16(output, description);
}
public int packetLength() {
return 1 + peerId.length() + 2 + description.length();
}
}

View File

@ -0,0 +1,30 @@
package net.lax1dude.eaglercraft.sp.relay.pkt;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class IPacket05ClientSuccess extends IPacket {
public String clientId;
public IPacket05ClientSuccess() {
}
public IPacket05ClientSuccess(String clientId) {
this.clientId = clientId;
}
public void read(DataInputStream input) throws IOException {
clientId = readASCII8(input);
}
public void write(DataOutputStream output) throws IOException {
writeASCII8(output, clientId);
}
public int packetLength() {
return 1 + clientId.length();
}
}

View File

@ -0,0 +1,30 @@
package net.lax1dude.eaglercraft.sp.relay.pkt;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class IPacket06ClientFailure extends IPacket {
public String clientId;
public IPacket06ClientFailure() {
}
public IPacket06ClientFailure(String clientId) {
this.clientId = clientId;
}
public void read(DataInputStream input) throws IOException {
clientId = readASCII8(input);
}
public void write(DataOutputStream output) throws IOException {
writeASCII8(output, clientId);
}
public int packetLength() {
return 1 + clientId.length();
}
}

View File

@ -0,0 +1,35 @@
package net.lax1dude.eaglercraft.sp.relay.pkt;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class IPacket07LocalWorlds extends IPacket {
public static class LocalWorld {
public final String worldName;
public final String worldCode;
public LocalWorld(String worldName, String worldCode) {
this.worldName = worldName;
this.worldCode = worldCode;
}
}
public final List<LocalWorld> worldsList;
public IPacket07LocalWorlds() {
this.worldsList = new ArrayList();
}
public void read(DataInputStream input) throws IOException {
int l = input.read();
for(int i = 0; i < l; ++i) {
worldsList.add(new LocalWorld(readASCII8(input), readASCII8(input)));
}
}
}

View File

@ -0,0 +1,27 @@
package net.lax1dude.eaglercraft.sp.relay.pkt;
import java.io.DataInputStream;
import java.io.IOException;
public class IPacket69Pong extends IPacket {
public int protcolVersion;
public String comment;
public String brand;
public IPacket69Pong(int protcolVersion, String comment, String brand) {
if(comment.length() > 255) {
comment = comment.substring(0, 256);
}
this.protcolVersion = protcolVersion;
this.comment = comment;
this.brand = brand;
}
public void read(DataInputStream output) throws IOException {
protcolVersion = output.read();
comment = readASCII8(output);
brand = readASCII8(output);
}
}

View File

@ -0,0 +1,51 @@
package net.lax1dude.eaglercraft.sp.relay.pkt;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
public class IPacketFEDisconnectClient extends IPacket {
public static final int TYPE_FINISHED_SUCCESS = 0x00;
public static final int TYPE_FINISHED_FAILED = 0x01;
public static final int TYPE_TIMEOUT = 0x02;
public static final int TYPE_INVALID_OPERATION = 0x03;
public static final int TYPE_INTERNAL_ERROR = 0x04;
public static final int TYPE_UNKNOWN = 0xFF;
public String clientId;
public int code;
public String reason;
public IPacketFEDisconnectClient() {
}
public IPacketFEDisconnectClient(String clientId, int code, String reason) {
this.clientId = clientId;
this.code = code;
this.reason = reason;
}
public void read(DataInputStream input) throws IOException {
clientId = readASCII8(input);
code = input.read();
reason = readASCII16(input);
}
public void write(DataOutputStream output) throws IOException {
writeASCII8(output, clientId);
output.write(code);
writeASCII16(output, reason);
}
public int packetLength() {
return -1;
}
public static final ByteBuffer ratelimitPacketTooMany = ByteBuffer.wrap(new byte[] { (byte)0xFC, (byte)0x00 });
public static final ByteBuffer ratelimitPacketBlock = ByteBuffer.wrap(new byte[] { (byte)0xFC, (byte)0x01 });
public static final ByteBuffer ratelimitPacketBlockLock = ByteBuffer.wrap(new byte[] { (byte)0xFC, (byte)0x02 });
public static final ByteBuffer ratelimitPacketLocked = ByteBuffer.wrap(new byte[] { (byte)0xFC, (byte)0x03 });
}

View File

@ -0,0 +1,46 @@
package net.lax1dude.eaglercraft.sp.relay.pkt;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class IPacketFFErrorCode extends IPacket {
public static final int TYPE_INTERNAL_ERROR = 0x00;
public static final int TYPE_PROTOCOL_VERSION = 0x01;
public static final int TYPE_INVALID_PACKET = 0x02;
public static final int TYPE_ILLEGAL_OPERATION = 0x03;
public static final int TYPE_CODE_LENGTH = 0x04;
public static final int TYPE_INCORRECT_CODE = 0x05;
public static final int TYPE_SERVER_DISCONNECTED = 0x06;
public static final int TYPE_UNKNOWN_CLIENT = 0x07;
public int code;
public String desc;
public IPacketFFErrorCode() {
}
public IPacketFFErrorCode(int code, String desc) {
this.code = code;
this.desc = desc;
}
@Override
public void read(DataInputStream input) throws IOException {
code = input.read();
desc = readASCII16(input);
}
@Override
public void write(DataOutputStream input) throws IOException {
input.write(code);
writeASCII16(input, desc);
}
@Override
public int packetLength() {
return 1 + 2 + desc.length();
}
}