Add shared world relay protocol classes

This commit is contained in:
lax1dude 2024-07-04 15:39:47 -07:00
parent cc1fe13421
commit 20799a0856
14 changed files with 1000 additions and 0 deletions

View File

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

View File

@ -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<Integer,Class<? extends RelayPacket>> definedPacketClasses = new HashMap();
private static final Map<Class<? extends RelayPacket>,Integer> definedPacketIds = new HashMap();
private static void register(int id, Class<? extends RelayPacket> 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<? extends RelayPacket> 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);
}
}

View File

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

View File

@ -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<RelayServer> 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<RelayServer> servers) {
this.servers = servers;
}
public void write(DataOutputStream output) throws IOException {
int l = servers.size();
output.writeShort(l);
Iterator<RelayServer> 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)
));
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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<LocalWorld> worldsList;
public RelayPacket07LocalWorlds() {
}
public RelayPacket07LocalWorlds(List<LocalWorld> 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;
}
}

View File

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

View File

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

View File

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

View File

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