Merge pull request #43 from Mineplex-LLC/alex-mcl

Fix Async Elo Ranked Bans
This commit is contained in:
Conrad 2016-04-30 14:46:49 -04:00
commit e0e30a8b7f
4 changed files with 159 additions and 102 deletions

View File

@ -1,18 +1,20 @@
package mineplex.core.elo;
import java.sql.ResultSet;
import java.sql.SQLException;
import mineplex.core.MiniDbClientPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.util.C;
import mineplex.core.common.util.Callback;
import mineplex.core.common.util.NautHashMap;
import mineplex.core.itemstack.ItemBuilder;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import java.sql.ResultSet;
import java.sql.SQLException;
public class EloManager extends MiniDbClientPlugin<EloClientData>
{
private EloRepository _repository;
@ -139,32 +141,74 @@ public class EloManager extends MiniDbClientPlugin<EloClientData>
}
/**
* Method for quickly checking if a player is banned from ranked games
* Checks if a player is banned from ranked games async
* @param accountId The player's account ID
* @param afterCheck Code to be executed with the fetched ban status
*/
public boolean isRankBanned(int accountId)
public void checkRankBannedAsync(int accountId, Callback<Long> afterCheck)
{
boolean banExpired = System.currentTimeMillis() >= getRankBanExpiry(accountId);
if (banExpired)
{
if (System.currentTimeMillis() >= _repository.getStrikeExpiry(accountId))
{
_repository.resetStrikes(accountId);
}
}
return !banExpired;
getRankBanExpiryAsync(accountId, expiry -> {
boolean expired = System.currentTimeMillis() >= expiry;
if (expired)
{
_repository.getStrikeExpiry(accountId, strikeExpiration -> {
if (System.currentTimeMillis() >= strikeExpiration)
{
_repository.resetStrikes(accountId);
}
});
}
afterCheck.run(expiry);
});
}
/**
* Method for getting a player's remaining ranked game ban duration if applicable
* Checks if a player is banned from ranked games (Should not be run on main thread)
* @param accountId The player's account ID
* @return The ban status of the player
*/
public boolean checkRankBanned(int accountId)
{
boolean expired = System.currentTimeMillis() >= getRankBanExpiry(accountId);
if (expired)
{
_repository.getStrikeExpiry(accountId, strikeExpiration -> {
if (System.currentTimeMillis() >= strikeExpiration)
{
_repository.resetStrikes(accountId);
}
});
}
return !expired;
}
/**
* Gets a player's remaining ranked game ban duration (Should not be run on main thread)
* @param accountId The player's account ID
* @return The ban expiry of the player (0 if not found)
*/
public long getRankBanExpiry(int accountId)
{
return _repository.getBanExpiry(accountId);
return _repository.getBanExpiry(accountId);
}
/**
* Method for banning a player from joining ranked games temporarily
* Gets a player's remaining ranked game ban duration if applicable async
* @param accountId The player's account ID
* @param afterFetch Code to be executed with the fetched ban expiration
*/
public void getRankBanExpiryAsync(int accountId, Callback<Long> afterFetch)
{
_repository.getBanExpiryAsync(accountId, afterFetch);
}
/**
* Bans a player from joining ranked games temporarily
* @param accountId The player's account ID
*/
public void banFromRanked(int accountId)
{
@ -172,7 +216,8 @@ public class EloManager extends MiniDbClientPlugin<EloClientData>
}
/**
* Method called when game ends to calculate new Elo and award it
* Called when game ends to calculate new Elo and award it
* @param gameId The game's ID
*/
public void endMatch(int gameId)
{

View File

@ -4,6 +4,7 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@ -47,7 +48,7 @@ public class EloRepository extends MinecraftRepository
public boolean saveElo(int accountId, int gameType, int oldElo, int elo) throws SQLException
{
final List<Boolean> ret = Lists.newArrayList();
List<Boolean> ret = Lists.newArrayList();
Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> {
boolean updateSucceeded = false;
@ -65,6 +66,8 @@ public class EloRepository extends MinecraftRepository
updateSucceeded = true;
}
}
ret.add(updateSucceeded);
});
if (ret.isEmpty())
@ -87,98 +90,92 @@ public class EloRepository extends MinecraftRepository
return clientData;
}
public long getStrikeExpiry(int accountId)
public void getStrikeExpiry(int accountId, Callback<Long> call)
{
final List<Long> expire = Lists.newArrayList();
Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> executeQuery(GRAB_STRIKE_EXPIRY, resultSet -> {
while (resultSet.next())
{
expire.add(resultSet.getLong(1));
call.run(resultSet.getLong(1));
}
}, new ColumnInt("accountId", accountId)));
if (expire.isEmpty())
{
expire.add(System.currentTimeMillis() - 5555);
}
return expire.get(0);
}
public long getBanExpiry(int accountId)
public void getBanExpiryAsync(int accountId, Callback<Long> call)
{
final List<Long> expire = Lists.newArrayList();
Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> executeQuery(GRAB_BAN_EXPIRY, resultSet -> {
while (resultSet.next())
{
expire.add(resultSet.getLong(1));
call.run(resultSet.getLong(1));
}
}, new ColumnInt("accountId", accountId)));
if (expire.isEmpty())
{
expire.add(System.currentTimeMillis() - 5555);
}
return expire.get(0);
}
public long getBanExpiry(int accountId)
{
List<Long> expiry = new ArrayList<Long>();
executeQuery(GRAB_BAN_EXPIRY, resultSet -> {
while (resultSet.next())
{
expiry.add(resultSet.getLong(1));
}
}, new ColumnInt("accountId", accountId));
if (expiry.isEmpty())
expiry.add(System.currentTimeMillis() - 5000);
return expiry.get(0);
}
public int getStrikes(int accountId)
public void getStrikes(int accountId, Callback<Integer> call)
{
final List<Integer> strike = Lists.newArrayList();
Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> executeQuery(GRAB_STRIKES, resultSet -> {
while (resultSet.next())
{
strike.add(resultSet.getInt(1));
call.run(resultSet.getInt(1));
}
}, new ColumnInt("accountId", accountId)));
if (strike.isEmpty())
{
strike.add(0);
}
return strike.get(0);
}
public void addRankedBan(int accountId)
{
int minutes = 1;
switch (getStrikes(accountId))
{
case 0:
minutes = 1;
break;
case 1:
minutes = 5;
break;
case 2:
minutes = 10;
break;
case 3:
minutes = 20;
break;
case 4:
minutes = 30;
break;
case 5:
minutes = 60;
break;
case 6:
minutes = 120;
break;
case 7:
minutes = 180;
break;
case 8:
minutes = 240;
break;
}
final long banEnd = System.currentTimeMillis() + UtilTime.convert(minutes, TimeUnit.MINUTES, TimeUnit.MILLISECONDS);
final long strikesExpire = System.currentTimeMillis() + UtilTime.convert(1, TimeUnit.DAYS, TimeUnit.MILLISECONDS);
final int newStrikes = Math.min(getStrikes(accountId) + 1, 8);
Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> executeUpdate(UPDATE_BAN, new ColumnInt("accountId", accountId), new ColumnInt("strikes", newStrikes), new ColumnLong("strikesExpire", strikesExpire), new ColumnLong("banEnd", banEnd)));
getStrikes(accountId, strikes -> {
int minutes = 1;
switch (strikes)
{
case 0:
minutes = 1;
break;
case 1:
minutes = 5;
break;
case 2:
minutes = 10;
break;
case 3:
minutes = 20;
break;
case 4:
minutes = 30;
break;
case 5:
minutes = 60;
break;
case 6:
minutes = 120;
break;
case 7:
minutes = 180;
break;
case 8:
minutes = 240;
break;
}
long banEnd = System.currentTimeMillis() + UtilTime.convert(minutes, TimeUnit.MINUTES, TimeUnit.MILLISECONDS);
long strikesExpire = System.currentTimeMillis() + UtilTime.convert(1, TimeUnit.DAYS, TimeUnit.MILLISECONDS);
int newStrikes = Math.min(strikes + 1, 8);
Bukkit.getScheduler().runTaskAsynchronously(getPlugin(), () -> executeUpdate(UPDATE_BAN, new ColumnInt("accountId", accountId), new ColumnInt("strikes", newStrikes), new ColumnLong("strikesExpire", strikesExpire), new ColumnLong("banEnd", banEnd)));
});
}
public void resetStrikes(int accountId)

View File

@ -1,5 +1,6 @@
package mineplex.core.elo;
import com.google.common.collect.Lists;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.C;
@ -10,12 +11,16 @@ import mineplex.core.slack.SlackMessage;
import mineplex.core.slack.SlackTeam;
import org.bukkit.entity.Player;
import java.util.List;
/**
* Generates a list of top elos
*/
public class TopEloCommand extends CommandBase<EloManager>
{
private static final List<String> NAMES = Lists.newArrayList("Relyh", "TadahTech");
public TopEloCommand(EloManager plugin)
{
super(plugin, Rank.ADMIN, "gettopelo", "topelo", "getelo");
@ -28,7 +33,11 @@ public class TopEloCommand extends CommandBase<EloManager>
{
return;
}
if(args.length != 1)
if (!NAMES.contains(caller.getName()))
{
return;
}
if (args.length != 1)
{
return;
}
@ -52,18 +61,18 @@ public class TopEloCommand extends CommandBase<EloManager>
caller.sendMessage(C.cWhite + "Top Elo Data");
caller.sendMessage(" ");
StringBuilder builder = new StringBuilder();
for(int i = 0; i < data.size(); i++){
for (int i = 0; i < data.size(); i++)
{
StringBuilder messageBuilder = new StringBuilder("#");
TopEloData topEloData = data.get(i);
builder.append((i + 1)).append(": ").append(topEloData.getName())
.append(" ").append(EloDivision.getDivision(topEloData.getElo())).append("").append("\n");
messageBuilder.append((i + 1)).append(": ").append(topEloData.getName())
.append(" ").append(EloDivision.getDivision(topEloData.getElo())).append("");
SlackMessage slackMessage = new SlackMessage(builder.toString());
SlackAPI.getInstance().sendMessage(SlackTeam.DEVELOPER, "#top-elo", slackMessage, false);
caller.sendMessage(C.cYellow + messageBuilder.toString());
}
SlackMessage slackMessage = new SlackMessage(builder.toString());
SlackAPI.getInstance().sendMessage(SlackTeam.DEVELOPER, "#top-elo", slackMessage, false);
caller.sendMessage(" ");
caller.sendMessage(C.cAquaB + C.Strike + "=============================================");
});

View File

@ -2,6 +2,7 @@ package nautilus.game.arcade.game;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mineplex.core.common.Rank;
import mineplex.core.common.util.Callback;
@ -14,9 +15,9 @@ import nautilus.game.arcade.kit.Kit;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerLoginEvent.Result;
import org.bukkit.event.player.PlayerQuitEvent;
@ -37,10 +38,10 @@ public abstract class RankedTeamGame extends TeamGame
this.SpectatorAllowed = false;
}
private int getAccountId(Player player)
private int getAccountId(UUID uuid)
{
final List<Integer> id = new ArrayList<Integer>();
Manager.GetClients().getRepository().getAccountId(player.getUniqueId(), new Callback<Integer>()
Manager.GetClients().getRepository().getAccountId(uuid, new Callback<Integer>()
{
@Override
public void run(Integer data)
@ -79,16 +80,21 @@ public abstract class RankedTeamGame extends TeamGame
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onLogin(AsyncPlayerPreLoginEvent event)
{
long expiry = Manager.getEloManager().getRankBanExpiry(getAccountId(event.getUniqueId()));
if (Manager.getEloManager().checkRankBanned(getAccountId(event.getUniqueId())))
{
String time = UtilTime.MakeStr(expiry - System.currentTimeMillis());
String message = ChatColor.RED + "You cannot join a ranked match yet because you left your last one early! Your ban expires in " + time;
event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_BANNED, message);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onLogin(PlayerLoginEvent event)
{
if (Manager.getEloManager().isRankBanned(getAccountId(event.getPlayer())))
{
String time = UtilTime.MakeStr(Manager.getEloManager().getRankBanExpiry(getAccountId(event.getPlayer())) - System.currentTimeMillis());
String message = ChatColor.RED + "You cannot join a ranked match yet because you left your last one early! Your ban expires in " + time;
event.disallow(Result.KICK_BANNED, message);
return;
}
if (MaxPlayers == -1)
return;
if (Bukkit.getOnlinePlayers().size() < MaxPlayers)
@ -115,7 +121,7 @@ public abstract class RankedTeamGame extends TeamGame
{
if (!Manager.IsObserver(event.getPlayer()))
{
Manager.getEloManager().banFromRanked(getAccountId(event.getPlayer()));
Manager.getEloManager().banFromRanked(getAccountId(event.getPlayer().getUniqueId()));
}
}
}