diff --git a/proxy/pom.xml b/proxy/pom.xml
index a50f2660..cf09fbfe 100644
--- a/proxy/pom.xml
+++ b/proxy/pom.xml
@@ -67,12 +67,6 @@
3.18.0-GA
runtime
-
- org.xerial
- sqlite-jdbc
- 3.7.2
- runtime
-
diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
index a6f65076..a7334d28 100644
--- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
+++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java
@@ -2,7 +2,7 @@ package net.md_5.bungee;
import com.google.common.io.ByteStreams;
import net.md_5.bungee.log.BungeeLogger;
-import net.md_5.bungee.reconnect.SQLReconnectHandler;
+import net.md_5.bungee.reconnect.YamlReconnectHandler;
import net.md_5.bungee.scheduler.BungeeScheduler;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.gson.Gson;
@@ -219,7 +219,7 @@ public class BungeeCord extends ProxyServer
config.load();
if ( reconnectHandler == null )
{
- reconnectHandler = new SQLReconnectHandler();
+ reconnectHandler = new YamlReconnectHandler();
}
isRunning = true;
diff --git a/proxy/src/main/java/net/md_5/bungee/reconnect/SQLReconnectHandler.java b/proxy/src/main/java/net/md_5/bungee/reconnect/SQLReconnectHandler.java
deleted file mode 100644
index 0f1d0a2b..00000000
--- a/proxy/src/main/java/net/md_5/bungee/reconnect/SQLReconnectHandler.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package net.md_5.bungee.reconnect;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.logging.Level;
-import net.md_5.bungee.api.ProxyServer;
-import net.md_5.bungee.api.config.ServerInfo;
-import net.md_5.bungee.api.connection.ProxiedPlayer;
-
-public class SQLReconnectHandler extends AbstractReconnectManager
-{
-
- private final Connection connection;
-
- public SQLReconnectHandler() throws ClassNotFoundException, SQLException
- {
- Class.forName( "org.sqlite.JDBC" );
- connection = DriverManager.getConnection( "jdbc:sqlite:bungee.sqlite" );
-
- try ( PreparedStatement ps = connection.prepareStatement(
- "CREATE TABLE IF NOT EXISTS players ("
- + "playerId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
- + "username TEXT NOT NULL UNIQUE COLLATE NOCASE,"
- + "seen INTEGER,"
- + "server TEXT"
- + ");" ) )
- {
- ps.executeUpdate();
- }
- }
-
- @Override
- protected ServerInfo getStoredServer(ProxiedPlayer player)
- {
- String server = null;
- try ( PreparedStatement ps = connection.prepareStatement( "SELECT server FROM players WHERE username = ?" ) )
- {
- ps.setString( 1, player.getName() );
- try ( ResultSet rs = ps.executeQuery() )
- {
- if ( rs.next() )
- {
- server = rs.getString( 1 );
- } else
- {
- try ( PreparedStatement playerUpdate = connection.prepareStatement( "INSERT INTO players( username ) VALUES( ? )" ) )
- {
- playerUpdate.setString( 1, player.getName() );
- playerUpdate.executeUpdate();
- }
- }
- }
- } catch ( SQLException ex )
- {
- ProxyServer.getInstance().getLogger().log( Level.WARNING, "Could not load location for player " + player.getName(), ex );
- }
-
- return ProxyServer.getInstance().getServerInfo( server );
- }
-
- @Override
- public void setServer(ProxiedPlayer player)
- {
-
- try ( PreparedStatement ps = connection.prepareStatement( "UPDATE players SET server = ?, seen = ? WHERE username = ?" ) )
- {
- ps.setString( 1, player.getServer().getInfo().getName() );
- ps.setInt( 2, (int) ( System.currentTimeMillis() / 1000L ) );
- ps.setString( 3, player.getName() );
- ps.executeUpdate();
- } catch ( SQLException ex )
- {
- ProxyServer.getInstance().getLogger().log( Level.WARNING, "Could not save location for player " + player.getName() + " on server " + player.getServer().getInfo().getName(), ex );
- }
- }
-
- @Override
- public void save()
- {
- }
-
- @Override
- public void close()
- {
- try
- {
- connection.close();
- } catch ( SQLException ex )
- {
- ProxyServer.getInstance().getLogger().log( Level.WARNING, "Error closing SQLite connection", ex );
- }
- }
-}
diff --git a/proxy/src/main/java/net/md_5/bungee/reconnect/YamlReconnectHandler.java b/proxy/src/main/java/net/md_5/bungee/reconnect/YamlReconnectHandler.java
new file mode 100644
index 00000000..ca05aaf6
--- /dev/null
+++ b/proxy/src/main/java/net/md_5/bungee/reconnect/YamlReconnectHandler.java
@@ -0,0 +1,102 @@
+package net.md_5.bungee.reconnect;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Level;
+import net.md_5.bungee.api.ProxyServer;
+import net.md_5.bungee.api.config.ServerInfo;
+import net.md_5.bungee.api.connection.ProxiedPlayer;
+import org.yaml.snakeyaml.Yaml;
+
+public class YamlReconnectHandler extends AbstractReconnectManager
+{
+
+ private final Yaml yaml = new Yaml();
+ private final File file = new File( "locations.yml" );
+ private final ReadWriteLock lock = new ReentrantReadWriteLock();
+ /*========================================================================*/
+ private Map data;
+
+ @SuppressWarnings("unchecked")
+ public YamlReconnectHandler()
+ {
+ try
+ {
+ file.createNewFile();
+ try ( FileReader rd = new FileReader( file ) )
+ {
+ data = yaml.loadAs( rd, Map.class );
+ }
+ } catch ( IOException ex )
+ {
+ ProxyServer.getInstance().getLogger().log( Level.WARNING, "Could not load reconnect locations", ex );
+ }
+
+ if ( data == null )
+ {
+ data = new HashMap<>();
+ }
+ }
+
+ @Override
+ protected ServerInfo getStoredServer(ProxiedPlayer player)
+ {
+ ServerInfo server = null;
+ lock.readLock().lock();
+ try
+ {
+ server = ProxyServer.getInstance().getServerInfo( data.get( key( player ) ) );
+ } finally
+ {
+ lock.readLock().unlock();
+ }
+ return server;
+ }
+
+ @Override
+ public void setServer(ProxiedPlayer player)
+ {
+ lock.writeLock().lock();
+ try
+ {
+ data.put( key( player ), player.getServer().getInfo().getName() );
+ } finally
+ {
+ lock.writeLock().unlock();
+ }
+ }
+
+ private String key(ProxiedPlayer player)
+ {
+ InetSocketAddress host = player.getPendingConnection().getVirtualHost();
+ return player.getName() + ";" + host.getHostString() + ":" + host.getPort();
+ }
+
+ @Override
+ public void save()
+ {
+ lock.readLock().lock();
+ try ( FileWriter wr = new FileWriter( file ) )
+ {
+ yaml.dump( data, wr );
+ } catch ( IOException ex )
+ {
+ ProxyServer.getInstance().getLogger().log( Level.WARNING, "Could not save reconnect locations", ex );
+ } finally
+ {
+ lock.readLock().unlock();
+ }
+ }
+
+ @Override
+ public void close()
+ {
+ }
+}