From 20799a08569f7546e056129f5b49749f06b9d453 Mon Sep 17 00:00:00 2001 From: lax1dude Date: Thu, 4 Jul 2024 15:39:47 -0700 Subject: [PATCH] Add shared world relay protocol classes --- .../v1_8/sp/relay/pkt/IRelayLogger.java | 30 +++ .../v1_8/sp/relay/pkt/RelayPacket.java | 211 ++++++++++++++++++ .../sp/relay/pkt/RelayPacket00Handshake.java | 57 +++++ .../sp/relay/pkt/RelayPacket01ICEServers.java | 105 +++++++++ .../sp/relay/pkt/RelayPacket02NewClient.java | 45 ++++ .../relay/pkt/RelayPacket03ICECandidate.java | 58 +++++ .../relay/pkt/RelayPacket04Description.java | 58 +++++ .../relay/pkt/RelayPacket05ClientSuccess.java | 45 ++++ .../relay/pkt/RelayPacket06ClientFailure.java | 45 ++++ .../relay/pkt/RelayPacket07LocalWorlds.java | 86 +++++++ .../v1_8/sp/relay/pkt/RelayPacket69Pong.java | 56 +++++ .../relay/pkt/RelayPacket70SpecialUpdate.java | 55 +++++ .../pkt/RelayPacketFEDisconnectClient.java | 67 ++++++ .../sp/relay/pkt/RelayPacketFFErrorCode.java | 82 +++++++ 14 files changed, 1000 insertions(+) create mode 100644 sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/IRelayLogger.java create mode 100644 sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket.java create mode 100644 sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket00Handshake.java create mode 100644 sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket01ICEServers.java create mode 100644 sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket02NewClient.java create mode 100644 sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket03ICECandidate.java create mode 100644 sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket04Description.java create mode 100644 sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket05ClientSuccess.java create mode 100644 sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket06ClientFailure.java create mode 100644 sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket07LocalWorlds.java create mode 100644 sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket69Pong.java create mode 100644 sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket70SpecialUpdate.java create mode 100644 sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacketFEDisconnectClient.java create mode 100644 sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacketFFErrorCode.java diff --git a/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/IRelayLogger.java b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/IRelayLogger.java new file mode 100644 index 0000000..3282f6d --- /dev/null +++ b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/IRelayLogger.java @@ -0,0 +1,30 @@ +package net.lax1dude.eaglercraft.v1_8.sp.relay.pkt; + +/** + * Copyright (c) 2024 lax1dude. All Rights Reserved. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +public interface IRelayLogger { + + void debug(String msg, Object...args); + + void info(String msg, Object...args); + + void warn(String msg, Object...args); + + void error(String msg, Object...args); + + void error(Throwable th); + +} diff --git a/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket.java b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket.java new file mode 100644 index 0000000..fd793ea --- /dev/null +++ b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket.java @@ -0,0 +1,211 @@ +package net.lax1dude.eaglercraft.v1_8.sp.relay.pkt; + +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; + +/** + * Copyright (c) 2022-2024 lax1dude. All Rights Reserved. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +public class RelayPacket { + + private static final Map> definedPacketClasses = new HashMap(); + private static final Map,Integer> definedPacketIds = new HashMap(); + + private static void register(int id, Class clazz) { + definedPacketClasses.put(id, clazz); + definedPacketIds.put(clazz, id); + } + + static { + register(0x00, RelayPacket00Handshake.class); + register(0x01, RelayPacket01ICEServers.class); + register(0x02, RelayPacket02NewClient.class); + register(0x03, RelayPacket03ICECandidate.class); + register(0x04, RelayPacket04Description.class); + register(0x05, RelayPacket05ClientSuccess.class); + register(0x06, RelayPacket06ClientFailure.class); + register(0x07, RelayPacket07LocalWorlds.class); + register(0x69, RelayPacket69Pong.class); + register(0x70, RelayPacket70SpecialUpdate.class); + register(0xFE, RelayPacketFEDisconnectClient.class); + register(0xFF, RelayPacketFFErrorCode.class); + } + + public static RelayPacket readPacket(DataInputStream input, IRelayLogger logger) throws IOException { + int i = input.read(); + try { + Class clazz = definedPacketClasses.get(i); + if(clazz == null) { + throw new IOException("Unknown packet type: " + i); + } + RelayPacket pkt = clazz.newInstance(); + pkt.read(input); + int j = input.available(); + if(j > 0) { + throw new IOException("Packet type " + i + " had " + j + " remaining bytes"); + } + return pkt; + } catch (InstantiationException | IllegalAccessException e) { + logger.error("Could not instanciate packet {}", i); + logger.error(e); + throw new IOException("Unknown packet type: " + i); + } + } + + public static byte[] writePacket(RelayPacket packet, IRelayLogger logger) 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) { + logger.debug("writePacket buffer for packet {} {} by {} bytes", packet.getClass().getSimpleName(), + len + 1 < ret.length ? "overflowed" : "underflowed", + len + 1 < ret.length ? ret.length - len - 1 : len + 1 - ret.length); + } + 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) { + throw new EOFException(); + } + ret[i] = (char)j; + } + 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) { + throw new EOFException(); + }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) { + throw new EOFException(); + }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)); + } + } + } + + public static byte[] readBytes16(InputStream is) throws IOException { + int hi = is.read(); + int lo = is.read(); + if(hi < 0 || lo < 0) { + throw new EOFException(); + }else { + byte[] ret = new byte[(hi << 8) | lo]; + is.read(ret); + return ret; + } + } + + public static void writeBytes16(OutputStream is, byte[] arr) throws IOException { + if(arr == null) { + is.write(0); + is.write(0); + }else { + is.write((arr.length >>> 8) & 0xFF); + is.write(arr.length & 0xFF); + for(int i = 0; i < arr.length; ++i) { + is.write(arr[i]); + } + } + } + + public static byte[] toASCIIBin(String txt) { + if(txt == null) { + return new byte[0]; + }else { + byte[] ret = new byte[txt.length()]; + for(int i = 0; i < ret.length; ++i) { + ret[i] = (byte)txt.charAt(i); + } + return ret; + } + } + + public static String toASCIIStr(byte[] bin) { + char[] charRet = new char[bin.length]; + for(int i = 0; i < charRet.length; ++i) { + charRet[i] = (char)((int)bin[i] & 0xFF); + } + return new String(charRet); + } +} diff --git a/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket00Handshake.java b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket00Handshake.java new file mode 100644 index 0000000..61999e8 --- /dev/null +++ b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket00Handshake.java @@ -0,0 +1,57 @@ +package net.lax1dude.eaglercraft.v1_8.sp.relay.pkt; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * Copyright (c) 2022-2024 lax1dude. All Rights Reserved. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +public class RelayPacket00Handshake extends RelayPacket { + + public int connectionType = 0; + public int connectionVersion = 1; + public String connectionCode = null; + + public RelayPacket00Handshake() { + } + + public RelayPacket00Handshake(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 = RelayPacket.readASCII8(input); + } + + @Override + public void write(DataOutputStream output) throws IOException { + output.write(connectionType); + output.write(connectionVersion); + RelayPacket.writeASCII8(output, connectionCode); + } + + @Override + public int packetLength() { + return 1 + 1 + (connectionCode != null ? 1 + connectionCode.length() : 0); + } + +} diff --git a/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket01ICEServers.java b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket01ICEServers.java new file mode 100644 index 0000000..a7bc7f6 --- /dev/null +++ b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket01ICEServers.java @@ -0,0 +1,105 @@ +package net.lax1dude.eaglercraft.v1_8.sp.relay.pkt; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +/** + * Copyright (c) 2022-2024 lax1dude. All Rights Reserved. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +public class RelayPacket01ICEServers extends RelayPacket { + + public final Collection servers; + + public static class RelayServer { + + public String address; + public RelayType type; + public String username; + public String password; + + public RelayServer(String address, RelayType type, String username, String password) { + this.address = address; + this.type = type; + this.username = username; + this.password = password; + } + + public String getICEString() { + if(username == null) { + return address; + }else { + return address + ";" + username + ";" + password; + } + } + + } + + public static enum RelayType { + NO_PASSWD, PASSWD; + } + + public RelayPacket01ICEServers() { + this.servers = new ArrayList(); + } + + public RelayPacket01ICEServers(Collection servers) { + this.servers = servers; + } + + public void write(DataOutputStream output) throws IOException { + int l = servers.size(); + output.writeShort(l); + Iterator itr = servers.iterator(); + while(itr.hasNext()) { + RelayServer srv = itr.next(); + if(srv.type == RelayType.NO_PASSWD) { + output.write('S'); + }else if(srv.type == RelayType.PASSWD) { + output.write('T'); + }else { + throw new IOException("Unknown/Unsupported Relay Type: " + srv.type.name()); + } + writeASCII16(output, srv.address); + writeASCII8(output, srv.username); + writeASCII8(output, srv.password); + } + } + + 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(); + RelayType typeEnum; + if(type == 'S') { + typeEnum = RelayType.NO_PASSWD; + }else if(type == 'T') { + typeEnum = RelayType.PASSWD; + }else { + throw new IOException("Unknown/Unsupported Relay Type: '" + type + "'"); + } + servers.add(new RelayServer( + readASCII16(input), + typeEnum, + readASCII8(input), + readASCII8(input) + )); + } + } +} diff --git a/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket02NewClient.java b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket02NewClient.java new file mode 100644 index 0000000..0f7b534 --- /dev/null +++ b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket02NewClient.java @@ -0,0 +1,45 @@ +package net.lax1dude.eaglercraft.v1_8.sp.relay.pkt; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * Copyright (c) 2022-2024 lax1dude. All Rights Reserved. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +public class RelayPacket02NewClient extends RelayPacket { + + public String clientId; + + public RelayPacket02NewClient(String clientId) { + this.clientId = clientId; + } + + public RelayPacket02NewClient() { + } + + public void write(DataOutputStream output) throws IOException { + writeASCII8(output, clientId); + } + + public void read(DataInputStream input) throws IOException { + clientId = readASCII8(input); + } + + public int packetLength() { + return 1 + clientId.length(); + } + +} diff --git a/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket03ICECandidate.java b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket03ICECandidate.java new file mode 100644 index 0000000..f9ac7bb --- /dev/null +++ b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket03ICECandidate.java @@ -0,0 +1,58 @@ +package net.lax1dude.eaglercraft.v1_8.sp.relay.pkt; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * Copyright (c) 2022-2024 lax1dude. All Rights Reserved. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +public class RelayPacket03ICECandidate extends RelayPacket { + + public String peerId; + public byte[] candidate; + + public RelayPacket03ICECandidate() { + } + + public RelayPacket03ICECandidate(String peerId, String desc) { + this.peerId = peerId; + this.candidate = toASCIIBin(desc); + } + + public RelayPacket03ICECandidate(String peerId, byte[] desc) { + this.peerId = peerId; + this.candidate = desc; + } + + public void read(DataInputStream input) throws IOException { + peerId = readASCII8(input); + candidate = readBytes16(input); + } + + public void write(DataOutputStream output) throws IOException { + writeASCII8(output, peerId); + writeBytes16(output, candidate); + } + + public String getCandidateString() { + return candidate == null ? null : toASCIIStr(candidate); + } + + public int packetLength() { + return 1 + peerId.length() + 2 + candidate.length; + } + +} \ No newline at end of file diff --git a/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket04Description.java b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket04Description.java new file mode 100644 index 0000000..ca9a904 --- /dev/null +++ b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket04Description.java @@ -0,0 +1,58 @@ +package net.lax1dude.eaglercraft.v1_8.sp.relay.pkt; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * Copyright (c) 2022-2024 lax1dude. All Rights Reserved. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +public class RelayPacket04Description extends RelayPacket { + + public String peerId; + public byte[] description; + + public RelayPacket04Description() { + } + + public RelayPacket04Description(String peerId, String desc) { + this.peerId = peerId; + this.description = toASCIIBin(desc); + } + + public RelayPacket04Description(String peerId, byte[] desc) { + this.peerId = peerId; + this.description = desc; + } + + public void read(DataInputStream input) throws IOException { + peerId = readASCII8(input); + description = readBytes16(input); + } + + public void write(DataOutputStream output) throws IOException { + writeASCII8(output, peerId); + writeBytes16(output, description); + } + + public String getDescriptionString() { + return description == null ? null : toASCIIStr(description); + } + + public int packetLength() { + return 1 + peerId.length() + 2 + description.length; + } + +} diff --git a/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket05ClientSuccess.java b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket05ClientSuccess.java new file mode 100644 index 0000000..e49d2fe --- /dev/null +++ b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket05ClientSuccess.java @@ -0,0 +1,45 @@ +package net.lax1dude.eaglercraft.v1_8.sp.relay.pkt; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * Copyright (c) 2022-2024 lax1dude. All Rights Reserved. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +public class RelayPacket05ClientSuccess extends RelayPacket { + + public String clientId; + + public RelayPacket05ClientSuccess() { + } + + public RelayPacket05ClientSuccess(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(); + } + +} diff --git a/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket06ClientFailure.java b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket06ClientFailure.java new file mode 100644 index 0000000..bf9c003 --- /dev/null +++ b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket06ClientFailure.java @@ -0,0 +1,45 @@ +package net.lax1dude.eaglercraft.v1_8.sp.relay.pkt; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * Copyright (c) 2022-2024 lax1dude. All Rights Reserved. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +public class RelayPacket06ClientFailure extends RelayPacket { + + public String clientId; + + public RelayPacket06ClientFailure() { + } + + public RelayPacket06ClientFailure(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(); + } + +} diff --git a/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket07LocalWorlds.java b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket07LocalWorlds.java new file mode 100644 index 0000000..23ece94 --- /dev/null +++ b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket07LocalWorlds.java @@ -0,0 +1,86 @@ +package net.lax1dude.eaglercraft.v1_8.sp.relay.pkt; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * Copyright (c) 2022-2024 lax1dude. All Rights Reserved. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +public class RelayPacket07LocalWorlds extends RelayPacket { + + 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 List worldsList; + + public RelayPacket07LocalWorlds() { + } + + public RelayPacket07LocalWorlds(List worldsList) { + this.worldsList = worldsList; + } + + public void write(DataOutputStream output) throws IOException { + if(worldsList == null) { + output.write(0); + }else { + int i = worldsList.size(); + if(i > 255) { + i = 255; + } + output.write(i); + for(int j = 0; j < i; ++j) { + LocalWorld w = worldsList.get(j); + writeASCII8(output, w.worldName); + writeASCII8(output, w.worldCode); + } + } + } + + public void read(DataInputStream input) throws IOException { + int l = input.read(); + if(worldsList == null) { + worldsList = new ArrayList(l); + }else { + worldsList.clear(); + } + for(int i = 0; i < l; ++i) { + worldsList.add(new LocalWorld(readASCII8(input), readASCII8(input))); + } + } + + public int packetLength() { + int accum = 1; + if(worldsList != null) { + for(int i = 0, l = worldsList.size(); i < l; ++i) { + LocalWorld j = worldsList.get(i); + accum += 2 + j.worldName.length() + j.worldCode.length(); + } + } + return accum; + } +} diff --git a/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket69Pong.java b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket69Pong.java new file mode 100644 index 0000000..9276c49 --- /dev/null +++ b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket69Pong.java @@ -0,0 +1,56 @@ +package net.lax1dude.eaglercraft.v1_8.sp.relay.pkt; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * Copyright (c) 2022-2024 lax1dude. All Rights Reserved. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +public class RelayPacket69Pong extends RelayPacket { + + public int protcolVersion; + public String comment; + public String brand; + + public RelayPacket69Pong(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 RelayPacket69Pong() { + } + + public void write(DataOutputStream output) throws IOException { + output.write(protcolVersion); + writeASCII8(output, comment); + writeASCII8(output, brand); + } + + public void read(DataInputStream output) throws IOException { + protcolVersion = output.read(); + comment = readASCII8(output); + brand = readASCII8(output); + } + + public int packetLength() { + return 3 + comment.length() + brand.length(); + } + +} diff --git a/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket70SpecialUpdate.java b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket70SpecialUpdate.java new file mode 100644 index 0000000..5d52292 --- /dev/null +++ b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacket70SpecialUpdate.java @@ -0,0 +1,55 @@ +package net.lax1dude.eaglercraft.v1_8.sp.relay.pkt; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * Copyright (c) 2024 lax1dude. All Rights Reserved. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +public class RelayPacket70SpecialUpdate extends RelayPacket { + + public static final int OPERATION_UPDATE_CERTIFICATE = 0x69; + + public int operation; + public byte[] updatePacket; + + public RelayPacket70SpecialUpdate() { + } + + public RelayPacket70SpecialUpdate(int operation, byte[] updatePacket) { + this.operation = operation; + this.updatePacket = updatePacket; + } + + @Override + public void read(DataInputStream input) throws IOException { + operation = input.read(); + updatePacket = new byte[input.readUnsignedShort()]; + input.read(updatePacket); + } + + @Override + public void write(DataOutputStream output) throws IOException { + output.write(operation); + output.writeShort(updatePacket.length); + output.write(updatePacket); + } + + @Override + public int packetLength() { + return 3 + updatePacket.length; + } +} diff --git a/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacketFEDisconnectClient.java b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacketFEDisconnectClient.java new file mode 100644 index 0000000..866a0af --- /dev/null +++ b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacketFEDisconnectClient.java @@ -0,0 +1,67 @@ +package net.lax1dude.eaglercraft.v1_8.sp.relay.pkt; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; + +/** + * Copyright (c) 2022-2024 lax1dude. All Rights Reserved. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +public class RelayPacketFEDisconnectClient extends RelayPacket { + + 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_SERVER_DISCONNECT = 0x05; + public static final int TYPE_UNKNOWN = 0xFF; + + public String clientId; + public int code; + public String reason; + + public RelayPacketFEDisconnectClient() { + } + + public RelayPacketFEDisconnectClient(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 + 1 + 2 + clientId.length() + (reason != null ? reason.length() : 0); + } + + 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 }); + +} diff --git a/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacketFFErrorCode.java b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacketFFErrorCode.java new file mode 100644 index 0000000..9ca959c --- /dev/null +++ b/sources/protocol-relay/java/net/lax1dude/eaglercraft/v1_8/sp/relay/pkt/RelayPacketFFErrorCode.java @@ -0,0 +1,82 @@ +package net.lax1dude.eaglercraft.v1_8.sp.relay.pkt; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +/** + * Copyright (c) 2022-2024 lax1dude. All Rights Reserved. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +public class RelayPacketFFErrorCode extends RelayPacket { + + 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 static final String[] packetTypes = new String[0x08]; + + static { + packetTypes[TYPE_INTERNAL_ERROR] = "TYPE_INTERNAL_ERROR"; + packetTypes[TYPE_PROTOCOL_VERSION] = "TYPE_PROTOCOL_VERSION"; + packetTypes[TYPE_INVALID_PACKET] = "TYPE_INVALID_PACKET"; + packetTypes[TYPE_ILLEGAL_OPERATION] = "TYPE_ILLEGAL_OPERATION"; + packetTypes[TYPE_CODE_LENGTH] = "TYPE_CODE_LENGTH"; + packetTypes[TYPE_INCORRECT_CODE] = "TYPE_INCORRECT_CODE"; + packetTypes[TYPE_SERVER_DISCONNECTED] = "TYPE_SERVER_DISCONNECTED"; + packetTypes[TYPE_UNKNOWN_CLIENT] = "TYPE_UNKNOWN_CLIENT"; + } + + public static String code2string(int i) { + if(i >= 0 || i < packetTypes.length) { + return packetTypes[i]; + }else { + return "UNKNOWN"; + } + } + + public int code; + public String desc; + + public RelayPacketFFErrorCode() { + } + + public RelayPacketFFErrorCode(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(); + } + +}