Convert PlayerStatus trackers, Bungee MOTD, and Bungee Server status' from MySQL storage to redis-based system using DataRepository's.

Re-organize structure of ServerData packaging.
This commit is contained in:
Ty Sayers 2015-03-14 01:03:22 -04:00
parent de9c861df2
commit af898e3306
68 changed files with 294 additions and 1489 deletions

View File

@ -9,9 +9,10 @@ import java.util.List;
import java.util.concurrent.TimeUnit;
import mineplex.serverdata.Region;
import mineplex.serverdata.ServerManager;
import mineplex.serverdata.ServerRepository;
import mineplex.serverdata.data.MinecraftServer;
import mineplex.serverdata.servers.ServerManager;
import mineplex.serverdata.servers.ServerRepository;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.event.ServerConnectEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin;

View File

@ -0,0 +1,40 @@
package mineplex.bungee.motd;
import java.util.List;
import mineplex.serverdata.data.Data;
/**
* A GlobalMotd represents a set of MOTD packaged lines.
* @author MrTwiggy
*
*/
public class GlobalMotd implements Data
{
// The unique name representing this MOTD set
private String _name;
// List of lines describing the MOTD
private List<String> _motd;
public List<String> getMotd() { return _motd; }
/**
* Constructor
* @param name
* @param motd
*/
public GlobalMotd(String name, List<String> motd)
{
_name = name;
_motd = motd;
}
/**
* Unique identifying ID associated with this {@link GlobalMotd}.
*/
public String getDataId()
{
return _name;
}
}

View File

@ -106,7 +106,7 @@ public class Motd implements CustomMotd
List<String> lines = _manager.getMotdLines();
if (lines != null && lines.size() > 0)
{
int index = _ticks / (MAX_TICKS / (lines.size()-1));
int index = _ticks / (MAX_TICKS / (lines.size()));
String currentLine = index >= lines.size() ? lines.get(lines.size() - 1) : lines.get(index);
desc += "\n" + currentLine;
}

View File

@ -1,8 +1,14 @@
package mineplex.bungee.motd;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import mineplex.serverdata.Region;
import mineplex.serverdata.data.BungeeServer;
import mineplex.serverdata.data.DataRepository;
import mineplex.serverdata.redis.RedisDataRepository;
import mineplex.serverdata.servers.ServerManager;
import net.md_5.bungee.api.event.ProxyPingEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin;
@ -14,7 +20,8 @@ import net.md_5.bungee.event.EventHandler;
public class MotdManager implements Listener, Runnable, CustomMotdFactory
{
private Plugin _plugin;
private MotdRepository _repository;
private DataRepository<GlobalMotd> _repository;
private String firstLine = " §b§l§m §8§l§m[ §r §9§lMineplex§r §f§lGames§r §8§l§m ]§b§l§m §r";
private List<String> _motdLines;
@ -26,8 +33,8 @@ public class MotdManager implements Listener, Runnable, CustomMotdFactory
_plugin.getProxy().getScheduler().schedule(_plugin, this, 5L, 30L, TimeUnit.SECONDS);
_plugin.getProxy().getPluginManager().registerListener(_plugin, this);
_repository = new MotdRepository();
_repository.initialize();
_repository = new RedisDataRepository<GlobalMotd>(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection(),
Region.ALL, GlobalMotd.class, "globalMotd");
}
@EventHandler
@ -37,24 +44,35 @@ public class MotdManager implements Listener, Runnable, CustomMotdFactory
String motd = firstLine;
if (_motdLines != null && _motdLines.size() > 0)
{
motd += "\n" + _motdLines.get(0);
}
event.setResponse(new net.md_5.bungee.api.ServerPing(serverPing.getVersion(), serverPing.getPlayers(), motd, serverPing.getFaviconObject()));
}
@Override
public void run()
{
_motdLines = _repository.retrieveMotd();
//if (true)
//{
InitialHandler.setCustomMotdFactory(this);
//}
//else
//{
// InitialHandler.setCustomMotdFactory(null);
//}
// Add in default MOTD listing to database
if (!_repository.elementExists("MainMotd") || true)
{
List<String> lines = new ArrayList<String>();
lines.add(" §b§lUltra Sale §a§l50% Off"); // TODO: Implement in-game command to update MOTD?
updateMainMotd(lines);
}
_motdLines = _repository.getElement("MainMotd").getMotd(); // Update MOTD lines
InitialHandler.setCustomMotdFactory(this);
}
/**
* Update the main {@link GlobalMotd} determining the MOTD for Bungee instances.
* @param motdLines - the lines to update the MOTD to.
*/
public void updateMainMotd(List<String> motdLines)
{
_repository.addElement(new GlobalMotd("MainMotd", motdLines));
}
public List<String> getMotdLines()

View File

@ -1,171 +0,0 @@
package mineplex.bungee.motd;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import net.md_5.bungee.api.ChatColor;
public class MotdRepository
{
private Connection _connection = null;
private String _connectionString = "jdbc:mysql://db.mineplex.com:3306/BungeeServers?autoReconnect=true&failOverReadOnly=false&maxReconnects=10";
private String _userName = "root";
private String _password = "tAbechAk3wR7tuTh";
private static String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS BungeeMotd (id INT NOT NULL AUTO_INCREMENT, motd VARCHAR(256), PRIMARY KEY (id));";
private static String RETRIEVE_MOTD = "SELECT motd FROM BungeeMotd;";
private static String RETRIEVE_ANIMATED = "SELECT value FROM bungeeSettings WHERE id='animatedMotd'";
public void initialize()
{
PreparedStatement preparedStatement = null;
try
{
if (_connection == null || _connection.isClosed())
_connection = DriverManager.getConnection(_connectionString, _userName, _password);
// Create table
preparedStatement = _connection.prepareStatement(CREATE_TABLE);
preparedStatement.execute();
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
if (preparedStatement != null)
{
try
{
preparedStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
System.out.println("Initialized MOTD.");
}
public List<String> retrieveMotd()
{
// String motd = "§b§l§m §8§l§m[ §r §9§lMineplex§r §f§lGames§r §8§l§m ]§b§l§m §r §c§l§m§kZ§6§l§m§kZ§e§l§m§kZ§a§l§m§kZ§b§l§m§kZ§r §f§lPLAY NOW§r §b§l§m§kZ§a§l§m§kZ§e§l§m§kZ§6§l§m§kZ§c§l§m§kZ";
ArrayList<String> lines = new ArrayList<String>();
// lines.add(" " + ChatColor.WHITE + ChatColor.BOLD + "New Game" + ChatColor.RED + ChatColor.BOLD + " Christmas Chaos");
// lines.add(" " + ChatColor.WHITE + ChatColor.BOLD + "Winter Sale" + ChatColor.BLUE + ChatColor.BOLD + " 33% Off Everything");
// lines.add(" " + ChatColor.WHITE + ChatColor.BOLD + "New Game" + ChatColor.RED + ChatColor.BOLD + " Christmas Chaos");
// return lines;
ResultSet resultSet = null;
PreparedStatement preparedStatement = null;
try
{
if (_connection == null || _connection.isClosed())
_connection = DriverManager.getConnection(_connectionString, _userName, _password);
preparedStatement = _connection.prepareStatement(RETRIEVE_MOTD);
resultSet = preparedStatement.executeQuery();
while (resultSet.next())
{
lines.add(resultSet.getString(1));
}
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
if (preparedStatement != null)
{
try
{
preparedStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
if (resultSet != null)
{
try
{
resultSet.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
return lines;
}
public boolean retrieveMotdAnimated()
{
boolean enabled = false;
ResultSet resultSet = null;
PreparedStatement preparedStatement = null;
try
{
if (_connection == null || _connection.isClosed())
_connection = DriverManager.getConnection(_connectionString, _userName, _password);
preparedStatement = _connection.prepareStatement(RETRIEVE_ANIMATED);
resultSet = preparedStatement.executeQuery();
while (resultSet.next())
{
enabled = resultSet.getBoolean(1);
}
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
if (preparedStatement != null)
{
try
{
preparedStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
if (resultSet != null)
{
try
{
resultSet.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
return enabled;
}
}

View File

@ -1,12 +1,16 @@
package mineplex.bungee.playerCount;
import java.io.File;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import mineplex.bungee.status.InternetStatus;
import mineplex.serverdata.Region;
import mineplex.serverdata.ServerManager;
import mineplex.serverdata.ServerRepository;
import mineplex.serverdata.data.BungeeServer;
import mineplex.serverdata.data.DataRepository;
import mineplex.serverdata.redis.RedisDataRepository;
import mineplex.serverdata.servers.ServerManager;
import mineplex.serverdata.servers.ServerRepository;
import net.md_5.bungee.api.ServerPing.Players;
import net.md_5.bungee.api.config.ListenerInfo;
import net.md_5.bungee.api.event.ProxyPingEvent;
@ -16,37 +20,64 @@ import net.md_5.bungee.event.EventHandler;
public class PlayerCount implements Listener, Runnable
{
private Plugin _plugin;
private ServerRepository _repository;
private DataRepository<BungeeServer> _repository;
private UUID _uuid;
private Region _region;
private ListenerInfo _listenerInfo;
private Plugin _plugin;
private int _totalPlayers = -1;
public PlayerCount(Plugin plugin)
{
_uuid = UUID.randomUUID();
_region = !new File("eu.dat").exists() ? Region.US : Region.EU;
_plugin = plugin;
_plugin.getProxy().getScheduler().schedule(_plugin, this, 500L, 500L, TimeUnit.MILLISECONDS);
_plugin.getProxy().getPluginManager().registerListener(_plugin, this);
_listenerInfo = _plugin.getProxy().getConfigurationAdapter().getListeners().iterator().next();
Region region = !new File("eu.dat").exists() ? Region.US : Region.EU;
_repository = ServerManager.getServerRepository(region);
_repository = new RedisDataRepository<BungeeServer>(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection(),
Region.ALL, BungeeServer.class, "bungeeServers");
}
public void run()
{
_repository.updateBungeeStatus(new BungeeServer(_listenerInfo.getHost().getAddress().getHostAddress(), _listenerInfo.getHost().getAddress().getHostAddress(), _listenerInfo.getHost().getPort(), _plugin.getProxy().getOnlineCount(), 1250, (int) ((Runtime.getRuntime().maxMemory() - Runtime.getRuntime().freeMemory()) / 1048576), (int) (Runtime.getRuntime().maxMemory() / 1048576)), 15);
int totalPlayers = 0;
BungeeServer snapshot = generateSnapshot();
_repository.addElement(snapshot, 15); // Update with a 15 second expiry on session
for (BungeeServer server : _repository.getGlobalBungeeStatuses())
_totalPlayers = fetchPlayerCount();
}
/**
* @return an up-to-date total player count across all active Bungee Servers.
*/
private int fetchPlayerCount()
{
int totalPlayers = 0;
for (BungeeServer server : _repository.getElements())
{
totalPlayers += server.getPlayerCount();
}
_totalPlayers = totalPlayers;
return totalPlayers;
}
/**
* @return a newly instantiated {@link BungeeServer} snapshot of the current state of this server.
*/
private BungeeServer generateSnapshot()
{
String name = _uuid.toString(); // Use random UUID for unique id name.
String host = _listenerInfo.getHost().getAddress().getHostAddress();
int port = _listenerInfo.getHost().getPort();
boolean connected = InternetStatus.isConnected();
int playerCount = _plugin.getProxy().getOnlineCount();
return new BungeeServer(name, _region, host, port, playerCount, connected);
}
@EventHandler

View File

@ -1,262 +0,0 @@
package mineplex.bungee.playerCount;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import mineplex.serverdata.Region;
public class PlayerCountRepository
{
private Connection _connection = null;
private String _connectionString = "jdbc:mysql://db.mineplex.com:3306/BungeeServers?autoReconnect=true&failOverReadOnly=false&maxReconnects=10";
private String _userName = "root";
private String _password = "tAbechAk3wR7tuTh";
private static String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS BungeeServers (id INT NOT NULL AUTO_INCREMENT, address VARCHAR(256), updated LONG, players INT, US BOOLEAN, maxPlayers INT, ram INT, maxRam INT, PRIMARY KEY (id));";
private static String INSERT_PLAYER_COUNT = "INSERT INTO BungeeServers(address, updated, US, players, maxPlayers, ram, maxRam) values(?, now(), ?, ?, ?, ?);";
private static String UPDATE_PLAYER_COUNT = "UPDATE BungeeServers SET updated = now(), players = ?, maxPlayers = ?, ram = ?, maxRam = ? WHERE id = ?;";
private static String RETRIEVE_ID = "SELECT id FROM BungeeServers WHERE address = ?;";
private static String RETRIEVE_PLAYER_COUNT = "SELECT SUM(players) AS playerCount, SUM(maxPlayers) AS maxPlayerCount FROM BungeeServers WHERE TIME_TO_SEC(TIMEDIFF(now(), BungeeServers.updated)) < 10;";
private int _id = -1;
private Region _region;
private String _address;
private int _maxPlayers = 0;
public PlayerCountRepository(Region region, String address, int maxPlayers)
{
_region = region;
_address = address;
_maxPlayers = maxPlayers;
}
public void initialize()
{
ResultSet resultSet = null;
PreparedStatement preparedStatement = null;
PreparedStatement preparedStatementRetrieve = null;
PreparedStatement preparedStatementInsert = null;
try
{
if (_connection == null || _connection.isClosed())
_connection = DriverManager.getConnection(_connectionString, _userName, _password);
// Create table
preparedStatement = _connection.prepareStatement(CREATE_TABLE);
preparedStatement.execute();
// Retrieve id
preparedStatementRetrieve = _connection.prepareStatement(RETRIEVE_ID);
preparedStatementRetrieve.setString(1, _address);
resultSet = preparedStatementRetrieve.executeQuery();
while (resultSet.next())
{
_id = resultSet.getInt("id");
}
// Insert if not there
if (_id == -1)
{
preparedStatementInsert = _connection.prepareStatement(INSERT_PLAYER_COUNT, Statement.RETURN_GENERATED_KEYS);
preparedStatementInsert.setString(1, _address);
preparedStatementInsert.setInt(2, 0);
preparedStatementInsert.setInt(3, _maxPlayers);
preparedStatementInsert.setBoolean(4, _region == Region.US);
preparedStatementInsert.setInt(5, (int) ((Runtime.getRuntime().maxMemory() - Runtime.getRuntime().freeMemory()) / 1048576));
preparedStatementInsert.setInt(6, (int) (Runtime.getRuntime().maxMemory() / 1048576));
int affectedRows = preparedStatementInsert.executeUpdate();
if (affectedRows == 0)
{
throw new SQLException("Creating bungee server failed, no rows affected.");
}
resultSet.close();
resultSet = preparedStatementInsert.getGeneratedKeys();
if (resultSet.next())
{
_id = resultSet.getInt(1);
System.out.println("id = " + _id);
}
}
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
if (preparedStatement != null)
{
try
{
preparedStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
if (preparedStatementRetrieve != null)
{
try
{
preparedStatementRetrieve.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
if (preparedStatementInsert != null)
{
try
{
preparedStatementInsert.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
if (resultSet != null)
{
try
{
resultSet.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
System.out.println("Initialized PlayerCount.");
}
public boolean updatePlayerCountInDatabase(int players)
{
PreparedStatement preparedStatement = null;
try
{
if (_connection == null || _connection.isClosed())
_connection = DriverManager.getConnection(_connectionString, _userName, _password);
preparedStatement = _connection.prepareStatement(UPDATE_PLAYER_COUNT, Statement.RETURN_GENERATED_KEYS);
preparedStatement.setInt(1, players);
preparedStatement.setInt(2, _maxPlayers);
preparedStatement.setInt(3, (int) ((Runtime.getRuntime().maxMemory() - Runtime.getRuntime().freeMemory()) / 1048576));
preparedStatement.setInt(4, (int) (Runtime.getRuntime().maxMemory() / 1048576));
preparedStatement.setInt(5, _id);
int affectedRows = preparedStatement.executeUpdate();
if (affectedRows == 0)
{
throw new SQLException("Updating bungee server player count failed, no rows affected.");
}
return true;
}
catch (Exception exception)
{
exception.printStackTrace();
try
{
Thread.sleep(10);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
return updatePlayerCountInDatabase(players);
}
finally
{
if (preparedStatement != null)
{
try
{
preparedStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
public PlayerTotalData retrievePlayerCount()
{
PlayerTotalData playerData = new PlayerTotalData();
ResultSet resultSet = null;
PreparedStatement preparedStatement = null;
try
{
if (_connection == null || _connection.isClosed())
_connection = DriverManager.getConnection(_connectionString, _userName, _password);
preparedStatement = _connection.prepareStatement(RETRIEVE_PLAYER_COUNT);
resultSet = preparedStatement.executeQuery();
while (resultSet.next())
{
playerData.CurrentPlayers = resultSet.getInt(1);
playerData.MaxPlayers = resultSet.getInt(2);
return playerData;
}
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
if (preparedStatement != null)
{
try
{
preparedStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
if (resultSet != null)
{
try
{
resultSet.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
return playerData;
}
}

View File

@ -1,7 +0,0 @@
package mineplex.bungee.playerCount;
public class PlayerTotalData
{
public int CurrentPlayers;
public int MaxPlayers;
}

View File

@ -1,6 +1,8 @@
package mineplex.serverdata.data;
package mineplex.bungee.playerTracker;
public class PlayerStatus
import mineplex.serverdata.data.Data;
public class PlayerStatus implements Data
{
// The name of this server.
private String _name;
@ -20,4 +22,12 @@ public class PlayerStatus
_name = name;
_server = server;
}
/**
* Unique identifying String ID associated with this {@link PlayerStatus}.
*/
public String getDataId()
{
return _name;
}
}

View File

@ -2,6 +2,10 @@ package mineplex.bungee.playerTracker;
import java.io.File;
import mineplex.serverdata.Region;
import mineplex.serverdata.data.DataRepository;
import mineplex.serverdata.redis.RedisDataRepository;
import mineplex.serverdata.servers.ServerManager;
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
import net.md_5.bungee.api.event.ServerConnectedEvent;
import net.md_5.bungee.api.plugin.Listener;
@ -10,8 +14,13 @@ import net.md_5.bungee.event.EventHandler;
public class PlayerTracker implements Listener
{
// Default period before status expiry (8 hours)
private static final int DEFAULT_STATUS_TIMEOUT = 60 * 60 * 8;
// Repository storing player status' across network.
private DataRepository<PlayerStatus> _repository;
private Plugin _plugin;
private PlayerTrackerRepository _repository = null;
public PlayerTracker(Plugin plugin)
{
@ -19,8 +28,9 @@ public class PlayerTracker implements Listener
_plugin.getProxy().getPluginManager().registerListener(_plugin, this);
_repository = new PlayerTrackerRepository();
_repository.initialize(!new File("eu.dat").exists());
Region region = !new File("eu.dat").exists() ? Region.US : Region.EU;
_repository = new RedisDataRepository<PlayerStatus>(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection(),
region, PlayerStatus.class, "playerStatus");
System.out.println("Initialized PlayerTracker.");
}
@ -32,7 +42,8 @@ public class PlayerTracker implements Listener
{
public void run()
{
_repository.updatePlayerServer(event.getPlayer().getName(), event.getServer().getInfo().getName());
PlayerStatus snapshot = new PlayerStatus(event.getPlayer().getName(), event.getServer().getInfo().getName());
_repository.addElement(snapshot, DEFAULT_STATUS_TIMEOUT);
}
});
}
@ -44,7 +55,7 @@ public class PlayerTracker implements Listener
{
public void run()
{
_repository.deleteServerTransfers(event.getPlayer().getName());
_repository.removeElement(event.getPlayer().getName());
}
});
}

View File

@ -1,203 +0,0 @@
package mineplex.bungee.playerTracker;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class PlayerTrackerRepository
{
private static Object _connectionLock = new Object();
private String _connectionString = "jdbc:mysql://db.mineplex.com:3306/Account?autoReconnect=true&failOverReadOnly=false&maxReconnects=10";
private String _userName = "root";
private String _password = "tAbechAk3wR7tuTh";
private boolean _us = true;
private static String CREATE_PLAYERMAP_TABLE = "CREATE TABLE IF NOT EXISTS playerMap (id INT NOT NULL AUTO_INCREMENT, playerName VARCHAR(256), serverName VARCHAR(256), us BOOLEAN NOT NULL DEFAULT 1, PRIMARY KEY (id), UNIQUE INDEX playerIndex (playerName));";
private static String RETRIEVE_PLAYERMAP = "SELECT playerName, serverName FROM playerMap WHERE playerName = ? AND us = ?;";
private static String INSERT_PLAYERMAP = "INSERT INTO playerMap (playerName, serverName, us) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE serverName = VALUES(serverName), us = VALUES(us);";
private static String DELETE_PLAYERMAP = "DELETE FROM playerMap WHERE playerName = ? AND us = ?;";
private Connection _connection = null;
public void initialize(boolean us)
{
_us = us;
PreparedStatement preparedStatement = null;
try
{
Class.forName("com.mysql.jdbc.Driver");
_connection = DriverManager.getConnection(_connectionString, _userName, _password);
// Create table
preparedStatement = _connection.prepareStatement(CREATE_PLAYERMAP_TABLE);
preparedStatement.execute();
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
if (preparedStatement != null)
{
try
{
preparedStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
public String retrievePlayerServer(String playerName)
{
ResultSet resultSet = null;
PreparedStatement preparedStatement = null;
String server = "N/A";
try
{
synchronized (_connectionLock)
{
if (_connection.isClosed())
{
_connection = DriverManager.getConnection(_connectionString, _userName, _password);
}
preparedStatement = _connection.prepareStatement(RETRIEVE_PLAYERMAP);
preparedStatement.setString(1, playerName);
preparedStatement.setBoolean(2, _us);
resultSet = preparedStatement.executeQuery();
while (resultSet.next())
{
server = resultSet.getString(1);
}
}
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
if (preparedStatement != null)
{
try
{
preparedStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
if (resultSet != null)
{
try
{
resultSet.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
return server;
}
public void deleteServerTransfers(String playerName)
{
PreparedStatement preparedStatement = null;
try
{
synchronized (_connectionLock)
{
if (_connection.isClosed())
{
_connection = DriverManager.getConnection(_connectionString, _userName, _password);
}
preparedStatement = _connection.prepareStatement(DELETE_PLAYERMAP);
preparedStatement.setString(1, playerName);
preparedStatement.setBoolean(2, _us);
preparedStatement.executeUpdate();
}
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
if (preparedStatement != null)
{
try
{
preparedStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
public void updatePlayerServer(String playerName, String serverName)
{
PreparedStatement preparedStatement = null;
try
{
synchronized (_connectionLock)
{
if (_connection.isClosed())
{
_connection = DriverManager.getConnection(_connectionString, _userName, _password);
}
preparedStatement = _connection.prepareStatement(INSERT_PLAYERMAP);
preparedStatement.setString(1, playerName);
preparedStatement.setString(2, serverName);
preparedStatement.setBoolean(3, _us);
preparedStatement.executeUpdate();
}
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
if (preparedStatement != null)
{
try
{
preparedStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
}

View File

@ -10,20 +10,15 @@ import net.md_5.bungee.api.plugin.Plugin;
public class InternetStatus implements Runnable
{
// Current internet connectivity status
private static boolean _connected = true;
public static boolean isConnected() { return _connected; }
private Plugin _plugin;
private StatusRepository _repository;
public InternetStatus(Plugin plugin)
{
_plugin = plugin;
ListenerInfo listenerInfo = _plugin.getProxy().getConfigurationAdapter().getListeners().iterator().next();
boolean us = !new File("eu.dat").exists();
String address = listenerInfo.getHost().getAddress().getHostAddress() + ":" + listenerInfo.getHost().getPort();
_repository = new StatusRepository(address, us);
_repository.initialize();
_plugin.getProxy().getScheduler().schedule(_plugin, this, 1L, 1L, TimeUnit.MINUTES);
System.out.println("Initialized InternetStatus.");
@ -32,48 +27,28 @@ public class InternetStatus implements Runnable
@Override
public void run()
{
_repository.updateOnlineStatus(isOnline());
_connected = isOnline(); // Update _connected flag.
}
private boolean isOnline()
{
if (testUrl("www.google.com"))
return true;
else if (testUrl("www.espn.com"))
return true;
else if (testUrl("www.bing.com"))
return true;
return false;
return testUrl("www.google.com")
|| testUrl("www.espn.com")
|| testUrl("www.bing.com");
}
private boolean testUrl(String url)
{
Socket socket = null;
boolean reachable = false;
try
try (Socket socket = new Socket(url, 80))
{
socket = new Socket(url, 80);
reachable = true;
}
catch (Exception e)
{
// Meh i don't care
}
finally
{
if (socket != null)
{
try
{
socket.close();
}
catch (IOException e)
{
}
}
}
return reachable;
}

View File

@ -1,120 +0,0 @@
package mineplex.bungee.status;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class StatusRepository
{
private String _connectionString = "jdbc:mysql://db.mineplex.com:3306/BungeeServers?autoReconnect=true&failOverReadOnly=false&maxReconnects=10";
private String _userName = "root";
private String _password = "tAbechAk3wR7tuTh";
private String _address;
private boolean _us;
private static String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS bungeeOnlineStatus (id INT NOT NULL AUTO_INCREMENT, address VARCHAR(40), online BOOLEAN NOT NULL DEFAULT 0, updated LONG, us BOOLEAN NOT NULL DEFAULT 1, lastOnline LONG, PRIMARY KEY (id), UNIQUE INDEX addressIndex(address));";
private static String INSERT_SERVER = "INSERT INTO bungeeOnlineStatus (address, online, us, updated) values(?, ?, ?, now()) ON DUPLICATE KEY UPDATE online = VALUES(online), updated = VALUES(updated);";
private static String INSERT_ONLINE_SERVER = "INSERT INTO bungeeOnlineStatus (address, online, us, updated, lastOnline) values(?, ?, ?, now(), now()) ON DUPLICATE KEY UPDATE online = VALUES(online), updated = VALUES(updated), lastOnline = VALUES(lastOnline);";
public StatusRepository(String address, boolean us)
{
_address = address;
_us = us;
}
public void initialize()
{
Connection connection = null;
PreparedStatement preparedStatement = null;
try
{
connection = DriverManager.getConnection(_connectionString, _userName, _password);
// Create table
preparedStatement = connection.prepareStatement(CREATE_TABLE);
preparedStatement.execute();
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
if (preparedStatement != null)
{
try
{
preparedStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
if (connection != null)
{
try
{
connection.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
public void updateOnlineStatus(boolean online)
{
Connection connection = null;
PreparedStatement preparedStatement = null;
try
{
connection = DriverManager.getConnection(_connectionString, _userName, _password);
preparedStatement = connection.prepareStatement(online ? INSERT_ONLINE_SERVER : INSERT_SERVER);
preparedStatement.setString(1, _address);
preparedStatement.setBoolean(2, online);
preparedStatement.setBoolean(3, _us);
preparedStatement.executeUpdate();
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
if (preparedStatement != null)
{
try
{
preparedStatement.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
if (connection != null)
{
try
{
connection.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
}

View File

@ -21,13 +21,16 @@ import mineplex.bungee.api.token.ARecord;
import mineplex.bungee.api.token.DnsRecord;
import mineplex.bungee.api.token.DomainRecords;
import mineplex.serverdata.Region;
import mineplex.serverdata.ServerManager;
import mineplex.serverdata.ServerRepository;
import mineplex.serverdata.data.BungeeServer;
import mineplex.serverdata.data.DataRepository;
import mineplex.serverdata.redis.RedisDataRepository;
import mineplex.serverdata.servers.ServerManager;
import mineplex.serverdata.servers.ServerRepository;
public class BungeeRotator
{
private static ServerRepository _repository = null;
private static DataRepository<BungeeServer> _repository;
//private static ServerRepository _repository = null;
private static SimpleDateFormat _dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
private static Logger _logger = Logger.getLogger("BungeeRotator");
@ -65,8 +68,9 @@ public class BungeeRotator
_debug = new File("debug.dat").exists();
Region region = !new File("eu.dat").exists() ? Region.US : Region.EU;
_repository = ServerManager.getServerRepository(region);
_repository = new RedisDataRepository<BungeeServer>(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection(),
Region.ALL, BungeeServer.class, "bungeeServers");
BungeeSorter bungeeSorter = new BungeeSorter();
int maxRecordCount = 10;
@ -74,16 +78,15 @@ public class BungeeRotator
{
try
{
List<BungeeServer> bungeeServers = new ArrayList<BungeeServer>(_repository.getGlobalBungeeStatuses());
List<BungeeServer> bungeeServers = new ArrayList<BungeeServer>(_repository.getElements());
Collections.sort(bungeeServers, bungeeSorter);
if (_debug)
{
for (BungeeServer server : bungeeServers)
{
System.out.println(server.getPublicAddress() + " " + server.getPlayerCount() + "/" + server.getMaxPlayerCount());
System.out.println(server.getPublicAddress() + " " + server.getPlayerCount() + "/" + server.getPlayerCount());
}
System.out.println("Count : " + bungeeServers.size());
}
else
@ -99,7 +102,7 @@ public class BungeeRotator
if (usServers.size() >= 2 && server.getPlayerCount() > 900)
continue;
log("SELECTED " + server.getPublicAddress() + " " + (server.getRegion() == Region.US ? "us" : "eu") + " " + server.getPlayerCount() + "/" + server.getMaxPlayerCount());
log("SELECTED " + server.getPublicAddress() + " " + (server.getRegion() == Region.US ? "us" : "eu") + " " + server.getPlayerCount() + "/" + server.getPlayerCount());
usServers.add(server.getPublicAddress());
}
else if (euServers.size() < maxRecordCount && server.getRegion() != Region.US)
@ -107,7 +110,7 @@ public class BungeeRotator
if (euServers.size() >= 2 && server.getPlayerCount() > 900)
continue;
log("SELECTED " + server.getPublicAddress() + " " + (server.getRegion() == Region.US ? "us" : "eu") + " " + server.getPlayerCount() + "/" + server.getMaxPlayerCount());
log("SELECTED " + server.getPublicAddress() + " " + (server.getRegion() == Region.US ? "us" : "eu") + " " + server.getPlayerCount() + "/" + server.getPlayerCount());
euServers.add(server.getPublicAddress());
}
}

View File

@ -35,8 +35,8 @@ import mineplex.core.punish.Punish;
import mineplex.core.punish.PunishClient;
import mineplex.core.punish.Punishment;
import mineplex.core.punish.PunishmentSentence;
import mineplex.serverdata.ServerCommandManager;
import mineplex.serverdata.transfers.AnnouncementCommand;
import mineplex.serverdata.commands.AnnouncementCommand;
import mineplex.serverdata.commands.ServerCommandManager;
public class MessageManager extends MiniClientPlugin<ClientMessage>
{

View File

@ -7,7 +7,7 @@ import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.message.MessageManager;
import mineplex.serverdata.transfers.AnnouncementCommand;
import mineplex.serverdata.commands.AnnouncementCommand;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;

View File

@ -5,7 +5,7 @@ import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.message.MessageManager;
import mineplex.serverdata.transfers.AnnouncementCommand;
import mineplex.serverdata.commands.AnnouncementCommand;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;

View File

@ -4,9 +4,9 @@ import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.serverdata.CommandCallback;
import mineplex.serverdata.ServerCommand;
import mineplex.serverdata.transfers.AnnouncementCommand;
import mineplex.serverdata.commands.AnnouncementCommand;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.ServerCommand;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;

View File

@ -4,8 +4,8 @@ import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import mineplex.core.message.MessageManager;
import mineplex.serverdata.CommandCallback;
import mineplex.serverdata.ServerCommand;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.ServerCommand;
public class MessageHandler implements CommandCallback
{

View File

@ -2,7 +2,7 @@ package mineplex.core.message.redis;
import java.util.UUID;
import mineplex.serverdata.ServerCommand;
import mineplex.serverdata.commands.ServerCommand;
/**
* Used to send a admin or normal message between servers

View File

@ -2,7 +2,7 @@ package mineplex.core.message.redis;
import java.util.UUID;
import mineplex.serverdata.ServerCommand;
import mineplex.serverdata.commands.ServerCommand;
/**
* Used as a response in return to a admin or normal message between servers.

View File

@ -16,10 +16,10 @@ import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.party.redis.RedisPartyData;
import mineplex.serverdata.Region;
import mineplex.serverdata.ServerManager;
import mineplex.serverdata.commands.ServerTransfer;
import mineplex.serverdata.commands.TransferCommand;
import mineplex.serverdata.data.ServerGroup;
import mineplex.serverdata.transfers.ServerTransfer;
import mineplex.serverdata.transfers.TransferCommand;
import mineplex.serverdata.servers.ServerManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;

View File

@ -14,7 +14,7 @@ import mineplex.core.portal.ServerTransferEvent;
import mineplex.core.preferences.PreferencesManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.serverdata.ServerCommandManager;
import mineplex.serverdata.commands.ServerCommandManager;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;

View File

@ -1,7 +1,7 @@
package mineplex.core.party.redis;
import mineplex.core.party.Party;
import mineplex.serverdata.ServerCommand;
import mineplex.serverdata.commands.ServerCommand;
public class RedisPartyData extends ServerCommand
{

View File

@ -2,8 +2,8 @@ package mineplex.core.party.redis;
import mineplex.core.party.Party;
import mineplex.core.party.PartyManager;
import mineplex.serverdata.CommandCallback;
import mineplex.serverdata.ServerCommand;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.ServerCommand;
public class RedisPartyHandler implements CommandCallback
{

View File

@ -23,9 +23,9 @@ import mineplex.core.common.util.UtilPlayer;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.recharge.Recharge;
import mineplex.serverdata.Region;
import mineplex.serverdata.ServerManager;
import mineplex.serverdata.ServerRepository;
import mineplex.serverdata.data.ServerGroup;
import mineplex.serverdata.servers.ServerManager;
import mineplex.serverdata.servers.ServerRepository;
public class PersonalServerManager extends MiniPlugin
{

View File

@ -24,12 +24,12 @@ import mineplex.core.common.util.UtilTabTitle;
import mineplex.core.portal.Commands.SendCommand;
import mineplex.core.portal.Commands.ServerCommand;
import mineplex.serverdata.Region;
import mineplex.serverdata.ServerCommandManager;
import mineplex.serverdata.ServerManager;
import mineplex.serverdata.ServerRepository;
import mineplex.serverdata.commands.ServerCommandManager;
import mineplex.serverdata.commands.ServerTransfer;
import mineplex.serverdata.commands.TransferCommand;
import mineplex.serverdata.data.MinecraftServer;
import mineplex.serverdata.transfers.ServerTransfer;
import mineplex.serverdata.transfers.TransferCommand;
import mineplex.serverdata.servers.ServerManager;
import mineplex.serverdata.servers.ServerRepository;
public class Portal extends MiniPlugin
{

View File

@ -1,9 +1,9 @@
package mineplex.core.portal;
import mineplex.serverdata.CommandCallback;
import mineplex.serverdata.ServerCommand;
import mineplex.serverdata.transfers.ServerTransfer;
import mineplex.serverdata.transfers.TransferCommand;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.ServerCommand;
import mineplex.serverdata.commands.ServerTransfer;
import mineplex.serverdata.commands.TransferCommand;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;

View File

@ -16,7 +16,7 @@ import mineplex.core.common.util.UtilTime.TimeUnit;
import mineplex.core.punish.Command.PunishCommand;
import mineplex.core.punish.Tokens.PunishClientToken;
import mineplex.core.punish.Tokens.PunishmentToken;
import mineplex.serverdata.ServerCommandManager;
import mineplex.serverdata.commands.ServerCommandManager;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
@ -44,7 +44,7 @@ public class Punish extends MiniPlugin
_clientManager = clientManager;
_repository = new PunishRepository(webServerAddress);
ServerCommandManager.getInstance().registerCommandType("PunishCommand", mineplex.serverdata.transfers.PunishCommand.class, new PunishmentHandler(this));
ServerCommandManager.getInstance().registerCommandType("PunishCommand", mineplex.serverdata.commands.PunishCommand.class, new PunishmentHandler(this));
}
public PunishRepository GetRepository()
@ -167,7 +167,7 @@ public class Punish extends MiniPlugin
if (target != null)
target.kickPlayer(kickReason);
else
new mineplex.serverdata.transfers.PunishCommand(playerName, true, false, kickReason).publish();
new mineplex.serverdata.commands.PunishCommand(playerName, true, false, kickReason).publish();
}
});
@ -193,7 +193,7 @@ public class Punish extends MiniPlugin
target.playSound(target.getLocation(), Sound.CAT_MEOW, 1f, 1f);
}
else
new mineplex.serverdata.transfers.PunishCommand(playerName, false, finalDuration != 0, F.main("Punish", F.elem(C.cGray + C.Bold + (finalDuration != 0 ? "Mute" : "Warning") + " Reason: ") + reason)).publish();
new mineplex.serverdata.commands.PunishCommand(playerName, false, finalDuration != 0, F.main("Punish", F.elem(C.cGray + C.Bold + (finalDuration != 0 ? "Mute" : "Warning") + " Reason: ") + reason)).publish();
_repository.LoadPunishClient(playerName, new Callback<PunishClientToken>()
{

View File

@ -3,9 +3,9 @@ package mineplex.core.punish;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.punish.Tokens.PunishClientToken;
import mineplex.serverdata.CommandCallback;
import mineplex.serverdata.ServerCommand;
import mineplex.serverdata.transfers.PunishCommand;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.PunishCommand;
import mineplex.serverdata.commands.ServerCommand;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;

View File

@ -3,7 +3,7 @@ package mineplex.core.report;
import java.util.HashSet;
import java.util.Set;
import mineplex.serverdata.Data;
import mineplex.serverdata.data.Data;
public class Report implements Data
{

View File

@ -9,10 +9,10 @@ import mineplex.core.command.CommandCenter;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.portal.Portal;
import mineplex.core.report.command.ReportNotification;
import mineplex.serverdata.DataRepository;
import mineplex.serverdata.RedisDataRepository;
import mineplex.serverdata.Region;
import mineplex.serverdata.Utility;
import mineplex.serverdata.data.DataRepository;
import mineplex.serverdata.redis.RedisDataRepository;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;

View File

@ -1,6 +1,6 @@
package mineplex.core.report;
import mineplex.serverdata.Data;
import mineplex.serverdata.data.Data;
public class ReportProfile implements Data
{

View File

@ -4,7 +4,7 @@ import org.bukkit.entity.Player;
import mineplex.core.common.util.UtilServer;
import mineplex.core.report.ReportManager;
import mineplex.serverdata.ServerCommand;
import mineplex.serverdata.commands.ServerCommand;
public class ReportNotification extends ServerCommand
{

View File

@ -14,8 +14,8 @@ import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.Rank;
import mineplex.serverdata.Region;
import mineplex.serverdata.ServerManager;
import mineplex.serverdata.data.ServerGroup;
import mineplex.serverdata.servers.ServerManager;
public class ServerConfiguration extends MiniPlugin
{

View File

@ -15,13 +15,13 @@ import mineplex.core.monitor.LagMeter;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.serverdata.Region;
import mineplex.serverdata.ServerCommandManager;
import mineplex.serverdata.ServerManager;
import mineplex.serverdata.ServerRepository;
import mineplex.serverdata.Utility;
import mineplex.serverdata.commands.ServerCommandManager;
import mineplex.serverdata.commands.SuicideCommand;
import mineplex.serverdata.data.MinecraftServer;
import mineplex.serverdata.data.ServerGroup;
import mineplex.serverdata.transfers.SuicideCommand;
import mineplex.serverdata.servers.ServerManager;
import mineplex.serverdata.servers.ServerRepository;
public class ServerStatusManager extends MiniPlugin
{

View File

@ -2,10 +2,10 @@ package mineplex.core.status;
import mineplex.core.common.util.F;
import mineplex.core.portal.Portal;
import mineplex.serverdata.CommandCallback;
import mineplex.serverdata.Region;
import mineplex.serverdata.ServerCommand;
import mineplex.serverdata.transfers.SuicideCommand;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.ServerCommand;
import mineplex.serverdata.commands.SuicideCommand;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;

View File

@ -23,7 +23,7 @@ import mineplex.core.common.util.NautHashMap;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilWorld;
import mineplex.serverdata.ServerCommandManager;
import mineplex.serverdata.commands.ServerCommandManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;

View File

@ -2,7 +2,7 @@ package mineplex.core.teleport.redis;
import java.util.UUID;
import mineplex.serverdata.ServerCommand;
import mineplex.serverdata.commands.ServerCommand;
public class RedisLocate extends ServerCommand
{

View File

@ -2,7 +2,7 @@ package mineplex.core.teleport.redis;
import java.util.UUID;
import mineplex.serverdata.ServerCommand;
import mineplex.serverdata.commands.ServerCommand;
public class RedisLocateCallback extends ServerCommand
{

View File

@ -2,9 +2,10 @@ package mineplex.core.teleport.redis;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import mineplex.core.teleport.Teleport;
import mineplex.serverdata.CommandCallback;
import mineplex.serverdata.ServerCommand;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.ServerCommand;
public class RedisLocateHandler implements CommandCallback
{

View File

@ -21,8 +21,8 @@ import mineplex.core.portal.Portal;
import mineplex.core.updater.event.RestartServerEvent;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.serverdata.Region;
import mineplex.serverdata.ServerCommandManager;
import mineplex.serverdata.transfers.RestartCommand;
import mineplex.serverdata.commands.RestartCommand;
import mineplex.serverdata.commands.ServerCommandManager;
public class FileUpdater extends MiniPlugin
{

View File

@ -2,10 +2,10 @@ package mineplex.core.updater;
import mineplex.core.common.util.F;
import mineplex.core.portal.Portal;
import mineplex.serverdata.CommandCallback;
import mineplex.serverdata.Region;
import mineplex.serverdata.ServerCommand;
import mineplex.serverdata.transfers.RestartCommand;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.RestartCommand;
import mineplex.serverdata.commands.ServerCommand;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;

View File

@ -9,7 +9,7 @@ import mineplex.core.common.util.Callback;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.portal.Portal;
import mineplex.serverdata.transfers.RestartCommand;
import mineplex.serverdata.commands.RestartCommand;
public class RestartServerCommand extends CommandBase<FileUpdater>
{

View File

@ -4,8 +4,8 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import mineplex.serverdata.Data;
import mineplex.serverdata.Region;
import mineplex.serverdata.data.Data;
public class QueueParty implements Data
{

View File

@ -9,16 +9,16 @@ import java.util.Set;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import mineplex.serverdata.ConnectionData;
import mineplex.serverdata.DataRepository;
import mineplex.serverdata.RedisDataRepository;
import mineplex.serverdata.Region;
import mineplex.serverdata.ServerManager;
import mineplex.serverdata.ServerRepository;
import mineplex.serverdata.Utility;
import mineplex.serverdata.commands.ServerTransfer;
import mineplex.serverdata.commands.TransferCommand;
import mineplex.serverdata.data.DataRepository;
import mineplex.serverdata.data.MinecraftServer;
import mineplex.serverdata.transfers.ServerTransfer;
import mineplex.serverdata.transfers.TransferCommand;
import mineplex.serverdata.redis.RedisDataRepository;
import mineplex.serverdata.servers.ConnectionData;
import mineplex.serverdata.servers.ServerManager;
import mineplex.serverdata.servers.ServerRepository;
public class QueueRepository
{

View File

@ -1,27 +0,0 @@
package mineplex.serverdata;
/**
* ConnectionData stores information relevant for initiating a connection to a repository.
* @author MrTwiggy
*
*/
public class ConnectionData
{
private String _host; // The host URL to connect to repository
public String getHost() { return _host; }
private int _port; // The port to connect to repository
public int getPort() { return _port; }
/**
* Constructor
* @param host - the host URL defining the repository
* @param port - the port used for connection to repository
*/
public ConnectionData(String host, int port)
{
_host = host;
_port = port;
}
}

View File

@ -1,20 +0,0 @@
package mineplex.serverdata;
import java.util.Comparator;
import mineplex.serverdata.data.DedicatedServer;
public class DedicatedServerSorter implements Comparator<DedicatedServer>
{
@Override
public int compare(DedicatedServer first, DedicatedServer second)
{
if (second.getAvailableRam() <= 1024) return -1;
else if (first.getAvailableRam() <= 1024) return 1;
else if (first.getAvailableRam() > second.getAvailableRam()) return -1;
else if (second.getAvailableRam() > first.getAvailableRam()) return 1;
else if (first.getAvailableCpu() > second.getAvailableCpu()) return -1;
else if (second.getAvailableCpu() > first.getAvailableCpu()) return 1;
else return 0;
}
}

View File

@ -1,68 +0,0 @@
package mineplex.serverdata;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* ServerManager handles the creation/management of {@link ServerRepository}s for use.
* @author Ty
*
*/
public class ServerManager
{
// Connection host to server database
private static final String DATABASE_HOST = "10.33.53.16";
// Ports associated with slave redis instances
private static final int[] SLAVE_PORTS = {6377, 6378, 6380, 6381, 6382};
private static Random random = new Random();
// The cached repository instances
private static Map<Region, ServerRepository> repositories = new HashMap<Region, ServerRepository>();
/**
* @param host - the host url used to connect to the database
* @param port - the port to connect to the repository
* @param region - the geographical region of the {@link ServerRepository}.
* @return a newly instanced (or cached) {@link ServerRepository} for the specified {@code region}.
*/
public static ServerRepository getServerRepository(ConnectionData writeConn, ConnectionData readConn, Region region)
{
if (repositories.containsKey(region)) return repositories.get(region);
ServerRepository repository = new RedisServerRepository(writeConn, readConn, region);
repositories.put(region, repository);
return repository;
}
/**
* {@code host} defaults to {@value DEFAULT_REDIS_HOST} and
* {@code port} defaults to {@value DEFAULT_REDIS_PORT}.
*
* @see #getServerRepository(String, int, Region)
*/
public static ServerRepository getServerRepository(Region region)
{
return getServerRepository(getMasterConnection(), getSlaveConnection(), region);
}
/**
* @return the {@link ConnectionData} associated with the master instance connection.
*/
public static ConnectionData getMasterConnection()
{
return new ConnectionData(DATABASE_HOST, 6379);
}
/**
* Non-Deterministic: Generates random slave instance connection.
* @return the {@link ConnectionData} associated with a random slave connection.
*/
public static ConnectionData getSlaveConnection()
{
int port = SLAVE_PORTS[random.nextInt(SLAVE_PORTS.length)];
return new ConnectionData(DATABASE_HOST, port);
}
}

View File

@ -1,95 +0,0 @@
package mineplex.serverdata;
import java.util.Collection;
import java.util.List;
import mineplex.serverdata.data.BungeeServer;
import mineplex.serverdata.data.DedicatedServer;
import mineplex.serverdata.data.MinecraftServer;
import mineplex.serverdata.data.PlayerStatus;
import mineplex.serverdata.data.ServerGroup;
/**
* The ServerRepository is used for storing/retrieving active sessions
* for {@link MinecraftServer}s, {@link DedicatedServer}s, and {@link ServerGroup}s
* from a persistent database/repoistory.
* @author Ty
*
*/
public interface ServerRepository
{
/**
* @return a newly instanced snapshot {@link Collection} of all currently active
* {@link MinecraftServer}s in the repository.
*/
public Collection<MinecraftServer> getServerStatuses();
public Collection<MinecraftServer> getServerStatusesByPrefix(String prefix);
public Collection<MinecraftServer> getServersByGroup(String serverGroup);
/**
* @param serverName - the name of the {@link MinecraftServer} to be fetched.
* @return the currently active {@link MinecraftServer} with a matching {@code serverName},
* if an active one exists, null otherwise.
*/
public MinecraftServer getServerStatus(String serverName);
/**
* Update (or add, if it doesn't already exist) a {@link MinecraftServer}s data
* in the repository.
*
* A {@link MinecraftServer} must be updated within {@code timeout} milliseconds before
* it expires and is removed from the repository.
* @param serverData - the {@link MinecraftServer} to add/update in the repository.
* @param timeout - the timeout (in milliseconds) before the {@link MinecraftServer} session expires.
*/
public void updataServerStatus(MinecraftServer serverData, int timeout);
/**
* Remove an active {@link MinecraftServer} from the repository.
* @param serverData - the {@link MinecraftServer} to be removed.
*/
public void removeServerStatus(MinecraftServer serverData);
public void updateBungeeStatus(BungeeServer serverData, int timeout);
public void removeBungeeStatus(BungeeServer serverData);
public Collection<BungeeServer> getBungeeStatuses();
public void updatePlayerStatus(PlayerStatus serverData, int timeout);
public void removePlayerStatus(PlayerStatus serverData);
public Collection<PlayerStatus> getPlayerStatuses();
/**
* @param serverName - the name of the server whose existence is being checked.
* @return true, if there exists an active {@link MinecraftServer} session with a
* matching {@code serverName}, false otherwise.
*/
public boolean serverExists(String serverName);
/**
* @return a newly instanced snapshot {@link Collection} of all the
* currently active {@link DedicatedServer}s in the repository.
*/
public Collection<DedicatedServer> getDedicatedServers();
/**
* @return a newly instanced snapshot {@link Collection} of all the
* currently active {@link ServerGroup}s in the repository.
*/
public Collection<ServerGroup> getServerGroups(Collection<MinecraftServer> servers);
public ServerGroup getServerGroup(String serverGroup);
public Collection<MinecraftServer> getDeadServers();
void updateServerGroup(ServerGroup serverGroup);
public void removeServerGroup(ServerGroup serverGroup);
PlayerStatus getPlayerStatus(String playerName);
public Collection<BungeeServer> getGlobalBungeeStatuses();
}

View File

@ -1,5 +1,7 @@
package mineplex.serverdata;
import mineplex.serverdata.servers.ConnectionData;
import mineplex.serverdata.servers.ServerManager;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

View File

@ -1,6 +1,5 @@
package mineplex.serverdata.transfers;
package mineplex.serverdata.commands;
import mineplex.serverdata.ServerCommand;
public class AnnouncementCommand extends ServerCommand
{

View File

@ -1,4 +1,5 @@
package mineplex.serverdata;
package mineplex.serverdata.commands;
public interface CommandCallback
{

View File

@ -1,4 +1,5 @@
package mineplex.serverdata;
package mineplex.serverdata.commands;
public class CommandType
{

View File

@ -1,6 +1,5 @@
package mineplex.serverdata.transfers;
package mineplex.serverdata.commands;
import mineplex.serverdata.ServerCommand;
public class PunishCommand extends ServerCommand
{

View File

@ -1,7 +1,6 @@
package mineplex.serverdata.transfers;
package mineplex.serverdata.commands;
import mineplex.serverdata.Region;
import mineplex.serverdata.ServerCommand;
public class RestartCommand extends ServerCommand
{

View File

@ -1,4 +1,5 @@
package mineplex.serverdata;
package mineplex.serverdata.commands;
public abstract class ServerCommand
{

View File

@ -1,4 +1,4 @@
package mineplex.serverdata;
package mineplex.serverdata.commands;
import redis.clients.jedis.JedisPubSub;

View File

@ -1,8 +1,10 @@
package mineplex.serverdata;
package mineplex.serverdata.commands;
import java.util.HashMap;
import java.util.Map;
import mineplex.serverdata.Utility;
import mineplex.serverdata.servers.ServerManager;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

View File

@ -1,4 +1,4 @@
package mineplex.serverdata.transfers;
package mineplex.serverdata.commands;
public class ServerTransfer
{

View File

@ -1,7 +1,6 @@
package mineplex.serverdata.transfers;
package mineplex.serverdata.commands;
import mineplex.serverdata.Region;
import mineplex.serverdata.ServerCommand;
public class SuicideCommand extends ServerCommand
{

View File

@ -1,6 +1,5 @@
package mineplex.serverdata.transfers;
package mineplex.serverdata.commands;
import mineplex.serverdata.ServerCommand;
/**
* The TransferCommand is sent across the server network to notify

View File

@ -1,32 +1,21 @@
package mineplex.serverdata.data;
import mineplex.serverdata.Region;
import mineplex.serverdata.data.Data;
public class BungeeServer
public class BungeeServer implements Data
{
// The name of this server.
private String _name;
public String getName() { return _name; }
// The geographical region of this Bungee Server.
private Region _region;
public Region getRegion() { return _region; }
// The number of players currently online.
private int _playerCount;
public int getPlayerCount() { return _playerCount; }
public void incrementPlayerCount(int amount) { this._playerCount += amount; }
// The maximum number of players allowed on the server.
private int _maxPlayerCount;
public int getMaxPlayerCount() { return _maxPlayerCount; }
// The current amount of RAM allocated to the server.
private int _ram;
public int getRam() { return _ram; }
// The maximum amount of available RAM that can be allocated to the server.
private int _maxRam;
public int getMaxRam() { return _maxRam; }
// The public I.P address used by players to connect to the server.
private String _publicAddress;
@ -36,42 +25,33 @@ public class BungeeServer
private int _port;
public int getPort() { return _port; }
// Whether the Bungee server can connect to the internet.
private boolean _connected;
public boolean isConnected() { return _connected; }
/**
* Class constructor
* @param name
* @param publicAddress
* @param port
* @param playerCount
* @param maxPlayerCount
* @param ram
* @param maxRam
* @param connected
*/
public BungeeServer(String name, String publicAddress, int port,
int playerCount, int maxPlayerCount, int ram, int maxRam)
public BungeeServer(String name, Region region, String publicAddress, int port, int playerCount, boolean connected)
{
_name = name;
_region = region;
_playerCount = playerCount;
_maxPlayerCount = maxPlayerCount;
_ram = ram;
_maxRam = maxRam;
_publicAddress = publicAddress;
_port = port;
_connected = connected;
}
/**
* @return true, if {@value _playerCount} equals 0, false otherwise.
* Unique identifying ID for this Bungee Server.
*/
public boolean isEmpty()
public String getDataId()
{
return _playerCount == 0;
}
public void setName(String name)
{
_name = name;
}
public void setRegion(Region region)
{
_region = region;
return _name;
}
}

View File

@ -1,4 +1,5 @@
package mineplex.serverdata;
package mineplex.serverdata.data;
public interface Data
{

View File

@ -1,4 +1,4 @@
package mineplex.serverdata;
package mineplex.serverdata.data;
import java.util.Collection;

View File

@ -1,4 +1,4 @@
package mineplex.serverdata;
package mineplex.serverdata.redis;
import java.util.ArrayList;
import java.util.Collection;
@ -6,6 +6,12 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import mineplex.serverdata.Region;
import mineplex.serverdata.Utility;
import mineplex.serverdata.data.Data;
import mineplex.serverdata.data.DataRepository;
import mineplex.serverdata.servers.ConnectionData;
import mineplex.serverdata.servers.ServerManager;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
@ -20,15 +26,17 @@ public class RedisDataRepository<T extends Data> implements DataRepository<T>
// The delimiter character used for redis key paths
public final char KEY_DELIMITER = '.';
// The pool used to retrieve jedis instances.
// The pools used to retrieve jedis instances.
private JedisPool _writePool;
private JedisPool _readPool;
// The geographical region of the servers stored by this ServerRepository
private Region _region;
// The class type of the elements stored in this repository
private Class<T> _elementType;
// A unique label designating the elements and this repository.
private String _elementLabel;
/**
@ -186,7 +194,7 @@ public class RedisDataRepository<T extends Data> implements DataRepository<T>
@Override
public void addElement(T element)
{
addElement(element, 1000 * 60 * 60 * 24 * 7 * 4 * 12 * 10); // Set the timeout to 10 years
addElement(element, 60 * 60 * 24 * 7 * 4 * 12 * 10); // Set the timeout to 10 years
}
@Override
@ -206,7 +214,7 @@ public class RedisDataRepository<T extends Data> implements DataRepository<T>
String dataKey = generateKey(dataId);
Transaction transaction = jedis.multi();
transaction.set(dataKey, null);
transaction.del(dataKey);
transaction.zrem(setKey, dataId);
transaction.exec();
}

View File

@ -1,4 +1,4 @@
package mineplex.serverdata;
package mineplex.serverdata.redis;
import java.util.ArrayList;
import java.util.Collection;
@ -9,11 +9,13 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import mineplex.serverdata.data.BungeeServer;
import mineplex.serverdata.Region;
import mineplex.serverdata.Utility;
import mineplex.serverdata.data.DedicatedServer;
import mineplex.serverdata.data.MinecraftServer;
import mineplex.serverdata.data.PlayerStatus;
import mineplex.serverdata.data.ServerGroup;
import mineplex.serverdata.servers.ConnectionData;
import mineplex.serverdata.servers.ServerRepository;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;
@ -555,312 +557,7 @@ public class RedisServerRepository implements ServerRepository
return server;
}
@Override
public void updateBungeeStatus(BungeeServer serverData, int timeout)
{
Jedis jedis = _writePool.getResource();
try
{
String serializedData = Utility.serialize(serverData);
String serverName = serverData.getName();
String setKey = concatenate("bungeestatus", "minecraft", _region.toString());
String dataKey = concatenate(setKey, serverName);
long expiry = Utility.currentTimeSeconds() + timeout;
Transaction transaction = jedis.multi();
transaction.set(dataKey, serializedData);
transaction.zadd(setKey, expiry, serverName);
transaction.exec();
}
catch (JedisConnectionException exception)
{
exception.printStackTrace();
_writePool.returnBrokenResource(jedis);
jedis = null;
}
finally
{
if (jedis != null)
{
_writePool.returnResource(jedis);
}
}
}
@Override
public void removeBungeeStatus(BungeeServer serverData)
{
Jedis jedis = _writePool.getResource();
try
{
String serverName = serverData.getName();
String setKey = concatenate("bungeestatus", "minecraft", _region.toString());
String dataKey = concatenate(setKey, serverName);
Transaction transaction = jedis.multi();
transaction.del(dataKey);
transaction.zrem(setKey, serverName);
transaction.exec();
}
catch (JedisConnectionException exception)
{
exception.printStackTrace();
_writePool.returnBrokenResource(jedis);
jedis = null;
}
finally
{
if (jedis != null)
{
_writePool.returnResource(jedis);
}
}
}
@Override
public Collection<BungeeServer> getBungeeStatuses()
{
Collection<BungeeServer> servers = new HashSet<BungeeServer>();
Jedis jedis = _readPool.getResource();
try
{
String setKey = concatenate("bungeestatus", "minecraft", _region.toString());
Pipeline pipeline = jedis.pipelined();
List<Response<String>> responses = new ArrayList<Response<String>>();
for (String serverName : getActiveNames(setKey))
{
String dataKey = concatenate(setKey, serverName);
responses.add(pipeline.get(dataKey));
}
pipeline.sync();
for (Response<String> response : responses)
{
String serializedData = response.get();
BungeeServer server = Utility.deserialize(serializedData, BungeeServer.class);
if (server != null)
{
servers.add(server);
}
}
}
catch (JedisConnectionException exception)
{
exception.printStackTrace();
_readPool.returnBrokenResource(jedis);
jedis = null;
}
finally
{
if (jedis != null)
{
_readPool.returnResource(jedis);
}
}
return servers;
}
@Override
public void updatePlayerStatus(PlayerStatus serverData, int timeout)
{
Jedis jedis = _writePool.getResource();
try
{
String serializedData = Utility.serialize(serverData);
String serverName = serverData.getName();
String setKey = concatenate("playerstatus", "minecraft", _region.toString());
String dataKey = concatenate(setKey, serverName);
long expiry = Utility.currentTimeSeconds() + timeout;
Transaction transaction = jedis.multi();
transaction.set(dataKey, serializedData);
transaction.zadd(setKey, expiry, serverName);
transaction.exec();
}
catch (JedisConnectionException exception)
{
exception.printStackTrace();
_writePool.returnBrokenResource(jedis);
jedis = null;
}
finally
{
if (jedis != null)
{
_writePool.returnResource(jedis);
}
}
}
@Override
public void removePlayerStatus(PlayerStatus serverData)
{
Jedis jedis = _writePool.getResource();
try
{
String serverName = serverData.getName();
String setKey = concatenate("playerstatus", "minecraft", _region.toString());
String dataKey = concatenate(setKey, serverName);
Transaction transaction = jedis.multi();
transaction.del(dataKey);
transaction.zrem(setKey, serverName);
transaction.exec();
}
catch (JedisConnectionException exception)
{
exception.printStackTrace();
_writePool.returnBrokenResource(jedis);
jedis = null;
}
finally
{
if (jedis != null)
{
_writePool.returnResource(jedis);
}
}
}
@Override
public PlayerStatus getPlayerStatus(String playerName)
{
PlayerStatus status = null;
Jedis jedis = _readPool.getResource();
try
{
String setKey = concatenate("playerstatus", "minecraft", _region.toString());
String dataKey = concatenate(setKey, playerName);
String serializedData = jedis.get(dataKey);
status = Utility.deserialize(serializedData, PlayerStatus.class);
}
catch (JedisConnectionException exception)
{
exception.printStackTrace();
_readPool.returnBrokenResource(jedis);
jedis = null;
}
finally
{
if (jedis != null)
{
_readPool.returnResource(jedis);
}
}
return status;
}
@Override
public Collection<PlayerStatus> getPlayerStatuses()
{
Collection<PlayerStatus> servers = new HashSet<PlayerStatus>();
Jedis jedis = _readPool.getResource();
try
{
String setKey = concatenate("playerstatus", "minecraft", _region.toString());
Pipeline pipeline = jedis.pipelined();
List<Response<String>> responses = new ArrayList<Response<String>>();
for (String serverName : getActiveNames(setKey))
{
String dataKey = concatenate(setKey, serverName);
responses.add(pipeline.get(dataKey));
}
pipeline.sync();
for (Response<String> response : responses)
{
String serializedData = response.get();
PlayerStatus server = Utility.deserialize(serializedData, PlayerStatus.class);
if (server != null)
{
servers.add(server);
}
}
}
catch (JedisConnectionException exception)
{
exception.printStackTrace();
_readPool.returnBrokenResource(jedis);
jedis = null;
}
finally
{
if (jedis != null)
{
_readPool.returnResource(jedis);
}
}
return servers;
}
@Override
public Collection<BungeeServer> getGlobalBungeeStatuses()
{
Collection<BungeeServer> servers = new HashSet<BungeeServer>();
Jedis jedis = _readPool.getResource();
try
{
for (Region region : Region.values())
{
String setKey = concatenate("bungeestatus", "minecraft", region.toString());
Pipeline pipeline = jedis.pipelined();
List<Response<String>> responses = new ArrayList<Response<String>>();
for (String serverName : getActiveNames(setKey))
{
String dataKey = concatenate(setKey, serverName);
responses.add(pipeline.get(dataKey));
}
pipeline.sync();
for (Response<String> response : responses)
{
String serializedData = response.get();
BungeeServer server = Utility.deserialize(serializedData, BungeeServer.class);
server.setRegion(region);
if (server != null)
{
servers.add(server);
}
}
}
}
catch (JedisConnectionException exception)
{
exception.printStackTrace();
_readPool.returnBrokenResource(jedis);
jedis = null;
}
finally
{
if (jedis != null)
{
_readPool.returnResource(jedis);
}
}
return servers;
}
/*
* <region> = "US" or "EU"
* serverstatus.minecraft.<region>.<name> stores the JSON encoded information of an active MinecraftServer instance.

View File

@ -20,15 +20,15 @@ import java.util.logging.FileHandler;
import java.util.logging.Logger;
import mineplex.core.common.util.NautHashMap;
import mineplex.serverdata.DedicatedServerSorter;
import mineplex.serverdata.Region;
import mineplex.serverdata.ServerManager;
import mineplex.serverdata.ServerRepository;
import mineplex.serverdata.commands.RestartCommand;
import mineplex.serverdata.commands.SuicideCommand;
import mineplex.serverdata.data.DedicatedServer;
import mineplex.serverdata.data.MinecraftServer;
import mineplex.serverdata.data.ServerGroup;
import mineplex.serverdata.transfers.RestartCommand;
import mineplex.serverdata.transfers.SuicideCommand;
import mineplex.serverdata.servers.DedicatedServerSorter;
import mineplex.serverdata.servers.ServerManager;
import mineplex.serverdata.servers.ServerRepository;
public class ServerMonitor
{