diff --git a/Plugins/Mineplex.Core/.classpath b/Plugins/Mineplex.Core/.classpath index f6f18e5b2..8171cd881 100644 --- a/Plugins/Mineplex.Core/.classpath +++ b/Plugins/Mineplex.Core/.classpath @@ -14,6 +14,5 @@ - diff --git a/Plugins/Mineplex.Core/src/mineplex/core/elo/EloManager.java b/Plugins/Mineplex.Core/src/mineplex/core/elo/EloManager.java index 74117863b..858e89198 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/elo/EloManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/elo/EloManager.java @@ -2,20 +2,13 @@ package mineplex.core.elo; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; import java.util.UUID; import mineplex.core.MiniDbClientPlugin; import mineplex.core.account.CoreClientManager; import mineplex.core.common.util.NautHashMap; -import mineplex.queuer.QueueParty; import org.bukkit.Bukkit; -import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; public class EloManager extends MiniDbClientPlugin @@ -23,66 +16,91 @@ public class EloManager extends MiniDbClientPlugin private static Object _playerEloLock = new Object(); private EloRepository _repository; - private RatingSystem _ratingSystem; - private Map _rankings; + private EloRatingSystem _ratingSystem; + private NautHashMap> _playerElos; public EloManager(JavaPlugin plugin, CoreClientManager clientManager) { super("Elo Rating", plugin, clientManager); _repository = new EloRepository(plugin); - _ratingSystem = new EloRatingSystem(); - _rankings = new HashMap(); - } - - public void resolveMatch(Team winner, Team loser, int gamemode) - { - Set winnerMembers = new HashSet(); - Set loserMembers = new HashSet(); - - for (String memberName : winner.getMemberNames()) - { - RankedPlayer player = getRankedPlayer(memberName); - winnerMembers.add(player); - } - - for (String memberName : loser.getMemberNames()) - { - RankedPlayer player = getRankedPlayer(memberName); - loserMembers.add(player); - } - - RankedTeam team1 = new RankedTeam(winnerMembers, gamemode); - RankedTeam team2 = new RankedTeam(loserMembers, gamemode); - RankedGame game = new RankedGame(team1, team2); - - // Allow the rating system to resolve and update player ratings from match - _ratingSystem.resolveGame(game); + _ratingSystem = new EloRatingSystem(new KFactor(0, 1200, 25), new KFactor(1201, 1600, 20), new KFactor(1601, 2000, 15), new KFactor(2001, 2500, 10)); + _playerElos = new NautHashMap>(); } - public EloRating getRating(String playerName, int gamemode) + public int getElo(UUID uuid, String gameType) { - return getRankedPlayer(playerName).getRating(gamemode); - } - - public RankedPlayer getRankedPlayer(String playerName) - { - return null; // TODO: Implement fetching for cached player ranking - } - - private void savePlayer(RankedPlayer player) - { - // TODO: Do this asynchronously! - for (EloRating rating : player.getRatings()) + int elo = 1000; + + synchronized (_playerEloLock) { - if (rating.isUpdated()) + if (_playerElos.containsKey(uuid.toString())) { - _repository.saveRating(rating); + if (_playerElos.get(uuid.toString()).containsKey(gameType)) + { + elo = _playerElos.get(uuid.toString()).get(gameType); + } } } + + return elo; + } + + public EloTeam getNewRatings(EloTeam teamA, EloTeam teamB, GameResult result) + { + EloTeam newTeam = new EloTeam(); + + System.out.println("Old " + result + " Team Rating:" + teamA.TotalElo); + + int newTotal = _ratingSystem.getNewRating(teamA.TotalElo / teamA.getPlayers().size(), teamB.TotalElo / teamB.getPlayers().size(), result) * teamA.getPlayers().size(); + + System.out.println("New " + result + " Team Rating:" + newTotal); + + for (EloPlayer player : teamA.getPlayers()) + { + EloPlayer newPlayer = new EloPlayer(); + newPlayer.UniqueId = player.UniqueId; + newPlayer.Rating = (int)(player.Rating + ((double)player.Rating / (double)teamA.TotalElo) * (newTotal - teamA.TotalElo)); + + System.out.println("Old:"); + player.printInfo(); + + System.out.println("New:"); + newPlayer.printInfo(); + + newTeam.addPlayer(newPlayer); + } + + return newTeam; + } + + public void saveElo(UUID uuid, String gameType, int elo) + { + saveElo(uuid.toString(), gameType, elo); + } + + public void saveElo(final String uuid, final String gameType, final int elo) + { + Bukkit.getServer().getScheduler().runTaskAsynchronously(getPlugin(), new Runnable() + { + public void run() + { + _repository.saveElo(uuid, gameType, elo); + + synchronized (_playerEloLock) + { + if (_playerElos.containsKey(uuid)) + { + if (_playerElos.get(uuid).containsKey(gameType)) + { + _playerElos.get(uuid).put(gameType, elo); + } + } + } + } + }); } - // TODO: DEPCRECATED? @Override protected EloClientData AddPlayer(String player) { @@ -92,15 +110,12 @@ public class EloManager extends MiniDbClientPlugin @Override public void processLoginResultSet(String playerName, ResultSet resultSet) throws SQLException { - Collection ratings = _repository.parseRatings(resultSet); - RankedPlayer rankedPlayer = new RankedPlayer(playerName, uuid, ratings); Set(playerName, _repository.loadClientInformation(resultSet)); } @Override public String getQuery(String uuid, String name) { - // Query elo ratings table for all the EloRatings associated with player logging in! - return "SELECT uuid, gamemode, elo, matchesPlayed FROM eloRating WHERE uuid = '" + uuid + "';"; + return "SELECT gameType, elo FROM eloRating WHERE uuid = '" + uuid + "';"; } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/elo/EloPlayer.java b/Plugins/Mineplex.Core/src/mineplex/core/elo/EloPlayer.java new file mode 100644 index 000000000..a2661fee3 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/elo/EloPlayer.java @@ -0,0 +1,12 @@ +package mineplex.core.elo; + +public class EloPlayer +{ + public String UniqueId; + public int Rating; + + public void printInfo() + { + System.out.println(UniqueId + "'s elo is " + Rating); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/elo/EloRating.java b/Plugins/Mineplex.Core/src/mineplex/core/elo/EloRating.java deleted file mode 100644 index de07f6621..000000000 --- a/Plugins/Mineplex.Core/src/mineplex/core/elo/EloRating.java +++ /dev/null @@ -1,63 +0,0 @@ -package mineplex.core.elo; - -public class EloRating -{ - public static final int PROVISIONAL_GAMES = 10; // Number of provisional games to ensure rating accuracy - public static final int DEFAULT_RATING = 1200; // Default starting ELO for first-time players. - - private int _rating; - public int getRating() { return _rating; } - - private int _gamemode; - public int getGamemode() { return _gamemode; } - - private String _uuid; - public String getUuid() { return _uuid; } - - private int _matchesPlayed; - public int getMatchesPlayed() { return _matchesPlayed; } - public void incrementMatchesPlayed() { _matchesPlayed++; } - - private boolean _updated; // Whether this EloRating has been updated/modified since caching - public boolean isUpdated() { return _updated; } - private void onUpdate() { _updated = true; } - - public EloRating(String uuid, int gamemode, int rating, int matchesPlayed) - { - _updated = false; - _uuid = uuid; - _gamemode = gamemode; - _rating = rating; - _matchesPlayed = matchesPlayed;; - } - - public EloRating(String uuid, int gamemode) - { - this(uuid, gamemode, DEFAULT_RATING, 0); - } - - public void updateRating(int eloDelta) - { - setRating(_rating + eloDelta); - } - - public double getKFactor() - { - if (_matchesPlayed < PROVISIONAL_GAMES) - { - double provisionalPercent = _matchesPlayed / (double) PROVISIONAL_GAMES; - return 50d - (25 * provisionalPercent); // Range of [50, 25] Kfactor for provisionl games period - } - else - { - double ratio = ((double) PROVISIONAL_GAMES) / _matchesPlayed; - return 10d + 15 * (ratio); // Range of [10, 25] KFactor for games after provisionals - } - } - - private void setRating(int rating) - { - _rating = Math.max(rating, 0); - onUpdate(); - } -} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/elo/EloRatingSystem.java b/Plugins/Mineplex.Core/src/mineplex/core/elo/EloRatingSystem.java index a27d308ba..d32433ed6 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/elo/EloRatingSystem.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/elo/EloRatingSystem.java @@ -1,8 +1,6 @@ package mineplex.core.elo; -import java.util.List; - -public class EloRatingSystem implements RatingSystem +public class EloRatingSystem { private final static int DEFAULT_KFACTOR = 25; @@ -10,37 +8,26 @@ public class EloRatingSystem implements RatingSystem public final static double DRAW = 0.5; public final static double LOSS = 0.0; - public EloRatingSystem() + private KFactor[] _kFactors = {}; + + public EloRatingSystem(KFactor...kFactors) { - + _kFactors = kFactors; } - @Override - public void resolveGame(RankedGame game) + public int getNewRating(int rating, int opponentRating, GameResult result) { - List teams = game.getSortedTeams(); - RankedTeam winner = teams.get(0); - RankedTeam loser = teams.get(1); // TODO: Impelement non-arbitrary rating? - double winningExpected = getExpectedScore(winner.getElo(), loser.getElo()); - double losingExpected = getExpectedScore(loser.getElo(), winner.getElo()); - - // Update the ratings of all participants - updateRatings(winner, winningExpected, 1.0d); - updateRatings(loser, losingExpected, 0.0d); - } - - private void updateRatings(RankedTeam team, double expectedScore, double score) - { - double scoreDelta = score - expectedScore; - for (EloRating rating : team.getRatings()) + switch (result) { - // R' = R + K(S - E) - int eloDelta = (int) (rating.getKFactor() * scoreDelta); - rating.updateRating(eloDelta); - rating.incrementMatchesPlayed(); - - System.out.println("Player with " + rating.getMatchesPlayed() + " games had ELO updated by " + eloDelta + " for new rating of " + rating.getRating()); + case Win: + return getNewRating(rating, opponentRating, WIN); + case Loss: + return getNewRating(rating, opponentRating, LOSS); + case Draw: + return getNewRating(rating, opponentRating, DRAW); } + + return -1; } /** @@ -58,7 +45,7 @@ public class EloRatingSystem implements RatingSystem */ public int getNewRating(int rating, int opponentRating, double score) { - double kFactor = 0;//getKFactor(rating); + double kFactor = getKFactor(rating); double expectedScore = getExpectedScore(rating, opponentRating); int newRating = calculateNewRating(rating, score, expectedScore, kFactor); @@ -70,7 +57,20 @@ public class EloRatingSystem implements RatingSystem return oldRating + (int) (kFactor * (score - expectedScore)); } - public static double getExpectedScore(int rating, int opponentRating) + private double getKFactor(int rating) + { + for (int i = 0; i < _kFactors.length; i++) + { + if (rating >= _kFactors[i].getStartIndex() && rating <= _kFactors[i].getEndIndex()) + { + return _kFactors[i].value; + } + } + + return DEFAULT_KFACTOR; + } + + private double getExpectedScore(int rating, int opponentRating) { return 1.0 / (1.0 + Math.pow(10.0, ((double) (opponentRating - rating) / 400.0))); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/elo/EloRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/elo/EloRepository.java index bdbee8acb..54503474f 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/elo/EloRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/elo/EloRepository.java @@ -2,8 +2,6 @@ package mineplex.core.elo; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.HashSet; -import java.util.Set; import org.bukkit.plugin.java.JavaPlugin; @@ -14,59 +12,40 @@ import mineplex.core.database.column.ColumnVarChar; public class EloRepository extends RepositoryBase { - private static String INSERT_ELO = "INSERT INTO eloRating (uuid, gamemode, elo, matchesPlayed) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE elo=VALUES(elo);"; + private static String CREATE_ELO_TABLE = "CREATE TABLE IF NOT EXISTS eloRating (id INT NOT NULL AUTO_INCREMENT, uuid VARCHAR(256), gameType VARCHAR(256), elo INT, PRIMARY KEY (id), UNIQUE INDEX uuid_gameType_index (uuid, gameType));"; + private static String INSERT_ELO = "INSERT INTO eloRating (uuid, gameType, elo) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE elo=VALUES(elo);"; - /** - * Constructor - * @param plugin - */ public EloRepository(JavaPlugin plugin) { super(plugin, DBPool.ACCOUNT); + + initialize(); } - - /** - * Save & update an {@link EloRating} into repository. - * @param rating - the rating to be saved/updated in the repository. - */ - public void saveRating(EloRating rating) + + public void initialize() { - String uuid = rating.getUuid(); - int gamemode = rating.getGamemode(); - int elo = rating.getRating(); - int matchesPlayed = rating.getMatchesPlayed(); - - // Execute update/insert - executeUpdate(INSERT_ELO, new ColumnVarChar("uuid", 100, uuid), new ColumnInt("gamemode", gamemode), - new ColumnInt("elo", elo), new ColumnInt("matchesPlayed", matchesPlayed)); + //executeUpdate(CREATE_ELO_TABLE); } - - /** - * Parse incoming SQL result from EloRatings table into usable {@link EloRating} objects. - * @param resultSet - the resulting set from SQL query for ELO ratings. - * @return parsed {@link EloRating} objects return from {@code resultSet}. - */ - public Set parseRatings(ResultSet resultSet) throws SQLException + + public void saveElo(String uuid, String gameType, int elo) { - Set ratings = new HashSet(); - + executeUpdate(INSERT_ELO, new ColumnVarChar("uuid", 100, uuid), new ColumnVarChar("gameType", 100, gameType), new ColumnInt("elo", elo)); + } + + public EloClientData loadClientInformation(ResultSet resultSet) throws SQLException + { + EloClientData clientData = new EloClientData(); + while (resultSet.next()) { - String uuid = resultSet.getString(1); - int gamemode = resultSet.getInt(2); - int elo = resultSet.getInt(3); - int matchesPlayed = resultSet.getInt(4); - - EloRating rating = new EloRating(uuid, gamemode, elo, matchesPlayed); - ratings.add(rating); + clientData.Elos.put(resultSet.getString(1), resultSet.getInt(2)); } - - return ratings; + + return clientData; } @Override - protected void update() { } - - @Override - protected void initialize() { } + protected void update() + { + } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/elo/EloTeam.java b/Plugins/Mineplex.Core/src/mineplex/core/elo/EloTeam.java new file mode 100644 index 000000000..73f54168a --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/elo/EloTeam.java @@ -0,0 +1,23 @@ +package mineplex.core.elo; + +import java.util.ArrayList; +import java.util.List; + +public class EloTeam +{ + private List _players = new ArrayList(); + + public int TotalElo = 0; + + public void addPlayer(EloPlayer player) + { + TotalElo += player.Rating; + + _players.add(player); + } + + public List getPlayers() + { + return _players; + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/elo/GameResult.java b/Plugins/Mineplex.Core/src/mineplex/core/elo/GameResult.java new file mode 100644 index 000000000..5c00d8d5f --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/elo/GameResult.java @@ -0,0 +1,8 @@ +package mineplex.core.elo; + +public enum GameResult +{ + Win, + Loss, + Draw +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/elo/KFactor.java b/Plugins/Mineplex.Core/src/mineplex/core/elo/KFactor.java new file mode 100644 index 000000000..81d9be811 --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/elo/KFactor.java @@ -0,0 +1,34 @@ +package mineplex.core.elo; + +public class KFactor +{ + public int startIndex, endIndex; + public double value; + + public KFactor(int startIndex, int endIndex, double value) + { + this.startIndex = startIndex; + this.endIndex = endIndex; + this.value = value; + } + + public int getStartIndex() + { + return startIndex; + } + + public int getEndIndex() + { + return endIndex; + } + + public double getValue() + { + return value; + } + + public String toString() + { + return "kfactor: " + startIndex + " " + endIndex + " " + value; + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/elo/RankedGame.java b/Plugins/Mineplex.Core/src/mineplex/core/elo/RankedGame.java deleted file mode 100644 index 6651404f9..000000000 --- a/Plugins/Mineplex.Core/src/mineplex/core/elo/RankedGame.java +++ /dev/null @@ -1,43 +0,0 @@ -package mineplex.core.elo; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Random; -import java.util.Set; - -public class RankedGame -{ - - private Set _teams; - - public RankedGame(RankedTeam team1, RankedTeam team2) - { - // TODO: Implement non-arbitrary ranking of multi-team game comps - _teams = new HashSet(); - _teams.add(team1); // Winner team - _teams.add(team2); // Loser team - } - - public List getSortedTeams() - { - List sortedTeams = new ArrayList(_teams); - - Random rand = new Random(); - double roll = rand.nextDouble(); - - int rating1 = sortedTeams.get(0).getElo(); - int rating2 = sortedTeams.get(1).getElo(); - - double chanceOfWinning = EloRatingSystem.getExpectedScore(rating1, rating2); - - if (roll > chanceOfWinning) - { - RankedTeam team1 = sortedTeams.remove(0); - sortedTeams.add(team1); - } - - return sortedTeams; - } - -} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/elo/RankedPlayer.java b/Plugins/Mineplex.Core/src/mineplex/core/elo/RankedPlayer.java deleted file mode 100644 index 03e1bf719..000000000 --- a/Plugins/Mineplex.Core/src/mineplex/core/elo/RankedPlayer.java +++ /dev/null @@ -1,47 +0,0 @@ -package mineplex.core.elo; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -public class RankedPlayer -{ - private String _name; - public String getName() { return _name; } - - private String _uuid; - private Map _ratings; - - public RankedPlayer(String playerName, String uuid, Collection ratings) - { - _name = playerName; - _uuid = uuid; - - // Initialize ratings - _ratings = new HashMap(); - for (EloRating rating : ratings) - { - _ratings.put(rating.getGamemode(), rating); - } - } - - public EloRating getRating(int gamemode) - { - if (!_ratings.containsKey(gamemode)) - { - _ratings.put(gamemode, generateRating(gamemode)); - } - - return _ratings.get(gamemode); - } - - public Collection getRatings() - { - return _ratings.values(); - } - - private EloRating generateRating(int gamemode) - { - return new EloRating(_uuid, gamemode); - } -} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/elo/RankedTeam.java b/Plugins/Mineplex.Core/src/mineplex/core/elo/RankedTeam.java deleted file mode 100644 index 1f37af442..000000000 --- a/Plugins/Mineplex.Core/src/mineplex/core/elo/RankedTeam.java +++ /dev/null @@ -1,58 +0,0 @@ -package mineplex.core.elo; - -import java.util.HashSet; -import java.util.Set; - -import mineplex.queuer.Ranked; - - -public class RankedTeam implements Ranked, Team -{ - - private Set _players; - private int _gamemode; - - public RankedTeam(Set players, int gamemode) - { - _players = players; - _gamemode = gamemode; - } - - @Override - public int getElo() - { - int totalElo = 0; - - for (EloRating rating : getRatings()) - { - totalElo += rating.getRating(); - } - - return totalElo / _players.size(); /// Return average elo - } - - @Override - public Set getMemberNames() - { - Set memberNames = new HashSet(); - - for (RankedPlayer player : _players) - { - memberNames.add(player.getName()); - } - - return memberNames; - } - - public Set getRatings() - { - Set ratings = new HashSet(); - - for (RankedPlayer player : _players) - { - ratings.add(player.getRating(_gamemode)); - } - - return ratings; - } -} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/elo/RatingSystem.java b/Plugins/Mineplex.Core/src/mineplex/core/elo/RatingSystem.java deleted file mode 100644 index f4f8d0808..000000000 --- a/Plugins/Mineplex.Core/src/mineplex/core/elo/RatingSystem.java +++ /dev/null @@ -1,12 +0,0 @@ -package mineplex.core.elo; - -public interface RatingSystem -{ - - /** - * Resolve a {@link RankedGame} by updating the rankings of all participants dependant on - * the outcome of the game. - * @param game - the game to be resolved after completion (must be a completed RankedGame) - */ - public void resolveGame(RankedGame game); -} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/elo/Team.java b/Plugins/Mineplex.Core/src/mineplex/core/elo/Team.java deleted file mode 100644 index 8e03b7171..000000000 --- a/Plugins/Mineplex.Core/src/mineplex/core/elo/Team.java +++ /dev/null @@ -1,9 +0,0 @@ -package mineplex.core.elo; - -import java.util.Set; - -public interface Team -{ - - public Set getMemberNames(); -} diff --git a/Plugins/Mineplex.Queue.Core/.classpath b/Plugins/Mineplex.Queue.Core/.classpath deleted file mode 100644 index 793451685..000000000 --- a/Plugins/Mineplex.Queue.Core/.classpath +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/Plugins/Mineplex.Queue.Core/.externalToolBuilders/Queue.Core.launch b/Plugins/Mineplex.Queue.Core/.externalToolBuilders/Queue.Core.launch deleted file mode 100644 index 2981815ed..000000000 --- a/Plugins/Mineplex.Queue.Core/.externalToolBuilders/Queue.Core.launch +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/Plugins/Mineplex.Queue.Core/.project b/Plugins/Mineplex.Queue.Core/.project deleted file mode 100644 index 669fb734b..000000000 --- a/Plugins/Mineplex.Queue.Core/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - Mineplex.Queue.Core - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/Plugins/Mineplex.Queue.Core/Mineplex.Queue.Core.iml b/Plugins/Mineplex.Queue.Core/Mineplex.Queue.Core.iml deleted file mode 100644 index d65267f31..000000000 --- a/Plugins/Mineplex.Queue.Core/Mineplex.Queue.Core.iml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/Plugins/Mineplex.Queue.Core/build.xml b/Plugins/Mineplex.Queue.Core/build.xml deleted file mode 100644 index bfa129910..000000000 --- a/Plugins/Mineplex.Queue.Core/build.xml +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Plugins/Mineplex.Queue.Core/src/mineplex/queuer/QueueParty.java b/Plugins/Mineplex.Queue.Core/src/mineplex/queuer/QueueParty.java deleted file mode 100644 index 0e76c9ad5..000000000 --- a/Plugins/Mineplex.Queue.Core/src/mineplex/queuer/QueueParty.java +++ /dev/null @@ -1,115 +0,0 @@ -package mineplex.queuer; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import mineplex.serverdata.Region; -import mineplex.serverdata.data.Data; -import mineplex.serverdata.data.ServerGroup; - -public class QueueParty implements Data, Ranked -{ - - private int _id; - public int getId() { return _id; } - - private String _state; - public String getState() { return _state; } - public void setState(String state) { this._state = state; } - - private Set _players; - public Set getPlayers() { return _players; } - - private int _assignedMatch; - public int getAssignedMatch () { return _assignedMatch; } - public void setAssignedMatch(int assignedMatch) { this._assignedMatch = assignedMatch; } - - private ServerGroup _serverGroup; - public ServerGroup getServerGroup() { return _serverGroup; } - - private int _averageElo; - public int getAverageElo() { return _averageElo; } - public int getElo() { return getAverageElo(); } - - public int getPlayerCount() { return _players.size(); } - - private long _queueStartTime; - public long getQueueDuration() { return System.currentTimeMillis() - _queueStartTime; } - - private boolean _prompted; - public boolean isPrompted() { return _prompted; } - public void setPrompted(boolean prompted) { this._prompted = prompted; } - - private Region _region; - - private Set _otherPartyStates; - public Set getOtherPartyStates() { return _otherPartyStates; } - public void setOtherPartyStates(Set otherPartyStates) { this._otherPartyStates = otherPartyStates; } - - private QueueParty(int id) - { - _id = id; - unassignMatch(); - _prompted = false; - _region = Region.US; - _players = new HashSet(); - _otherPartyStates = new HashSet(); - _queueStartTime = System.currentTimeMillis(); - } - - public QueueParty(int id, Collection players, ServerGroup serverGroup, int averageElo) - { - this(id); - _players.addAll(players); - _serverGroup = serverGroup; - _averageElo = averageElo; - } - - public boolean hasAssignedMatch() - { - return _assignedMatch != -1; - } - - /** - * @return true, if the {@link QueueParty}s status is set to 'Ready', false otherwise. - */ - public boolean isReady() - { - return getState().equalsIgnoreCase("Ready"); - } - - /** - * Assign a {@link Match} to this queue party. - * @param match - the match to be assigned for this party - */ - public void assignMatch(Match match) - { - setState("Awaiting Players"); - setAssignedMatch(match.getId()); - } - - /** - * Unassign any matches from this QueueParty. - */ - public void unassignMatch() - { - setState("Awaiting Match"); - setAssignedMatch(-1); - } - - /** - * Initiate the sending of gameplay invite to the party when the assigned match - * is ready to start. - */ - public void sendInvites() - { - setState("Awaiting Confirmation"); - } - - @Override - public String getDataId() - { - return Integer.toString(_id); - } -} diff --git a/Plugins/Mineplex.Queue.Core/src/mineplex/queuer/Ranked.java b/Plugins/Mineplex.Queue.Core/src/mineplex/queuer/Ranked.java deleted file mode 100644 index f1fbe0ada..000000000 --- a/Plugins/Mineplex.Queue.Core/src/mineplex/queuer/Ranked.java +++ /dev/null @@ -1,15 +0,0 @@ -package mineplex.queuer; - -/** - * Ranked represents any object that can be classified as possessing an ELO ranking. - * @author MrTwiggy - * - */ -public interface Ranked -{ - - /** - * @return the ELO point ranking associated with this {@link Ranked} object. - */ - public int getElo(); -} diff --git a/Plugins/Mineplex.Queuer/.classpath b/Plugins/Mineplex.Queuer/.classpath index dc40c82a0..945e9a997 100644 --- a/Plugins/Mineplex.Queuer/.classpath +++ b/Plugins/Mineplex.Queuer/.classpath @@ -8,7 +8,5 @@ - - diff --git a/Plugins/Mineplex.Queue.Core/src/mineplex/queuer/Match.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/Match.java similarity index 52% rename from Plugins/Mineplex.Queue.Core/src/mineplex/queuer/Match.java rename to Plugins/Mineplex.Queuer/src/mineplex/queuer/Match.java index 93bbb70ea..747c8e5a4 100644 --- a/Plugins/Mineplex.Queue.Core/src/mineplex/queuer/Match.java +++ b/Plugins/Mineplex.Queuer/src/mineplex/queuer/Match.java @@ -1,11 +1,11 @@ package mineplex.queuer; +import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.Set; -import mineplex.serverdata.data.ServerGroup; - -public class Match implements Ranked +public class Match { private int _id; public int getId() { return _id; } @@ -16,23 +16,16 @@ public class Match implements Ranked private boolean _waitingForInvites; public boolean isWaitingForInvites() { return _waitingForInvites; } - private boolean _ready; - public boolean isReady() { return _ready; } - public void setReady(boolean ready) { _ready = ready; } - private long _waitingStartTime; public long getWaitDuration() { return System.currentTimeMillis() - _waitingStartTime; } - private ServerGroup _serverGroup; // The server group associated with this Match type. - public ServerGroup getServerGroup() { return _serverGroup; } + private int _averageElo; + public int getAverageElo() { return _averageElo; } - public Match(int id, ServerGroup serverGroup, QueueParty... parties) + public Match(int id, int averageElo, QueueParty... parties) { - _ready = false; - _id = id; - _parties = new HashSet(); - _waitingForInvites = false; - _serverGroup = serverGroup; + this._id = id; + this._averageElo = averageElo; for (QueueParty party : parties) { @@ -58,32 +51,6 @@ public class Match implements Ranked _parties.remove(queueParty); } - /** - * @return average ELO of all members of the match, if the match contains players, 0 otherwise. - */ - @Override - public int getElo() - { - if (_parties.size() == 0) return 0; - - int totalElo = 0; - for (QueueParty party : _parties) - { - totalElo += (party.getAverageElo() * party.getPlayerCount()); - } - - return totalElo / getPlayerCount(); - } - - /** - * @return the number of open slots remaining in the match to be filled. - */ - public int getOpenSlots() - { - int openSlots = _serverGroup.getMaxPlayers() - getPlayerCount(); - return Math.max(openSlots, 0); - } - public int getPlayerCount() { int playerCount = 0; diff --git a/Plugins/Mineplex.Queuer/src/mineplex/queuer/QueueParty.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/QueueParty.java new file mode 100644 index 000000000..19dd01fdb --- /dev/null +++ b/Plugins/Mineplex.Queuer/src/mineplex/queuer/QueueParty.java @@ -0,0 +1,78 @@ +package mineplex.queuer; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import mineplex.serverdata.Region; +import mineplex.serverdata.data.Data; + +public class QueueParty implements Data +{ + + private int _id; + public int getId() { return _id; } + + private String _state; + public String getState() { return _state; } + public void setState(String state) { this._state = state; } + + private Set _players; + public Set getPlayers() { return _players; } + + private int _assignedMatch; + public int getAssignedMatch () { return _assignedMatch; } + public void setAssignedMatch(int assignedMatch) { this._assignedMatch = assignedMatch; } + + private int _variance; + private String _gameType; + + private int _averageElo; + public int getAverageElo() { return _averageElo; } + + private int _playerCount; + public int getPlayerCount() { return _playerCount; } + + private long _queueStartTime; + + private boolean _prompted; + public boolean isPrompted() { return _prompted; } + public void setPrompted(boolean prompted) { this._prompted = prompted; } + + private Region _region; + + private Set _otherPartyStates; + public Set getOtherPartyStates() { return _otherPartyStates; } + public void setOtherPartyStates(Set otherPartyStates) { this._otherPartyStates = otherPartyStates; } + + public QueueParty() + { + this._id = -1; + this._state = "Awaiting Match"; + this._assignedMatch = -1; + this._variance = 25; + this._prompted = false; + this._region = Region.US; + this._players = new HashSet(); + this._otherPartyStates = new HashSet(); + this._queueStartTime = System.currentTimeMillis(); + } + + public QueueParty(Collection players, String gameType, int averageElo) + { + this._players.addAll(players); + this._gameType = gameType; + this._averageElo = averageElo; + } + + public boolean hasAssignedMatch() + { + return _assignedMatch != -1; + } + + @Override + public String getDataId() + { + return Integer.toString(_id); + } +} diff --git a/Plugins/Mineplex.Queue.Core/src/mineplex/queuer/QueuePartySorter.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/QueuePartySorter.java similarity index 100% rename from Plugins/Mineplex.Queue.Core/src/mineplex/queuer/QueuePartySorter.java rename to Plugins/Mineplex.Queuer/src/mineplex/queuer/QueuePartySorter.java diff --git a/Plugins/Mineplex.Queue.Core/src/mineplex/queuer/QueueRepository.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/QueueRepository.java similarity index 61% rename from Plugins/Mineplex.Queue.Core/src/mineplex/queuer/QueueRepository.java rename to Plugins/Mineplex.Queuer/src/mineplex/queuer/QueueRepository.java index b3ce4004c..eeef5c327 100644 --- a/Plugins/Mineplex.Queue.Core/src/mineplex/queuer/QueueRepository.java +++ b/Plugins/Mineplex.Queuer/src/mineplex/queuer/QueueRepository.java @@ -14,42 +14,27 @@ import mineplex.serverdata.Utility; import mineplex.serverdata.commands.ServerTransfer; import mineplex.serverdata.commands.TransferCommand; import mineplex.serverdata.data.DataRepository; -import mineplex.serverdata.data.DedicatedServer; import mineplex.serverdata.data.MinecraftServer; -import mineplex.serverdata.data.ServerGroup; import mineplex.serverdata.redis.RedisDataRepository; import mineplex.serverdata.servers.ConnectionData; import mineplex.serverdata.servers.ServerManager; import mineplex.serverdata.servers.ServerRepository; -import mineplex.serverprocesses.GenericRunnable; -import mineplex.serverprocesses.ProcessManager; -import mineplex.serverprocesses.ProcessRunner; public class QueueRepository { - private ServerRepository _serverRepository; private DataRepository _partyRepository; - private long _cacheTimeout; - private long _lastUpdated; - private Map _cachedParties; - private int _serverId; - /** * Class constructor * @param host - the host to connect the QueueRepository to * @param port - the designated port of the QueueRepository database * @param region - the region of server queues to manage */ - public QueueRepository(ConnectionData connectionData, Region region, long cacheTimeout) + public QueueRepository(ConnectionData connectionData, Region region) { - _serverRepository = ServerManager.getServerRepository(region); - _partyRepository = new RedisDataRepository(connectionData, region, + this._partyRepository = new RedisDataRepository(connectionData, region, QueueParty.class, "queue-parties"); - _cacheTimeout = cacheTimeout; - _lastUpdated = 0; - _serverId = 0; } /** @@ -60,23 +45,24 @@ public class QueueRepository */ public QueueRepository(Region region) { - this(ServerManager.getMasterConnection(), region, 1000); + this(ServerManager.getMasterConnection(), region); } public QueueParty getQueueParty(int partyId) { - updatePartyCache(); - return _cachedParties.get(partyId); + return _partyRepository.getElement(Integer.toString(partyId)); + } + + public QueueParty createQueueParty(Collection players, String gameType, int averageElo) + { + QueueParty queueParty = new QueueParty(players, gameType, averageElo); + updateQueueParty(queueParty); + return queueParty; } - /** - * Update/save a Queue Party object to the repository. - * @param queueParty - the queue party to be updated/saved in repo. - */ public void updateQueueParty(QueueParty queueParty) { _partyRepository.addElement(queueParty); - _cachedParties.put(queueParty.getId(), queueParty); } public void deleteQueueParty(int partyId) @@ -97,20 +83,9 @@ public class QueueRepository } } - public boolean queuePartyExists(int partyId) - { - return getQueueParty(partyId) != null; - } - - /** - * - * @return a cached set of active {@link QueueParty}'s that are guaranteed - * to have been cached less than {@code cacheTimeout} milliseconds. - */ public Collection getQueueParties() { - updatePartyCache(); - return _cachedParties.values(); + return _partyRepository.getElements(); } public Collection getJoinedQueueParties(int matchId) @@ -142,16 +117,46 @@ public class QueueRepository public void assignMatch(QueueParty queueParty, Match match) { - queueParty.assignMatch(match); + queueParty.setAssignedMatch(match.getId()); + queueParty.setState("Awaiting Confirmation"); updateQueueParty(queueParty); } - public void sendInvite(QueueParty queueParty) + public void startMatch(int matchId) { - queueParty.sendInvites(); - updateQueueParty(queueParty); - } + MinecraftServer emptyServer = getEmptyServer(); + if (emptyServer != null) + { + for (QueueParty queueParty : getJoinedQueueParties(matchId)) + { + for (String playerName : queueParty.getPlayers()) + { + // Execute a transfer command + ServerTransfer serverTransfer = new ServerTransfer(playerName, emptyServer.getName()); + TransferCommand transferCommand = new TransferCommand(serverTransfer); + transferCommand.publish(); + } + } + } + } + + protected MinecraftServer getEmptyServer() + { + ServerRepository serverRepository = ServerManager.getServerRepository(Region.US); + Collection servers = serverRepository.getServersByGroup("DominateElo"); + + for (MinecraftServer server : servers) + { + if (server.getPlayerCount() == 0) + { + return server; + } + } + + return null; + } + public void deleteMatch(int matchId) { for (QueueParty queueParty : getJoinedQueueParties(matchId)) @@ -161,27 +166,4 @@ public class QueueRepository updateQueueParty(queueParty); } } - - /** - * Update the internal cache of {@link QueueParty}s if the cache age is - * older than {@code _cacheTimeout}. - */ - private void updatePartyCache() - { - long cacheAge = (System.currentTimeMillis() - _lastUpdated); - if (cacheAge >= _cacheTimeout) // Old cache, update contents - { - _cachedParties = new HashMap(); - - for (QueueParty queueParty : _partyRepository.getElements()) - { - _cachedParties.put(queueParty.getId(), queueParty); - } - } - } - - private static void log(String message) - { - System.out.println(message); - } } \ No newline at end of file diff --git a/Plugins/Mineplex.Queuer/src/mineplex/queuer/Queuer.java b/Plugins/Mineplex.Queuer/src/mineplex/queuer/Queuer.java index a008c7054..331d025a2 100644 --- a/Plugins/Mineplex.Queuer/src/mineplex/queuer/Queuer.java +++ b/Plugins/Mineplex.Queuer/src/mineplex/queuer/Queuer.java @@ -9,55 +9,208 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Random; import java.util.Set; -import java.util.UUID; import mineplex.serverdata.Region; -import mineplex.serverdata.commands.ServerTransfer; -import mineplex.serverdata.commands.TransferCommand; -import mineplex.serverdata.data.DedicatedServer; -import mineplex.serverdata.data.ServerGroup; -import mineplex.serverdata.servers.ConnectionData; -import mineplex.serverdata.servers.ServerManager; -import mineplex.serverdata.servers.ServerRepository; -import mineplex.serverprocesses.GenericRunnable; -import mineplex.serverprocesses.ProcessManager; -import mineplex.serverprocesses.ProcessRunner; public class Queuer { - public static final int MIN_QUEUE_WAIT = 0; // The number of seconds required in queue before creating a new match for a party. - private static QueueRepository _repo; - private static ServerRepository _serverRepository; - private static Set _pendingMatches; // Set of all matches awaiting players - private static int _matchId = 0; - private static int _matchesMade = 0; - private static int _updates = 0; - private static int _partyId = 0; - private static int _serverId = 0; public static void main (String args[]) { Region region = (!new File("eu.dat").exists()) ? Region.US : Region.EU; - _serverRepository = ServerManager.getServerRepository(region); + _repo = new QueueRepository(region); - _pendingMatches = new HashSet(); + + HashMap playerVarianceMap = new HashMap(); + HashMap playerPrepMatchMap = new HashMap(); + Set matches = new HashSet(); + + QueuePartySorter partySorter = new QueuePartySorter(); + + int matchId = 1; while (true) - { - _updates++; - updateQueuer(); - ProcessManager.getInstance().updateProcesses(); + { + int matchesMade = 0; + matchId %= 1500; - log("Total pending matches after update: " + _pendingMatches.size()); - log("Total queued parties after update: " + _repo.getQueueParties().size()); + List assignedMatchIdChecked = new ArrayList(); + Map queueParties = _repo.getMappedQueueParties(); + + int matchPlayerCount = 2; + + System.out.println("Checking " + queueParties.size() + " queues..."); + for (QueueParty queueParty : queueParties.values()) + { + int partyId = queueParty.getId(); + int variance = playerVarianceMap.containsKey(partyId) ? playerVarianceMap.get(partyId) : 0; + variance += 25; + playerVarianceMap.put(partyId, variance); + + if (queueParty.hasAssignedMatch()) + { + for (Match match : matches) + { + if (Math.abs(match.getAverageElo() - queueParty.getAverageElo()) <= variance) + { + if (playerPrepMatchMap.containsKey(partyId)) + { + if (playerPrepMatchMap.get(partyId) == match) + break; + + playerPrepMatchMap.get(partyId).quitQueueParty(queueParty); + } + + match.joinQueueParty(queueParty); + playerPrepMatchMap.put(partyId, match); + + log("Found prep match for '" + queueParty.getId() + "'"); + break; + } + } + + if (!playerPrepMatchMap.containsKey(partyId)) + { + Match match = new Match(matchId++, queueParty.getAverageElo(), queueParty); + + playerPrepMatchMap.put(partyId, match); + matches.add(match); + } + } + else if (!assignedMatchIdChecked.contains(queueParty.getAssignedMatch())) + { + int assignedMatchId = queueParty.getAssignedMatch(); + log("Checking if match '" + assignedMatchId + "' is ready."); + //List matchStatuses = _repo.getMatchStatuses(queueRecord.AssignedMatch); + Collection joinedParties = _repo.getJoinedQueueParties(assignedMatchId); + boolean matchReady = true; + boolean matchDeny = false; + + for (QueueParty joinedParty : joinedParties) + { + String partyState = joinedParty.getState(); + if (partyState.equalsIgnoreCase("Deny")) + { + matchDeny = true; + matchReady = false; + break; + } + else if (!partyState.equalsIgnoreCase("Ready")) + { + matchReady = false; + } + } + + if (matchReady) + { + _repo.startMatch(assignedMatchId); + _repo.deleteAssignedParties(assignedMatchId); + + System.out.println("Starting match '" + assignedMatchId + "'"); + } + else if (matchDeny) + { + _repo.deleteMatch(assignedMatchId); + } + + assignedMatchIdChecked.add(assignedMatchId); + } + } + + System.out.println("Checking " + matches.size() + " matches..."); + + // Check for and kick off invites for ready matches + for (Iterator matchIterator = matches.iterator(); matchIterator.hasNext();) + { + Match match = matchIterator.next(); + + // Don't give me crap about not using iterator...can't cuz of stupid thing. + Set partiesToRemove = new HashSet(); + + for (QueueParty queueParty : match.getParties()) + { + if (!queueParties.containsKey(queueParty.getId())) + { + log("Removing matchStatus : " + queueParty.getId()); + partiesToRemove.add(queueParty); + + if (match.isWaitingForInvites()) + { + _repo.deleteMatch(match.getId()); + match.setWaitingForInvites(false); + } + } + } + + for (QueueParty party : partiesToRemove) + { + match.quitQueueParty(party); + } + + if (match.isWaitingForInvites()) + { + if ((match.getWaitDuration()) > 15000) + { + for (QueueParty queueParty : match.getParties()) + { + if (!queueParty.getState().equalsIgnoreCase("Ready")) + { + _repo.deleteQueueParty(queueParty.getId()); + } + } + + _repo.deleteMatch(match.getId()); + match.setWaitingForInvites(false); + } + + continue; + } + + if (match.getPlayerCount() >= matchPlayerCount) + { + List partyList = new ArrayList(match.getParties()); + Collections.sort(partyList, partySorter); + + int playerCount = 0; + for (QueueParty party : partyList) + { + if (playerCount + party.getPlayerCount() > matchPlayerCount) + { + match.quitQueueParty(party); + playerPrepMatchMap.remove(party.getId()); + log("Oops hit player cap, can't fit you in this match."); + continue; + } + + playerCount += party.getPlayerCount(); + } + + if (playerCount == matchPlayerCount) + { + log("Sent match invites for '" + match.getId() + "'"); + + for (QueueParty party : match.getParties()) + { + playerPrepMatchMap.remove(party.getId()); + _repo.assignMatch(party, match); + } + + match.setWaitingForInvites(true); + matchesMade++; + } + } + else if (match.getPlayerCount() == 0) + { + matchIterator.remove(); + } + } try { - if (_matchesMade > 0) - System.out.println("Made " + _matchesMade + " matches."); + if (matchesMade > 0) + System.out.println("Made " + matchesMade + " matches."); Thread.sleep(1000); } @@ -69,291 +222,6 @@ public class Queuer } - - /** - * Tick & update the Queuer as a whole, making one whole pass through all queued players and pending matches to - * assign matches to parties and start matches. - */ - private static void updateQueuer() - { - // Update the status of each queue party, searching for best matchings and assigning matches to parties. - for (QueueParty queueParty : _repo.getQueueParties()) - { - updateParty(queueParty); - } - - // Update all matches, and remove pending matches if they are finished. - Iterator iterator = _pendingMatches.iterator(); - while (iterator.hasNext()) - { - Match match = iterator.next(); - boolean matchFinished = updateMatch(match); - - // Remove match if it is completed/finished - if (matchFinished) iterator.remove(); - } - } - - /** - * Update the status of a {@link QueueParty} by attempting to locate the best resulting - * {@code Match} available, or creating a new one if required. - * @param queueParty - the queue party to be updated for matchmaking purposes. - */ - private static void updateParty(QueueParty queueParty) - { - int queueDuration = (int) queueParty.getQueueDuration() / 1000; // Queue duration in seconds - Match bestMatch = getBestMatch(queueParty); - - if (queueParty.hasAssignedMatch()) - { - // TODO: If player has been waiting too long in current game and there is a better match, join that! - } - else - { - if (bestMatch != null) // Assign party into best match! - { - bestMatch.joinQueueParty(queueParty); - _repo.assignMatch(queueParty, bestMatch); - } - else if (queueDuration >= MIN_QUEUE_WAIT) // Create a new match for others to join! - { - Match match = new Match(_matchId++, queueParty.getServerGroup(), queueParty); - _pendingMatches.add(match); - _repo.assignMatch(queueParty, match); - } - } - } - - /** - * Update a {@link Match} by verifying it's player statuses, sending out invites - * and managing a Match from creation to deletion. - * @param match - the match to be updated. - * @return true, if the match is no longer required (successful or otherwise) and should be removed, false otherwise. - */ - private static boolean updateMatch(Match match) - { - // Remove queued parties that have left queue/match - // Don't give me crap about not using iterator...can't cuz of stupid thing. - Set partiesToRemove = new HashSet(); - for (QueueParty queueParty : match.getParties()) - { - int partyId = queueParty.getId(); - if (!_repo.queuePartyExists(partyId)) - { - log("Removing matchStatus : " + queueParty.getId()); - partiesToRemove.add(queueParty); - - if (match.isWaitingForInvites()) - { - _repo.deleteMatch(match.getId()); - match.setWaitingForInvites(false); - } - } - } - for (QueueParty party : partiesToRemove) - { - match.quitQueueParty(party); - } - - // If match took too long to find players, or is empty, quit match. - if (match.getPlayerCount() == 0) - { - return true; // Match is empty, remove from pending matches. - } - - // If match sent invites and is waiting for too long (15 seconds), kick players who didn't - // accept and keep looking - // Otherwise if everyone accepted, start game! - if (match.isWaitingForInvites()) - { - boolean matchReady = true; - for (QueueParty party : _repo.getJoinedQueueParties(match.getId())) - { - if (!party.isReady()) - { - matchReady = false; - } - } - - if (!matchReady && match.getWaitDuration() > 500) - { - matchReady = true; - } - - if (match.isReady()) // Invites accepted, MinecraftServer started, and players transferred. - { - return true; - } - else if (matchReady) // Players accepted invites, start match! - { - startMatch(match); - return false; - } - else if (match.getWaitDuration() > 15000) - { - for (QueueParty queueParty : match.getParties()) - { - if (!queueParty.isReady()) - { - _repo.deleteQueueParty(queueParty.getId()); - } - } - - _repo.deleteMatch(match.getId()); - match.setWaitingForInvites(false); - } - - return false; - } - - // Match has filled up, send out invites! - if (match.getOpenSlots() == 0) - { - for (QueueParty party : match.getParties()) - { - _repo.sendInvite(party); - } - - match.setWaitingForInvites(true); - } - - return false; - } - - /** - * @param queueParty - the party for whom a match is being searched. - * @return the best matching {@link Match} for the {@code queueParty}, if an acceptable {@link Match} - * could be found, null otherwise. - */ - private static Match getBestMatch(QueueParty queueParty) - { - Match best = null; - int minEloDelta = 0; - int variance = getSearchVariance(queueParty); - - for (Match match : _pendingMatches) - { - if (match.getOpenSlots() >= queueParty.getPlayerCount()) - { - int eloDelta = getEloDelta(queueParty, match); - if (eloDelta <= variance && (eloDelta < minEloDelta || best == null)) - { - best = match; - minEloDelta = eloDelta; - } - } - } - - return best; - } - - /** - * @param r1 - * @param r2 - * @return the ELO point delta (difference) between two {@link Ranked} objects. - */ - private static int getEloDelta(Ranked r1, Ranked r2) - { - return Math.abs(r1.getElo() - r2.getElo()); - } - - public static boolean startMatch(Match match) - { - ServerGroup group = match.getServerGroup(); - DedicatedServer bestServer = getBestDedicatedServer(group); - startServer(bestServer, group, match); - return true; - } - - /** - * Transfer all players queue'd into a {@link Match} to one server. - * @param match - the match whose queue'd players are to be transferred - * @param serverName - the name of the server to transfer the players to - */ - public static void transferPlayers(Match match, String serverName) - { - for (QueueParty queueParty : _repo.getJoinedQueueParties(match.getId())) - { - for (String playerName : queueParty.getPlayers()) - { - // Execute a transfer command - ServerTransfer serverTransfer = new ServerTransfer(playerName, serverName); - TransferCommand transferCommand = new TransferCommand(serverTransfer); - transferCommand.publish(); - } - } - } - - /** - * @return newly generated unique server id. - */ - public static int generateServerId() - { - return _serverId++; - } - - private static void startServer(final DedicatedServer serverSpace, final ServerGroup serverGroup, final Match match) - { - String cmd = "/home/mineplex/easyRemoteStartServerCustom.sh"; - final String groupPrefix = serverGroup.getPrefix(); - final String serverName = serverSpace.getName(); - final String serverAddress = serverSpace.getPublicAddress(); - final int serverId = generateServerId(); - - ProcessRunner pr = new ProcessRunner(new String[] {"/bin/sh", cmd, serverAddress, serverSpace.getPrivateAddress(), (serverGroup.getPortSection() + serverId) + "", serverGroup.getRequiredRam() + "", serverGroup.getWorldZip(), serverGroup.getPlugin(), serverGroup.getConfigPath(), serverGroup.getName(), serverGroup.getPrefix() + "-" + serverId, serverSpace.isUsRegion() ? "true" : "false", serverGroup.getAddNoCheat() + "" }); - pr.start(new GenericRunnable() - { - public void run(Boolean error) - { - if (!error) - { - // Successfully started server, now transfer players - transferPlayers(match, serverName); - } - else - { - // TODO: Error in starting server for ELO match, try again or disband queued match? - log("[" + serverName + ":" + serverAddress + " Free Resources; CPU " + serverSpace.getAvailableCpu() + " RAM " + serverSpace.getAvailableRam() + "MB] Errored " + serverName + "(" + groupPrefix+ "-" + serverId + ")"); - } - - } - }); - - ProcessManager.getInstance().addProcess(pr); - serverSpace.incrementServerCount(serverGroup); - } - - private static DedicatedServer getBestDedicatedServer(ServerGroup serverGroup) - { - Collection dedicatedServers = _serverRepository.getDedicatedServers(); - DedicatedServer bestServer = null; - - for (DedicatedServer serverData : dedicatedServers) - { - if (serverData.getAvailableRam() > serverGroup.getRequiredRam() - && serverData.getAvailableCpu() > serverGroup.getRequiredCpu()) - { - if (bestServer == null || serverData.getServerCount(serverGroup) < bestServer.getServerCount(serverGroup)) - { - bestServer = serverData; - } - } - } - - return bestServer; - } - - /** - * @param party - the party whose ELO search variance is being fetched. - * @return the variance in ELO search parameters for {@code party}. - * I.E: Queuer searches for potential matches in [party.elo - variance, party.elo + variance] ELO range. - */ - private static int getSearchVariance(QueueParty party) - { - int seconds = (int) party.getQueueDuration() / 1000; // Duration of queue in seconds - - return seconds * 10; // 5 ELO variance for every second in queue - } private static void log(String message) { diff --git a/Plugins/.externalToolBuilders/Queuer.launch b/Plugins/Mineplex.ServerData/.externalToolBuilders/New_Builder.launch similarity index 88% rename from Plugins/.externalToolBuilders/Queuer.launch rename to Plugins/Mineplex.ServerData/.externalToolBuilders/New_Builder.launch index 7fe0fe5da..0c6e0f696 100644 --- a/Plugins/.externalToolBuilders/Queuer.launch +++ b/Plugins/Mineplex.ServerData/.externalToolBuilders/New_Builder.launch @@ -1,11 +1,11 @@ - - - + + + - + @@ -13,5 +13,5 @@ - + diff --git a/Plugins/Mineplex.ServerData/.project b/Plugins/Mineplex.ServerData/.project index 669fb734b..87c600cb6 100644 --- a/Plugins/Mineplex.ServerData/.project +++ b/Plugins/Mineplex.ServerData/.project @@ -1,6 +1,6 @@ - Mineplex.Queue.Core + Mineplex.ServerData @@ -10,6 +10,16 @@ + + org.eclipse.ui.externaltools.ExternalToolBuilder + auto,full,incremental, + + + LaunchConfigHandle + <project>/.externalToolBuilders/ServerData.launch + + + org.eclipse.jdt.core.javanature diff --git a/Plugins/Mineplex.ServerData/build.xml b/Plugins/Mineplex.ServerData/build.xml index bc33f19cd..411a60854 100644 --- a/Plugins/Mineplex.ServerData/build.xml +++ b/Plugins/Mineplex.ServerData/build.xml @@ -13,7 +13,7 @@ - + diff --git a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ConnectionData.java b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ConnectionData.java index 45c28a85b..efb265fc1 100644 --- a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ConnectionData.java +++ b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ConnectionData.java @@ -4,11 +4,10 @@ package mineplex.serverdata.servers; * ConnectionData stores information relevant for initiating a connection to a repository. * @author MrTwiggy * - * */ - public class ConnectionData { + private String _host; // The host URL to connect to repository public String getHost() { return _host; } diff --git a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java index 5be9b16ef..81a87c6a4 100644 --- a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java +++ b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java @@ -16,10 +16,10 @@ public class ServerManager { // Connection host to server database - private static final String DATABASE_HOST = "localhost";// TESTING, REPLACE WITH ORIGINAL: "10.33.53.16"; + private static final String DATABASE_HOST = "10.33.53.16"; // Ports associated with slave redis instances - private static final int[] SLAVE_PORTS = {6379}; // TESTING, REPLACE WITH: {6377, 6378, 6380, 6381, 6382}; + private static final int[] SLAVE_PORTS = {6377, 6378, 6380, 6381, 6382}; private static Random random = new Random(); // The cached repository instances diff --git a/Plugins/Mineplex.ServerMonitor/.classpath b/Plugins/Mineplex.ServerMonitor/.classpath index 23fda4021..49e473eb4 100644 --- a/Plugins/Mineplex.ServerMonitor/.classpath +++ b/Plugins/Mineplex.ServerMonitor/.classpath @@ -7,6 +7,5 @@ - diff --git a/Plugins/Mineplex.ServerProcesses/src/mineplex/serverprocesses/GenericRunnable.java b/Plugins/Mineplex.ServerMonitor/src/mineplex/servermonitor/GenericRunnable.java similarity index 62% rename from Plugins/Mineplex.ServerProcesses/src/mineplex/serverprocesses/GenericRunnable.java rename to Plugins/Mineplex.ServerMonitor/src/mineplex/servermonitor/GenericRunnable.java index a1e509698..2541be020 100644 --- a/Plugins/Mineplex.ServerProcesses/src/mineplex/serverprocesses/GenericRunnable.java +++ b/Plugins/Mineplex.ServerMonitor/src/mineplex/servermonitor/GenericRunnable.java @@ -1,4 +1,4 @@ -package mineplex.serverprocesses; +package mineplex.servermonitor; public interface GenericRunnable { diff --git a/Plugins/Mineplex.ServerProcesses/src/mineplex/serverprocesses/ProcessRunner.java b/Plugins/Mineplex.ServerMonitor/src/mineplex/servermonitor/ProcessRunner.java similarity index 95% rename from Plugins/Mineplex.ServerProcesses/src/mineplex/serverprocesses/ProcessRunner.java rename to Plugins/Mineplex.ServerMonitor/src/mineplex/servermonitor/ProcessRunner.java index dc9fc6217..6e2056ca7 100644 --- a/Plugins/Mineplex.ServerProcesses/src/mineplex/serverprocesses/ProcessRunner.java +++ b/Plugins/Mineplex.ServerMonitor/src/mineplex/servermonitor/ProcessRunner.java @@ -1,4 +1,4 @@ -package mineplex.serverprocesses; +package mineplex.servermonitor; import java.io.BufferedReader; import java.io.InputStreamReader; @@ -12,7 +12,7 @@ public class ProcessRunner extends Thread boolean _done = false; Boolean _error = false; - public ProcessRunner(String[] args) + ProcessRunner(String[] args) { super("ProcessRunner " + args); _processBuilder = new ProcessBuilder(args); diff --git a/Plugins/Mineplex.ServerMonitor/src/mineplex/servermonitor/ServerMonitor.java b/Plugins/Mineplex.ServerMonitor/src/mineplex/servermonitor/ServerMonitor.java index 8f7506b67..441cfe60b 100644 --- a/Plugins/Mineplex.ServerMonitor/src/mineplex/servermonitor/ServerMonitor.java +++ b/Plugins/Mineplex.ServerMonitor/src/mineplex/servermonitor/ServerMonitor.java @@ -29,15 +29,13 @@ import mineplex.serverdata.data.ServerGroup; import mineplex.serverdata.servers.DedicatedServerSorter; import mineplex.serverdata.servers.ServerManager; import mineplex.serverdata.servers.ServerRepository; -import mineplex.serverprocesses.GenericRunnable; -import mineplex.serverprocesses.ProcessManager; -import mineplex.serverprocesses.ProcessRunner; public class ServerMonitor { private static ServerRepository _repository = null; private static StatusHistoryRepository _historyRepository = null; private static int _count = 0; + private static HashSet _processes = new HashSet(); private static HashMap _badServers = new HashMap(); private static Collection _serverStatuses = null; private static Collection _serverGroups = null; @@ -285,7 +283,55 @@ public class ServerMonitor } } - ProcessManager.getInstance().updateProcesses(); + int processWaits = 0; + + while (_processes.size() > 0) + { + for (Iterator iterator = _processes.iterator(); iterator.hasNext();) + { + ProcessRunner pr = iterator.next(); + + try + { + pr.join(100); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + + if (pr.isDone()) + iterator.remove(); + } + + if (_processes.size() > 0) + { + try + { + log("Sleeping while processes run..."); + Thread.sleep(6000); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + + if (processWaits >= 10) + { + log("Killing stale processes."); + + for (Iterator iterator = _processes.iterator(); iterator.hasNext();) + { + iterator.next().abort(); + iterator.remove(); + } + } + + processWaits++; + } + + processWaits = 0; try { @@ -519,9 +565,7 @@ public class ServerMonitor if (!pr.isDone()) - { - ProcessManager.getInstance().addProcess(pr); - } + _processes.add(pr); } private static boolean isServerOffline(DedicatedServer serverData) @@ -622,9 +666,7 @@ public class ServerMonitor serverSpace.incrementServerCount(serverGroup); if (!pr.isDone()) - { - ProcessManager.getInstance().addProcess(pr); - } + _processes.add(pr); } private static void log(String message) diff --git a/Plugins/Mineplex.ServerProcesses/.classpath b/Plugins/Mineplex.ServerProcesses/.classpath deleted file mode 100644 index fceb4801b..000000000 --- a/Plugins/Mineplex.ServerProcesses/.classpath +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/Plugins/Mineplex.ServerProcesses/.project b/Plugins/Mineplex.ServerProcesses/.project deleted file mode 100644 index 66b31cde0..000000000 --- a/Plugins/Mineplex.ServerProcesses/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - Mineplex.ServerProcesses - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/Plugins/Mineplex.ServerProcesses/src/mineplex/serverprocesses/ProcessManager.java b/Plugins/Mineplex.ServerProcesses/src/mineplex/serverprocesses/ProcessManager.java deleted file mode 100644 index 9a7f80d34..000000000 --- a/Plugins/Mineplex.ServerProcesses/src/mineplex/serverprocesses/ProcessManager.java +++ /dev/null @@ -1,119 +0,0 @@ -package mineplex.serverprocesses; - -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -/** - * Handles the management and cleaning of {@link ProcessRunnner}s. - * @author MrTwiggy - * - */ -public class ProcessManager -{ - - private static ProcessManager _instance; // Singleton instance - private Set _processes; // Set of running processes currently managed. - - /** - * Private class constructor to prevent non-singletons. - */ - private ProcessManager() - { - _processes = new HashSet(); - } - - /** - * Add a {@link ProcessRunner} to the manager to be updated and cleaned after completion. - * @param process - the process to be added to the manager. - */ - public void addProcess(ProcessRunner process) - { - _processes.add(process); - } - - /** - * Update processes and clean up stale ones. - * NOTE: Blocks calling thread while polling process states. - * @return the number of {@link ProcessRunner}s that were finished and cleaned up. - */ - public int updateProcesses() - { - int cleanedProcesses = 0; - int processWaits = 0; - - while (_processes.size() > 0) - { - for (Iterator iterator = _processes.iterator(); iterator.hasNext();) - { - ProcessRunner pr = iterator.next(); - - try - { - pr.join(100); - } - catch (InterruptedException e) - { - e.printStackTrace(); - } - - if (pr.isDone()) - { - iterator.remove(); - cleanedProcesses++; - } - } - - if (_processes.size() > 0) - { - try - { - log("Sleeping while processes run..."); - Thread.sleep(6000); - } - catch (InterruptedException e) - { - e.printStackTrace(); - } - } - - if (processWaits >= 10) - { - log("Killing stale processes."); - - for (Iterator iterator = _processes.iterator(); iterator.hasNext();) - { - iterator.next().abort(); - iterator.remove(); - cleanedProcesses++; - } - } - - processWaits++; - } - - return cleanedProcesses; - } - - /** - * @return a singleton instance of {@link ProcessManager}. - */ - public static ProcessManager getInstance() - { - if (_instance == null) - { - _instance = new ProcessManager(); - } - - return _instance; - } - - /** - * Log a message to developer output. - * @param message - the message to be logged. - */ - private static void log(String message) - { - System.out.println(message); // Is this technically considered logging? - } -} diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java index d09b71120..95feec423 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java @@ -96,7 +96,7 @@ public abstract class Game implements Listener public ArcadeManager Manager; //Game - protected GameType _gameType; + private GameType _gameType; protected String[] _gameDesc; //Map @@ -260,6 +260,9 @@ public abstract class Game implements Listener public String Winner = "Nobody"; public GameTeam WinnerTeam = null; + public boolean EloRanking = false; + public int EloStart = 1000; + public boolean CanAddStats = true; public boolean CanGiveLoot = true; @@ -865,6 +868,18 @@ public abstract class Game implements Listener Scoreboard.SetPlayerTeam(player, "SPEC"); } + @EventHandler + public void eloStart(PlayerLoginEvent event) + { + if (EloRanking) + { + if (Manager.getEloManager().getElo(event.getPlayer().getUniqueId(), GetName()) == -1) + { + Manager.getEloManager().saveElo(event.getPlayer().getUniqueId(), GetName(), EloStart); + } + } + } + @EventHandler public abstract void ScoreboardUpdate(UpdateEvent event); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/GameTeam.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/GameTeam.java index 20537ec44..87e8f7f6f 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/GameTeam.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/GameTeam.java @@ -4,14 +4,12 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.Set; import mineplex.core.common.util.C; import mineplex.core.common.util.F; import mineplex.core.common.util.UtilMath; import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilServer; -import mineplex.core.elo.Team; import nautilus.game.arcade.game.GameTeam.PlayerState; import nautilus.game.arcade.kit.Kit; import nautilus.game.arcade.kit.KitAvailability; @@ -23,7 +21,7 @@ import org.bukkit.entity.Creature; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; -public class GameTeam implements Team +public class GameTeam { private Game Host; @@ -383,17 +381,4 @@ public class GameTeam implements Team return _places; } - - @Override - public Set getMemberNames() - { - Set memberNames = new HashSet(); - - for (Player player : _players.keySet()) - { - memberNames.add(player.getName()); - } - - return memberNames; - } } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/TeamGame.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/TeamGame.java index af0e35cd9..dcc877d8f 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/TeamGame.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/TeamGame.java @@ -27,9 +27,6 @@ public abstract class TeamGame extends Game protected NautHashMap RejoinHealth = new NautHashMap(); protected long RejoinTime = 120000; - - // Whether or not this is a Ranked match. - protected boolean Ranked = false; public TeamGame(ArcadeManager manager, GameType gameType, Kit[] kits, String[] gameDesc) { @@ -215,19 +212,6 @@ public abstract class TeamGame extends Game if (player.isOnline()) AddGems(player, 10, "Participation", false, false); } - - // Update and resolve match for ranked games - if (Ranked) - { - if (GetTeamList().size() == 2) // Must have matches of 2 teams for now - { - List teamList = GetTeamList(); - GameTeam loserTeam = (teamList.get(1).equals(WinnerTeam)) ? teamList.get(0) : teamList.get(1); - int gamemode = _gameType.getGameId(); - - Manager.getEloManager().resolveMatch(WinnerTeam, loserTeam, gamemode); // Resolves and updates player ratings. - } - } //End SetState(GameState.End); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/ChampionsDominate.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/ChampionsDominate.java index 713a67f33..59f2f34d4 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/ChampionsDominate.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/champions/ChampionsDominate.java @@ -61,6 +61,9 @@ public class ChampionsDominate extends Domination InventoryOpenChest = true; + EloRanking = false; + EloStart = 1000; + this.DisableKillCommand = false; registerStatTrackers( diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/common/Domination.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/common/Domination.java index 891dc238d..cc96c5dad 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/common/Domination.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/common/Domination.java @@ -6,7 +6,6 @@ import java.util.HashMap; - import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.entity.Entity; @@ -22,6 +21,9 @@ import org.bukkit.event.player.PlayerPickupItemEvent; import mineplex.core.common.util.C; import mineplex.core.common.util.UtilBlock; import mineplex.core.common.util.UtilPlayer; +import mineplex.core.elo.EloPlayer; +import mineplex.core.elo.EloTeam; +import mineplex.core.elo.GameResult; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.minecraft.game.core.combat.CombatComponent; @@ -277,6 +279,48 @@ public class Domination extends TeamGame if (player.isOnline()) AddGems(player, 10, "Participation", false, false); } + + if (EloRanking) + { + EloTeam teamWinner = new EloTeam(); + EloTeam teamLoser = new EloTeam(); + + for (GameTeam team : GetTeamList()) + { + if (WinnerTeam != null && team.equals(WinnerTeam)) + { + for (Player player : WinnerTeam.GetPlayers(false)) + { + EloPlayer eloPlayer = new EloPlayer(); + eloPlayer.UniqueId = player.getUniqueId().toString(); + eloPlayer.Rating = Manager.getEloManager().getElo(player.getUniqueId(), GetName()); + + teamWinner.addPlayer(eloPlayer); + } + } + else + { + for (Player player : team.GetPlayers(false)) + { + EloPlayer eloPlayer = new EloPlayer(); + eloPlayer.UniqueId = player.getUniqueId().toString(); + eloPlayer.Rating = Manager.getEloManager().getElo(player.getUniqueId(), GetName()); + + teamLoser.addPlayer(eloPlayer); + } + } + } + + for (EloPlayer eloPlayer : Manager.getEloManager().getNewRatings(teamWinner, teamLoser, GameResult.Win).getPlayers()) + { + Manager.getEloManager().saveElo(eloPlayer.UniqueId, GetName(), eloPlayer.Rating); + } + + for (EloPlayer eloPlayer : Manager.getEloManager().getNewRatings(teamLoser, teamWinner, GameResult.Loss).getPlayers()) + { + Manager.getEloManager().saveElo(eloPlayer.UniqueId, GetName(), eloPlayer.Rating); + } + } //End SetState(GameState.End); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/common/TeamDeathmatch.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/common/TeamDeathmatch.java index f52ec3294..4ea0687be 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/common/TeamDeathmatch.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/common/TeamDeathmatch.java @@ -21,7 +21,9 @@ import mineplex.core.common.util.UtilMath; import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilTime; - +import mineplex.core.elo.EloPlayer; +import mineplex.core.elo.EloTeam; +import mineplex.core.elo.GameResult; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; import mineplex.minecraft.game.core.combat.DeathMessageType; @@ -321,6 +323,48 @@ public class TeamDeathmatch extends TeamGame AddGems(player, 10, "Participation", false, false); } + if (EloRanking) + { + EloTeam teamWinner = new EloTeam(); + EloTeam teamLoser = new EloTeam(); + + for (GameTeam team : GetTeamList()) + { + if (WinnerTeam != null && team.equals(WinnerTeam)) + { + for (Player player : WinnerTeam.GetPlayers(false)) + { + EloPlayer eloPlayer = new EloPlayer(); + eloPlayer.UniqueId = player.getUniqueId().toString(); + eloPlayer.Rating = Manager.getEloManager().getElo(player.getUniqueId(), GetName()); + + teamWinner.addPlayer(eloPlayer); + } + } + else + { + for (Player player : team.GetPlayers(false)) + { + EloPlayer eloPlayer = new EloPlayer(); + eloPlayer.UniqueId = player.getUniqueId().toString(); + eloPlayer.Rating = Manager.getEloManager().getElo(player.getUniqueId(), GetName()); + + teamLoser.addPlayer(eloPlayer); + } + } + } + + for (EloPlayer eloPlayer : Manager.getEloManager().getNewRatings(teamWinner, teamLoser, GameResult.Win).getPlayers()) + { + Manager.getEloManager().saveElo(eloPlayer.UniqueId, GetName(), eloPlayer.Rating); + } + + for (EloPlayer eloPlayer : Manager.getEloManager().getNewRatings(teamLoser, teamWinner, GameResult.Loss).getPlayers()) + { + Manager.getEloManager().saveElo(eloPlayer.UniqueId, GetName(), eloPlayer.Rating); + } + } + //End SetState(GameState.End); } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLobbyManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLobbyManager.java index 451319d92..fe3a858b4 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLobbyManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameLobbyManager.java @@ -1022,8 +1022,7 @@ public class GameLobbyManager implements Listener, IPacketHandler objective.getScore(_serverName).setScore(line--); //ELO - // TODO: Implement GUI based for ELO ranking/ratings? - /*if (Manager.GetGame() != null && Manager.GetGame().EloRanking) + if (Manager.GetGame() != null && Manager.GetGame().EloRanking) { objective.getScore(" ").setScore(line--); objective.getScore(C.cPurple + C.Bold + "Elo").setScore(line--); @@ -1033,7 +1032,7 @@ public class GameLobbyManager implements Listener, IPacketHandler // Set new objective.getScore(Manager.getEloManager().getElo(entry.getKey().getUniqueId(), Manager.GetGame().GetName()) + " ").setScore(line--); - }*/ + } } _oldPlayerCount = UtilServer.getPlayers().length;