diff --git a/.gitignore b/.gitignore index 8c942dcac..faa4d8cb7 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,8 @@ update Reference /Plugins/.idea/workspace.xml -/Plugins/out \ No newline at end of file +/Plugins/out +BungeeCord +/Plugins/Mineplex.Bungee.Mineplexer/*.gitignore +Reference_1_7 +Servers diff --git a/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerTracker/PlayerTrackerRepository.java b/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerTracker/PlayerTrackerRepository.java index e3f229d3f..fdbce7049 100644 --- a/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerTracker/PlayerTrackerRepository.java +++ b/Plugins/Mineplex.Bungee.Mineplexer/src/mineplex/bungee/playerTracker/PlayerTrackerRepository.java @@ -8,7 +8,7 @@ import java.sql.SQLException; public class PlayerTrackerRepository { - private String _connectionString = "jdbc:mysql://db.mineplex.com:3306/PlayerTracker"; + private String _connectionString = "jdbc:mysql://db.mineplex.com:3306/PlayerTracker?autoReconnect=true&failOverReadOnly=false&maxReconnects=10"; private String _userName = "root"; private String _password = "tAbechAk3wR7tuTh"; diff --git a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHackRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHackRepository.java index 5493abaff..ac5f67281 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHackRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/antihack/AntiHackRepository.java @@ -17,7 +17,7 @@ public class AntiHackRepository private String _serverName; private static Connection _connection; - private String _connectionString = "jdbc:mysql://sqlstats.mineplex.com:3306/Mineplex?autoReconnect=true"; + private String _connectionString = "jdbc:mysql://sqlstats.mineplex.com:3306/Mineplex?autoReconnect=true&failOverReadOnly=false&maxReconnects=10"; private String _userName = "root"; private String _password = "tAbechAk3wR7tuTh"; diff --git a/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java b/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java index d021dbc17..527887935 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java @@ -85,7 +85,7 @@ public class Chat extends MiniClientPlugin { try { - GetPlugin().getConfig().addDefault("chat.connectionurl", "jdbc:mysql://db.mineplex.com:3306/Account"); + GetPlugin().getConfig().addDefault("chat.connectionurl", "jdbc:mysql://db.mineplex.com:3306/Account?autoReconnect=true&failOverReadOnly=false&maxReconnects=10"); GetPlugin().getConfig().set("chat.connectionurl", GetPlugin().getConfig().getString("chat.connectionurl")); GetPlugin().saveConfig(); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/elo/EloManager.java b/Plugins/Mineplex.Core/src/mineplex/core/elo/EloManager.java index 33855e439..10981c224 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/elo/EloManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/elo/EloManager.java @@ -30,7 +30,7 @@ public class EloManager extends MiniPlugin { try { - plugin.getConfig().addDefault("elo.connectionurl", "jdbc:mysql://sqlstats.mineplex.com:3306/Mineplex"); + plugin.getConfig().addDefault("elo.connectionurl", "jdbc:mysql://sqlstats.mineplex.com:3306/Mineplex?autoReconnect=true&failOverReadOnly=false&maxReconnects=10"); plugin.getConfig().set("elo.connectionurl", plugin.getConfig().getString("elo.connectionurl")); plugin.saveConfig(); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/logger/Logger.java b/Plugins/Mineplex.Core/src/mineplex/core/logger/Logger.java index 1f0a73eca..26f34e986 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/logger/Logger.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/logger/Logger.java @@ -37,7 +37,7 @@ public class Logger { try { - plugin.getConfig().addDefault("log.connectionurl", "jdbc:mysql://sqlstats.mineplex.com:3306/Mineplex"); + plugin.getConfig().addDefault("log.connectionurl", "jdbc:mysql://sqlstats.mineplex.com:3306/Mineplex?autoReconnect=true&failOverReadOnly=false&maxReconnects=10"); plugin.getConfig().set("log.connectionurl", plugin.getConfig().getString("log.connectionurl")); plugin.saveConfig(); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/portal/PortalRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/portal/PortalRepository.java new file mode 100644 index 000000000..affd38e05 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/portal/PortalRepository.java @@ -0,0 +1,175 @@ +package mineplex.core.portal; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import mineplex.core.common.util.NautHashMap; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +public class PortalRepository +{ + private static Object _connectionLock = new Object(); + + private String _connectionString = "jdbc:mysql://db.mineplex.com:3306/Queue?autoReconnect=true&failOverReadOnly=false&maxReconnects=10"; + private String _userName = "root"; + private String _password = "tAbechAk3wR7tuTh"; + + private boolean _us = true; + + private static String CREATE_TRANSFER_TABLE = "CREATE TABLE IF NOT EXISTS playerServerTransfer (id INT NOT NULL AUTO_INCREMENT, playerName VARCHAR(256), serverName VARCHAR(256), PRIMARY KEY (id));"; + private static String RETRIEVE_TRANSFER_RECORDS = "SELECT playerName, serverName FROM playerServerTransfer WHERE playerName IN "; + private static String DELETE_TRANSFER_RECORDS = "DELETE FROM playerServerTransfer WHERE playerName = ?;"; + + 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_TRANSFER_TABLE); + preparedStatement.execute(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } + + public NautHashMap retrieveServerTransfers() + { + ResultSet resultSet = null; + PreparedStatement preparedStatement = null; + NautHashMap serverTransfers = new NautHashMap(); + + try + { + synchronized (_connectionLock) + { + if (_connection.isClosed()) + { + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + } + + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(RETRIEVE_TRANSFER_RECORDS + "("); + + for (Player player : Bukkit.getOnlinePlayers()) + { + stringBuilder.append("'" + player.getName() + "', "); + } + + stringBuilder.delete(stringBuilder.length() - 2, stringBuilder.length()); + + stringBuilder.append(");"); + + preparedStatement = _connection.prepareStatement(stringBuilder.toString()); + + resultSet = preparedStatement.executeQuery(); + + while (resultSet.next()) + { + serverTransfers.put(resultSet.getString(1), resultSet.getString(2)); + } + } + } + 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 serverTransfers; + } + + public void deleteServerTransfers(String playerName) + { + PreparedStatement preparedStatement = null; + + try + { + synchronized (_connectionLock) + { + if (_connection.isClosed()) + { + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + } + + preparedStatement = _connection.prepareStatement(DELETE_TRANSFER_RECORDS); + preparedStatement.setString(1, playerName); + + preparedStatement.executeUpdate(); + } + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/status/ServerStatusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/status/ServerStatusManager.java index 05ad067bb..c347c7b13 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/status/ServerStatusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/status/ServerStatusManager.java @@ -70,7 +70,7 @@ public class ServerStatusManager extends MiniPlugin { try { - GetPlugin().getConfig().addDefault("serverstatus.connectionurl", "jdbc:mysql://db.mineplex.com:3306/ServerStatus"); + GetPlugin().getConfig().addDefault("serverstatus.connectionurl", "jdbc:mysql://db.mineplex.com:3306/ServerStatus&autoReconnect=true&failOverReadOnly=false&maxReconnects=10"); GetPlugin().getConfig().set("serverstatus.connectionurl", GetPlugin().getConfig().getString("serverstatus.connectionurl")); GetPlugin().getConfig().addDefault("serverstatus.username", "root"); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/queue/PlayerMatchStatus.java b/Plugins/Mineplex.Hub/src/mineplex/hub/queue/PlayerMatchStatus.java new file mode 100644 index 000000000..94865ce63 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/queue/PlayerMatchStatus.java @@ -0,0 +1,13 @@ +package mineplex.hub.queue; + +import java.util.ArrayList; +import java.util.List; + +public class PlayerMatchStatus +{ + public int Id = -1; + public String State = "Awaiting Match"; + public int AssignedMatch = -1; + public List OtherStatuses = new ArrayList(); + public boolean Prompted = false; +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/queue/QueueManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/queue/QueueManager.java new file mode 100644 index 000000000..d888f9efc --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/queue/QueueManager.java @@ -0,0 +1,303 @@ +package mineplex.hub.queue; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import mineplex.core.MiniPlugin; +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.NautHashMap; +import mineplex.core.donation.DonationManager; +import mineplex.core.elo.EloManager; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.hub.party.PartyManager; +import mineplex.hub.queue.ui.QueueShop; + +public class QueueManager extends MiniPlugin +{ + private static Object _queueLock = new Object(); + private static Object _assignedLock = new Object(); + + private EloManager _eloManager; + private PartyManager _partyManager; + private QueueRepository _repository; + private NautHashMap _queuedPlayerMatchList = new NautHashMap(); + private NautHashMap _assignedPlayerMatchList = new NautHashMap(); + + public QueueManager(JavaPlugin plugin, CoreClientManager clientManager, DonationManager donationManager, EloManager eloManager, PartyManager partyManager) + { + super("Queue Manager", plugin); + + setupConfigValues(); + + _eloManager = eloManager; + _partyManager = partyManager; + _repository = new QueueRepository(plugin.getConfig().getString("queue.connectionurl"), plugin.getConfig().getBoolean("queue.us")); + } + + private void setupConfigValues() + { + try + { + GetPlugin().getConfig().addDefault("queue.connectionurl", "jdbc:mysql://db.mineplex.com:3306/Queue&autoReconnect=true&failOverReadOnly=false&maxReconnects=10"); + GetPlugin().getConfig().set("queue.connectionurl", GetPlugin().getConfig().getString("queue.connectionurl")); + + GetPlugin().getConfig().addDefault("queue.us", true); + GetPlugin().getConfig().set("queue.us", GetPlugin().getConfig().getBoolean("queue.us")); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + public boolean isQueued(Player player) + { + boolean queued = false; + + synchronized (_queueLock) + { + queued = _queuedPlayerMatchList.containsKey(player.getName()); + } + + if (queued) + return queued; + + synchronized (_assignedLock) + { + queued = _assignedPlayerMatchList.containsKey(player.getName()); + } + + return queued; + } + + public boolean isInPrepMatch(Player player) + { + synchronized (_assignedLock) + { + return _assignedPlayerMatchList.containsKey(player.getName()); + } + } + + public PlayerMatchStatus getQueuedPlayerStatus(Player player) + { + synchronized (_queueLock) + { + return _queuedPlayerMatchList.get(player.getName()); + } + } + + public PlayerMatchStatus getPrepMatchStatus(Player player) + { + synchronized (_assignedLock) + { + return _assignedPlayerMatchList.get(player.getName()); + } + } + + public void queuePlayer(final String gameType, final Player...players) + { + int eloCumulative = 0; + + for (Player player : players) + { + eloCumulative = _eloManager.getElo(player.getUniqueId(), gameType); + } + + final int elo = eloCumulative / players.length; + + Bukkit.getScheduler().runTaskAsynchronously(GetPlugin(), new Runnable() + { + public void run() + { + StringBuilder stringBuilder = new StringBuilder(); + + for (Player player : players) + { + stringBuilder.append(player.getName() + ", "); + } + + String playerList = stringBuilder.toString().substring(0, stringBuilder.length() - 2); + + PlayerMatchStatus matchStatus = _repository.addQueueRecord(playerList, players.length, gameType, elo); + + synchronized (_queueLock) + { + _queuedPlayerMatchList.put(players[0].getName(), matchStatus); + } + } + }); + } + + @EventHandler + public void removeDisconnectingPlayer(PlayerQuitEvent event) + { + synchronized (_queueLock) + { + PlayerMatchStatus matchStatus = _queuedPlayerMatchList.remove(event.getPlayer().getName()); + + if (matchStatus == null) + { + matchStatus = _assignedPlayerMatchList.remove(event.getPlayer().getName()); + } + + if (matchStatus != null) + _repository.deleteQueueRecord(matchStatus); + } + } + + @EventHandler + public void updateQueues(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + return; + + final NautHashMap listCopy = new NautHashMap(); + + synchronized (_queueLock) + { + for (Entry entry : _queuedPlayerMatchList.entrySet()) + { + listCopy.put(entry.getKey(), entry.getValue()); + } + } + + Bukkit.getScheduler().runTaskAsynchronously(GetPlugin(), new Runnable() + { + public void run() + { + for (Entry entry : listCopy.entrySet()) + { + entry.setValue(_repository.checkForAssignedMatch(entry.getValue().Id)); + } + + for (String key : listCopy.keySet()) + { + if (listCopy.get(key).AssignedMatch != -1) + { + synchronized (_assignedLock) + { + _assignedPlayerMatchList.put(key, listCopy.get(key)); + } + + synchronized (_queueLock) + { + _queuedPlayerMatchList.remove(key); + } + } + if (_queuedPlayerMatchList.containsKey(key)) + { + synchronized (_assignedLock) + { + _assignedPlayerMatchList.remove(key); + } + + synchronized (_queueLock) + { + _queuedPlayerMatchList.put(key, listCopy.get(key)); + } + } + } + } + }); + } + + @EventHandler + public void checkAssignedQueues(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + return; + + Bukkit.getScheduler().runTaskAsynchronously(GetPlugin(), new Runnable() + { + public void run() + { + NautHashMap assignedCopy = new NautHashMap(); + + synchronized (_assignedLock) + { + for (Entry entry : _assignedPlayerMatchList.entrySet()) + { + assignedCopy.put(entry.getKey(), entry.getValue()); + } + } + + for (Entry entry : assignedCopy.entrySet()) + { + entry.setValue(_repository.updateOtherPlayersMatchStatus(entry.getValue())); + } + + for (String key : assignedCopy.keySet()) + { + synchronized (_assignedLock) + { + if (_assignedPlayerMatchList.containsKey(key)) + _assignedPlayerMatchList.put(key, assignedCopy.get(key)); + } + } + } + }); + } + + public List findPlayersNeedingPrompt() + { + List players = new ArrayList(); + + synchronized (_assignedLock) + { + for (Entry entry : _assignedPlayerMatchList.entrySet()) + { + if (!entry.getValue().Prompted) + { + Player player = Bukkit.getPlayer(entry.getKey()); + + if (player == null) + continue; + + players.add(player); + entry.getValue().Prompted = true; + } + } + } + + return players; + } + + public void respondToInvite(final Player player, final boolean accepted) + { + Bukkit.getScheduler().runTaskAsynchronously(GetPlugin(), new Runnable() + { + public void run() + { + PlayerMatchStatus matchStatus = null; + + synchronized (_assignedLock) + { + matchStatus = _assignedPlayerMatchList.get(player.getName()); + } + + matchStatus.State = accepted ? "Ready" : "Denied"; + + _repository.updateState(matchStatus); + } + }); + } + + public EloManager getEloManager() + { + return _eloManager; + } + + public PartyManager getPartyManager() + { + return _partyManager; + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/queue/QueueRepository.java b/Plugins/Mineplex.Hub/src/mineplex/hub/queue/QueueRepository.java new file mode 100644 index 000000000..4e5a249a4 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/queue/QueueRepository.java @@ -0,0 +1,345 @@ +package mineplex.hub.queue; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +public class QueueRepository +{ + private static Object _connectionLock = new Object(); + + private String _connectionString; + private String _userName = "root"; + private String _password = "tAbechAk3wR7tuTh"; + + private boolean _us = true; + + private static String CREATE_ELO_QUEUE_TABLE = "CREATE TABLE IF NOT EXISTS playerQueue (id INT NOT NULL AUTO_INCREMENT, playerList VARCHAR(256), gameType VARCHAR(256), playerCount INT, elo INT, state VARCHAR(256), time LONG, assignedMatch INT, US BOOLEAN NOT NULL DEFAULT '1', PRIMARY KEY (id));"; + private static String SAVE_STATE_VALUE = "UPDATE playerQueue SET state = ? WHERE id = ?;"; + private static String DELETE_QUEUE_RECORD = "DELETE FROM playerQueue WHERE id = ?;"; + private static String INSERT_ACCOUNT = "INSERT INTO playerQueue (playerList, gameType, elo, state, time, playerCount, assignedMatch) VALUES (?, ?, ?, 'Awaiting Match', now(), ?, -1);"; + private static String RETRIEVE_MATCH_STATUS = "SELECT state, assignedMatch FROM playerQueue WHERE id = ?;"; + private static String RETRIEVE_OTHER_MATCH_STATUS = "SELECT state, playerCount FROM playerQueue WHERE assignedMatch = ? AND id != ? ORDER BY id DESC;"; + + private Connection _connection = null; + + public QueueRepository(String connectionUrl, boolean us) + { + _connectionString = connectionUrl; + _us = us; + + initialize(); + } + + public void initialize() + { + PreparedStatement preparedStatement = null; + + try + { + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + + // Create table + preparedStatement = _connection.prepareStatement(CREATE_ELO_QUEUE_TABLE); + preparedStatement.execute(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } + + public void deleteQueueRecord(PlayerMatchStatus matchStatus) + { + PreparedStatement preparedStatement = null; + + try + { + synchronized (_connectionLock) + { + if (_connection.isClosed()) + { + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + } + + preparedStatement = _connection.prepareStatement(DELETE_QUEUE_RECORD); + + preparedStatement.setInt(1, matchStatus.Id); + + if (preparedStatement.executeUpdate() == 0) + { + System.out.println("Error deleting queue record."); + } + } + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } + + public void updateState(PlayerMatchStatus matchStatus) + { + PreparedStatement preparedStatement = null; + + try + { + synchronized (_connectionLock) + { + if (_connection.isClosed()) + { + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + } + + preparedStatement = _connection.prepareStatement(SAVE_STATE_VALUE); + preparedStatement.setString(1, matchStatus.State); + preparedStatement.setInt(2, matchStatus.Id); + + if (preparedStatement.executeUpdate() == 0) + { + System.out.println("Error updating state."); + } + } + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } + + public PlayerMatchStatus addQueueRecord(String playerList, int playerCount, String gameType, int elo) + { + ResultSet resultSet = null; + PreparedStatement preparedStatement = null; + PlayerMatchStatus matchStatus = new PlayerMatchStatus(); + + try + { + synchronized (_connectionLock) + { + if (_connection.isClosed()) + { + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + } + + preparedStatement = _connection.prepareStatement(INSERT_ACCOUNT, Statement.RETURN_GENERATED_KEYS); + preparedStatement.setString(1, playerList); + preparedStatement.setString(2, gameType); + preparedStatement.setInt(3, elo); + //preparedStatement.setBoolean(4, _us); + preparedStatement.setInt(4, playerCount); + + preparedStatement.executeUpdate(); + resultSet = preparedStatement.getGeneratedKeys(); + + while (resultSet.next()) + { + matchStatus.Id = resultSet.getInt(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 matchStatus; + } + + public PlayerMatchStatus checkForAssignedMatch(int id) + { + ResultSet resultSet = null; + PreparedStatement preparedStatement = null; + PlayerMatchStatus matchStatus = new PlayerMatchStatus(); + + try + { + synchronized (_connectionLock) + { + if (_connection.isClosed()) + { + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + } + + preparedStatement = _connection.prepareStatement(RETRIEVE_MATCH_STATUS); + preparedStatement.setInt(1, id); + + resultSet = preparedStatement.executeQuery(); + + while (resultSet.next()) + { + matchStatus.Id = id; + matchStatus.State = resultSet.getString(1); + matchStatus.AssignedMatch = resultSet.getInt(2); + } + } + } + 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 matchStatus; + } + + public PlayerMatchStatus updateOtherPlayersMatchStatus(PlayerMatchStatus matchStatus) + { + ResultSet resultSet = null; + PreparedStatement preparedStatement = null; + + try + { + synchronized (_connectionLock) + { + if (_connection.isClosed()) + { + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + } + + preparedStatement = _connection.prepareStatement(RETRIEVE_OTHER_MATCH_STATUS); + preparedStatement.setInt(1, matchStatus.AssignedMatch); + preparedStatement.setInt(2, matchStatus.Id); + + resultSet = preparedStatement.executeQuery(); + matchStatus.OtherStatuses.clear(); + + while (resultSet.next()) + { + int playerCount = resultSet.getInt(2); + + for (int i = 0; i < playerCount; i++) + matchStatus.OtherStatuses.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 matchStatus; + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/AcceptButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/AcceptButton.java new file mode 100644 index 000000000..b7325b0f0 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/AcceptButton.java @@ -0,0 +1,6 @@ +package mineplex.hub.queue.ui; + +public class AcceptButton +{ + +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/DenyButton.java b/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/DenyButton.java new file mode 100644 index 000000000..0b6397c2c --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/DenyButton.java @@ -0,0 +1,6 @@ +package mineplex.hub.queue.ui; + +public class DenyButton +{ + +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/QueuePage.java b/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/QueuePage.java new file mode 100644 index 000000000..aeb67225c --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/QueuePage.java @@ -0,0 +1,222 @@ +package mineplex.hub.queue.ui; + +import java.util.ArrayList; +import java.util.List; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.donation.DonationManager; +import mineplex.core.shop.item.IButton; +import mineplex.core.shop.item.ShopItem; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.hub.party.Party; +import mineplex.hub.queue.QueueManager; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; + +public class QueuePage extends ShopPageBase +{ + private int _circleIndex = 0; + + public QueuePage(QueueManager plugin, QueueShop shop, CoreClientManager clientManager, DonationManager donationManager, String name, Player player) + { + super(plugin, shop, clientManager, donationManager, name, player, 54); + + BuildPage(); + } + + @Override + protected void BuildPage() + { + clear(); + + if (Plugin.isQueued(Player)) + { + if (Plugin.isInPrepMatch(Player)) + { + if (Plugin.getPrepMatchStatus(Player).State.equalsIgnoreCase("Ready")) + { + setItem(22, new ShopItem(Material.BOOK, "Waiting for players to accept.", new String[] { }, 1, false)); + + int i = 45; + + for (String state : Plugin.getPrepMatchStatus(Player).OtherStatuses) + { + if (state.equalsIgnoreCase("Awaiting Confirmation")) + { + setItem(i, new ShopItem(Material.WOOL, "Waiting for reply...", new String[] { }, 1, false)); + } + else if (state.equalsIgnoreCase("Denied")) + { + setItem(i, new ShopItem(Material.WOOL, (byte)14, "Denied match.", new String[] { }, 1, false, false)); + } + else if (state.equalsIgnoreCase("Ready")) + { + setItem(i, new ShopItem(Material.WOOL, (byte)5, "Accepted match.", new String[] { }, 1, false, false)); + } + + i++; + } + } + else + { + IButton okClicked = new IButton() + { + @Override + public void ClickedLeft(Player player) + { + OkClicked(player); + } + + @Override + public void ClickedRight(Player player) + { + OkClicked(player); + } + }; + + IButton cancelClicked = new IButton() + { + @Override + public void ClickedLeft(Player player) + { + CancelClicked(player); + } + + @Override + public void ClickedRight(Player player) + { + CancelClicked(player); + } + }; + + buildSquareAt(19, new ShopItem(Material.EMERALD_BLOCK, (byte)0, ChatColor.GREEN + "OK", null, 1, false, true), okClicked); + buildSquareAt(23, new ShopItem(Material.REDSTONE_BLOCK, (byte)0, ChatColor.RED + "CANCEL", null, 1, false, true), cancelClicked);} + } + else + { + setItem(22, new ShopItem(Material.BOOK, "Looking for match...", new String[] { "Average wait time : DERP DERP DERP." }, 1, false)); + + drawCircle(); + } + } + else + { + IButton queueButton = new IButton() + { + @Override + public void ClickedLeft(Player player) + { + queuePlayer("Dominate", player); + } + + @Override + public void ClickedRight(Player player) + { + queuePlayer("Dominate", player); + } + }; + + AddButton(22, new ShopItem(Material.BOOK, "Play", new String[] { "Click me to enter play queue." }, 1, false), queueButton); + } + } + + public void Update() + { + _circleIndex++; + _circleIndex %= 3; + + BuildPage(); + } + + private void queuePlayer(String gameType, Player player) + { + Party party = Plugin.getPartyManager().GetParty(player); + + if (party != null) + { + if (player.getName().equals(party.GetLeader())) + { + List players = new ArrayList(); + + for (String name : party.GetPlayers()) + { + Player partyPlayer = UtilPlayer.searchExact(name); + + if (partyPlayer == null) + continue; + + players.add(partyPlayer); + } + + Plugin.queuePlayer(gameType, players.toArray(new Player[] {})); + } + } + else + { + Plugin.queuePlayer(gameType, player); + } + + BuildPage(); + } + + protected void OkClicked(Player player) + { + Plugin.respondToInvite(player, true); + + BuildPage(); + } + + protected void CancelClicked(Player player) + { + Plugin.respondToInvite(player, false); + + player.closeInventory(); + } + + private void buildSquareAt(int slot, ShopItem item, IButton button) + { + AddButton(slot, item, button); + AddButton(slot + 1, item, button); + AddButton(slot + 2, item, button); + + slot += 9; + + AddButton(slot, item, button); + AddButton(slot + 1, item, button); + AddButton(slot + 2, item, button); + + slot += 9; + + AddButton(slot, item, button); + AddButton(slot + 1, item, button); + AddButton(slot + 2, item, button); + } + + private void drawCircle() + { + if (_circleIndex == 0) + { + setItem(3, new ShopItem(Material.EYE_OF_ENDER, "Beep", 1, false)); + setItem(15, new ShopItem(Material.EYE_OF_ENDER, "Beep", 1, false)); + setItem(41, new ShopItem(Material.EYE_OF_ENDER, "Beep", 1, false)); + setItem(29, new ShopItem(Material.EYE_OF_ENDER, "Beep", 1, false)); + } + else if (_circleIndex == 1) + { + setItem(4, new ShopItem(Material.EYE_OF_ENDER, "Beep", 1, false)); + setItem(24, new ShopItem(Material.EYE_OF_ENDER, "Beep", 1, false)); + setItem(40, new ShopItem(Material.EYE_OF_ENDER, "Beep", 1, false)); + setItem(20, new ShopItem(Material.EYE_OF_ENDER, "Beep", 1, false)); + } + else if (_circleIndex == 2) + { + setItem(5, new ShopItem(Material.EYE_OF_ENDER, "Beep", 1, false)); + setItem(33, new ShopItem(Material.EYE_OF_ENDER, "Beep", 1, false)); + setItem(39, new ShopItem(Material.EYE_OF_ENDER, "Beep", 1, false)); + setItem(11, new ShopItem(Material.EYE_OF_ENDER, "Beep", 1, false)); + } + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/QueueShop.java b/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/QueueShop.java new file mode 100644 index 000000000..ed29dec07 --- /dev/null +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/queue/ui/QueueShop.java @@ -0,0 +1,61 @@ +package mineplex.hub.queue.ui; + +import mineplex.core.account.CoreClientManager; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.shop.ShopBase; +import mineplex.core.shop.page.ShopPageBase; +import mineplex.core.updater.UpdateType; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.hub.party.Party; +import mineplex.hub.queue.QueueManager; + +import org.bukkit.ChatColor; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; + +public class QueueShop extends ShopBase +{ + public QueueShop(QueueManager plugin, CoreClientManager clientManager, mineplex.core.donation.DonationManager donationManager, String name) + { + super(plugin, clientManager, donationManager, name); + } + + @Override + protected ShopPageBase> BuildPagesFor(Player player) + { + return new QueuePage(Plugin, this, ClientManager, DonationManager, " " + ChatColor.UNDERLINE + "Queuer 9001", player); + } + + @Override + protected boolean CanOpenShop(Player player) + { + Party party = Plugin.getPartyManager().GetParty(player); + + if (party != null && !player.getName().equalsIgnoreCase(party.GetLeader())) + { + player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, .6f); + player.sendMessage(F.main("Party", "Only Party Leaders can join games.")); + player.sendMessage(F.main("Party", "Type " + C.cGreen + "/party leave" + C.cGray + " if you wish to leave your party.")); + return false; + } + + return true; + } + + @EventHandler + public void UpdatePages(UpdateEvent event) + { + if (event.getType() != UpdateType.FASTER) + return; + + for (ShopPageBase> page : PlayerPageMap.values()) + { + if (page instanceof QueuePage) + { + ((QueuePage)page).Update(); + } + } + } +} diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ServerManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ServerManager.java index 72e91ea87..04dacadfc 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/server/ServerManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/server/ServerManager.java @@ -12,8 +12,10 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; +import org.bukkit.Sound; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -180,9 +182,20 @@ public class ServerManager extends MiniPlugin if (event.getType() != UpdateType.SEC) return; - for (Player player : _queueManager.findPlayersNeedingPrompt()) + for (final Player player : _queueManager.findPlayersNeedingPrompt()) { - _domShop.attemptShopOpen(player); + player.playSound(player.getLocation(), Sound.ENDERDRAGON_GROWL, 5f, 1f); + + Bukkit.getScheduler().runTaskLater(GetPlugin(), new Runnable() + { + public void run() + { + if (player.isOnline()) + { + _domShop.attemptShopOpen(player); + } + } + }, 20); } } diff --git a/Plugins/Mineplex.Queuer/.externalToolBuilders/New_Builder.launch b/Plugins/Mineplex.Queuer/.externalToolBuilders/New_Builder.launch new file mode 100644 index 000000000..0c6e0f696 --- /dev/null +++ b/Plugins/Mineplex.Queuer/.externalToolBuilders/New_Builder.launch @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/Plugins/Mineplex.ServerStatus/.externalToolBuilders/ServerStatus.launch b/Plugins/Mineplex.Queuer/.externalToolBuilders/Queuer.launch similarity index 85% rename from Plugins/Mineplex.ServerStatus/.externalToolBuilders/ServerStatus.launch rename to Plugins/Mineplex.Queuer/.externalToolBuilders/Queuer.launch index 95583c397..7fe0fe5da 100644 --- a/Plugins/Mineplex.ServerStatus/.externalToolBuilders/ServerStatus.launch +++ b/Plugins/Mineplex.Queuer/.externalToolBuilders/Queuer.launch @@ -1,10 +1,11 @@ - - - + + + + @@ -12,5 +13,5 @@ - + diff --git a/Plugins/Mineplex.Queuer/.gitignore b/Plugins/Mineplex.Queuer/.gitignore new file mode 100644 index 000000000..5e56e040e --- /dev/null +++ b/Plugins/Mineplex.Queuer/.gitignore @@ -0,0 +1 @@ +/bin diff --git a/Plugins/Mineplex.ServerStatus/.project b/Plugins/Mineplex.Queuer/.project similarity index 83% rename from Plugins/Mineplex.ServerStatus/.project rename to Plugins/Mineplex.Queuer/.project index f8f0a0c6b..e799bd1fc 100644 --- a/Plugins/Mineplex.ServerStatus/.project +++ b/Plugins/Mineplex.Queuer/.project @@ -1,6 +1,6 @@ - Mineplex.ServerStatus + Mineplex.Queuer @@ -16,7 +16,7 @@ LaunchConfigHandle - <project>/.externalToolBuilders/ServerStatus.launch + <project>/.externalToolBuilders/Queuer.launch diff --git a/Plugins/Mineplex.ServerStatus/.settings/org.eclipse.jdt.core.prefs b/Plugins/Mineplex.Queuer/.settings/org.eclipse.jdt.core.prefs similarity index 100% rename from Plugins/Mineplex.ServerStatus/.settings/org.eclipse.jdt.core.prefs rename to Plugins/Mineplex.Queuer/.settings/org.eclipse.jdt.core.prefs diff --git a/Plugins/Mineplex.Queuer/Mineplex.Queuer.iml b/Plugins/Mineplex.Queuer/Mineplex.Queuer.iml new file mode 100644 index 000000000..c68cf7cf9 --- /dev/null +++ b/Plugins/Mineplex.Queuer/Mineplex.Queuer.iml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugins/Mineplex.Queuer/src/mineplex/queuer/DynamicServerData.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/DynamicServerData.java new file mode 100644 index 000000000..50ab90bc6 --- /dev/null +++ b/Plugins/Mineplex.Queuer/src/mineplex/queuer/DynamicServerData.java @@ -0,0 +1,33 @@ +package mineplex.queuer; + +import java.util.HashMap; + +public class DynamicServerData +{ + public String Name; + public String Address; + public int AvailableCPU = 32; + public int AvailableRAM = 14000; + + public HashMap ServerGroupCount = new HashMap(); + public boolean US; + public String PrivateAddress; + + public void setServerGroupCount(ServerGroupData groupData, int count) + { + if (ServerGroupCount.containsKey(groupData.Name)) + { + AvailableCPU += groupData.RequiredCPU * ServerGroupCount.get(groupData.Name); + AvailableRAM += groupData.RequiredRAM * ServerGroupCount.get(groupData.Name); + } + + ServerGroupCount.put(groupData.Name, count); + AvailableCPU -= groupData.RequiredCPU * count; + AvailableRAM -= groupData.RequiredRAM * count; + } + + public void printInfo() + { + System.out.println("DynamicServerData - Name:" + Name + " Address:" + Address + " RAM:" + AvailableRAM + " CPU:" + AvailableCPU); + } +} diff --git a/Plugins/Mineplex.Queuer/src/mineplex/queuer/DynamicServerSorter.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/DynamicServerSorter.java new file mode 100644 index 000000000..b7aa54f3a --- /dev/null +++ b/Plugins/Mineplex.Queuer/src/mineplex/queuer/DynamicServerSorter.java @@ -0,0 +1,30 @@ +package mineplex.queuer; + +import java.util.Comparator; + +public class DynamicServerSorter implements Comparator +{ + @Override + public int compare(DynamicServerData first, DynamicServerData second) + { + if (second.AvailableRAM <= 1024) + return -1; + + if (first.AvailableRAM <= 1024) + return 1; + + if (first.AvailableRAM > second.AvailableRAM) + return -1; + + if (second.AvailableRAM > first.AvailableRAM) + return 1; + + if (first.AvailableCPU > second.AvailableCPU) + return -1; + + if (second.AvailableCPU < first.AvailableCPU) + return 1; + + return 1; + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Queuer/src/mineplex/queuer/EloPlayerSorter.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/EloPlayerSorter.java new file mode 100644 index 000000000..3e3b96096 --- /dev/null +++ b/Plugins/Mineplex.Queuer/src/mineplex/queuer/EloPlayerSorter.java @@ -0,0 +1,27 @@ +package mineplex.queuer; + +import java.util.Comparator; + +public class EloPlayerSorter implements Comparator +{ + public int EloMark = -1; + + public EloPlayerSorter(int eloMark) + { + EloMark = eloMark; + } + + public int compare(PlayerMatchStatus playerA, PlayerMatchStatus playerB) + { + if (playerA.Elo - EloMark < playerB.Elo - EloMark) + return -1; + + if (playerB.Elo - EloMark < playerA.Elo - EloMark) + return 1; + + if (playerA.Id < playerB.Id) + return -1; + + return 1; + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Queuer/src/mineplex/queuer/GenericRunnable.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/GenericRunnable.java new file mode 100644 index 000000000..3f8eca396 --- /dev/null +++ b/Plugins/Mineplex.Queuer/src/mineplex/queuer/GenericRunnable.java @@ -0,0 +1,6 @@ +package mineplex.queuer; + +public interface GenericRunnable +{ + void run(T t); +} diff --git a/Plugins/Mineplex.Queuer/src/mineplex/queuer/GroupStatusData.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/GroupStatusData.java new file mode 100644 index 000000000..efaad563b --- /dev/null +++ b/Plugins/Mineplex.Queuer/src/mineplex/queuer/GroupStatusData.java @@ -0,0 +1,113 @@ +package mineplex.queuer; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class GroupStatusData +{ + private int _serverNum = 0; + private int _totalCount = 0; + private int _joinableCount = 0; + + public int Players; + public int MaxPlayers; + public int MaxServerNumber; + + public List EmptyServers = new ArrayList(); + public List KillServers = new ArrayList(); + public HashMap Servers = new HashMap(); + + public void addServer(ServerStatusData serverStatusData) + { + if (Servers.containsKey(Integer.parseInt(serverStatusData.Name.split("-")[1]))) + { + ServerStatusData existingServer = Servers.get(Integer.parseInt(serverStatusData.Name.split("-")[1])); + int existingCount = existingServer.Players; + int newCount = serverStatusData.Players; + + if (newCount == 0 || newCount < existingCount) + { + KillServers.add(serverStatusData); + return; + } + else if (existingCount == 0 || newCount > existingCount) + { + KillServers.add(existingServer); + Players -= existingServer.Players; + MaxPlayers -= existingServer.MaxPlayers; + + if (existingServer.Motd != null && (existingServer.Motd.contains("Starting") || existingServer.Motd.contains("Recruiting") || existingServer.Motd.contains("Waiting") || existingServer.Motd.contains("Cup") || existingServer.Motd.isEmpty() || existingServer.Motd.equals(""))) + { + if (existingServer.Players < existingServer.MaxPlayers) + { + // Lobby joinable checking + if (existingServer.Motd.isEmpty() || existingServer.Motd.equals("")) + { + if (existingServer.Players / existingServer.MaxPlayers < 10) + _joinableCount--; + } + else + { + _joinableCount--; + } + } + } + } + } + + Players += serverStatusData.Players; + MaxPlayers += serverStatusData.MaxPlayers; + + if (serverStatusData.Motd != null && (serverStatusData.Motd.contains("Starting") || serverStatusData.Motd.contains("Recruiting") || serverStatusData.Motd.contains("Waiting") || serverStatusData.Motd.contains("Cup") || serverStatusData.Motd.isEmpty() || serverStatusData.Motd.equals(""))) + { + if (serverStatusData.Players < serverStatusData.MaxPlayers) + { + // Lobby joinable checking + if (serverStatusData.Motd.isEmpty() || serverStatusData.Motd.equals("")) + { + if (serverStatusData.Players / serverStatusData.MaxPlayers < 10) + _joinableCount++; + } + else + { + _joinableCount++; + } + } + } + + _totalCount++; + + if (serverStatusData.Empty) + { + EmptyServers.add(serverStatusData); + } + + Servers.put(Integer.parseInt(serverStatusData.Name.split("-")[1]), serverStatusData); + } + + public int getTotalServers() + { + return _totalCount; + } + + public int getJoinableCount() + { + return _joinableCount; + } + + public int getNextServerNumber() + { + _serverNum++; + + while (true) + { + if (!Servers.containsKey(_serverNum)) + { + return _serverNum; + } + + _serverNum++; + } + } +} diff --git a/Plugins/Mineplex.Queuer/src/mineplex/queuer/JsonWebCall.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/JsonWebCall.java new file mode 100644 index 000000000..da84c41ef --- /dev/null +++ b/Plugins/Mineplex.Queuer/src/mineplex/queuer/JsonWebCall.java @@ -0,0 +1,357 @@ +package mineplex.queuer; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Type; + +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.PoolingClientConnectionManager; +import org.apache.http.message.BasicHeader; +import org.apache.http.protocol.HTTP; + +import com.google.gson.Gson; + +import mineplex.core.common.util.Callback; + +public class JsonWebCall +{ + private String _url; + private PoolingClientConnectionManager _connectionManager; + + public JsonWebCall(String url) + { + _url = url; + + SchemeRegistry schemeRegistry = new SchemeRegistry(); + schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); + + _connectionManager = new PoolingClientConnectionManager(schemeRegistry); + _connectionManager.setMaxTotal(200); + _connectionManager.setDefaultMaxPerRoute(20); + } + + public String ExecuteReturnStream(Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + String result = null; + + try + { + HttpResponse response; + + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + response = httpClient.execute(request); + + if (response != null) + { + in = response.getEntity().getContent(); + result = convertStreamToString(in); + } + } + catch (Exception ex) + { + System.out.println("Error executing JsonWebCall: \n" + ex.getMessage()); + System.out.println("Result: \n" + result); + + for (StackTraceElement trace : ex.getStackTrace()) + { + System.out.println(trace); + } + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + + return result; + } + + public void Execute() + { + Execute((Object)null); + } + + public void Execute(Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + + try + { + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + httpClient.execute(request); + } + catch (Exception ex) + { + System.out.println("JsonWebCall.Execute() Error:\n" + ex.getMessage()); + + for (StackTraceElement trace : ex.getStackTrace()) + { + System.out.println(trace); + } + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + } + + public T Execute(Class returnClass) + { + return Execute(returnClass, (Object)null); + } + + public T Execute(Type returnType, Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + T returnData = null; + String result = null; + + try + { + HttpResponse response; + + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + response = httpClient.execute(request); + + if (response != null) + { + in = response.getEntity().getContent(); + + result = convertStreamToString(in); + returnData = new Gson().fromJson(result, returnType); + } + } + catch (Exception ex) + { + System.out.println("Error executing JsonWebCall: \n" + ex.getMessage()); + System.out.println("Result: \n" + result); + + for (StackTraceElement trace : ex.getStackTrace()) + { + System.out.println(trace); + } + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + + return returnData; + } + + public T Execute(Class returnClass, Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + T returnData = null; + String result = null; + + try + { + HttpResponse response; + + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + response = httpClient.execute(request); + + if (response != null) + { + in = response.getEntity().getContent(); + + result = convertStreamToString(in); + returnData = new Gson().fromJson(result, returnClass); + } + } + catch (Exception ex) + { + System.out.println("Error executing JsonWebCall: \n" + ex.getMessage()); + System.out.println("Result: \n" + result); + + for (StackTraceElement trace : ex.getStackTrace()) + { + System.out.println(trace); + } + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + + return returnData; + } + + public void Execute(Class callbackClass, Callback callback) + { + Execute(callbackClass, callback, (Object)null); + } + + public void Execute(Class callbackClass, Callback callback, Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + String result = null; + + try + { + HttpResponse response; + + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + response = httpClient.execute(request); + + if (response != null && callback != null) + { + in = response.getEntity().getContent(); + + result = convertStreamToString(in); + callback.run(new Gson().fromJson(result, callbackClass)); + } + } + catch (Exception ex) + { + System.out.println("Error executing JsonWebCall: \n" + ex.getMessage()); + System.out.println("Result: \n" + result); + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + } + + protected String convertStreamToString(InputStream is) + { + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + StringBuilder sb = new StringBuilder(); + + String line = null; + try { + while ((line = reader.readLine()) != null) { + sb.append(line + "\n"); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return sb.toString(); + } +} diff --git a/Plugins/Mineplex.Queuer/src/mineplex/queuer/PlayerMatch.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/PlayerMatch.java new file mode 100644 index 000000000..f0f4f05e3 --- /dev/null +++ b/Plugins/Mineplex.Queuer/src/mineplex/queuer/PlayerMatch.java @@ -0,0 +1,38 @@ +package mineplex.queuer; + +import java.util.Collection; +import java.util.HashMap; + +public class PlayerMatch +{ + private HashMap _players = new HashMap(); + private int _playerCount = 0; + + public int MatchId = -1; + public int Elo = 0; + + + public void addPlayerRecord(PlayerMatchStatus record) + { + _players.put(record.Id, record); + + _playerCount += record.PlayerCount; + } + + public void removePlayerRecord(PlayerMatchStatus record) + { + _players.remove(record.Id); + + _playerCount -= record.PlayerCount; + } + + public int getPlayerCount() + { + return _playerCount; + } + + public Collection getPlayerRecords() + { + return _players.values(); + } +} diff --git a/Plugins/Mineplex.Queuer/src/mineplex/queuer/PlayerMatchStatus.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/PlayerMatchStatus.java new file mode 100644 index 000000000..894e57871 --- /dev/null +++ b/Plugins/Mineplex.Queuer/src/mineplex/queuer/PlayerMatchStatus.java @@ -0,0 +1,19 @@ +package mineplex.queuer; + +public class PlayerMatchStatus +{ + public int Id = -1; + public String State = "Awaiting Match"; + public int AssignedMatch = -1; + public int Variance = 25; + public String GameType; + public int Elo; + public int PlayerCount; + public long QueuedStartTime; + + + public void printInfo() + { + System.out.println("PlayerMatchStatus: Id=" + Id + " State=" + State + " AssignedMatch=" + AssignedMatch + " Variance=" + Variance + " GameType=" + GameType + " Elo=" + Elo + " PlayerCount=" + PlayerCount + " QueuedStartTime=" + QueuedStartTime); + } +} diff --git a/Plugins/Mineplex.Queuer/src/mineplex/queuer/ProcessRunner.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/ProcessRunner.java new file mode 100644 index 000000000..9e6353dad --- /dev/null +++ b/Plugins/Mineplex.Queuer/src/mineplex/queuer/ProcessRunner.java @@ -0,0 +1,81 @@ +package mineplex.queuer; + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +public class ProcessRunner extends Thread +{ + private ProcessBuilder _processBuilder; + private Process _process; + private GenericRunnable _runnable; + + boolean _done = false; + Boolean _error = false; + + ProcessRunner(String[] args) + { + super("ProcessRunner " + args); + _processBuilder = new ProcessBuilder(args); + } + + public void run() + { + try + { + _process = _processBuilder.start(); + _process.waitFor(); + + BufferedReader reader=new BufferedReader(new InputStreamReader(_process.getInputStream())); + String line = reader.readLine(); + + while(line != null) + { + if (line.equals("255")) + _error = true; + + line=reader.readLine(); + } + } + catch (Exception e) + { + System.out.println(e.getMessage()); + } + finally + { + _done = true; + + if (_runnable != null) + _runnable.run(_error); + } + } + + public void start(GenericRunnable runnable) + { + super.start(); + + _runnable = runnable; + } + + public int exitValue() throws IllegalStateException + { + if (_process != null) + { + return _process.exitValue(); + } + + throw new IllegalStateException("Process not started yet"); + } + + public boolean isDone() + { + return _done; + } + + public void abort() + { + if (!isDone()) + { + _process.destroy(); + } + } + } diff --git a/Plugins/Mineplex.Queuer/src/mineplex/queuer/Queuer.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/Queuer.java new file mode 100644 index 000000000..6e43afbbf --- /dev/null +++ b/Plugins/Mineplex.Queuer/src/mineplex/queuer/Queuer.java @@ -0,0 +1,168 @@ +package mineplex.queuer; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +public class Queuer +{ + private static Repository _repository = new Repository(); + + public static void main (String args[]) + { + boolean us = !new File("eu.dat").exists(); + + _repository.initialize(us); + + HashMap playerVarianceMap = new HashMap(); + HashMap playerPrepMatchMap = new HashMap(); + List matchList = new ArrayList(); + + EloPlayerSorter playerSorter = new EloPlayerSorter(1250); + + int matchId = 1; + + while (true) + { + int matchesMade = 0; + matchId %= 1500; + + List assignedMatchIdChecked = new ArrayList(); + List queueRecords = _repository.retrieveQueuedRecords(); + + System.out.println("Checking " + queueRecords.size() + " queues..."); + for (PlayerMatchStatus queueRecord : queueRecords) + { + Integer keyId = queueRecord.Id; + + // Add or increase variance mapping + if (playerVarianceMap.containsKey(keyId)) + playerVarianceMap.put(keyId, playerVarianceMap.get(keyId) + 25); + else + playerVarianceMap.put(keyId, 25); + + int playerVariance = playerVarianceMap.get(keyId); + + if (queueRecord.AssignedMatch == -1) + { + for (PlayerMatch match : matchList) + { + if (Math.abs(match.Elo - queueRecord.Elo) <= playerVariance) + { + if (playerPrepMatchMap.containsKey(keyId)) + { + if (playerPrepMatchMap.get(keyId) == match) + break; + + playerPrepMatchMap.get(keyId).removePlayerRecord(queueRecord); + } + + match.addPlayerRecord(queueRecord); + playerPrepMatchMap.put(keyId, match); + + System.out.println("Found prep match for '" + queueRecord.Id + "'"); + + break; + } + } + + if (!playerPrepMatchMap.containsKey(keyId)) + { + PlayerMatch match = new PlayerMatch(); + match.Elo = queueRecord.Elo; + match.MatchId = matchId; + match.addPlayerRecord(queueRecord); + + playerPrepMatchMap.put(keyId, match); + matchList.add(match); + + matchId++; + } + } + else if (!assignedMatchIdChecked.contains(queueRecord.AssignedMatch)) + { + System.out.println("Checking if match '" + queueRecord.AssignedMatch + "' is ready."); + + if (_repository.isMatchReady(queueRecord.AssignedMatch)) + { + _repository.startMatch(queueRecord.AssignedMatch); + _repository.deleteQueuesByAssignedMatch(queueRecord.AssignedMatch); + + System.out.println("Starting match '" + queueRecord.AssignedMatch + "'"); + } + + assignedMatchIdChecked.add(queueRecord.AssignedMatch); + } + } + + System.out.println("Checking " + matchList.size() + " matches..."); + + // Check for and kick off invites for ready matches + for (Iterator matchIterator = matchList.iterator(); matchIterator.hasNext();) + { + PlayerMatch match = matchIterator.next(); + + if (match.getPlayerCount() >= 4) + { + playerSorter.EloMark = match.Elo; + + List playerList = new ArrayList(); + playerList.addAll(match.getPlayerRecords()); + + Collections.sort(playerList, playerSorter); + + int playerCount = 0; + + for (int i = 0; i < playerList.size(); i++) + { + PlayerMatchStatus player = playerList.get(i); + + if (playerCount + player.PlayerCount > 4) + { + match.removePlayerRecord(player); + playerPrepMatchMap.remove(player.Id); + + System.out.println("Oops hit player cap, can't fit you in this match."); + continue; + } + + playerCount += player.PlayerCount; + } + + if (playerCount == 4) + { + System.out.println("Sent match invites for '" + match.MatchId + "'"); + + for (PlayerMatchStatus player : match.getPlayerRecords()) + { + playerPrepMatchMap.remove(player.Id); + _repository.assignMatch(player.Id, match.MatchId); + } + + matchIterator.remove(); + matchesMade += 1; + } + } + else if (match.getPlayerCount() == 0) + matchIterator.remove(); + } + + _repository.clearOldServerTransfers(); + + try + { + if (matchesMade > 0) + System.out.println("Made " + matchesMade + " matches."); + + Thread.sleep(1000); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + } +} diff --git a/Plugins/Mineplex.Queuer/src/mineplex/queuer/Repository.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/Repository.java new file mode 100644 index 000000000..7d84beca5 --- /dev/null +++ b/Plugins/Mineplex.Queuer/src/mineplex/queuer/Repository.java @@ -0,0 +1,561 @@ +package mineplex.queuer; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Repository +{ + private static Object _connectionLock = new Object(); + + private String _connectionString = "jdbc:mysql://db.mineplex.com:3306/Queue&autoReconnect=true&failOverReadOnly=false&maxReconnects=10"; + private String _serverStatusConnectionString = "jdbc:mysql://db.mineplex.com:3306/ServerStatus&autoReconnect=true&failOverReadOnly=false&maxReconnects=10"; + private String _userName = "root"; + private String _password = "tAbechAk3wR7tuTh"; + + private boolean _us = true; + + private static String CREATE_TRANSFER_TABLE = "CREATE TABLE IF NOT EXISTS playerServerTransfer (id INT NOT NULL AUTO_INCREMENT, playerName VARCHAR(256), serverName VARCHAR(256), updated LONG, PRIMARY KEY (id));"; + private static String INSERT_TRANSFER_RECORD = "INSERT INTO playerServerTransfer (playerName, serverName, updated) VALUES (?, ?, now());"; + private static String DELETE_OLD_TRANSFER_RECORDS = "DELETE FROM playerServerTransfer WHERE TIME_TO_SEC(TIMEDIFF(now(), updated)) > 15;"; + + private static String CREATE_ELO_QUEUE_TABLE = "CREATE TABLE IF NOT EXISTS playerQueue (id INT NOT NULL AUTO_INCREMENT, playerList VARCHAR(256), gameType VARCHAR(256), elo INT, state VARCHAR(256), time LONG, assignedMatch INT, us BOOLEAN NOT NULL DEFAULT 'true', PRIMARY KEY (id));"; + private static String SAVE_STATE_VALUE = "UPDATE playerQueue SET state = ? WHERE id = ?;"; + private static String DELETE_QUEUE_RECORD = "DELETE FROM playerQueue WHERE assignedMatch = ?;"; + private static String RETRIEVE_QUEUE_RECORDS = "SELECT id, gameType, elo, playerCount, assignedMatch, time, us FROM playerQueue WHERE us = ?;"; + private static String RETRIEVE_MATCH_STATUS = "SELECT state, playerList FROM playerQueue WHERE assignedMatch = ?;"; + private static String UPDATE_MATCH_STATUS = "UPDATE playerQueue SET assignedMatch = ?, state = ? WHERE id = ?;"; + + private static String RETRIEVE_SERVERGROUP_STATUSES = "SELECT serverName, now(), updated FROM ServerStatus WHERE players = 0 AND serverGroup = ?"; + + private Connection _connection = null; + private Connection _serverStatusConnection = 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_ELO_QUEUE_TABLE); + preparedStatement.execute(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + + try + { + if (_connection.isClosed()) + { + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + } + + // Create table + preparedStatement = _connection.prepareStatement(CREATE_TRANSFER_TABLE); + preparedStatement.execute(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } + + public void updateState(PlayerMatchStatus matchStatus) + { + PreparedStatement preparedStatement = null; + + try + { + synchronized (_connectionLock) + { + if (_connection.isClosed()) + { + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + } + + preparedStatement = _connection.prepareStatement(SAVE_STATE_VALUE); + preparedStatement.setString(1, matchStatus.State); + preparedStatement.setInt(2, matchStatus.Id); + + if (preparedStatement.executeUpdate() == 0) + { + System.out.println("Error updating state."); + } + } + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } + + public PlayerMatchStatus checkForAssignedMatch(int id) + { + ResultSet resultSet = null; + PreparedStatement preparedStatement = null; + PlayerMatchStatus matchStatus = new PlayerMatchStatus(); + + try + { + synchronized (_connectionLock) + { + if (_connection.isClosed()) + { + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + } + + preparedStatement = _connection.prepareStatement(RETRIEVE_MATCH_STATUS); + preparedStatement.setInt(1, id); + + resultSet = preparedStatement.getGeneratedKeys(); + + while (resultSet.next()) + { + matchStatus.Id = id; + matchStatus.State = resultSet.getString(1); + matchStatus.AssignedMatch = resultSet.getInt(2); + } + } + } + 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 matchStatus; + } + + public List retrieveQueuedRecords() + { + ResultSet resultSet = null; + PreparedStatement preparedStatement = null; + List queueRecords = new ArrayList(); + + try + { + synchronized (_connectionLock) + { + if (_connection.isClosed()) + { + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + } + + preparedStatement = _connection.prepareStatement(RETRIEVE_QUEUE_RECORDS); + preparedStatement.setBoolean(1, _us); + + resultSet = preparedStatement.executeQuery(); + + while (resultSet.next()) + { + PlayerMatchStatus matchStatus = new PlayerMatchStatus(); + + matchStatus.Id = resultSet.getInt(1); + matchStatus.GameType = resultSet.getString(2); + matchStatus.Elo = resultSet.getInt(3); + matchStatus.PlayerCount = resultSet.getInt(4); + matchStatus.AssignedMatch = resultSet.getInt(5); + matchStatus.QueuedStartTime = resultSet.getLong(6); + + queueRecords.add(matchStatus); + } + } + } + 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 queueRecords; + } + + public boolean isMatchReady(int assignedMatch) + { + ResultSet resultSet = null; + PreparedStatement preparedStatement = null; + boolean matchReady = true; + + try + { + synchronized (_connectionLock) + { + if (_connection.isClosed()) + { + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + } + + preparedStatement = _connection.prepareStatement(RETRIEVE_MATCH_STATUS); + preparedStatement.setInt(1, assignedMatch); + + resultSet = preparedStatement.executeQuery(); + + while (resultSet.next()) + { + if (!resultSet.getString(1).equalsIgnoreCase("Ready")) + { + matchReady = false; + break; + } + } + } + } + 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 matchReady; + } + + public void deleteQueuesByAssignedMatch(int matchId) + { + PreparedStatement preparedStatement = null; + + try + { + synchronized (_connectionLock) + { + if (_connection.isClosed()) + { + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + } + + preparedStatement = _connection.prepareStatement(DELETE_QUEUE_RECORD); + + preparedStatement.setInt(1, matchId); + + if (preparedStatement.executeUpdate() == 0) + { + System.out.println("Error deleting queue record."); + } + } + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } + + public void clearOldServerTransfers() + { + PreparedStatement preparedStatement = null; + + try + { + if (_connection == null || _connection.isClosed()) + _connection = DriverManager.getConnection(_serverStatusConnectionString, _userName, _password); + + preparedStatement = _connection.prepareStatement(DELETE_OLD_TRANSFER_RECORDS); + + preparedStatement.executeUpdate(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } + + public void startMatch(int assignedMatch) + { + ResultSet resultSet = null; + PreparedStatement preparedStatement = null; + PreparedStatement addTransferStatement = null; + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + String serverName = ""; + + try + { + if (_serverStatusConnection == null || _serverStatusConnection.isClosed()) + _serverStatusConnection = DriverManager.getConnection(_serverStatusConnectionString, _userName, _password); + + preparedStatement = _serverStatusConnection.prepareStatement(RETRIEVE_SERVERGROUP_STATUSES); + preparedStatement.setString(1, "DominateElo"); + + resultSet = preparedStatement.executeQuery(); + + while (resultSet.next()) + { + long current = dateFormat.parse(resultSet.getString(2)).getTime(); + long updated = dateFormat.parse(resultSet.getString(3)).getTime(); + + if (current - updated < 15000) + { + serverName = resultSet.getString(1); + break; + } + } + + resultSet.close(); + preparedStatement.close(); + + if (_connection == null || _connection.isClosed()) + _connection = DriverManager.getConnection(_serverStatusConnectionString, _userName, _password); + + preparedStatement = _connection.prepareStatement(RETRIEVE_MATCH_STATUS); + preparedStatement.setInt(1, assignedMatch); + + addTransferStatement = _connection.prepareStatement(INSERT_TRANSFER_RECORD); + + resultSet = preparedStatement.executeQuery(); + + while (resultSet.next()) + { + for (String name : Arrays.asList(resultSet.getString(2).split("\\s*,\\s*"))) + { + addTransferStatement.setString(1, name); + addTransferStatement.setString(2, serverName); + addTransferStatement.addBatch(); + } + } + + addTransferStatement.executeBatch(); + } + 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(); + } + } + } + } + + public void assignMatch(int id, int matchId) + { + ResultSet resultSet = null; + PreparedStatement preparedStatement = null; + + try + { + synchronized (_connectionLock) + { + if (_connection.isClosed()) + { + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + } + + preparedStatement = _connection.prepareStatement(UPDATE_MATCH_STATUS); + preparedStatement.setInt(1, matchId); + preparedStatement.setString(2, "Awaiting Reply"); + preparedStatement.setInt(3, id); + + preparedStatement.executeUpdate(); + } + } + 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(); + } + } + } + } +} diff --git a/Plugins/Mineplex.Queuer/src/mineplex/queuer/ServerGroupData.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/ServerGroupData.java new file mode 100644 index 000000000..3d6b30f9d --- /dev/null +++ b/Plugins/Mineplex.Queuer/src/mineplex/queuer/ServerGroupData.java @@ -0,0 +1,17 @@ +package mineplex.queuer; + +public class ServerGroupData +{ + public String Name; + public String Prefix; + public String ScriptName; + public int RequiredRAM; + public int RequiredCPU; + public int RequiredTotalServers; + public int RequiredJoinableServers; + + public void printInfo() + { + System.out.println("ServerGroupData - Name:" + Name + " Prefix:" + Prefix + " ScriptName:" + ScriptName + " RAM:" + RequiredRAM + " CPU:" + RequiredCPU + " ReqTotal:" + RequiredTotalServers + " ReqJoin:" + RequiredJoinableServers); + } +} diff --git a/Plugins/Mineplex.Queuer/src/mineplex/queuer/ServerStatusData.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/ServerStatusData.java new file mode 100644 index 000000000..bf00453b4 --- /dev/null +++ b/Plugins/Mineplex.Queuer/src/mineplex/queuer/ServerStatusData.java @@ -0,0 +1,13 @@ +package mineplex.queuer; + +public class ServerStatusData +{ + public String Name; + public String Motd; + public int Players; + public int MaxPlayers; + public String Address; + public String PrivateAddress; + public int Port; + public boolean Empty = false; +} diff --git a/Plugins/Mineplex.Queuer/src/mineplex/queuer/ServerTargetData.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/ServerTargetData.java new file mode 100644 index 000000000..58cd66ba6 --- /dev/null +++ b/Plugins/Mineplex.Queuer/src/mineplex/queuer/ServerTargetData.java @@ -0,0 +1,8 @@ +package mineplex.queuer; + +public class ServerTargetData +{ + public DynamicServerData DedicatedServer; + public int ServerNumber; + public String ServerGroup; +} diff --git a/Plugins/Mineplex.ServerMonitor/src/mineplex/servermonitor/JsonWebCall.java b/Plugins/Mineplex.ServerMonitor/src/mineplex/servermonitor/JsonWebCall.java new file mode 100644 index 000000000..9ea4d4572 --- /dev/null +++ b/Plugins/Mineplex.ServerMonitor/src/mineplex/servermonitor/JsonWebCall.java @@ -0,0 +1,357 @@ +package mineplex.servermonitor; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Type; + +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.PoolingClientConnectionManager; +import org.apache.http.message.BasicHeader; +import org.apache.http.protocol.HTTP; + +import com.google.gson.Gson; + +import mineplex.core.common.util.Callback; + +public class JsonWebCall +{ + private String _url; + private PoolingClientConnectionManager _connectionManager; + + public JsonWebCall(String url) + { + _url = url; + + SchemeRegistry schemeRegistry = new SchemeRegistry(); + schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); + + _connectionManager = new PoolingClientConnectionManager(schemeRegistry); + _connectionManager.setMaxTotal(200); + _connectionManager.setDefaultMaxPerRoute(20); + } + + public String ExecuteReturnStream(Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + String result = null; + + try + { + HttpResponse response; + + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + response = httpClient.execute(request); + + if (response != null) + { + in = response.getEntity().getContent(); + result = convertStreamToString(in); + } + } + catch (Exception ex) + { + System.out.println("Error executing JsonWebCall: \n" + ex.getMessage()); + System.out.println("Result: \n" + result); + + for (StackTraceElement trace : ex.getStackTrace()) + { + System.out.println(trace); + } + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + + return result; + } + + public void Execute() + { + Execute((Object)null); + } + + public void Execute(Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + + try + { + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + httpClient.execute(request); + } + catch (Exception ex) + { + System.out.println("JsonWebCall.Execute() Error:\n" + ex.getMessage()); + + for (StackTraceElement trace : ex.getStackTrace()) + { + System.out.println(trace); + } + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + } + + public T Execute(Class returnClass) + { + return Execute(returnClass, (Object)null); + } + + public T Execute(Type returnType, Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + T returnData = null; + String result = null; + + try + { + HttpResponse response; + + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + response = httpClient.execute(request); + + if (response != null) + { + in = response.getEntity().getContent(); + + result = convertStreamToString(in); + returnData = new Gson().fromJson(result, returnType); + } + } + catch (Exception ex) + { + System.out.println("Error executing JsonWebCall: \n" + ex.getMessage()); + System.out.println("Result: \n" + result); + + for (StackTraceElement trace : ex.getStackTrace()) + { + System.out.println(trace); + } + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + + return returnData; + } + + public T Execute(Class returnClass, Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + T returnData = null; + String result = null; + + try + { + HttpResponse response; + + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + response = httpClient.execute(request); + + if (response != null) + { + in = response.getEntity().getContent(); + + result = convertStreamToString(in); + returnData = new Gson().fromJson(result, returnClass); + } + } + catch (Exception ex) + { + System.out.println("Error executing JsonWebCall: \n" + ex.getMessage()); + System.out.println("Result: \n" + result); + + for (StackTraceElement trace : ex.getStackTrace()) + { + System.out.println(trace); + } + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + + return returnData; + } + + public void Execute(Class callbackClass, Callback callback) + { + Execute(callbackClass, callback, (Object)null); + } + + public void Execute(Class callbackClass, Callback callback, Object argument) + { + HttpClient httpClient = new DefaultHttpClient(_connectionManager); + InputStream in = null; + String result = null; + + try + { + HttpResponse response; + + Gson gson = new Gson(); + HttpPost request = new HttpPost(_url); + + if (argument != null) + { + StringEntity params = new StringEntity(gson.toJson(argument)); + params.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + request.setEntity(params); + } + + response = httpClient.execute(request); + + if (response != null && callback != null) + { + in = response.getEntity().getContent(); + + result = convertStreamToString(in); + callback.run(new Gson().fromJson(result, callbackClass)); + } + } + catch (Exception ex) + { + System.out.println("Error executing JsonWebCall: \n" + ex.getMessage()); + System.out.println("Result: \n" + result); + } + finally + { + httpClient.getConnectionManager().shutdown(); + + if (in != null) + { + try + { + in.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + } + } + + protected String convertStreamToString(InputStream is) + { + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + StringBuilder sb = new StringBuilder(); + + String line = null; + try { + while ((line = reader.readLine()) != null) { + sb.append(line + "\n"); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return sb.toString(); + } +} diff --git a/Plugins/Mineplex.ServerMonitor/src/mineplex/servermonitor/Repository.java b/Plugins/Mineplex.ServerMonitor/src/mineplex/servermonitor/Repository.java index 1c76989fb..20e02c3c6 100644 --- a/Plugins/Mineplex.ServerMonitor/src/mineplex/servermonitor/Repository.java +++ b/Plugins/Mineplex.ServerMonitor/src/mineplex/servermonitor/Repository.java @@ -13,7 +13,7 @@ import java.util.List; public class Repository { - private String _connectionString = "jdbc:mysql://db.mineplex.com:3306/ServerStatus"; + private String _connectionString = "jdbc:mysql://db.mineplex.com:3306/ServerStatus&autoReconnect=true&failOverReadOnly=false&maxReconnects=10"; private String _userName = "root"; private String _password = "tAbechAk3wR7tuTh"; private boolean _us = true; diff --git a/Plugins/Mineplex.ServerStatus/.classpath b/Plugins/Mineplex.ServerStatifier/.classpath similarity index 73% rename from Plugins/Mineplex.ServerStatus/.classpath rename to Plugins/Mineplex.ServerStatifier/.classpath index fb5011632..8325d3454 100644 --- a/Plugins/Mineplex.ServerStatus/.classpath +++ b/Plugins/Mineplex.ServerStatifier/.classpath @@ -1,6 +1,6 @@ - + diff --git a/Plugins/Mineplex.ServerStatifier/.externalToolBuilders/New_Builder.launch b/Plugins/Mineplex.ServerStatifier/.externalToolBuilders/New_Builder.launch new file mode 100644 index 000000000..0c6e0f696 --- /dev/null +++ b/Plugins/Mineplex.ServerStatifier/.externalToolBuilders/New_Builder.launch @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/Plugins/Mineplex.ServerStatifier/.externalToolBuilders/ServerStatifier.launch b/Plugins/Mineplex.ServerStatifier/.externalToolBuilders/ServerStatifier.launch new file mode 100644 index 000000000..d2a6c4998 --- /dev/null +++ b/Plugins/Mineplex.ServerStatifier/.externalToolBuilders/ServerStatifier.launch @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/Plugins/Mineplex.ServerStatifier/.project b/Plugins/Mineplex.ServerStatifier/.project new file mode 100644 index 000000000..f63f97e29 --- /dev/null +++ b/Plugins/Mineplex.ServerStatifier/.project @@ -0,0 +1,27 @@ + + + Mineplex.ServerStatifier + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.ui.externaltools.ExternalToolBuilder + auto,full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/ServerStatifier.launch + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/Plugins/Mineplex.ServerStatifier/Mineplex.ServerStatifier.iml b/Plugins/Mineplex.ServerStatifier/Mineplex.ServerStatifier.iml new file mode 100644 index 000000000..d7dc62371 --- /dev/null +++ b/Plugins/Mineplex.ServerStatifier/Mineplex.ServerStatifier.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Plugins/Mineplex.ServerStatifier/src/mineplex/serverstatifier/BungeeStatusData.java b/Plugins/Mineplex.ServerStatifier/src/mineplex/serverstatifier/BungeeStatusData.java new file mode 100644 index 000000000..825a3da78 --- /dev/null +++ b/Plugins/Mineplex.ServerStatifier/src/mineplex/serverstatifier/BungeeStatusData.java @@ -0,0 +1,9 @@ +package mineplex.serverstatifier; + +public class BungeeStatusData +{ + public int Players; + public int MaxPlayers; + public String Address; + public boolean US; +} diff --git a/Plugins/Mineplex.ServerStatifier/src/mineplex/serverstatifier/GroupStatusData.java b/Plugins/Mineplex.ServerStatifier/src/mineplex/serverstatifier/GroupStatusData.java new file mode 100644 index 000000000..d9f89ef1d --- /dev/null +++ b/Plugins/Mineplex.ServerStatifier/src/mineplex/serverstatifier/GroupStatusData.java @@ -0,0 +1,77 @@ +package mineplex.serverstatifier; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class GroupStatusData +{ + private int _serverNum = 0; + private int _totalCount = 0; + private int _joinableCount = 0; + + public String Name; + public int Players; + public int MaxPlayers; + public int MaxServerNumber; + + public List EmptyServers = new ArrayList(); + public HashMap Servers = new HashMap(); + + public void addServer(ServerStatusData serverStatusData) + { + Players += serverStatusData.Players; + MaxPlayers += serverStatusData.MaxPlayers; + + if (serverStatusData.Motd != null && (serverStatusData.Motd.contains("Starting") || serverStatusData.Motd.contains("Recruiting") || serverStatusData.Motd.contains("Waiting") || serverStatusData.Motd.contains("Cup") || serverStatusData.Motd.isEmpty() || serverStatusData.Motd.equals(""))) + { + if (serverStatusData.Players < serverStatusData.MaxPlayers) + { + // Lobby joinable checking + if (serverStatusData.Motd.isEmpty() || serverStatusData.Motd.equals("")) + { + if (serverStatusData.Players / serverStatusData.MaxPlayers < 10) + _joinableCount++; + } + else + { + _joinableCount++; + } + } + } + + _totalCount++; + + if (serverStatusData.Empty) + { + EmptyServers.add(serverStatusData); + } + + Servers.put(Integer.parseInt(serverStatusData.Name.split("-")[1]), serverStatusData); + } + + public int getTotalServers() + { + return _totalCount; + } + + public int getJoinableCount() + { + return _joinableCount; + } + + public int getNextServerNumber() + { + _serverNum++; + + while (true) + { + if (!Servers.containsKey(_serverNum)) + { + return _serverNum; + } + + _serverNum++; + } + } +} diff --git a/Plugins/Mineplex.ServerStatifier/src/mineplex/serverstatifier/ServerStatifier.java b/Plugins/Mineplex.ServerStatifier/src/mineplex/serverstatifier/ServerStatifier.java new file mode 100644 index 000000000..f3da60bf8 --- /dev/null +++ b/Plugins/Mineplex.ServerStatifier/src/mineplex/serverstatifier/ServerStatifier.java @@ -0,0 +1,35 @@ +package mineplex.serverstatifier; + +public class ServerStatifier +{ + private static StatusSnapshotRepository _statusSnapshotRepository = new StatusSnapshotRepository(); + private static StatusHistoryRepository _statusHistoryRepository = new StatusHistoryRepository(); + private static int count = 0; + + public static void main (String args[]) + { + _statusSnapshotRepository.initialize(); + _statusHistoryRepository.initialize(); + + while (true) + { + _statusHistoryRepository.saveServerStats(_statusSnapshotRepository.retrieveGroupStatusData()); + + _statusHistoryRepository.saveBungeeStats(_statusSnapshotRepository.retrieveBungeeStatuses()); + + try + { + Thread.sleep(60000); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + + count++; + + if (count % 5 == 0) + System.out.println("5 Minute status update....still awesome."); + } + } +} diff --git a/Plugins/Mineplex.ServerStatifier/src/mineplex/serverstatifier/ServerStatusData.java b/Plugins/Mineplex.ServerStatifier/src/mineplex/serverstatifier/ServerStatusData.java new file mode 100644 index 000000000..75a1b86f7 --- /dev/null +++ b/Plugins/Mineplex.ServerStatifier/src/mineplex/serverstatifier/ServerStatusData.java @@ -0,0 +1,14 @@ +package mineplex.serverstatifier; + +public class ServerStatusData +{ + public String Name; + public String Motd; + public int Players; + public int MaxPlayers; + public String Address; + public String PrivateAddress; + public int Port; + public boolean Empty = false; + public boolean US; +} diff --git a/Plugins/Mineplex.ServerStatifier/src/mineplex/serverstatifier/StatusHistoryRepository.java b/Plugins/Mineplex.ServerStatifier/src/mineplex/serverstatifier/StatusHistoryRepository.java new file mode 100644 index 000000000..5a512bbc0 --- /dev/null +++ b/Plugins/Mineplex.ServerStatifier/src/mineplex/serverstatifier/StatusHistoryRepository.java @@ -0,0 +1,176 @@ +package mineplex.serverstatifier; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map.Entry; + +public class StatusHistoryRepository +{ + private String _connectionString = "jdbc:mysql://sqlstats.mineplex.com:3306/ServerStats"; + private String _userName = "root"; + private String _password = "tAbechAk3wR7tuTh"; + + private static String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS ServerStats (id INT NOT NULL AUTO_INCREMENT, serverGroup VARCHAR(256), updated LONG, players INT, maxPlayers INT, US BOOLEAN NOT NULL DEFAULT '1', joinableServers INT, PRIMARY KEY (id));"; + private static String CREATE_BUNGEE_TABLE = "CREATE TABLE IF NOT EXISTS BungeeStats (id INT NOT NULL AUTO_INCREMENT, address VARCHAR(256), updated LONG, players INT, maxPlayers INT, US BOOLEAN NOT NULL DEFAULT '1', PRIMARY KEY (id));"; + + private static String INSERT_SERVER_STATS = "INSERT INTO ServerStats (serverGroup, updated, players, maxPlayers, US, joinableServers) VALUES (?, now(), ?, ?, ?, ?);"; + private static String INSERT_BUNGEE_STATS = "INSERT INTO BungeeStats (address, updated, players, maxPlayers, US) VALUES (?, now(), ?, ?, ?);"; + + public static Connection connection; + + public void initialize() + { + PreparedStatement preparedStatement = null; + + try + { + Class.forName("com.mysql.jdbc.Driver"); + + 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(); + } + } + } + + preparedStatement = null; + + try + { + if (connection == null || connection.isClosed()) + connection = DriverManager.getConnection(_connectionString, _userName, _password); + + // Create table + preparedStatement = connection.prepareStatement(CREATE_BUNGEE_TABLE); + preparedStatement.execute(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } + + public void saveServerStats(HashMap> globalGroupStatusData) + { + PreparedStatement preparedStatement = null; + + try + { + if (connection == null || connection.isClosed()) + connection = DriverManager.getConnection(_connectionString, _userName, _password); + + preparedStatement = connection.prepareStatement(INSERT_SERVER_STATS); + + for (Entry> serverGroupData : globalGroupStatusData.entrySet()) + { + for (Entry serverGroup : serverGroupData.getValue().entrySet()) + { + preparedStatement.setString(1, serverGroup.getKey()); + preparedStatement.setInt(2, serverGroup.getValue().Players); + preparedStatement.setInt(3, serverGroup.getValue().MaxPlayers); + preparedStatement.setBoolean(4, serverGroupData.getKey()); + preparedStatement.setInt(5, serverGroup.getValue().getJoinableCount()); + preparedStatement.addBatch(); + } } + + preparedStatement.executeBatch(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } + + public void saveBungeeStats(List retrieveBungeeStatuses) + { + PreparedStatement preparedStatement = null; + + try + { + if (connection == null || connection.isClosed()) + connection = DriverManager.getConnection(_connectionString, _userName, _password); + + preparedStatement = connection.prepareStatement(INSERT_BUNGEE_STATS); + + for (BungeeStatusData bungeeStatusData : retrieveBungeeStatuses) + { + preparedStatement.setString(1, bungeeStatusData.Address); + preparedStatement.setInt(2, bungeeStatusData.Players); + preparedStatement.setInt(3, bungeeStatusData.MaxPlayers); + preparedStatement.setBoolean(4, bungeeStatusData.US); + preparedStatement.addBatch(); + } + + preparedStatement.executeBatch(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } +} diff --git a/Plugins/Mineplex.ServerStatifier/src/mineplex/serverstatifier/StatusSnapshotRepository.java b/Plugins/Mineplex.ServerStatifier/src/mineplex/serverstatifier/StatusSnapshotRepository.java new file mode 100644 index 000000000..5c6d71d45 --- /dev/null +++ b/Plugins/Mineplex.ServerStatifier/src/mineplex/serverstatifier/StatusSnapshotRepository.java @@ -0,0 +1,232 @@ +package mineplex.serverstatifier; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class StatusSnapshotRepository +{ + private String _serverStatusConnectionString = "jdbc:mysql://db.mineplex.com:3306/ServerStatus"; + private String _userName = "root"; + private String _password = "tAbechAk3wR7tuTh"; + + private String _bungeeConnectionString = "jdbc:mysql://db.mineplex.com:3306/BungeeServers"; + + private static String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS ServerStatus (id INT NOT NULL AUTO_INCREMENT, serverName VARCHAR(256), serverGroup VARCHAR(256), address VARCHAR(256), port VARCHAR(11), updated LONG, lastTimeWithPlayers LONG, motd VARCHAR(256), players INT, maxPlayers INT, tps INT, ram INT, maxRam INT, PRIMARY KEY (id));"; + + private static String CREATE_DYNAMIC_TABLE = "CREATE TABLE IF NOT EXISTS DynamicServers (id INT NOT NULL AUTO_INCREMENT, serverName VARCHAR(256), address VARCHAR(256), privateAddress VARCHAR(256), US BOOLEAN NOT NULL DEFAULT 'true', PRIMARY KEY (id));"; + private static String RETRIEVE_SERVERGROUP_STATUSES = "SELECT ServerStatus.serverName, DynamicServers.US, serverGroup, motd, DynamicServers.address, ServerStatus.address, ServerStatus.port, players, maxPlayers, case when TIME_TO_SEC(TIMEDIFF(now(), ServerStatus.lastTimeWithPlayers)) > 300 then 1 else 0 end as empty, now(), updated FROM ServerStatus INNER JOIN DynamicServers ON ServerStatus.address = DynamicServers.privateAddress"; + + private static String RETRIEVE_BUNGEE_STATUSES = "SELECT address, US, players, maxPlayers FROM BungeeServers"; + + public static Connection serverStatusConnection; + public static Connection bungeeConnection; + + public void initialize() + { + PreparedStatement preparedStatement = null; + + try + { + Class.forName("com.mysql.jdbc.Driver"); + + if (serverStatusConnection == null || serverStatusConnection.isClosed()) + serverStatusConnection = DriverManager.getConnection(_serverStatusConnectionString, _userName, _password); + + // Create table + preparedStatement = serverStatusConnection.prepareStatement(CREATE_TABLE); + preparedStatement.execute(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + + preparedStatement = null; + + try + { + Class.forName("com.mysql.jdbc.Driver"); + + // Create table + preparedStatement = serverStatusConnection.prepareStatement(CREATE_DYNAMIC_TABLE); + preparedStatement.execute(); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + } + + public List retrieveBungeeStatuses() + { + ResultSet resultSet = null; + PreparedStatement preparedStatement = null; + List bungeeData = new ArrayList(); + + try + { + if (bungeeConnection == null || bungeeConnection.isClosed()) + bungeeConnection = DriverManager.getConnection(_bungeeConnectionString, _userName, _password); + + preparedStatement = bungeeConnection.prepareStatement(RETRIEVE_BUNGEE_STATUSES); + resultSet = preparedStatement.executeQuery(); + + while (resultSet.next()) + { + BungeeStatusData data = new BungeeStatusData(); + data.Address = resultSet.getString(1); + data.US = resultSet.getBoolean(2); + data.Players = resultSet.getInt(3); + data.MaxPlayers = resultSet.getInt(4); + + bungeeData.add(data); + } + } + 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 bungeeData; + } + + public HashMap> retrieveGroupStatusData() + { + ResultSet resultSet = null; + PreparedStatement preparedStatement = null; + HashMap> groupData = new HashMap>(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + groupData.put(true, new HashMap()); + groupData.put(false, new HashMap()); + + try + { + if (serverStatusConnection == null || serverStatusConnection.isClosed()) + serverStatusConnection = DriverManager.getConnection(_serverStatusConnectionString, _userName, _password); + + preparedStatement = serverStatusConnection.prepareStatement(RETRIEVE_SERVERGROUP_STATUSES); + resultSet = preparedStatement.executeQuery(); + + while (resultSet.next()) + { + ServerStatusData serverStatusData = new ServerStatusData(); + + serverStatusData.Name = resultSet.getString(1); + serverStatusData.US = resultSet.getBoolean(2); + String serverGroup = resultSet.getString(3); + serverStatusData.Motd = resultSet.getString(4); + serverStatusData.Address = resultSet.getString(5); + serverStatusData.PrivateAddress = resultSet.getString(6); + serverStatusData.Port = Integer.parseInt(resultSet.getString(7)); + serverStatusData.Players = resultSet.getInt(8); + serverStatusData.MaxPlayers = resultSet.getInt(9); + serverStatusData.Empty = resultSet.getBoolean(10); + + if (!groupData.get(serverStatusData.US).containsKey(serverGroup)) + { + groupData.get(serverStatusData.US).put(serverGroup, new GroupStatusData()); + } + + long current = dateFormat.parse(resultSet.getString(11)).getTime(); + long updated = dateFormat.parse(resultSet.getString(12)).getTime(); + + if (current - updated < 15000) + groupData.get(serverStatusData.US).get(serverGroup).addServer(serverStatusData); + } + } + 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 groupData; + } +} diff --git a/Plugins/Mineplex.ServerStatus/.settings/org.eclipse.core.resources.prefs b/Plugins/Mineplex.ServerStatus/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 99f26c020..000000000 --- a/Plugins/Mineplex.ServerStatus/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 diff --git a/Plugins/Mineplex.ServerStatus/src/mineplex/serverstatus/Repository.java b/Plugins/Mineplex.ServerStatus/src/mineplex/serverstatus/Repository.java deleted file mode 100644 index 9f180aa89..000000000 --- a/Plugins/Mineplex.ServerStatus/src/mineplex/serverstatus/Repository.java +++ /dev/null @@ -1,201 +0,0 @@ -package mineplex.serverstatus; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -public class Repository -{ - private String _connectionString = "jdbc:mysql://localhost:3306/ServerStatus"; - private String _userName = "root"; - private String _password = "y2D4atu3Pene2asw"; - - private static String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS DynamicServers (id INT NOT NULL AUTO_INCREMENT, serverName VARCHAR(256), address VARCHAR(256), US BOOLEAN NOT NULL DEFAULT 'true', updated LONG, PRIMARY KEY (id));"; - private static String RETRIEVE_ID = "SELECT id FROM DynamicServers WHERE serverName = ? AND address = ?;"; - private static String CREATE_SERVER = "INSERT INTO DynamicServers (serverName, address, US, availableRAM, availableCpu, updated) values(?, ?, ?, ?, ?, now());"; - private static String UPDATE_SERVER = "UPDATE DynamicServers SET updated = now();"; - - private int _id = -1; - - public void initialize(String serverName, String address, boolean us, int ram, int cpu) - { - Connection connection = null; - ResultSet resultSet = null; - PreparedStatement preparedStatement = null; - PreparedStatement preparedStatementRetrieve = null; - PreparedStatement preparedStatementInsert = null; - - try - { - Class.forName("com.mysql.jdbc.Driver"); - - 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, serverName); - preparedStatementRetrieve.setString(2, address); - resultSet = preparedStatementRetrieve.executeQuery(); - - while (resultSet.next()) - { - _id = resultSet.getInt("id"); - } - - // Insert if not there - if (_id == -1) - { - preparedStatementInsert = connection.prepareStatement(CREATE_SERVER, Statement.RETURN_GENERATED_KEYS); - - preparedStatementInsert.setString(1, serverName); - preparedStatementInsert.setString(2, address); - preparedStatementInsert.setBoolean(3, us); - preparedStatementInsert.setInt(4, ram); - preparedStatementInsert.setInt(5, cpu); - - int affectedRows = preparedStatementInsert.executeUpdate(); - - if (affectedRows == 0) - { - throw new SQLException("Creating dynamic server failed, no rows affected."); - } - - resultSet.close(); - - resultSet = preparedStatementInsert.getGeneratedKeys(); - - if (resultSet.next()) - { - _id = resultSet.getInt(1); - } - } - } - 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(); - } - } - - if (connection != null) - { - try - { - connection.close(); - } - catch (SQLException e) - { - e.printStackTrace(); - } - } - } - } - - public boolean updateServer() - { - Connection connection = null; - PreparedStatement preparedStatement = null; - - try - { - connection = DriverManager.getConnection(_connectionString, _userName, _password); - - preparedStatement = connection.prepareStatement(UPDATE_SERVER, Statement.RETURN_GENERATED_KEYS); - - int affectedRows = preparedStatement.executeUpdate(); - - if (affectedRows == 0) - { - throw new SQLException("Updating dynamic server failed, no rows affected."); - } - - return true; - } - catch (Exception exception) - { - exception.printStackTrace(); - return false; - } - finally - { - if (preparedStatement != null) - { - try - { - preparedStatement.close(); - } - catch (SQLException e) - { - e.printStackTrace(); - } - } - - if (connection != null) - { - try - { - connection.close(); - } - catch (SQLException e) - { - e.printStackTrace(); - } - } - } - } -} diff --git a/Plugins/Mineplex.ServerStatus/src/mineplex/serverstatus/ServerStatus.java b/Plugins/Mineplex.ServerStatus/src/mineplex/serverstatus/ServerStatus.java deleted file mode 100644 index 69187a421..000000000 --- a/Plugins/Mineplex.ServerStatus/src/mineplex/serverstatus/ServerStatus.java +++ /dev/null @@ -1,262 +0,0 @@ -package mineplex.serverstatus; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.UUID; - -public class ServerStatus -{ - private static Repository _repository = new Repository(); - private static int _count = 0; - - private static String _serverName = "bam"; - private static String _address = "asdf"; - private static boolean _us = true; - - public static void main (String args[]) - { - //loadConfiguration(); - //_repository.initialize(_serverName, _address, _us, 30000, 32); - - /* - while (true) - { - _repository.updateServer(); - - if (_count % 2 == 0) - { - for (ServerStatusData statusData : _repository.retrieveOldServerStatuses()) - { - System.out.println("----Old Server Status----> " + statusData.Address + ", " + statusData.Name); - killServer(statusData); - } - - List dynamicServers = new ArrayList(_repository.retrieveDynamicServers()); - Collection serverGroups = _repository.retrieveServerGroups(); - HashMap groupStatusList = _repository.retrieveGroupStatusData(); - - for (ServerGroupData serverGroup : serverGroups) - { - if (!groupStatusList.containsKey(serverGroup.Name)) - { - groupStatusList.put(serverGroup.Name, new GroupStatusData()); - } - - GroupStatusData groupStatus = groupStatusList.get(serverGroup.Name); - - - - int serversToAdd = Math.max(serverGroup.RequiredTotalServers - groupStatus.getTotalServers(), serverGroup.RequiredJoinableServers - groupStatus.getJoinableCount()); - int serversToKill = (groupStatus.getTotalServers() > serverGroup.RequiredTotalServers && groupStatus.getJoinableCount() > serverGroup.RequiredJoinableServers) ? Math.min(groupStatus.getJoinableCount() - serverGroup.RequiredJoinableServers, groupStatus.EmptyServers.size()) : 0; - - while (serversToAdd > 0) - { - int serverNum = groupStatus.getNextServerNumber(); - Collections.sort(dynamicServers, new DynamicServerSorter()); - DynamicServerData bestServer = getBestDynamicServer(dynamicServers, serverGroup); - - if (bestServer == null) - { - System.out.println("No best dynamic server available for group " + serverGroup.Name); - break; - } - - System.out.println("Adding server for Server Group " + serverGroup.Name + " Req Total: " + serverGroup.RequiredTotalServers + " Req Joinable: " + serverGroup.RequiredJoinableServers + " | Actual Total: " + groupStatus.getTotalServers() + " Actual Joinable: " + groupStatus.getJoinableCount()); - startServer(bestServer, serverGroup, serverNum); - - serversToAdd--; - } - - while (serversToKill > 0) - { - System.out.println("Killing excess server for Server Group " + serverGroup.Name + " Req Total: " + serverGroup.RequiredTotalServers + " Req Joinable: " + serverGroup.RequiredJoinableServers + " | Actual Total: " + groupStatus.getTotalServers() + " Actual Joinable: " + groupStatus.getJoinableCount()); - killServer(groupStatus.EmptyServers.get(0)); - serversToKill--; - } - } - } - - try - { - Thread.sleep(2000); - } - catch (InterruptedException e) - { - e.printStackTrace(); - } - } - */ - List folderNames = getFolderNames(); - - //removeExcessFolders(screenNames); - - System.exit(0); - } - - private static void removeExcessFolders(List screenNames) - { - Process process = null; - - for (String screen : screenNames) - { - try - { - process = new ProcessBuilder(new String[] { "rm", "-Rf", "/home/mineplex/servers/" + screen }).start(); - process.waitFor(); - } - catch (Exception e) - { - e.printStackTrace(); - } - finally - { - if (process != null) - { - process.destroy(); - } - } - } - - //return screens; - } - - private static void loadConfiguration() - { - FileInputStream fstream = null; - BufferedReader br = null; - - /* - try - { - File npcFile = new File("npcs.dat"); - - if (npcFile.exists()) - { - fstream = new FileInputStream(npcFile); - br = new BufferedReader(new InputStreamReader(fstream)); - - String line = br.readLine(); - - while (line != null) - { - UUID uuid = UUID.fromString(line.split(" ")[0]); - String location = line.split(" ")[1]; - Integer radius = Integer.parseInt(line.split(" ")[2]); - - _npcs.put(uuid.toString(), new NpcEntry(null, null, radius, UtilWorld.strToLoc(location))); - - line = br.readLine(); - } - } - } - catch (Exception e) - { - System.out.println("Error parsing configuration."); - } - finally - { - if (br != null) - { - try - { - br.close(); - } - catch (IOException e) - { - e.printStackTrace(); - } - } - - if (fstream != null) - { - try - { - fstream.close(); - } - catch (IOException e) - { - e.printStackTrace(); - } - } - } - */ - } - - private static List getFolderNames() - { - Process process = null; - List screens = new ArrayList(); - List folderNames = new ArrayList(); - - try - { - process = new ProcessBuilder(new String[] { "screen", "-list" }).start(); - process.waitFor(); - BufferedReader reader=new BufferedReader(new InputStreamReader(process.getInputStream())); - String line = reader.readLine(); - - while(line != null) - { - int stopIndex = line.contains("(Detached)") ? line.indexOf("(Detached)") : line.contains("(Detached)") ? line.indexOf("(Attached)") : -1; - - if (stopIndex != -1) - { - screens.add(line.substring(line.indexOf(".") + 1, stopIndex).trim()); - } - - line=reader.readLine(); - } - } - catch (Exception e) - { - e.printStackTrace(); - } - finally - { - if (process != null) - { - process.destroy(); - } - } - - try - { - process = new ProcessBuilder(new String[] { "ls", "/home/mineplex/servers" }).start(); - process.waitFor(); - BufferedReader reader=new BufferedReader(new InputStreamReader(process.getInputStream())); - String line = reader.readLine(); - - while(line != null) - { - for (String folderName : line.split(" ")) - { - if (!screens.contains(folderName.trim()) && !folderName.equalsIgnoreCase("Arenas")) - folderNames.add(folderName.trim()); - } - - line=reader.readLine(); - } - } - catch (Exception e) - { - e.printStackTrace(); - } - finally - { - if (process != null) - { - process.destroy(); - } - } - - return folderNames; - } -}