Prevent farming elo up with multiple games by dc and joining new game.
This commit is contained in:
parent
ddd1c5af9b
commit
7b18efa7b0
@ -2,9 +2,11 @@ package mineplex.core.elo;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashSet;
|
||||
|
||||
import mineplex.core.MiniDbClientPlugin;
|
||||
import mineplex.core.account.CoreClientManager;
|
||||
import mineplex.core.common.util.NautHashMap;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
@ -13,6 +15,7 @@ public class EloManager extends MiniDbClientPlugin<EloClientData>
|
||||
{
|
||||
private EloRepository _repository;
|
||||
private EloRatingSystem _ratingSystem;
|
||||
private NautHashMap<String, EloTeam> _eloTeams = new NautHashMap<>();
|
||||
|
||||
public EloManager(JavaPlugin plugin, CoreClientManager clientManager)
|
||||
{
|
||||
@ -53,7 +56,7 @@ public class EloManager extends MiniDbClientPlugin<EloClientData>
|
||||
for (EloPlayer player : teamA.getPlayers())
|
||||
{
|
||||
int newRating = (int)(player.getRating() + ((double)_ratingSystem.getKFactor(player.getRating()) / (double)kTotal) * (newTotal - teamA.TotalElo));
|
||||
EloPlayer newPlayer = new EloPlayer(player.getPlayer(), newRating);
|
||||
EloPlayer newPlayer = new EloPlayer(player.getPlayer(), player.getAccountId(), newRating);
|
||||
|
||||
newTeam.addPlayer(newPlayer);
|
||||
}
|
||||
@ -61,7 +64,7 @@ public class EloManager extends MiniDbClientPlugin<EloClientData>
|
||||
return newTeam;
|
||||
}
|
||||
|
||||
public void saveElo(final Player player, final int gameType, final int elo)
|
||||
public void saveElo(final Player player, final int accountId, final int gameType, final int oldElo, final int elo)
|
||||
{
|
||||
runAsync(new Runnable()
|
||||
{
|
||||
@ -71,7 +74,7 @@ public class EloManager extends MiniDbClientPlugin<EloClientData>
|
||||
|
||||
try
|
||||
{
|
||||
success = _repository.saveElo(getClientManager().getAccountId(player), gameType, elo);
|
||||
success = _repository.saveElo(accountId, gameType, oldElo, elo);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
@ -79,12 +82,24 @@ public class EloManager extends MiniDbClientPlugin<EloClientData>
|
||||
}
|
||||
finally
|
||||
{
|
||||
System.out.println("Saving " + player.getName() + "'s new elo rating of " + elo + " for gameType " + gameType + (success ? " SUCCEEDED." : " FAILED."));
|
||||
System.out.println("Saving " + accountId + "'s new elo rating of " + elo + " for gameType " + gameType + (success ? " SUCCEEDED." : " FAILED."));
|
||||
}
|
||||
|
||||
final boolean finalSuccess = success;
|
||||
|
||||
runSync(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
if (finalSuccess)
|
||||
{
|
||||
if (player.isOnline())
|
||||
Get(player).Elos.put(gameType, elo);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Get(player).Elos.put(gameType, elo);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String getPlayerDivision(Player player, int gameType)
|
||||
@ -145,4 +160,44 @@ public class EloManager extends MiniDbClientPlugin<EloClientData>
|
||||
{
|
||||
return "SELECT gameType, elo FROM eloRating WHERE accountId = '" + accountId + "';";
|
||||
}
|
||||
|
||||
public void addTeam(String displayName, EloTeam eloTeam)
|
||||
{
|
||||
_eloTeams.put(displayName, eloTeam);
|
||||
}
|
||||
|
||||
public void setWinningTeam(String displayName)
|
||||
{
|
||||
_eloTeams.get(displayName).Winner = true;
|
||||
}
|
||||
|
||||
public void endMatch(int gameId)
|
||||
{
|
||||
EloTeam teamWinner = null;
|
||||
EloTeam teamLoser = null;
|
||||
|
||||
for (EloTeam team : _eloTeams.values())
|
||||
{
|
||||
if (team.Winner)
|
||||
teamWinner = team;
|
||||
else
|
||||
teamLoser = team;
|
||||
}
|
||||
|
||||
EloTeam teamWinnerNew = getNewRatings(teamWinner, teamLoser, GameResult.Win);
|
||||
EloTeam teamLoserNew = getNewRatings(teamLoser, teamWinner, GameResult.Loss);
|
||||
|
||||
// Use teams to calculate Elo
|
||||
for (EloPlayer eloPlayer : teamWinnerNew.getPlayers())
|
||||
{
|
||||
saveElo(eloPlayer.getPlayer(), eloPlayer.getAccountId(), gameId, teamWinner.getPlayer(eloPlayer.getPlayer().getUniqueId().toString()).getRating(), eloPlayer.getRating());
|
||||
}
|
||||
|
||||
for (EloPlayer eloPlayer : teamLoserNew.getPlayers())
|
||||
{
|
||||
saveElo(eloPlayer.getPlayer(), eloPlayer.getAccountId(), gameId, teamLoser.getPlayer(eloPlayer.getPlayer().getUniqueId().toString()).getRating(), eloPlayer.getRating());
|
||||
}
|
||||
|
||||
_eloTeams.clear();
|
||||
}
|
||||
}
|
||||
|
@ -5,11 +5,13 @@ import org.bukkit.entity.Player;
|
||||
public class EloPlayer
|
||||
{
|
||||
private Player _player;
|
||||
public int _rating;
|
||||
private int _accountId;
|
||||
private int _rating;
|
||||
|
||||
public EloPlayer(Player player, int rating)
|
||||
public EloPlayer(Player player, int accountId, int rating)
|
||||
{
|
||||
_player = player;
|
||||
_accountId = accountId;
|
||||
_rating = rating;
|
||||
}
|
||||
|
||||
@ -18,16 +20,16 @@ public class EloPlayer
|
||||
return _player;
|
||||
}
|
||||
|
||||
public void setRating(int rating)
|
||||
{
|
||||
_rating = rating;
|
||||
}
|
||||
|
||||
public int getRating()
|
||||
{
|
||||
return _rating;
|
||||
}
|
||||
|
||||
public int getAccountId()
|
||||
{
|
||||
return _accountId;
|
||||
}
|
||||
|
||||
public void printInfo()
|
||||
{
|
||||
System.out.println(_player.getName() + "'s elo is " + _rating);
|
||||
|
@ -12,7 +12,8 @@ import org.bukkit.plugin.java.JavaPlugin;
|
||||
public class EloRepository extends MinecraftRepository
|
||||
{
|
||||
private static String INSERT_ELO = "INSERT INTO eloRating (accountId, gameType, elo) VALUES (?, ?, ?);";
|
||||
private static String UPDATE_ELO = "UPDATE eloRating SET elo=? WHERE accountId = ? AND gameType = ?;";
|
||||
private static String UPDATE_ELO = "UPDATE eloRating SET elo = elo + ? WHERE accountId = ? AND gameType = ?;";
|
||||
private static String UPDATE_ELO_ONLY_IF_MATCH = "UPDATE eloRating SET elo = elo + ? WHERE accountId = ? AND gameType = ? AND elo = ?;";
|
||||
|
||||
public EloRepository(JavaPlugin plugin)
|
||||
{
|
||||
@ -23,14 +24,21 @@ public class EloRepository extends MinecraftRepository
|
||||
|
||||
public void initialize() { }
|
||||
|
||||
public boolean saveElo(int accountId, int gameType, int elo) throws SQLException
|
||||
public boolean saveElo(int accountId, int gameType, int oldElo, int elo) throws SQLException
|
||||
{
|
||||
if (executeUpdate(UPDATE_ELO, new ColumnInt("elo", elo), new ColumnInt("accountId", accountId), new ColumnInt("gameType", gameType)) > 0)
|
||||
return true;
|
||||
else if (executeUpdate(INSERT_ELO, new ColumnInt("accountId", accountId), new ColumnInt("gameType", gameType), new ColumnInt("elo", elo)) > 0)
|
||||
return true;
|
||||
boolean updateSucceeded = false;
|
||||
|
||||
return false;
|
||||
// If we're increasing in elo we verify the server version matches the database version (prevent d/c and double wins with concurrent matches)
|
||||
// Otherwise we always take their elo down if they lose.
|
||||
if (elo > oldElo)
|
||||
updateSucceeded = executeUpdate(UPDATE_ELO_ONLY_IF_MATCH, new ColumnInt("elo", elo - oldElo), new ColumnInt("accountId", accountId), new ColumnInt("gameType", gameType), new ColumnInt("elo", oldElo)) > 0;
|
||||
else
|
||||
updateSucceeded = executeUpdate(UPDATE_ELO, new ColumnInt("elo", elo - oldElo), new ColumnInt("accountId", accountId), new ColumnInt("gameType", gameType)) > 0;
|
||||
|
||||
if (!updateSucceeded && executeUpdate(INSERT_ELO, new ColumnInt("accountId", accountId), new ColumnInt("gameType", gameType), new ColumnInt("elo", elo)) > 0)
|
||||
updateSucceeded = true;
|
||||
|
||||
return updateSucceeded;
|
||||
}
|
||||
|
||||
public EloClientData loadClientInformation(ResultSet resultSet) throws SQLException
|
||||
|
@ -1,33 +1,29 @@
|
||||
package mineplex.core.elo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
|
||||
import mineplex.core.common.util.NautHashMap;
|
||||
|
||||
public class EloTeam
|
||||
{
|
||||
private List<EloPlayer> _players = new ArrayList<EloPlayer>();
|
||||
|
||||
private NautHashMap<String, EloPlayer> _players = new NautHashMap<>();
|
||||
public int TotalElo = 0;
|
||||
public boolean Winner = false;
|
||||
|
||||
public void addPlayer(EloPlayer player)
|
||||
{
|
||||
TotalElo += player.getRating();
|
||||
|
||||
_players.add(player);
|
||||
_players.put(player.getPlayer().getUniqueId().toString(), player);
|
||||
}
|
||||
|
||||
public List<EloPlayer> getPlayers()
|
||||
public EloPlayer getPlayer(String uuid)
|
||||
{
|
||||
return _players;
|
||||
return _players.get(uuid);
|
||||
}
|
||||
|
||||
public void printTeamInfo()
|
||||
public Collection<EloPlayer> getPlayers()
|
||||
{
|
||||
System.out.println("TotalElo: " + TotalElo);
|
||||
|
||||
for (EloPlayer player : _players)
|
||||
{
|
||||
System.out.println(player.getPlayer().getName() + "'s Elo: " + player.getRating());
|
||||
}
|
||||
return _players.values();
|
||||
}
|
||||
}
|
||||
|
@ -1568,55 +1568,38 @@ public abstract class Game implements Listener
|
||||
SetState(GameState.End);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onGameStart(GameStateChangeEvent event)
|
||||
{
|
||||
if (event.GetState() == GameState.Live)
|
||||
{
|
||||
if (EloRanking)
|
||||
{
|
||||
// Populate teams
|
||||
for (GameTeam team : GetTeamList())
|
||||
{
|
||||
EloTeam eloTeam = new EloTeam();
|
||||
|
||||
for (Player player : team.GetPlayers(false))
|
||||
{
|
||||
eloTeam.addPlayer(new EloPlayer(player, Manager.GetClients().getAccountId(player), Manager.getEloManager().getElo(player, GetType().getGameId())));
|
||||
}
|
||||
|
||||
Manager.getEloManager().addTeam(team.getDisplayName(), eloTeam);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Elo at end of game -- method can be overridden in different game modes to meet their individual needs
|
||||
protected void endElo()
|
||||
{
|
||||
if (EloRanking)
|
||||
{
|
||||
// Make a list of all players to help find average Elo
|
||||
EloTeam teamWinner = new EloTeam();
|
||||
EloTeam teamLoser = new EloTeam();
|
||||
if (WinnerTeam != null)
|
||||
Manager.getEloManager().setWinningTeam(WinnerTeam.getDisplayName());
|
||||
|
||||
// Populate teams
|
||||
for (GameTeam team : GetTeamList())
|
||||
{
|
||||
if (WinnerTeam != null && team.equals(WinnerTeam))
|
||||
{
|
||||
for (Player player : WinnerTeam.GetPlayers(false))
|
||||
{
|
||||
teamWinner.addPlayer(new EloPlayer(player, Manager.getEloManager().getElo(player, GetType().getGameId())));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Player player : team.GetPlayers(false))
|
||||
{
|
||||
teamLoser.addPlayer(new EloPlayer(player, Manager.getEloManager().getElo(player, GetType().getGameId())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EloTeam teamWinnerNew = Manager.getEloManager().getNewRatings(teamWinner, teamLoser, GameResult.Win);
|
||||
EloTeam teamLoserNew = Manager.getEloManager().getNewRatings(teamLoser, teamWinner, GameResult.Loss);
|
||||
|
||||
System.out.println("Winning team:");
|
||||
teamWinner.printTeamInfo();
|
||||
teamWinnerNew.printTeamInfo();
|
||||
|
||||
System.out.println("Losing team:");
|
||||
teamLoser.printTeamInfo();
|
||||
teamLoserNew.printTeamInfo();
|
||||
|
||||
// Use teams to calculate Elo
|
||||
for (EloPlayer eloPlayer : teamWinnerNew.getPlayers())
|
||||
{
|
||||
Manager.getEloManager().saveElo(eloPlayer.getPlayer(), GetType().getGameId(), eloPlayer.getRating());
|
||||
}
|
||||
|
||||
for (EloPlayer eloPlayer : teamLoserNew.getPlayers())
|
||||
{
|
||||
Manager.getEloManager().saveElo(eloPlayer.getPlayer(), GetType().getGameId(), eloPlayer.getRating());
|
||||
}
|
||||
Manager.getEloManager().endMatch(GetType().getGameId());
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user