diff --git a/lwjgl-rundir/resources/lang/en_US.lang b/lwjgl-rundir/resources/lang/en_US.lang
index 0ee135d..ec2ef51 100644
--- a/lwjgl-rundir/resources/lang/en_US.lang
+++ b/lwjgl-rundir/resources/lang/en_US.lang
@@ -31,8 +31,8 @@ menu.generatingTerrain=Building terrain
 menu.convertingLevel=Converting world
 menu.simulating=Simulating the world for a bit
 menu.respawning=Respawning
-menu.shareToLan=Open to LAN
-menu.closeLan=Close LAN
+menu.shareToLan=Invite
+menu.closeLan=Stop Sharing
 
 menu.skinCapeSettings=Skins/Capes Settings
 menu.skinCapeSettingsNote0=I put the button up here so
@@ -250,15 +250,15 @@ addServer.enterName=Server Name
 addServer.enterIp=Server Address
 addServer.add=Done
 addServer.hideAddress=Hide Address
-lanServer.title=LAN World
+lanServer.title=Shared World
 lanServer.scanning=Scanning for games on your local network
-lanServer.start=Start LAN World
+lanServer.start=Start Shared World
 lanServer.otherPlayers=Settings for Other Players
 mcoServer.title=yeeeeeee
 addServer.SSLWarn1=you are on an https: page!
 addServer.SSLWarn2=html5 will only allow wss://
 directConnect.prompt=What would you like to do?
-directConnect.lanWorld=Join LAN World
+directConnect.lanWorld=Join Shared World
 directConnect.lanWorldCode=Enter Join Code:
 directConnect.networkSettingsNote=Click 'Network Settings' to add a relay URL
 directConnect.ipGrabNote=Note: The world's owner can get your IP address
@@ -266,7 +266,7 @@ directConnect.serverJoin=Connect to Server
 directConnect.lanWorldJoin=Join World
 directConnect.lanWorldRelay=Network Settings
 
-lanServer.pauseMenu0=Sharing to LAN
+lanServer.pauseMenu0=Sharing World
 lanServer.pauseMenu1=Relay URL:
 lanServer.pauseMenu2=Join Code:
 
@@ -276,13 +276,13 @@ lanServer.worldName=World Name:
 lanServer.hidden=Hidden:
 lanServer.hideCode=hide details
 lanServer.showCode=show details
-lanServer.opened=LAN world opened on $relay$, join code is §a$code$
-lanServer.closed=LAN world closed
+lanServer.opened=Shared world opened on $relay$, join code is §a$code$
+lanServer.closed=Shared world closed
 lanServer.pleaseWait=Please Wait...
-lanServer.relayDisconnected=Error: connection to LAN relay was lost, you must re-share the world to invide more people
+lanServer.relayDisconnected=Error: connection to shared world relay was lost, you must re-share the world to invide more people
 lanServer.ipGrabNote=Note: Players joining your world can get your IP address
 
-networkSettings.title=LAN World Relay Servers
+networkSettings.title=Shared World Relay Servers
 networkSettings.add=Add Relay
 networkSettings.delete=Delete Relay
 networkSettings.default=Set Primary
diff --git a/lwjgl-rundir/resources/relay_download.zip b/lwjgl-rundir/resources/relay_download.zip
index 6d3de60..5b5db2c 100644
Binary files a/lwjgl-rundir/resources/relay_download.zip and b/lwjgl-rundir/resources/relay_download.zip differ
diff --git a/sp-relay/Java-WebSocket-1.5.1-with-dependencies.jar b/sp-relay/Java-WebSocket-1.5.1-with-dependencies.jar
deleted file mode 100644
index 8f103a7..0000000
Binary files a/sp-relay/Java-WebSocket-1.5.1-with-dependencies.jar and /dev/null differ
diff --git a/sp-relay/protocol.txt b/sp-relay/protocol.txt
deleted file mode 100644
index a07e803..0000000
--- a/sp-relay/protocol.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-
- Relay Packet Order:
- ~~~~~~~~~~~~~~~~~~
-
- Opening LAN world:
-
- [Server -> Relay] Open WebSocket
- [Server -> Relay] PKT 0x00: Send protocol id, identify as server
- [Relay -> Server] PKT 0x00: Reply protocol id, assign join code
- [Relay -> Server] PKT 0x01: Send ICE server list to server
-
- Client connects:
-
- [Client -> Relay] Open WebSocket
- [Client -> Relay] PKT 0x00: Send protocol id, identify as client, send server join code
- [Relay -> Client] PKT 0x00: Reply protocol id, assign client id
- [Relay -> Client] PKT 0x01: Send ICE server list to client
- [Relay -> Server] PKT 0x02: Notify server of the client, send client's id to server
- [Client -> Relay -> Server] PKT 0x04: Send client description to server
- [Server -> Relay -> Client] PKT 0x04: Send server description to client
- [Client -> Relay -> Server] PKT 0x03: Send client ICE Candidate to server
- [Server -> Relay -> Client] PKT 0x03: Send server ICE Candidate to client
- [Client -> Relay -> Server] PKT 0x05 or 0x06: Client signals sucess or failure
- [Relay -> Client] PKT 0xFE: Signal to close WebSocket
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/ByteBufferInputStream.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/ByteBufferInputStream.java
deleted file mode 100644
index b7779d8..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/ByteBufferInputStream.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package net.lax1dude.eaglercraft.sp.relay;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-
-public class ByteBufferInputStream extends InputStream {
-	
-	private final ByteBuffer buffer;
-	
-	public ByteBufferInputStream(ByteBuffer buf) {
-		buffer = buf;
-	}
-
-	@Override
-	public int read(byte[] b, int off, int len) throws IOException {
-		int max = buffer.remaining();
-		if(len > max) {
-			len = max;
-		}
-		buffer.get(b, off, len);
-		return len;
-	}
-	
-	@Override
-	public int read() throws IOException {
-		if(buffer.remaining() == 0) {
-			return -1;
-		}else {
-			return (int)buffer.get() & 0xFF;
-		}
-	}
-
-	@Override
-	public long skip(long n) throws IOException {
-		int max = buffer.remaining();
-		if(n > max) {
-			n = (int)max;
-		}
-		return max;
-	}
-
-	@Override
-	public int available() throws IOException {
-		return buffer.remaining();
-	}
-
-	@Override
-	public synchronized void mark(int readlimit) {
-		buffer.mark();
-	}
-
-	@Override
-	public synchronized void reset() throws IOException {
-		buffer.reset();
-	}
-
-	@Override
-	public boolean markSupported() {
-		return true;
-	}
-
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/Constants.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/Constants.java
deleted file mode 100644
index 580f14e..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/Constants.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package net.lax1dude.eaglercraft.sp.relay;
-
-public class Constants {
-	
-	public static final String versionName = "0.1a";
-	public static final String versionBrand = "lax1dude";
-	public static final int protocolVersion = 1;
-
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/DebugLogger.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/DebugLogger.java
deleted file mode 100644
index baa0c39..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/DebugLogger.java
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (c) 2022 Calder Young. All rights reserved.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * 
- * 1. Redistributions of source code must retain the above copyright notice, this
- *    list of conditions and the following disclaimer.
- * 
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- * 
- * 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.
- * 
- */
-
-package net.lax1dude.eaglercraft.sp.relay;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.net.InetSocketAddress;
-import java.nio.charset.StandardCharsets;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-public class DebugLogger {
-	
-	private static Level debugLoggingLevel = Level.INFO;
-	
-	public static void enableDebugLogging(Level level) {
-		if(level == null) {
-			level = Level.NONE;
-		}
-		debugLoggingLevel = level;
-	}
-	
-	public static boolean debugLoggingEnabled() {
-		return debugLoggingLevel != Level.NONE;
-	}
-	
-	private static final Map<String,DebugLogger> loggers = new HashMap();
-	
-	public static DebugLogger getLogger(String name) {
-		DebugLogger ret = loggers.get(name);
-		if(ret == null) {
-			ret = new DebugLogger(name);
-			loggers.put(name, ret);
-		}
-		return ret;
-	}
-	
-	private final String name;
-	
-	private DebugLogger(String name) {
-		this.name = name;
-	}
-	
-	public static enum Level {
-		
-		NONE("NONE", 0, System.out), DEBUG("DEBUG", 4, System.out), INFO("INFO", 3, System.out),
-		WARN("WARN", 2, System.err), ERROR("ERROR", 1, System.err);
-		
-		public final String label;
-		public final int level;
-		public final PrintStream output;
-		
-		private Level(String label, int level, PrintStream output) {
-			this.label = label;
-			this.level = level;
-			this.output = output;
-		}
-		
-	}
-	
-	private class LogStream extends OutputStream {
-		
-		private final Level logLevel;
-		private final ByteArrayOutputStream lineBuffer = new ByteArrayOutputStream();
-		
-		private LogStream(Level logLevel) {
-			this.logLevel = logLevel;
-		}
-
-		@Override
-		public void write(int b) throws IOException {
-			if(b == (int)'\r') {
-				return;
-			}else if(b == (int)'\n') {
-				byte[] line = lineBuffer.toByteArray();
-				lineBuffer.reset();
-				log(logLevel, new String(line, StandardCharsets.UTF_8));
-			}else {
-				lineBuffer.write(b);
-			}
-		}
-		
-	}
-
-	private OutputStream infoOutputStream = null;
-	private PrintStream infoPrintStream = null;
-	
-	private OutputStream warnOutputStream = null;
-	private PrintStream warnPrintStream = null;
-	
-	private OutputStream errorOutputStream = null;
-	private PrintStream errorPrintStream = null;
-	
-	public OutputStream getOutputStream(Level lvl) {
-		switch(lvl) {
-		case INFO:
-		default:
-			if(infoOutputStream == null) {
-				infoOutputStream = new LogStream(Level.INFO);
-			}
-			return infoOutputStream;
-		case WARN:
-			if(warnOutputStream == null) {
-				warnOutputStream = new LogStream(Level.WARN);
-			}
-			return warnOutputStream;
-		case ERROR:
-			if(errorOutputStream == null) {
-				errorOutputStream = new LogStream(Level.ERROR);
-			}
-			return errorOutputStream;
-		}
-	}
-	
-	public PrintStream getPrintStream(Level lvl) {
-		switch(lvl) {
-		case INFO:
-		default:
-			if(infoPrintStream == null) {
-				infoPrintStream = new PrintStream(getOutputStream(Level.INFO));
-			}
-			return infoPrintStream;
-		case WARN:
-			if(warnPrintStream == null) {
-				warnPrintStream = new PrintStream(getOutputStream(Level.WARN));
-			}
-			return warnPrintStream;
-		case ERROR:
-			if(errorPrintStream == null) {
-				errorPrintStream = new PrintStream(getOutputStream(Level.ERROR));
-			}
-			return errorPrintStream;
-		}
-	}
-	
-	private static final SimpleDateFormat fmt = new SimpleDateFormat("hh:mm:ss+SSS");
-	private final Date dateInstance = new Date();
-	
-	public static String formatParams(String msg, Object... params) {
-		if(params.length > 0) {
-			StringBuilder builtString = new StringBuilder();
-			for(int i = 0; i < params.length; ++i) {
-				int idx = msg.indexOf("{}");
-				if(idx != -1) {
-					builtString.append(msg.substring(0, idx));
-					if(params[i] instanceof InetSocketAddress) {
-						params[i] = Util.sock2String((InetSocketAddress)params[i]);
-					}
-					builtString.append(params[i]);
-					msg = msg.substring(idx + 2);
-				}else {
-					break;
-				}
-			}
-			builtString.append(msg);
-			return builtString.toString();
-		}else {
-			return msg;
-		}
-	}
-	
-	public void log(Level lvl, String msg, Object... params) {
-		if(debugLoggingLevel.level >= lvl.level) {
-			synchronized(this) {
-				dateInstance.setTime(System.currentTimeMillis());
-				System.out.println("[" + fmt.format(dateInstance) + "][" + Thread.currentThread().getName() + "/" + lvl.label + "][" + name + "]: " + 
-						(params.length == 0 ? msg : formatParams(msg, params)));
-			}
-		}
-	}
-	
-	public void log(Level lvl, Throwable stackTrace) {
-		stackTrace.printStackTrace(getPrintStream(lvl));
-	}
-	
-	public void debug(String msg) {
-		if(debugLoggingLevel.level >= Level.DEBUG.level) {
-			log(Level.DEBUG, msg);
-		}
-	}
-	
-	public void debug(String msg, Object... params) {
-		if(debugLoggingLevel.level >= Level.DEBUG.level) {
-			log(Level.DEBUG, msg, params);
-		}
-	}
-	
-	public void debug(Throwable t) {
-		if(debugLoggingLevel.level >= Level.DEBUG.level) {
-			log(Level.DEBUG, t);
-		}
-	}
-	
-	public void info(String msg) {
-		if(debugLoggingLevel.level >= Level.INFO.level) {
-			log(Level.INFO, msg);
-		}
-	}
-	
-	public void info(String msg, Object... params) {
-		if(debugLoggingLevel.level >= Level.INFO.level) {
-			log(Level.INFO, msg, params);
-		}
-	}
-	
-	public void info(Throwable t) {
-		if(debugLoggingLevel.level >= Level.INFO.level) {
-			log(Level.INFO, t);
-		}
-	}
-	
-	public void warn(String msg) {
-		if(debugLoggingLevel.level >= Level.WARN.level) {
-			log(Level.WARN, msg);
-		}
-	}
-	
-	public void warn(String msg, Object... params) {
-		if(debugLoggingLevel.level >= Level.WARN.level) {
-			log(Level.WARN, msg, params);
-		}
-	}
-	
-	public void warn(Throwable t) {
-		if(debugLoggingLevel.level >= Level.WARN.level) {
-			log(Level.WARN, t);
-		}
-	}
-	
-	public void error(String msg) {
-		if(debugLoggingLevel.level >= Level.ERROR.level) {
-			log(Level.ERROR, msg);
-		}
-	}
-	
-	public void error(String msg, Object... params) {
-		if(debugLoggingLevel.level >= Level.ERROR.level) {
-			log(Level.ERROR, msg, params);
-		}
-	}
-	
-	public void error(Throwable t) {
-		if(debugLoggingLevel.level >= Level.ERROR.level) {
-			log(Level.ERROR, t);
-		}
-	}
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/EaglerSPClient.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/EaglerSPClient.java
deleted file mode 100644
index 24524a6..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/EaglerSPClient.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package net.lax1dude.eaglercraft.sp.relay;
-
-import java.io.IOException;
-import java.util.Random;
-
-import org.java_websocket.WebSocket;
-
-import net.lax1dude.eaglercraft.sp.relay.pkt.IPacket;
-import net.lax1dude.eaglercraft.sp.relay.pkt.IPacket04Description;
-import net.lax1dude.eaglercraft.sp.relay.pkt.IPacket03ICECandidate;
-import net.lax1dude.eaglercraft.sp.relay.pkt.IPacket05ClientSuccess;
-import net.lax1dude.eaglercraft.sp.relay.pkt.IPacket06ClientFailure;
-import net.lax1dude.eaglercraft.sp.relay.pkt.IPacketFEDisconnectClient;
-
-public class EaglerSPClient {
-	
-	public final WebSocket socket;
-	public final EaglerSPServer server;
-	public final String id;
-	public final long createdOn;
-	public boolean serverNotifiedOfClose = false;
-	public LoginState state = LoginState.INIT;
-	public final String address;
-	
-	EaglerSPClient(WebSocket sock, EaglerSPServer srv, String id, String addr) {
-		this.socket = sock;
-		this.server = srv;
-		this.id = id;
-		this.createdOn = System.currentTimeMillis();
-		this.address = addr;
-	}
-	
-	public void send(IPacket packet) {
-		if(this.socket.isOpen()) {
-			try {
-				this.socket.send(IPacket.writePacket(packet));
-			}catch(IOException ex) {
-				EaglerSPRelay.logger.debug("Error sending data to {}", (String) this.socket.getAttachment());
-				EaglerSPRelay.logger.debug(ex);
-				disconnect(IPacketFEDisconnectClient.TYPE_INTERNAL_ERROR, "Internal Server Error");
-				this.socket.close();
-			}
-		}else {
-			EaglerSPRelay.logger.debug("WARNING: Tried to send data to {} after the connection closed.", (String) this.socket.getAttachment());
-		}
-	}
-	
-	public boolean handle(IPacket packet) throws IOException {
-		if(packet instanceof IPacket03ICECandidate) {
-			if(LoginState.assertEquals(this, LoginState.RECIEVED_DESCRIPTION)) {
-				state = LoginState.SENT_ICE_CANDIDATE;
-				server.handleClientICECandidate(this, (IPacket03ICECandidate)packet);
-				EaglerSPRelay.logger.debug("[{}][Client -> Relay -> Server] PKT 0x03: ICECandidate", (String) socket.getAttachment());
-			}
-			return true;
-		}else if(packet instanceof IPacket04Description) {
-			if(LoginState.assertEquals(this, LoginState.INIT)) {
-				state = LoginState.SENT_DESCRIPTION;
-				server.handleClientDescription(this, (IPacket04Description)packet);
-				EaglerSPRelay.logger.debug("[{}][Client -> Relay -> Server] PKT 0x04: Description", (String) socket.getAttachment());
-			}
-			return true;
-		}else if(packet instanceof IPacket05ClientSuccess) {
-			if(LoginState.assertEquals(this, LoginState.RECIEVED_ICE_CANIDATE)) {
-				state = LoginState.FINISHED;
-				server.handleClientSuccess(this, (IPacket05ClientSuccess)packet);
-				EaglerSPRelay.logger.debug("[{}][Client -> Relay -> Server] PKT 0x05: ClientSuccess", (String) socket.getAttachment());
-				disconnect(IPacketFEDisconnectClient.TYPE_FINISHED_SUCCESS, "Successful connection");
-			}
-			return true;
-		}else if(packet instanceof IPacket06ClientFailure) {
-			if(LoginState.assertEquals(this, LoginState.RECIEVED_ICE_CANIDATE)) {
-				state = LoginState.FINISHED;
-				server.handleClientFailure(this, (IPacket06ClientFailure)packet);
-				EaglerSPRelay.logger.debug("[{}][Client -> Relay -> Server] PKT 0x05: ClientFailure", (String) socket.getAttachment());
-				disconnect(IPacketFEDisconnectClient.TYPE_FINISHED_FAILED, "Failed connection");
-			}
-			return true;
-		}else {
-			return false;
-		}
-	}
-	
-	public void handleServerICECandidate(IPacket03ICECandidate desc) {
-		send(new IPacket03ICECandidate("", desc.candidate));
-	}
-	
-	public void handleServerDescription(IPacket04Description desc) {
-		send(new IPacket04Description("", desc.description));
-	}
-
-	public void handleServerDisconnectClient(IPacketFEDisconnectClient packet) {
-		disconnect(packet.code, packet.reason);
-	}
-	
-	public void disconnect(int code, String reason) {
-		IPacket pkt = new IPacketFEDisconnectClient(id, code, reason);
-		if(!serverNotifiedOfClose) {
-			if (code != IPacketFEDisconnectClient.TYPE_FINISHED_SUCCESS) server.send(pkt);
-			serverNotifiedOfClose = true;
-		}
-		if(this.socket.isOpen()) {
-			send(pkt);
-			socket.close();
-		}
-		EaglerSPRelay.logger.debug("[{}][Relay -> Client] PKT 0xFE: #{} {}", (String) socket.getAttachment(), code, reason);
-	}
-	
-	public static final int clientCodeLength = 16;
-	private static final String clientCodeChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-	
-	public static String generateClientId() {
-		Random r = new Random();
-		char[] ret = new char[clientCodeLength];
-		for(int i = 0; i < ret.length; ++i) {
-			ret[i] = clientCodeChars.charAt(r.nextInt(clientCodeChars.length()));
-		}
-		return new String(ret);
-	}
-
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/EaglerSPRelay.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/EaglerSPRelay.java
deleted file mode 100644
index 96e18a8..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/EaglerSPRelay.java
+++ /dev/null
@@ -1,514 +0,0 @@
-package net.lax1dude.eaglercraft.sp.relay;
-
-import java.io.BufferedReader;
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.java_websocket.WebSocket;
-import org.java_websocket.handshake.ClientHandshake;
-import org.java_websocket.server.WebSocketServer;
-
-import net.lax1dude.eaglercraft.sp.relay.RateLimiter.RateLimit;
-import net.lax1dude.eaglercraft.sp.relay.pkt.*;
-import net.lax1dude.eaglercraft.sp.relay.pkt.IPacket07LocalWorlds.LocalWorld;
-
-public class EaglerSPRelay extends WebSocketServer {
-
-	public static EaglerSPRelay instance;
-	public static final EaglerSPRelayConfig config = new EaglerSPRelayConfig();
-	
-	private static RateLimiter pingRateLimiter = null;
-	private static RateLimiter worldRateLimiter = null;
-	
-	public static final DebugLogger logger = DebugLogger.getLogger("EaglerSPRelay");
-
-	public static void main(String[] args) throws IOException, InterruptedException {
-		for(int i = 0; i < args.length; ++i) {
-			if(args[i].equalsIgnoreCase("--debug")) {
-				DebugLogger.enableDebugLogging(DebugLogger.Level.DEBUG);
-				logger.debug("Debug logging enabled");
-			}
-		}
-		
-		logger.info("Starting EaglerSPRelay version {}...", Constants.versionName);
-		config.load(new File("relayConfig.ini"));
-		
-		if(config.isPingRateLimitEnable()) {
-			pingRateLimiter = new RateLimiter(config.getPingRateLimitPeriod() * 1000,
-					config.getPingRateLimitLimit(), config.getPingRateLimitLockoutLimit(),
-					config.getPingRateLimitLockoutDuration() * 1000);
-		}
-		
-		if(config.isWorldRateLimitEnable()) {
-			worldRateLimiter = new RateLimiter(config.getWorldRateLimitPeriod() * 1000,
-					config.getWorldRateLimitLimit(), config.getWorldRateLimitLockoutLimit(),
-					config.getWorldRateLimitLockoutDuration() * 1000);
-		}
-		
-		EaglerSPRelayConfigRelayList.loadRelays(new File("relays.txt"));
-		
-		logger.info("Starting WebSocket Server...");
-		instance = new EaglerSPRelay(new InetSocketAddress(config.getAddress(), config.getPort()));
-		instance.setConnectionLostTimeout(20);
-		instance.setReuseAddr(true);
-		instance.start();
-		
-		Thread tickThread = new Thread((() -> {
-			int rateLimitUpdateCounter = 0;
-			while(true) {
-				try {
-					long millis = System.currentTimeMillis();
-					synchronized(pendingConnections) {
-						Iterator<Entry<WebSocket,PendingConnection>> itr = pendingConnections.entrySet().iterator();
-						while(itr.hasNext()) {
-							Entry<WebSocket,PendingConnection> etr = itr.next();
-							if(millis - etr.getValue().openTime > 500l) {
-								etr.getKey().close();
-								itr.remove();
-							}
-						}
-					}
-					synchronized(clientConnections) {
-						Iterator<EaglerSPClient> itr = clientConnections.values().iterator();
-						while(itr.hasNext()) {
-							EaglerSPClient cl = itr.next();
-							if(millis - cl.createdOn > 10000l) {
-								cl.disconnect(IPacketFEDisconnectClient.TYPE_TIMEOUT, "Took too long to connect!");
-							}
-						}
-					}
-					if(++rateLimitUpdateCounter > 300) {
-						if(pingRateLimiter != null) {
-							pingRateLimiter.update();
-						}
-						if(worldRateLimiter != null) {
-							worldRateLimiter.update();
-						}
-						rateLimitUpdateCounter = 0;
-					}
-				}catch(Throwable t) {
-					logger.error("Error in update loop!");
-					logger.error(t);
-				}
-				Util.sleep(100l);
-			}
-		}), "Relay Tick");
-		tickThread.setDaemon(true);
-		tickThread.start();
-		
-		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
-		String s;
-		while((s = reader.readLine()) != null) {
-			s = s.trim();
-			if(s.equalsIgnoreCase("stop") || s.equalsIgnoreCase("end")) {
-				logger.info("Shutting down...");
-				instance.stop();
-				System.exit(0);
-			}else if(s.equalsIgnoreCase("reset")) {
-				logger.info("Clearing all ratelimits");
-				if(pingRateLimiter != null) pingRateLimiter.reset();
-				if(worldRateLimiter != null) worldRateLimiter.reset();
-			}else {
-				logger.info("Unknown command: {}", s);
-				logger.info("Type 'stop' to exit" + ((worldRateLimiter != null || pingRateLimiter != null) ? ", 'reset' to clear ratelimits" : ""));
-			}
-		}
-		
-	}
-	
-	private EaglerSPRelay(InetSocketAddress addr) {
-		super(addr);
-	}
-	
-	private static class PendingConnection {
-		
-		private final long openTime;
-		private final String address;
-		
-		public PendingConnection(long openTime, String address) {
-			this.openTime = openTime;
-			this.address = address;
-		}
-		
-	}
-
-	private static final Map<WebSocket,PendingConnection> pendingConnections = new HashMap();
-	private static final Map<String,EaglerSPClient> clientIds = new HashMap();
-	private static final Map<WebSocket,EaglerSPClient> clientConnections = new HashMap();
-	private static final Map<String,EaglerSPServer> serverCodes = new HashMap();
-	private static final Map<WebSocket,EaglerSPServer> serverConnections = new HashMap();
-	private static final Map<String,List<EaglerSPClient>> clientAddressSets = new HashMap();
-	private static final Map<String,List<EaglerSPServer>> serverAddressSets = new HashMap();
-
-	@Override
-	public void onStart() {
-		logger.info("Listening on {}", getAddress());
-		logger.info("Type 'stop' to exit" + ((worldRateLimiter != null || pingRateLimiter != null) ? ", 'reset' to clear ratelimits" : ""));
-	}
-	
-	@Override
-	public void onOpen(WebSocket arg0, ClientHandshake arg1) {
-		if(!config.getIsWhitelisted(arg1.getFieldValue("origin"))) {
-			arg0.close();
-			return;
-		}
-		
-		String addr;
-		long millis = System.currentTimeMillis();
-		if(config.isEnableRealIpHeader() && arg1.hasFieldValue(config.getRealIPHeaderName())) {
-			addr = arg1.getFieldValue(config.getRealIPHeaderName()).toLowerCase();
-		}else {
-			addr = arg0.getRemoteSocketAddress().getAddress().getHostAddress().toLowerCase();
-		}
-		
-		int totalCons = 0;
-		synchronized(pendingConnections) {
-			Iterator<PendingConnection> pendingItr = pendingConnections.values().iterator();
-			while(pendingItr.hasNext()) {
-				if(pendingItr.next().address.equals(addr)) {
-					++totalCons;
-				}
-			}
-		}
-		synchronized(clientAddressSets) {
-			List<EaglerSPClient> lst = clientAddressSets.get(addr);
-			if(lst != null) {
-				totalCons += lst.size();
-			}
-		}
-		
-		if(totalCons >= config.getConnectionsPerIP()) {
-			logger.debug("[{}]: Too many connections are open on this address", (String) arg0.getAttachment());
-			arg0.send(IPacketFEDisconnectClient.ratelimitPacketTooMany);
-			arg0.close();
-			return;
-		}
-		
-		arg0.setAttachment(addr);
-		
-		PendingConnection waiting = new PendingConnection(millis, addr);
-		logger.debug("[{}]: Connection opened", arg0.getRemoteSocketAddress());
-		synchronized(pendingConnections) {
-			pendingConnections.put(arg0, waiting);
-		}
-	}
-
-	@Override
-	public void onMessage(WebSocket arg0, ByteBuffer arg1) {
-		DataInputStream sid = new DataInputStream(new ByteBufferInputStream(arg1));
-		PendingConnection waiting;
-		synchronized(pendingConnections) {
-			waiting = pendingConnections.remove(arg0);
-		}
-		try {
-			IPacket pkt = IPacket.readPacket(sid);
-			if(waiting != null) {
-				if(pkt instanceof IPacket00Handshake) {
-					IPacket00Handshake ipkt = (IPacket00Handshake)pkt;
-					if(ipkt.connectionVersion != Constants.protocolVersion) {
-						logger.debug("[{}]: Connected with unsupported protocol version: {} (supported "
-								+ "version: {})", (String) arg0.getAttachment(), ipkt.connectionVersion, Constants.protocolVersion);
-						if(ipkt.connectionVersion < Constants.protocolVersion) {
-							arg0.send(IPacket.writePacket(new IPacketFFErrorCode(IPacketFFErrorCode.TYPE_PROTOCOL_VERSION,
-									"Outdated Client! (v" + Constants.protocolVersion + " req)")));
-						}else {
-							arg0.send(IPacket.writePacket(new IPacketFFErrorCode(IPacketFFErrorCode.TYPE_PROTOCOL_VERSION,
-									"Outdated Server! (still on v" + Constants.protocolVersion + ")")));
-						}
-						arg0.close();
-						return;
-					}
-					if(ipkt.connectionType == 0x01) {
-						if(!rateLimit(worldRateLimiter, arg0, waiting.address)) {
-							logger.debug("[{}]: Got world ratelimited", (String) arg0.getAttachment());
-							return;
-						}
-						synchronized(serverAddressSets) {
-							List<EaglerSPServer> lst = serverAddressSets.get(waiting.address);
-							if(lst != null) {
-								if(lst.size() >= config.getWorldsPerIP()) {
-									logger.debug("[{}]: Too many worlds are open on this address", (String) arg0.getAttachment());
-									arg0.send(IPacketFEDisconnectClient.ratelimitPacketTooMany);
-									arg0.close();
-									return;
-								}
-							}
-						}
-						logger.debug("[{}]: Connected as a server", (String) arg0.getAttachment());
-						EaglerSPServer srv;
-						synchronized(serverCodes) {
-							int j = 0;
-							String code;
-							do {
-								if(++j > 100) {
-									logger.error("Error: relay is running out of codes!");
-									logger.error("Closing connection to {}", (String) arg0.getAttachment());
-									arg0.send(IPacket.writePacket(new IPacketFFErrorCode(IPacketFFErrorCode.TYPE_INTERNAL_ERROR,
-											"Internal Server Error")));
-									arg0.close();
-									return;
-								}
-								code = config.generateCode();
-							}while(serverCodes.containsKey(code));
-							srv = new EaglerSPServer(arg0, code, ipkt.connectionCode, waiting.address);
-							serverCodes.put(code, srv);
-							ipkt.connectionCode = code;
-							arg0.send(IPacket.writePacket(ipkt));
-							logger.debug("[{}][Relay -> Server] PKT 0x00: Assign join code: {}", (String) arg0.getAttachment(), code);
-						}
-						synchronized(serverConnections) {
-							serverConnections.put(arg0, srv);
-						}
-						synchronized(serverAddressSets) {
-							List<EaglerSPServer> lst = serverAddressSets.get(srv.serverAddress);
-							if(lst == null) {
-								lst = new ArrayList();
-								serverAddressSets.put(srv.serverAddress, lst);
-							}
-							lst.add(srv);
-						}
-						srv.send(new IPacket01ICEServers(EaglerSPRelayConfigRelayList.relayServers));
-						logger.debug("[{}][Relay -> Server] PKT 0x01: Send ICE server list to server", (String) arg0.getAttachment());
-					}else {
-						if(!rateLimit(pingRateLimiter, arg0, waiting.address)) {
-							logger.debug("[{}]: Got ping ratelimited", (String) arg0.getAttachment());
-							return;
-						}
-						if(ipkt.connectionType == 0x02) {
-							String code = ipkt.connectionCode;
-							logger.debug("[{}]: Connected as a client, requested server code: {}", (String) arg0.getAttachment(), code);
-							if(code.length() != config.getCodeLength()) {
-								logger.debug("The code '{}' is invalid because it's the wrong length, disconnecting", code);
-								arg0.send(IPacket.writePacket(new IPacketFFErrorCode(IPacketFFErrorCode.TYPE_CODE_LENGTH,
-										"The join code is the wrong length, it should be " + config.getCodeLength() + " chars long")));
-								arg0.close();
-							}else {
-								if(!config.isCodeMixCase()) {
-									code = code.toLowerCase();
-								}
-								EaglerSPServer srv;
-								synchronized(serverCodes) {
-									srv = serverCodes.get(code);
-								}
-								if(srv == null) {
-									arg0.send(IPacket.writePacket(new IPacketFFErrorCode(IPacketFFErrorCode.TYPE_INCORRECT_CODE,
-											"Invalid code, no LAN world found!")));
-									arg0.close();
-									return;
-								}
-								String id;
-								EaglerSPClient cl;
-								synchronized(clientIds) {
-									int j = 0;
-									do {
-										id = EaglerSPClient.generateClientId();
-									}while(clientIds.containsKey(id));
-									cl = new EaglerSPClient(arg0, srv, id, waiting.address);
-									clientIds.put(id, cl);
-									ipkt.connectionCode = id;
-									arg0.send(IPacket.writePacket(ipkt));
-									srv.handleNewClient(cl);
-								}
-								synchronized(clientConnections) {
-									clientConnections.put(arg0, cl);
-								}
-								synchronized(clientAddressSets) {
-									List<EaglerSPClient> lst = clientAddressSets.get(cl.address);
-									if(lst == null) {
-										lst = new ArrayList();
-										clientAddressSets.put(cl.address, lst);
-									}
-									lst.add(cl);
-								}
-								cl.send(new IPacket01ICEServers(EaglerSPRelayConfigRelayList.relayServers));
-								logger.debug("[{}][Relay -> Client] PKT 0x01: Send ICE server list to client", (String) arg0.getAttachment());
-							}
-						}else if(ipkt.connectionType == 0x03) {
-							logger.debug("[{}]: Pinging the server", (String) arg0.getAttachment());
-							arg0.send(IPacket.writePacket(new IPacket69Pong(Constants.protocolVersion, config.getComment(), Constants.versionBrand)));
-							arg0.close();
-						}else if(ipkt.connectionType == 0x04) {
-							logger.debug("[{}]: Polling the server for other worlds", (String) arg0.getAttachment());
-							if(config.isEnableShowLocals()) {
-								arg0.send(IPacket.writePacket(new IPacket07LocalWorlds(getLocalWorlds(waiting.address))));
-							}else {
-								arg0.send(IPacket.writePacket(new IPacket07LocalWorlds(null)));
-							}
-							arg0.close();
-						}else {
-							logger.debug("[{}]: Unknown connection type: {}", (String) arg0.getAttachment(), ipkt.connectionType);
-							arg0.send(IPacket.writePacket(new IPacketFFErrorCode(IPacketFFErrorCode.TYPE_ILLEGAL_OPERATION,
-									"Unexpected Init Packet")));
-							arg0.close();
-						}
-					}
-				}else {
-					logger.debug("[{}]: Pending connection did not send a 0x00 packet to identify "
-							+ "as a client or server", (String) arg0.getAttachment());
-					arg0.send(IPacket.writePacket(new IPacketFFErrorCode(IPacketFFErrorCode.TYPE_ILLEGAL_OPERATION,
-							"Unexpected Init Packet")));
-					arg0.close();
-				}
-			}else {
-				EaglerSPServer srv;
-				synchronized(serverConnections) {
-					srv = serverConnections.get(arg0);
-				}
-				if(srv != null) {
-					if(!srv.handle(pkt)) {
-						logger.debug("[{}]: Server sent invalid packet: {}", (String) arg0.getAttachment(), pkt.getClass().getSimpleName());
-						arg0.send(IPacket.writePacket(new IPacketFFErrorCode(IPacketFFErrorCode.TYPE_INVALID_PACKET,
-								"Invalid Packet Recieved")));
-						arg0.close();
-					}
-				}else {
-					EaglerSPClient cl;
-					synchronized(clientConnections) {
-						cl = clientConnections.get(arg0);
-					}
-					if(cl != null) {
-						if(!cl.handle(pkt)) {
-							logger.debug("[{}]: Client sent invalid packet: {}", (String) arg0.getAttachment(), pkt.getClass().getSimpleName());
-							arg0.send(IPacket.writePacket(new IPacketFFErrorCode(IPacketFFErrorCode.TYPE_INVALID_PACKET,
-									"Invalid Packet Recieved")));
-							arg0.close();
-						}
-					}else {
-						logger.debug("[{}]: Connection has no client/server attached to it!", (String) arg0.getAttachment());
-						arg0.send(IPacket.writePacket(new IPacketFFErrorCode(IPacketFFErrorCode.TYPE_ILLEGAL_OPERATION,
-								"Internal Server Error")));
-						arg0.close();
-					}
-				}
-			}
-		}catch(Throwable t) {
-			logger.error("[{}]: Failed to handle binary frame: {}", (String) arg0.getAttachment(), t);
-			arg0.close();
-		}
-	}
-
-	@Override
-	public void onMessage(WebSocket arg0, String arg1) {
-		logger.debug("[{}]: Sent a text frame, disconnecting", (String) arg0.getAttachment());
-		arg0.close();
-	}
-
-	@Override
-	public void onClose(WebSocket arg0, int arg1, String arg2, boolean arg3) {
-		EaglerSPServer srv;
-		synchronized(serverConnections) {
-			srv = serverConnections.remove(arg0);
-		}
-		if(srv != null) {
-			logger.debug("[{}]: Server closed, code: {}", (String) arg0.getAttachment(), srv.code);
-			synchronized(serverCodes) {
-				serverCodes.remove(srv.code);
-			}
-			synchronized(serverAddressSets) {
-				List<EaglerSPServer> lst = serverAddressSets.get(srv.serverAddress);
-				if(lst != null) {
-					lst.remove(srv);
-					if(lst.size() == 0) {
-						serverAddressSets.remove(srv.serverAddress);
-					}
-				}
-			}
-			ArrayList<EaglerSPClient> clientList;
-			synchronized(clientConnections) {
-				clientList = new ArrayList(clientConnections.values());
-			}
-			Iterator<EaglerSPClient> itr = clientList.iterator();
-			while(itr.hasNext()) {
-				EaglerSPClient cl = itr.next();
-				if(cl.server == srv) {
-					logger.debug("[{}]: Disconnecting client: {} (id: ", (String) cl.socket.getAttachment(), cl.id);
-					cl.socket.close();
-				}
-			}
-		}else {
-			EaglerSPClient cl;
-			synchronized(clientConnections) {
-				cl = clientConnections.remove(arg0);
-			}
-			if(cl != null) {
-				synchronized(clientAddressSets) {
-					List<EaglerSPClient> lst = clientAddressSets.get(cl.address);
-					if(lst != null) {
-						lst.remove(cl);
-						if(lst.size() == 0) {
-							clientAddressSets.remove(cl.address);
-						}
-					}
-				}
-				logger.debug("[{}]: Client closed, id: {}", (String) arg0.getAttachment(), cl.id);
-				synchronized(clientIds) {
-					clientIds.remove(cl.id);
-				}
-				cl.server.handleClientDisconnect(cl);
-			}else {
-				logger.debug("[{}]: Connection Closed", (String) arg0.getAttachment());
-			}
-		}
-	}
-
-	@Override
-	public void onError(WebSocket arg0, Exception arg1) {
-		logger.error("[{}]: Exception thrown: {}", (arg0 == null ? "SERVER" : (String) arg0.getAttachment()), arg1.toString());
-		logger.debug(arg1);
-		arg0.close();
-	}
-	
-	private List<IPacket07LocalWorlds.LocalWorld> getLocalWorlds(String addr) {
-		List<IPacket07LocalWorlds.LocalWorld> lst = new ArrayList();
-		synchronized(serverAddressSets) {
-			List<EaglerSPServer> srvs = serverAddressSets.get(addr);
-			if(srvs != null) {
-				if(srvs.size() == 0) {
-					serverAddressSets.remove(addr);
-				}else {
-					for(EaglerSPServer s : srvs) {
-						if(!s.serverHidden) {
-							lst.add(new LocalWorld(s.serverName, s.code));
-						}
-					}
-				}
-			}
-		}
-		return lst;
-	}
-	
-	private boolean rateLimit(RateLimiter limiter, WebSocket sock, String addr) {
-		if(limiter != null) {
-			RateLimit l = limiter.limit(addr);
-			if(l == RateLimit.NONE) {
-				return true;
-			}else if(l == RateLimit.LIMIT) {
-				sock.send(IPacketFEDisconnectClient.ratelimitPacketBlock);
-				sock.close();
-				return false;
-			}else if(l == RateLimit.LIMIT_NOW_LOCKOUT) {
-				sock.send(IPacketFEDisconnectClient.ratelimitPacketBlockLock);
-				sock.close();
-				return false;
-			}else if(l == RateLimit.LOCKOUT) {
-				sock.close();
-				return false;
-			}else {
-				return true; // ?
-			}
-		}else {
-			return true;
-		}
-	}
-
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/EaglerSPRelayConfig.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/EaglerSPRelayConfig.java
deleted file mode 100644
index 3dc8f45..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/EaglerSPRelayConfig.java
+++ /dev/null
@@ -1,480 +0,0 @@
-package net.lax1dude.eaglercraft.sp.relay;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-public class EaglerSPRelayConfig {
-
-	private String address = "0.0.0.0";
-	private int port = 6699;
-	private int codeLength = 5;
-	private String codeChars = "abcdefghijklmnopqrstuvwxyz0123456789";
-	private boolean codeMixCase = false;
-	
-	private int connectionsPerIP = 128;
-	private int worldsPerIP = 32;
-	
-	private boolean openRateLimitEnable = true;
-	private int openRateLimitPeriod = 192;
-	private int openRateLimitLimit = 32;
-	private int openRateLimitLockoutLimit = 48;
-	private int openRateLimitLockoutDuration = 600;
-	
-	private boolean pingRateLimitEnable = true;
-	private int pingRateLimitPeriod = 256;
-	private int pingRateLimitLimit = 128;
-	private int pingRateLimitLockoutLimit = 192;
-	private int pingRateLimitLockoutDuration = 300;
-	
-	private String originWhitelist = "";
-	private String[] originWhitelistArray = new String[0];
-	private boolean enableRealIpHeader = false;
-	private String realIpHeaderName = "X-Real-IP";
-	private boolean enableShowLocals = true;
-	private String serverComment = "Eags. Public LAN Relay";
-
-	public void load(File conf) {
-		if(!conf.isFile()) {
-			EaglerSPRelay.logger.info("Creating config file: {}", conf.getAbsoluteFile());
-			save(conf);
-		}else {
-			EaglerSPRelay.logger.info("Loading config file: {}", conf.getAbsoluteFile());
-			boolean gotPort = false, gotCodeLength = false, gotCodeChars = false;
-			boolean gotCodeMixCase = false;
-			boolean gotConnectionsPerIP = false, gotWorldsPerIP = false,
-					gotOpenRateLimitEnable = false, gotOpenRateLimitPeriod = false,
-					gotOpenRateLimitLimit = false, gotOpenRateLimitLockoutLimit = false,
-					gotOpenRateLimitLockoutDuration = false;
-			boolean gotPingRateLimitEnable = false, gotPingRateLimitPeriod = false,
-					gotPingRateLimitLimit = false, gotPingRateLimitLockoutLimit = false,
-					gotPingRateLimitLockoutDuration = false;
-			boolean gotOriginWhitelist = false, gotEnableRealIpHeader = false,
-					gotRealIpHeaderName = false, gotAddress = false, gotComment = false,
-					gotShowLocals = false;
-			
-			Throwable t2 = null;
-			try(BufferedReader reader = new BufferedReader(new FileReader(conf))) {
-				String s;
-				while((s = reader.readLine()) != null) {
-					String[] ss = s.trim().split(":", 2);
-					if(ss.length == 2) {
-						ss[0] = ss[0].trim();
-						ss[1] = ss[1].trim();
-						if(ss[0].equalsIgnoreCase("port")) {
-							try {
-								port = Integer.parseInt(ss[1]);
-								gotPort = true;
-							}catch(Throwable t) {
-								t2 = t;
-								break;
-							}
-						}else if(ss[0].equalsIgnoreCase("address")) {
-							address = ss[1];
-							gotAddress = true;
-						}else if(ss[0].equalsIgnoreCase("code-length")) {
-							try {
-								codeLength = Integer.parseInt(ss[1]);
-								gotCodeLength = true;
-							}catch(Throwable t) {
-								EaglerSPRelay.logger.warn("Invalid code-length {} in conf {}", ss[1], conf.getAbsoluteFile());
-								EaglerSPRelay.logger.warn(t);
-								t2 = t;
-								break;
-							}
-						}else if(ss[0].equalsIgnoreCase("code-chars")) {
-							if(ss[1].length() < 2) {
-								t2 = new IllegalArgumentException("not enough chars");
-								EaglerSPRelay.logger.warn("Invalid code-chars {} in conf {}", ss[1], conf.getAbsoluteFile());
-								EaglerSPRelay.logger.warn(t2);
-							}else {
-								codeChars = ss[1];
-								gotCodeChars = true;
-							}
-						}else if(ss[0].equalsIgnoreCase("code-mix-case")) {
-							try {
-								codeMixCase = getBooleanValue(ss[1]);
-								gotCodeMixCase = true;
-							}catch(Throwable t) {
-								EaglerSPRelay.logger.warn("Invalid code-mix-case {} in conf {}", ss[1], conf.getAbsoluteFile());
-								EaglerSPRelay.logger.warn(t);
-								t2 = t;
-								break;
-							}
-						}else if(ss[0].equalsIgnoreCase("worlds-per-ip")) {
-							try {
-								worldsPerIP = Integer.parseInt(ss[1]);
-								gotWorldsPerIP = true;
-							}catch(Throwable t) {
-								EaglerSPRelay.logger.warn("Invalid worlds-per-ip {} in conf {}", ss[1], conf.getAbsoluteFile());
-								EaglerSPRelay.logger.warn(t);
-								t2 = t;
-								break;
-							}
-						}else if(ss[0].equalsIgnoreCase("world-ratelimit-enable")) {
-							try {
-								openRateLimitEnable = getBooleanValue(ss[1]);
-								gotOpenRateLimitEnable = true;
-							}catch(Throwable t) {
-								EaglerSPRelay.logger.warn("Invalid world-ratelimit-enable {} in conf {}", ss[1], conf.getAbsoluteFile());
-								EaglerSPRelay.logger.warn(t);
-								t2 = t;
-								break;
-							}
-						}else if(ss[0].equalsIgnoreCase("world-ratelimit-period")) {
-							try {
-								openRateLimitPeriod = Integer.parseInt(ss[1]);
-								gotOpenRateLimitPeriod = true;
-							}catch(Throwable t) {
-								EaglerSPRelay.logger.warn("Invalid world-ratelimit-period {} in conf {}", ss[1], conf.getAbsoluteFile());
-								EaglerSPRelay.logger.warn(t);
-								t2 = t;
-								break;
-							}
-						}else if(ss[0].equalsIgnoreCase("world-ratelimit-limit")) {
-							try {
-								openRateLimitLimit = Integer.parseInt(ss[1]);
-								gotOpenRateLimitLimit = true;
-							}catch(Throwable t) {
-								EaglerSPRelay.logger.warn("Invalid world-ratelimit-limit {} in conf {}", ss[1], conf.getAbsoluteFile());
-								EaglerSPRelay.logger.warn(t);
-								t2 = t;
-								break;
-							}
-						}else if(ss[0].equalsIgnoreCase("world-ratelimit-lockout-limit")) {
-							try {
-								openRateLimitLockoutLimit = Integer.parseInt(ss[1]);
-								gotOpenRateLimitLockoutLimit = true;
-							}catch(Throwable t) {
-								EaglerSPRelay.logger.warn("Invalid world-ratelimit-lockout-limit {} in conf {}", ss[1], conf.getAbsoluteFile());
-								EaglerSPRelay.logger.warn(t);
-								t2 = t;
-								break;
-							}
-						}else if(ss[0].equalsIgnoreCase("world-ratelimit-lockout-duration")) {
-							try {
-								openRateLimitLockoutDuration = Integer.parseInt(ss[1]);
-								gotOpenRateLimitLockoutDuration = true;
-							}catch(Throwable t) {
-								EaglerSPRelay.logger.warn("Invalid world-ratelimit-lockout-duration {} in conf {}", ss[1], conf.getAbsoluteFile());
-								EaglerSPRelay.logger.warn(t);
-								t2 = t;
-								break;
-							}
-						}else if(ss[0].equalsIgnoreCase("connections-per-ip")) {
-							try {
-								connectionsPerIP = Integer.parseInt(ss[1]);
-								gotConnectionsPerIP = true;
-							}catch(Throwable t) {
-								EaglerSPRelay.logger.warn("Invalid connections-per-ip {} in conf {}", ss[1], conf.getAbsoluteFile());
-								EaglerSPRelay.logger.warn(t);
-								t2 = t;
-								break;
-							}
-						}else if(ss[0].equalsIgnoreCase("ping-ratelimit-enable")) {
-							try {
-								pingRateLimitEnable = getBooleanValue(ss[1]);
-								gotPingRateLimitEnable = true;
-							}catch(Throwable t) {
-								EaglerSPRelay.logger.warn("Invalid ping-ratelimit-enable {} in conf {}", ss[1], conf.getAbsoluteFile());
-								EaglerSPRelay.logger.warn(t);
-								t2 = t;
-								break;
-							}
-						}else if(ss[0].equalsIgnoreCase("ping-ratelimit-period")) {
-							try {
-								pingRateLimitPeriod = Integer.parseInt(ss[1]);
-								gotPingRateLimitPeriod = true;
-							}catch(Throwable t) {
-								EaglerSPRelay.logger.warn("Invalid ping-ratelimit-period {} in conf {}", ss[1], conf.getAbsoluteFile());
-								EaglerSPRelay.logger.warn(t);
-								t2 = t;
-								break;
-							}
-						}else if(ss[0].equalsIgnoreCase("ping-ratelimit-limit")) {
-							try {
-								pingRateLimitLimit = Integer.parseInt(ss[1]);
-								gotPingRateLimitLimit = true;
-							}catch(Throwable t) {
-								EaglerSPRelay.logger.warn("Invalid ping-ratelimit-limit {} in conf {}", ss[1], conf.getAbsoluteFile());
-								EaglerSPRelay.logger.warn(t);
-								t2 = t;
-								break;
-							}
-						}else if(ss[0].equalsIgnoreCase("ping-ratelimit-lockout-limit")) {
-							try {
-								pingRateLimitLockoutLimit = Integer.parseInt(ss[1]);
-								gotPingRateLimitLockoutLimit = true;
-							}catch(Throwable t) {
-								EaglerSPRelay.logger.warn("Invalid ping-ratelimit-lockout-limit {} in conf {}", ss[1], conf.getAbsoluteFile());
-								EaglerSPRelay.logger.warn(t);
-								t2 = t;
-								break;
-							}
-						}else if(ss[0].equalsIgnoreCase("ping-ratelimit-lockout-duration")) {
-							try {
-								pingRateLimitLockoutDuration = Integer.parseInt(ss[1]);
-								gotPingRateLimitLockoutDuration = true;
-							}catch(Throwable t) {
-								EaglerSPRelay.logger.warn("Invalid ping-ratelimit-lockout-duration {} in conf {}", ss[1], conf.getAbsoluteFile());
-								EaglerSPRelay.logger.warn(t);
-								t2 = t;
-								break;
-							}
-						}else if(ss[0].equalsIgnoreCase("origin-whitelist")) {
-							originWhitelist = ss[1];
-							gotOriginWhitelist = true;
-						}else if(ss[0].equalsIgnoreCase("enable-real-ip-header")) {
-							try {
-								enableRealIpHeader = getBooleanValue(ss[1]);
-								gotEnableRealIpHeader = true;
-							}catch(Throwable t) {
-								EaglerSPRelay.logger.warn("Invalid enable-real-ip-header {} in conf {}", ss[1], conf.getAbsoluteFile());
-								EaglerSPRelay.logger.warn(t);
-								t2 = t;
-								break;
-							}
-						}else if(ss[0].equalsIgnoreCase("real-ip-header-name")) {
-							realIpHeaderName = ss[1];
-							gotRealIpHeaderName = true;
-						}else if(ss[0].equalsIgnoreCase("show-local-worlds")) {
-							try {
-								enableShowLocals = getBooleanValue(ss[1]);
-								gotShowLocals = true;
-							}catch(Throwable t) {
-								EaglerSPRelay.logger.warn("Invalid show-local-worlds {} in conf {}", ss[1], conf.getAbsoluteFile());
-								EaglerSPRelay.logger.warn(t);
-								t2 = t;
-								break;
-							}
-						}else if(ss[0].equalsIgnoreCase("server-comment")) {
-							serverComment = ss[1];
-							gotComment = true;
-						}
-					}
-				}
-			}catch(IOException t) {
-				EaglerSPRelay.logger.error("Failed to load config file: {}", conf.getAbsoluteFile());
-				EaglerSPRelay.logger.error(t);
-			}catch(Throwable t) {
-				EaglerSPRelay.logger.warn("Invalid config file: {}", conf.getAbsoluteFile());
-				EaglerSPRelay.logger.warn(t);
-				t2 = t;
-			}
-			if(t2 != null || !gotPort || !gotCodeLength || !gotCodeChars ||
-					!gotCodeMixCase || !gotWorldsPerIP || !gotOpenRateLimitEnable ||
-					!gotOpenRateLimitPeriod || !gotOpenRateLimitLimit ||
-					!gotOpenRateLimitLockoutLimit || !gotOpenRateLimitLockoutDuration ||
-					!gotConnectionsPerIP || !gotPingRateLimitEnable ||
-					!gotPingRateLimitPeriod || !gotPingRateLimitLimit ||
-					!gotPingRateLimitLockoutLimit || !gotPingRateLimitLockoutDuration ||
-					!gotOriginWhitelist || !gotEnableRealIpHeader || !gotAddress ||
-					!gotComment || !gotShowLocals || !gotRealIpHeaderName) {
-				EaglerSPRelay.logger.warn("Updating config file: {}", conf.getAbsoluteFile());
-				save(conf);
-			}
-			String[] splitted = originWhitelist.split(";");
-			List<String> splittedList = new ArrayList();
-			for(int i = 0; i < splitted.length; ++i) {
-				splitted[i] = splitted[i].trim().toLowerCase();
-				if(splitted[i].length() > 0) {
-					splittedList.add(splitted[i]);
-				}
-			}
-			originWhitelistArray = new String[splittedList.size()];
-			for(int i = 0; i < originWhitelistArray.length; ++i) {
-				originWhitelistArray[i] = splittedList.get(i);
-			}
-		}
-	}
-	
-	public void save(File conf) {
-		try(PrintWriter w = new PrintWriter(new FileOutputStream(conf))) {
-			w.println("[EaglerSPRelay]");
-			w.println("address: " + address);
-			w.println("port: " + port);
-			w.println("code-length: " + codeLength);
-			w.println("code-chars: " + codeChars);
-			w.println("code-mix-case: " + codeMixCase);
-			w.println("connections-per-ip: " + connectionsPerIP);
-			w.println("ping-ratelimit-enable: " + pingRateLimitEnable);
-			w.println("ping-ratelimit-period: " + pingRateLimitPeriod);
-			w.println("ping-ratelimit-limit: " + pingRateLimitLimit);
-			w.println("ping-ratelimit-lockout-limit: " + pingRateLimitLockoutLimit);
-			w.println("ping-ratelimit-lockout-duration: " + pingRateLimitLockoutDuration);
-			w.println("worlds-per-ip: " + worldsPerIP);
-			w.println("world-ratelimit-enable: " + openRateLimitEnable);
-			w.println("world-ratelimit-period: " + openRateLimitPeriod);
-			w.println("world-ratelimit-limit: " + openRateLimitLimit);
-			w.println("world-ratelimit-lockout-limit: " + openRateLimitLockoutLimit);
-			w.println("world-ratelimit-lockout-duration: " + openRateLimitLockoutDuration);
-			w.println("origin-whitelist: " + originWhitelist);
-			w.println("real-ip-header-name: " + realIpHeaderName);
-			w.println("enable-real-ip-header: " + enableRealIpHeader);
-			w.println("show-local-worlds: " + isEnableShowLocals());
-			w.print("server-comment: " + serverComment);
-		}catch(IOException t) {
-			EaglerSPRelay.logger.error("Failed to write config file: {}", conf.getAbsoluteFile());
-			EaglerSPRelay.logger.error(t);
-		}
-	}
-	
-	private static boolean getBooleanValue(String str) {
-		if(str.equalsIgnoreCase("true") || str.equals("1")) {
-			return true;
-		}else if(str.equalsIgnoreCase("false") || str.equals("0")) {
-			return false;
-		}else {
-			throw new IllegalArgumentException("Not a boolean: " + str);
-		}
-	}
-
-	public String getAddress() {
-		return address;
-	}
-
-	public int getPort() {
-		return port;
-	}
-
-	public int getCodeLength() {
-		return codeLength;
-	}
-
-	public String getCodeChars() {
-		return codeChars;
-	}
-
-	public boolean isCodeMixCase() {
-		return codeMixCase;
-	}
-
-	public int getConnectionsPerIP() {
-		return connectionsPerIP;
-	}
-
-	public boolean isPingRateLimitEnable() {
-		return pingRateLimitEnable;
-	}
-
-	public int getPingRateLimitPeriod() {
-		return pingRateLimitPeriod;
-	}
-
-	public int getPingRateLimitLimit() {
-		return pingRateLimitLimit;
-	}
-
-	public int getPingRateLimitLockoutLimit() {
-		return pingRateLimitLockoutLimit;
-	}
-
-	public int getPingRateLimitLockoutDuration() {
-		return pingRateLimitLockoutDuration;
-	}
-
-	public int getWorldsPerIP() {
-		return worldsPerIP;
-	}
-
-	public boolean isWorldRateLimitEnable() {
-		return openRateLimitEnable;
-	}
-
-	public int getWorldRateLimitPeriod() {
-		return openRateLimitPeriod;
-	}
-
-	public int getWorldRateLimitLimit() {
-		return openRateLimitLimit;
-	}
-
-	public int getWorldRateLimitLockoutLimit() {
-		return openRateLimitLockoutLimit;
-	}
-
-	public int getWorldRateLimitLockoutDuration() {
-		return openRateLimitLockoutDuration;
-	}
-
-	public String getOriginWhitelist() {
-		return originWhitelist;
-	}
-
-	public String[] getOriginWhitelistArray() {
-		return originWhitelistArray;
-	}
-	
-	public boolean getIsWhitelisted(String domain) {
-		if(originWhitelistArray.length == 0) {
-			return true;
-		}else {
-			if(domain == null) {
-				domain = "null";
-			}else {
-				domain = domain.toLowerCase();
-				if(domain.equals("null")) {
-					domain = "offline";
-				}else {
-					if(domain.startsWith("http://")) {
-						domain = domain.substring(7);
-					}else if(domain.startsWith("https://")) {
-						domain = domain.substring(8);
-					}
-				}
-			}
-			for(int i = 0; i < originWhitelistArray.length; ++i) {
-				String etr = originWhitelistArray[i].toLowerCase();
-				if(etr.startsWith("*")) {
-					if(domain.endsWith(etr.substring(1))) {
-						return true;
-					}
-				}else {
-					if(domain.equals(etr)) {
-						return true;
-					}
-				}
-			}
-			return false;
-		}
-	}
-
-	public String getRealIPHeaderName() {
-		return realIpHeaderName;
-	}
-
-	public boolean isEnableRealIpHeader() {
-		return enableRealIpHeader;
-	}
-
-	public String getComment() {
-		return serverComment;
-	}
-	
-	public String generateCode() {
-		Random r = new Random();
-		char[] ret = new char[codeLength];
-		for(int i = 0; i < codeLength; ++i) {
-			ret[i] = codeChars.charAt(r.nextInt(codeChars.length()));
-			if(codeMixCase) {
-				if(r.nextBoolean()) {
-					ret[i] = Character.toLowerCase(ret[i]);
-				}else {
-					ret[i] = Character.toUpperCase(ret[i]);
-				}
-			}
-		}
-		return new String(ret);
-	}
-
-	public boolean isEnableShowLocals() {
-		return enableShowLocals;
-	}
-	
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/EaglerSPRelayConfigRelayList.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/EaglerSPRelayConfigRelayList.java
deleted file mode 100644
index ee691aa..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/EaglerSPRelayConfigRelayList.java
+++ /dev/null
@@ -1,149 +0,0 @@
-package net.lax1dude.eaglercraft.sp.relay;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-
-public class EaglerSPRelayConfigRelayList {
-	
-	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;
-		}
-		
-	}
-	
-	public static final Collection<RelayServer> relayServers = new ArrayList();
-	
-	public static void loadRelays(File list) throws IOException {
-		ArrayList<RelayServer> loading = new ArrayList();
-		
-		if(!list.isFile()) {
-			EaglerSPRelay.logger.info("Creating new {}...", list.getName());
-			try(InputStream is = EaglerSPRelayConfigRelayList.class.getResourceAsStream("/relays.txt");
-					FileOutputStream os = new FileOutputStream(list)) {
-				byte[] buffer = new byte[4096];
-				int i;
-				while((i = is.read(buffer)) != -1) {
-					os.write(buffer, 0, i);
-				}
-			}
-		}
-
-		EaglerSPRelay.logger.info("Loading STUN/TURN relays from: {}", list.getName());
-		
-		RelayType addType = null;
-		String addAddress = null;
-		String addUsername = null;
-		String addPassword = null;
-		try(BufferedReader reader = new BufferedReader(new FileReader(list))) {
-			String line;
-			while((line = reader.readLine()) != null) {
-				line = line.trim();
-				if(line.length() == 0) {
-					continue;
-				}
-				boolean isSTUNHead = line.equals("[STUN]");
-				boolean isTURNHead = line.equals("[TURN]");
-				if(isSTUNHead || isTURNHead) {
-					if(addType != null) {
-						add(list.getName(), loading, addType, addAddress, addUsername, addPassword);
-					}
-					addAddress = null;
-					addUsername = null;
-					addPassword = null;
-					addType = null;
-				}
-				if(isSTUNHead) {
-					addType = RelayType.STUN;
-				}else if(isTURNHead) {
-					addType = RelayType.TURN;
-				}else if(line.startsWith("url")) {
-					int spidx = line.indexOf('=') + 1;
-					if(spidx < 3) {
-						EaglerSPRelay.logger.error("Error: Invalid line in {}: ", line);
-					}else {
-						line = line.substring(spidx).trim();
-						if(line.length() < 1) {
-							EaglerSPRelay.logger.error("Error: Invalid line in {}: ", line);
-						}else {
-							addAddress = line;
-						}
-					}
-				}else if(line.startsWith("username")) {
-					int spidx = line.indexOf('=') + 1;
-					if(spidx < 8) {
-						EaglerSPRelay.logger.error("Error: Invalid line in {}: ", line);
-					}else {
-						line = line.substring(spidx).trim();
-						if(line.length() < 1) {
-							EaglerSPRelay.logger.error("Error: Invalid line in {}: ", line);
-						}else {
-							addUsername = line;
-						}
-					}
-				}else if(line.startsWith("password")) {
-					int spidx = line.indexOf('=') + 1;
-					if(spidx < 8) {
-						EaglerSPRelay.logger.error("Error: Invalid line in {}: ", line);
-					}else {
-						line = line.substring(spidx).trim();
-						if(line.length() < 1) {
-							EaglerSPRelay.logger.error("Error: Invalid line in {}: ", line);
-						}else {
-							addPassword = line;
-						}
-					}
-				}else {
-					EaglerSPRelay.logger.error("Error: Invalid line in {}: ", line);
-				}
-			}
-		}
-		
-		if(addType != null) {
-			add(list.getName(), loading, addType, addAddress, addUsername, addPassword);
-		}
-		
-		if(loading.size() == 0) {
-			throw new IOException(list.getName() + ": no servers loaded");
-		}else {
-			relayServers.clear();
-			relayServers.addAll(loading);
-		}
-		
-	}
-	
-	private static void add(String filename, Collection<RelayServer> loading, RelayType type, String url, String user, String pass) {
-		if(url == null) {
-			EaglerSPRelay.logger.error("Error: Invalid relay in {}, missing 'url'", filename);
-		}else {
-			loading.add(new RelayServer(type, url, user, pass));
-		}
-	}
-	
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/EaglerSPServer.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/EaglerSPServer.java
deleted file mode 100644
index 8bc8bde..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/EaglerSPServer.java
+++ /dev/null
@@ -1,145 +0,0 @@
-package net.lax1dude.eaglercraft.sp.relay;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.java_websocket.WebSocket;
-
-import net.lax1dude.eaglercraft.sp.relay.pkt.IPacket;
-import net.lax1dude.eaglercraft.sp.relay.pkt.IPacket02NewClient;
-import net.lax1dude.eaglercraft.sp.relay.pkt.IPacket04Description;
-import net.lax1dude.eaglercraft.sp.relay.pkt.IPacket03ICECandidate;
-import net.lax1dude.eaglercraft.sp.relay.pkt.IPacket05ClientSuccess;
-import net.lax1dude.eaglercraft.sp.relay.pkt.IPacket06ClientFailure;
-import net.lax1dude.eaglercraft.sp.relay.pkt.IPacketFEDisconnectClient;
-import net.lax1dude.eaglercraft.sp.relay.pkt.IPacketFFErrorCode;
-
-public class EaglerSPServer {
-	
-	public final WebSocket socket;
-	public final String code;
-	public final Map<String,EaglerSPClient> clients;
-	public final String serverName;
-	public final String serverAddress;
-	public final boolean serverHidden;
-	
-	EaglerSPServer(WebSocket sock, String code, String serverName, String serverAddress) {
-		this.socket = sock;
-		this.code = code;
-		this.clients = new HashMap();
-		
-		if(serverName.endsWith(";1")) {
-			this.serverHidden = true;
-			serverName = serverName.substring(0, serverName.length() - 2);
-		}else if(serverName.endsWith(";0")) {
-			this.serverHidden = false;
-			serverName = serverName.substring(0, serverName.length() - 2);
-		}else {
-			this.serverHidden = false;
-		}
-		
-		this.serverName = serverName;
-		this.serverAddress = serverAddress;
-	}
-	
-	public void send(IPacket packet) {
-		if(this.socket.isOpen()) {
-			try {
-				this.socket.send(IPacket.writePacket(packet));
-			}catch(IOException ex) {
-				EaglerSPRelay.logger.debug("Error sending data to {}", this.serverAddress);
-				EaglerSPRelay.logger.debug(ex);
-				try {
-					this.socket.send(IPacket.writePacket(new IPacketFFErrorCode(IPacketFFErrorCode.TYPE_INTERNAL_ERROR,
-							"Internal Server Error")));
-				}catch(IOException ex2) {
-				}
-				this.socket.close();
-			}
-		}else {
-			EaglerSPRelay.logger.debug("WARNING: Tried to send data to {} after the connection closed.", this.serverAddress);
-		}
-	}
-	
-	public boolean handle(IPacket _packet) throws IOException {
-		if(_packet instanceof IPacket03ICECandidate) {
-			IPacket03ICECandidate packet = (IPacket03ICECandidate)_packet;
-			EaglerSPClient cl = clients.get(packet.peerId);
-			if(cl != null) {
-				if(LoginState.assertEquals(cl, LoginState.SENT_ICE_CANDIDATE)) {
-					cl.state = LoginState.RECIEVED_ICE_CANIDATE;
-					cl.handleServerICECandidate(packet);
-					EaglerSPRelay.logger.debug("[{}][Server -> Relay -> Client] PKT 0x03: ICECandidate", (String) cl.socket.getAttachment());
-				}
-			}else {
-				this.socket.send(IPacket.writePacket(new IPacketFFErrorCode(IPacketFFErrorCode.TYPE_UNKNOWN_CLIENT,
-						"Unknown Client ID: " + packet.peerId)));
-			}
-			return true;
-		}else if(_packet instanceof IPacket04Description) {
-			IPacket04Description packet = (IPacket04Description)_packet;
-			EaglerSPClient cl = clients.get(packet.peerId);
-			if(cl != null) {
-				if(LoginState.assertEquals(cl, LoginState.SENT_DESCRIPTION)) {
-					cl.state = LoginState.RECIEVED_DESCRIPTION;
-					cl.handleServerDescription(packet);
-					EaglerSPRelay.logger.debug("[{}][Server -> Relay -> Client] PKT 0x04: Description", (String) cl.socket.getAttachment());
-				}
-			}else {
-				this.socket.send(IPacket.writePacket(new IPacketFFErrorCode(IPacketFFErrorCode.TYPE_UNKNOWN_CLIENT,
-						"Unknown Client ID: " + packet.peerId)));
-			}
-			return true;
-		}else if(_packet instanceof IPacketFEDisconnectClient) {
-			IPacketFEDisconnectClient packet = (IPacketFEDisconnectClient)_packet;
-			EaglerSPClient cl = clients.get(packet.clientId);
-			if(cl != null) {
-				cl.handleServerDisconnectClient(packet);
-				EaglerSPRelay.logger.debug("[{}][Server -> Relay -> Client] PKT 0xFE: Disconnect: {}: {}", (String) cl.socket.getAttachment(),
-						packet.code, packet.reason);
-			}else {
-				this.socket.send(IPacket.writePacket(new IPacketFFErrorCode(IPacketFFErrorCode.TYPE_UNKNOWN_CLIENT,
-						"Unknown Client ID: " + packet.clientId)));
-			}
-			return true;
-		}else {
-			return false;
-		}
-	}
-	
-	public void handleNewClient(EaglerSPClient client) {
-		synchronized(clients) {
-			clients.put(client.id, client);
-			send(new IPacket02NewClient(client.id));
-			EaglerSPRelay.logger.debug("[{}][Relay -> Server] PKT 0x02: Notify server of the client, id: {}", serverAddress, client.id);
-		}
-	}
-	
-	public void handleClientDisconnect(EaglerSPClient client) {
-		synchronized(clients) {
-			clients.remove(client.id);
-		}
-		if(!client.serverNotifiedOfClose) {
-			send(new IPacketFEDisconnectClient(client.id, IPacketFEDisconnectClient.TYPE_UNKNOWN, "End of stream"));
-			client.serverNotifiedOfClose = true;
-		}
-	}
-
-	public void handleClientICECandidate(EaglerSPClient client, IPacket03ICECandidate packet) {
-		send(new IPacket03ICECandidate(client.id, packet.candidate));
-	}
-
-	public void handleClientDescription(EaglerSPClient client, IPacket04Description packet) {
-		send(new IPacket04Description(client.id, packet.description));
-	}
-
-	public void handleClientSuccess(EaglerSPClient client, IPacket05ClientSuccess packet) {
-		send(new IPacket05ClientSuccess(client.id));
-	}
-
-	public void handleClientFailure(EaglerSPClient client, IPacket06ClientFailure packet) {
-		send(new IPacket06ClientFailure(client.id));
-	}
-
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/LoginState.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/LoginState.java
deleted file mode 100644
index c494689..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/LoginState.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.lax1dude.eaglercraft.sp.relay;
-
-import net.lax1dude.eaglercraft.sp.relay.pkt.IPacketFEDisconnectClient;
-
-/**
- * SENT = Client has sent something to the server<br>
- * RECIEVED = Server has sent something to the client
- */
-public enum LoginState {
-	
-	INIT, SENT_ICE_CANDIDATE, RECIEVED_ICE_CANIDATE, SENT_DESCRIPTION, RECIEVED_DESCRIPTION, FINISHED;
-	
-	public static boolean assertEquals(EaglerSPClient client, LoginState state) {
-		if(client.state != state) {
-			String msg = "client is in state " + client.state.name() + " when it was supposed to be " + state.name();
-			client.disconnect(IPacketFEDisconnectClient.TYPE_INVALID_OPERATION, msg);
-			EaglerSPRelay.logger.debug("[{}][Relay -> Client] PKT 0xFE: TYPE_INVALID_OPERATION: {}", (String) client.socket.getAttachment(), msg);
-			return false;
-		}else {
-			return true;
-		}
-	}
-	
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/RateLimiter.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/RateLimiter.java
deleted file mode 100644
index 5814aca..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/RateLimiter.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package net.lax1dude.eaglercraft.sp.relay;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-public class RateLimiter {
-	
-	private final int period;
-	private final int limit;
-	private final int lockoutLimit;
-	private final int lockoutDuration;
-	
-	private class RateLimitEntry {
-		
-		protected long timer;
-		protected int count;
-		protected long lockedTimer;
-		protected boolean locked;
-		
-		protected RateLimitEntry() {
-			timer = System.currentTimeMillis();
-			count = 0;
-			lockedTimer = 0l;
-			locked = false;
-		}
-		
-		protected void update() {
-			long millis = System.currentTimeMillis();
-			if(locked) {
-				if(millis - lockedTimer > RateLimiter.this.lockoutDuration) {
-					timer = millis;
-					count = 0;
-					lockedTimer = 0l;
-					locked = false;
-				}
-			}else {
-				long p = RateLimiter.this.period / RateLimiter.this.limit;
-				int breaker = 0;
-				while(millis - timer > p) {
-					timer += p;
-					--count;
-					if(count < 0 || ++breaker > 100) {
-						timer = millis;
-						count = 0;
-						break;
-					}
-				}
-			}
-		}
-		
-	}
-	
-	public static enum RateLimit {
-		NONE, LIMIT, LIMIT_NOW_LOCKOUT, LOCKOUT;
-	}
-	
-	private final Map<String, RateLimitEntry> limiters = new HashMap();
-	
-	public RateLimiter(int period, int limit, int lockoutLimit, int lockoutDuration) {
-		this.period = period;
-		this.limit = limit;
-		this.lockoutLimit = lockoutLimit;
-		this.lockoutDuration = lockoutDuration;
-	}
-	
-	public RateLimit limit(String addr) {
-		synchronized(this) {
-			RateLimitEntry etr = limiters.get(addr);
-			
-			if(etr == null) {
-				etr = new RateLimitEntry();
-				limiters.put(addr, etr);
-			}else {
-				etr.update();
-			}
-			
-			if(etr.locked) {
-				return RateLimit.LOCKOUT;
-			}
-			
-			++etr.count;
-			if(etr.count >= lockoutLimit) {
-				etr.count = 0;
-				etr.locked = true;
-				etr.lockedTimer = System.currentTimeMillis();
-				return RateLimit.LIMIT_NOW_LOCKOUT;
-			}else if(etr.count > limit) {
-				return RateLimit.LIMIT;
-			}else {
-				return RateLimit.NONE;
-			}
-		}
-	}
-	
-	public void update() {
-		synchronized(this) {
-			Iterator<RateLimitEntry> itr = limiters.values().iterator();
-			while(itr.hasNext()) {
-				if(itr.next().count == 0) {
-					itr.remove();
-				}
-			}
-		}
-	}
-	
-	public void reset() {
-		synchronized(this) {
-			limiters.clear();
-		}
-	}
-
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/Util.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/Util.java
deleted file mode 100644
index e4129a1..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/Util.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package net.lax1dude.eaglercraft.sp.relay;
-
-import java.net.InetSocketAddress;
-
-public class Util {
-
-	public static void sleep(long millis) {
-		try {
-			Thread.sleep(millis);
-		} catch (InterruptedException e) {
-		}
-	}
-	
-	public static String sock2String(InetSocketAddress sock) {
-		return sock.getAddress().getHostAddress() + ":" + sock.getPort();
-	}
-	
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket.java
deleted file mode 100644
index c38f3c1..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket.java
+++ /dev/null
@@ -1,152 +0,0 @@
-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;
-
-import net.lax1dude.eaglercraft.sp.relay.EaglerSPRelay;
-
-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);
-			int j = input.available();
-			if(j > 0) {
-				throw new IOException("Packet type " + i + " had " + j + " remaining bytes");
-			}
-			return pkt;
-		} catch (InstantiationException | IllegalAccessException e) {
-			EaglerSPRelay.logger.error("Could not instanciate packet {}", i);
-			EaglerSPRelay.logger.error(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) {
-				EaglerSPRelay.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) {
-				return null;
-			}
-			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) {
-			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));
-			}
-		}
-	}
-	
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket00Handshake.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket00Handshake.java
deleted file mode 100644
index 268c7f9..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket00Handshake.java
+++ /dev/null
@@ -1,42 +0,0 @@
-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);
-		output.write(connectionVersion);
-		IPacket.writeASCII8(output, connectionCode);
-	}
-	
-	@Override
-	public int packetLength() {
-		return 1 + 1 + (connectionCode != null ? 1 + connectionCode.length() : 0);
-	}
-
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket01ICEServers.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket01ICEServers.java
deleted file mode 100644
index 3a55ae9..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket01ICEServers.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package net.lax1dude.eaglercraft.sp.relay.pkt;
-
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Iterator;
-
-import net.lax1dude.eaglercraft.sp.relay.EaglerSPRelayConfigRelayList.RelayServer;
-import net.lax1dude.eaglercraft.sp.relay.EaglerSPRelayConfigRelayList.RelayType;
-
-public class IPacket01ICEServers extends IPacket {
-	
-	public final Collection<RelayServer> servers;
-	
-	public IPacket01ICEServers(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.STUN) {
-				output.write('S');
-			}else if(srv.type == RelayType.TURN) {
-				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);
-		}
-	}
-	
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket02NewClient.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket02NewClient.java
deleted file mode 100644
index 4fa91cf..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket02NewClient.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package net.lax1dude.eaglercraft.sp.relay.pkt;
-
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-public class IPacket02NewClient extends IPacket {
-	
-	public String clientId;
-	
-	public IPacket02NewClient(String clientId) {
-		this.clientId = clientId;
-	}
-	
-	public IPacket02NewClient() {
-	}
-	
-	public void write(DataOutputStream output) throws IOException {
-		writeASCII8(output, clientId);
-	}
-	
-	public int packetLength() {
-		return 1 + clientId.length();
-	}
-	
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket03ICECandidate.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket03ICECandidate.java
deleted file mode 100644
index 239a27f..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket03ICECandidate.java
+++ /dev/null
@@ -1,34 +0,0 @@
-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();
-	}
-
-}
\ No newline at end of file
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket04Description.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket04Description.java
deleted file mode 100644
index 8693c7b..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket04Description.java
+++ /dev/null
@@ -1,34 +0,0 @@
-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();
-	}
-
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket05ClientSuccess.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket05ClientSuccess.java
deleted file mode 100644
index a215a1a..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket05ClientSuccess.java
+++ /dev/null
@@ -1,30 +0,0 @@
-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();
-	}
-	
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket06ClientFailure.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket06ClientFailure.java
deleted file mode 100644
index fceae93..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket06ClientFailure.java
+++ /dev/null
@@ -1,30 +0,0 @@
-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();
-	}
-	
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket07LocalWorlds.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket07LocalWorlds.java
deleted file mode 100644
index f8135f7..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket07LocalWorlds.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package net.lax1dude.eaglercraft.sp.relay.pkt;
-
-import java.io.DataOutputStream;
-import java.io.IOException;
-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(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);
-			}
-		}
-	}
-	
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket69Pong.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket69Pong.java
deleted file mode 100644
index 20848e2..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacket69Pong.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package net.lax1dude.eaglercraft.sp.relay.pkt;
-
-import java.io.DataOutputStream;
-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 IPacket69Pong() {
-	}
-	
-	public void write(DataOutputStream output) throws IOException {
-		output.write(protcolVersion);
-		writeASCII8(output, comment);
-		writeASCII8(output, brand);
-	}
-	
-	public int packetLength() {
-		return 3 + comment.length() + brand.length();
-	}
-	
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacketFEDisconnectClient.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacketFEDisconnectClient.java
deleted file mode 100644
index d67894a..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacketFEDisconnectClient.java
+++ /dev/null
@@ -1,52 +0,0 @@
-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_SERVER_DISCONNECT = 0x05;
-	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 });
-	
-}
diff --git a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacketFFErrorCode.java b/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacketFFErrorCode.java
deleted file mode 100644
index 8effe08..0000000
--- a/sp-relay/src/main/java/net/lax1dude/eaglercraft/sp/relay/pkt/IPacketFFErrorCode.java
+++ /dev/null
@@ -1,46 +0,0 @@
-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();
-	}
-
-}
diff --git a/sp-relay/src/main/resources/relays.txt b/sp-relay/src/main/resources/relays.txt
deleted file mode 100644
index 06308f4..0000000
--- a/sp-relay/src/main/resources/relays.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-
-[STUN]
-url=stun:stun.l.google.com:19302
-
-[STUN]
-url=stun:stun1.l.google.com:19302
-
-[STUN]
-url=stun:stun2.l.google.com:19302
-
-[STUN]
-url=stun:stun3.l.google.com:19302
-
-[STUN]
-url=stun:stun4.l.google.com:19302
-
-[STUN]
-url=stun:openrelay.metered.ca:80
-
-[TURN]
-url=turn:openrelay.metered.ca:443
-username=openrelayproject
-password=openrelayproject
-
-[TURN]
-url=turn:openrelay.metered.ca:443?transport=tcp
-username=openrelayproject
-password=openrelayproject