Revamped TFM_BanManager, TFM_Ban and TFM_ServerInterface

Better ban type checking
Moved ban reason compilation to TFM_Ban
TFM_ServerInterface: Less expensive operations first
Command_rollback now polls TFM_RollbackManager for available players
This commit is contained in:
unknown 2014-08-25 13:57:13 +02:00
parent ef9ce2a9a7
commit aca62caec1
8 changed files with 188 additions and 188 deletions

View File

@ -1,3 +1,3 @@
#Build Number for ANT. Do not edit! #Build Number for ANT. Do not edit!
#Sat Aug 02 16:25:24 CEST 2014 #Mon Aug 25 13:55:08 CEST 2014
build.number=920 build.number=923

View File

@ -16,16 +16,16 @@ public class Command_rollback extends TFM_Command
{ {
if (args.length == 1) if (args.length == 1)
{ {
if ("purgeall".equalsIgnoreCase(args[0])) if ("purgeall".equals(args[0]))
{ {
TFM_Util.adminAction(sender.getName(), "Purging all rollback history", false); TFM_Util.adminAction(sender.getName(), "Purging all rollback history", false);
playerMsg("Purged all rollback history for " + TFM_RollbackManager.purgeEntries() + " players."); playerMsg("Purged all rollback history for " + TFM_RollbackManager.purgeEntries() + " players.");
} }
else else
{ {
String playerName = getPlayerName(args[0]); final String playerName = TFM_RollbackManager.findPlayer(args[1]);
if (!TFM_RollbackManager.canRollback(playerName)) if (playerName == null)
{ {
playerMsg("That player has no entries stored."); playerMsg("That player has no entries stored.");
return true; return true;
@ -45,9 +45,9 @@ public class Command_rollback extends TFM_Command
{ {
if ("purge".equalsIgnoreCase(args[0])) if ("purge".equalsIgnoreCase(args[0]))
{ {
String playerName = getPlayerName(args[1]); final String playerName = TFM_RollbackManager.findPlayer(args[1]);
if (!TFM_RollbackManager.canRollback(playerName)) if (playerName == null)
{ {
playerMsg("That player has no entries stored."); playerMsg("That player has no entries stored.");
return true; return true;
@ -57,9 +57,9 @@ public class Command_rollback extends TFM_Command
} }
else if ("undo".equalsIgnoreCase(args[0])) else if ("undo".equalsIgnoreCase(args[0]))
{ {
String playerName = getPlayerName(args[1]); final String playerName = TFM_RollbackManager.findPlayer(args[1]);
if (!TFM_RollbackManager.canUndoRollback(playerName)) if (playerName == null)
{ {
playerMsg("That player hasn't been rolled back recently."); playerMsg("That player hasn't been rolled back recently.");
return true; return true;
@ -80,23 +80,4 @@ public class Command_rollback extends TFM_Command
return true; return true;
} }
private String getPlayerName(String playerNameInput)
{
String playerName = null;
final Player player = getPlayer(playerNameInput);
if (player != null)
{
playerName = player.getName();
}
if (playerName == null)
{
playerName = TFM_PlayerList.getEntry(playerNameInput).getLastLoginName();
}
return playerName;
}
} }

View File

@ -1,14 +1,19 @@
package me.StevenLawson.TotalFreedomMod; package me.StevenLawson.TotalFreedomMod;
import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.UUID; import java.util.UUID;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import me.StevenLawson.TotalFreedomMod.Config.TFM_ConfigEntry;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerLoginEvent;
public class TFM_Ban public class TFM_Ban
{ {
public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd \'at\' HH:mm:ss z");
public static final Pattern IP_BAN_REGEX; public static final Pattern IP_BAN_REGEX;
public static final Pattern UUID_BAN_REGEX; public static final Pattern UUID_BAN_REGEX;
@ -30,30 +35,37 @@ public class TFM_Ban
+ ":(\\d+)" + ":(\\d+)"
+ ":([\\s\\S]+)$"); + ":([\\s\\S]+)$");
} }
private boolean complete; private final BanType type;
private final boolean complete;
private String subject; // uuid or IP private String subject; // uuid or IP
private String lastLoginName; private String lastLoginName;
private String by; private String by;
private long expireUnix; private long expireUnix;
private String reason; private String reason;
public TFM_Ban(UUID uuid, String lastLoginName)
{
this(uuid, lastLoginName, null, null, null);
}
public TFM_Ban(String ip, String lastLoginName) public TFM_Ban(String ip, String lastLoginName)
{ {
this(ip, lastLoginName, null, null, null); this(ip, lastLoginName, null, null, null);
} }
public TFM_Ban(UUID uuid, String lastLoginName, String sender, Date expire, String reason) public TFM_Ban(String ip, String lastLoginName, String sender, Date expire, String reason)
{ {
this(uuid.toString(), lastLoginName, sender, expire, reason); this(ip, lastLoginName, sender, expire, reason, BanType.IP);
} }
public TFM_Ban(String subject, String lastLoginName, String sender, Date expire, String reason) public TFM_Ban(UUID uuid, String lastLoginName)
{ {
this(uuid, lastLoginName, null, null, null);
}
public TFM_Ban(UUID uuid, String lastLoginName, String sender, Date expire, String reason)
{
this(uuid.toString(), lastLoginName, sender, expire, reason, BanType.UUID);
}
private TFM_Ban(String subject, String lastLoginName, String sender, Date expire, String reason, BanType type)
{
this.type = type;
this.subject = subject; this.subject = subject;
this.lastLoginName = (lastLoginName == null ? "none" : lastLoginName); this.lastLoginName = (lastLoginName == null ? "none" : lastLoginName);
this.by = (sender == null ? "none" : sender); this.by = (sender == null ? "none" : sender);
@ -62,23 +74,15 @@ public class TFM_Ban
complete = true; complete = true;
} }
public TFM_Ban(String banString, boolean ip) public TFM_Ban(String banString, BanType type)
{ {
final Matcher matcher; this.type = type;
if (ip) final Matcher matcher = (type == BanType.IP ? IP_BAN_REGEX.matcher(banString) : UUID_BAN_REGEX.matcher(banString));
{
matcher = IP_BAN_REGEX.matcher(banString);
}
else
{
matcher = UUID_BAN_REGEX.matcher(banString);
}
complete = false;
if (!matcher.find()) if (!matcher.find())
{ {
complete = false;
return; return;
} }
@ -87,10 +91,20 @@ public class TFM_Ban
by = matcher.group(3); by = matcher.group(3);
expireUnix = Long.valueOf(matcher.group(4)); expireUnix = Long.valueOf(matcher.group(4));
reason = TFM_Util.colorize(matcher.group(5)); reason = TFM_Util.colorize(matcher.group(5));
complete = true; complete = true;
} }
public static enum BanType
{
IP,
UUID;
}
public BanType getType()
{
return type;
}
public String getSubject() public String getSubject()
{ {
return subject; return subject;
@ -126,6 +140,26 @@ public class TFM_Ban
return complete; return complete;
} }
public String getKickMessage()
{
final StringBuilder message = new StringBuilder("You");
message.append(type == BanType.IP ? "r IP address is" : " are").append(" temporarily banned from this server.");
message.append("\nAppeal at ").append(ChatColor.GOLD).append(TFM_ConfigEntry.SERVER_BAN_URL.getString());
if (!reason.equals("none"))
{
message.append("\nReason: ").append(reason);
}
if (getExpireUnix() != 0)
{
message.append("\nYour ban will be removed on ").append(DATE_FORMAT.format(TFM_Util.getUnixDate(expireUnix)));
}
return message.toString();
}
// subject:lastLoginName:bannedBy:expireUnix:reason // subject:lastLoginName:bannedBy:expireUnix:reason
@Override @Override
public String toString() public String toString()

View File

@ -7,6 +7,7 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import me.StevenLawson.TotalFreedomMod.Config.TFM_Config; import me.StevenLawson.TotalFreedomMod.Config.TFM_Config;
import me.StevenLawson.TotalFreedomMod.Config.TFM_ConfigEntry; import me.StevenLawson.TotalFreedomMod.Config.TFM_ConfigEntry;
import me.StevenLawson.TotalFreedomMod.TFM_Ban.BanType;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -42,7 +43,7 @@ public class TFM_BanManager
{ {
try try
{ {
addIpBan(new TFM_Ban(banString, true)); addIpBan(new TFM_Ban(banString, BanType.IP));
} }
catch (RuntimeException ex) catch (RuntimeException ex)
{ {
@ -54,7 +55,7 @@ public class TFM_BanManager
{ {
try try
{ {
addUuidBan(new TFM_Ban(banString, false)); addUuidBan(new TFM_Ban(banString, BanType.UUID));
} }
catch (RuntimeException ex) catch (RuntimeException ex)
{ {

View File

@ -114,7 +114,7 @@ public class TFM_CommandBlocker
} }
} }
TFM_Log.info("Loaded " + BLOCKED_COMMANDS.size() + " blocked commands."); TFM_Log.info("Loaded " + BLOCKED_COMMANDS.size() + " blocked commands");
} }
public static boolean isCommandBlocked(String command, CommandSender sender) public static boolean isCommandBlocked(String command, CommandSender sender)

View File

@ -13,7 +13,7 @@ import org.bukkit.entity.Player;
public class TFM_PlayerList public class TFM_PlayerList
{ {
private static final Map<UUID, TFM_Player> playerList; private static final Map<UUID, TFM_Player> playerList = new HashMap<UUID, TFM_Player>();
private TFM_PlayerList() private TFM_PlayerList()
{ {
@ -40,7 +40,7 @@ public class TFM_PlayerList
timer.update(); timer.update();
TFM_Log.info("Loaded playerdata for " + playerList.size() + " players in " + timer.getTotal() + " ms."); TFM_Log.info("Loaded playerdata for " + playerList.size() + " players in " + timer.getTotal() + " ms");
} }
public static void saveAll() public static void saveAll()
@ -51,20 +51,6 @@ public class TFM_PlayerList
} }
} }
@Deprecated
private static TFM_Player getEntry(String player)
{
for (TFM_Player entry : playerList.values())
{
if (entry.getLastLoginName().equalsIgnoreCase(player))
{
return entry;
}
}
return null;
}
// May return null // May return null
public static TFM_Player getEntry(UUID uuid) public static TFM_Player getEntry(UUID uuid)
{ {

View File

@ -43,6 +43,30 @@ public class TFM_RollbackManager
} }
} }
// May return null
public static String findPlayer(String partial)
{
partial = partial.toLowerCase();
for (String player : PLAYER_HISTORY.keySet())
{
if (player.toLowerCase().equals(partial))
{
return player;
}
}
for (String player : PLAYER_HISTORY.keySet())
{
if (player.toLowerCase().contains(partial))
{
return player;
}
}
return null;
}
public static int purgeEntries() public static int purgeEntries()
{ {
Iterator<List<RollbackEntry>> it = PLAYER_HISTORY.values().iterator(); Iterator<List<RollbackEntry>> it = PLAYER_HISTORY.values().iterator();
@ -240,7 +264,7 @@ public class TFM_RollbackManager
{ {
try try
{ {
return new Location(Bukkit.getWorld(worldName), (double) x, (double) y, (double) z); return new Location(Bukkit.getWorld(worldName), x, (int) y, z);
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -18,7 +18,6 @@ public class TFM_ServerInterface
{ {
public static final String COMPILE_NMS_VERSION = "v1_7_R3"; public static final String COMPILE_NMS_VERSION = "v1_7_R3";
public static final Pattern USERNAME_REGEX = Pattern.compile("^[\\w\\d_]{3,20}$"); public static final Pattern USERNAME_REGEX = Pattern.compile("^[\\w\\d_]{3,20}$");
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd \'at\' HH:mm:ss z");
public static void setOnlineMode(boolean mode) public static void setOnlineMode(boolean mode)
{ {
@ -66,13 +65,12 @@ public class TFM_ServerInterface
public static void handlePlayerLogin(PlayerLoginEvent event) public static void handlePlayerLogin(PlayerLoginEvent event)
{ {
final Server server = TotalFreedomMod.server; final Server server = TotalFreedomMod.server;
final Player player = event.getPlayer(); final Player player = event.getPlayer();
final String username = player.getName(); final String username = player.getName();
final UUID uuid = TFM_Util.getUniqueId(username); final UUID uuid = TFM_Util.getUniqueId(username);
final String ip = event.getAddress().getHostAddress().trim(); final String ip = event.getAddress().getHostAddress().trim();
// Perform username checks
if (username.length() < 3 || username.length() > 20) if (username.length() < 3 || username.length() > 20)
{ {
event.disallow(Result.KICK_OTHER, "Your username is an invalid length (must be between 3 and 20 characters long)."); event.disallow(Result.KICK_OTHER, "Your username is an invalid length (must be between 3 and 20 characters long).");
@ -81,11 +79,12 @@ public class TFM_ServerInterface
if (!USERNAME_REGEX.matcher(username).find()) if (!USERNAME_REGEX.matcher(username).find())
{ {
event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "Your username contains invalid characters."); event.disallow(Result.KICK_OTHER, "Your username contains invalid characters.");
return; return;
} }
// not safe to use TFM_Util.isSuperAdmin for player logging in because player.getAddress() will return a null until after player login. // Check if player is admin
// Not safe to use TFM_Util.isSuperAdmin for player logging in because player.getAddress() will return a null until after player login.
final boolean isAdmin; final boolean isAdmin;
if (server.getOnlineMode()) if (server.getOnlineMode())
{ {
@ -98,119 +97,9 @@ public class TFM_ServerInterface
} }
// Validation below this point // Validation below this point
if (!isAdmin) // If the player is not an admin if (isAdmin) // Player is superadmin
{ {
// UUID bans // force-allow log in
if (TFM_BanManager.isUuidBanned(uuid))
{
final TFM_Ban ban = TFM_BanManager.getByUuid(uuid);
String kickMessage = ChatColor.RED + "You are temporarily banned from this server."
+ "\nAppeal at " + ChatColor.GOLD + TFM_ConfigEntry.SERVER_BAN_URL.getString();
if (!ban.getReason().equals("none"))
{
kickMessage = kickMessage + "\nReason: " + ban.getReason();
}
if (ban.getExpireUnix() != 0)
{
kickMessage = kickMessage + "\nYour ban will be removed on " + dateFormat.format(TFM_Util.getUnixDate(ban.getExpireUnix()));
}
event.disallow(Result.KICK_OTHER, kickMessage);
return;
}
if (TFM_BanManager.isIpBanned(ip))
{
final TFM_Ban ban = TFM_BanManager.getByIp(ip);
String kickMessage = ChatColor.RED + "Your IP address is temporarily banned from this server."
+ "\nAppeal at " + ChatColor.GOLD + TFM_ConfigEntry.SERVER_BAN_URL.getString();
if (!ban.getReason().equals("none"))
{
kickMessage = kickMessage + "\nReason: " + ban.getReason();
}
if (ban.getExpireUnix() != 0)
{
kickMessage = kickMessage + "\nYour ban will be removed on " + dateFormat.format(TFM_Util.getUnixDate(ban.getExpireUnix()));
}
event.disallow(Result.KICK_OTHER, kickMessage);
return;
}
// Permbanned Ips
for (String testIp : TFM_PermbanList.getPermbannedIps())
{
if (TFM_Util.fuzzyIpMatch(testIp, ip, 4))
{
event.disallow(Result.KICK_OTHER,
ChatColor.RED + "Your IP address is permanently banned from this server.\nRelease procedures are available at\n"
+ ChatColor.GOLD + TFM_ConfigEntry.SERVER_PERMBAN_URL.getString());
return;
}
}
// Permbanned names
for (String testPlayer : TFM_PermbanList.getPermbannedPlayers())
{
if (testPlayer.equalsIgnoreCase(username))
{
event.disallow(Result.KICK_OTHER,
ChatColor.RED + "Your username is permanently banned from this server.\nRelease procedures are available at\n"
+ ChatColor.GOLD + TFM_ConfigEntry.SERVER_PERMBAN_URL.getString());
return;
}
}
// Server full check
if (server.getOnlinePlayers().length >= server.getMaxPlayers())
{
event.disallow(PlayerLoginEvent.Result.KICK_FULL, "Sorry, but this server is full.");
return;
}
// Admin-only mode
if (TFM_ConfigEntry.ADMIN_ONLY_MODE.getBoolean())
{
event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "Server is temporarily open to admins only.");
return;
}
// Lockdown mode
if (TotalFreedomMod.lockdownEnabled)
{
event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "Server is currently in lockdown mode.");
return;
}
// Whitelist check
if (isWhitelisted())
{
if (!getWhitelisted().contains(username.toLowerCase()))
{
event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "You are not whitelisted on this server.");
return;
}
}
// Username already logged in check
for (Player onlinePlayer : server.getOnlinePlayers())
{
if (onlinePlayer.getName().equalsIgnoreCase(username))
{
event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "Your username is already logged into this server.");
return;
}
}
}
else // Player is superadmin
{
// force-allow superadmins to log in
event.allow(); event.allow();
for (Player onlinePlayer : server.getOnlinePlayers()) for (Player onlinePlayer : server.getOnlinePlayers())
@ -241,10 +130,95 @@ public class TFM_ServerInterface
if (count >= server.getMaxPlayers()) if (count >= server.getMaxPlayers())
{ {
event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "The server is full and a player could not be kicked, sorry!"); event.disallow(Result.KICK_OTHER, "The server is full and a player could not be kicked, sorry!");
return; return;
} }
return;
}
// Player is not an admin
// Server full check
if (server.getOnlinePlayers().length >= server.getMaxPlayers())
{
event.disallow(Result.KICK_FULL, "Sorry, but this server is full.");
return;
}
// Admin-only mode
if (TFM_ConfigEntry.ADMIN_ONLY_MODE.getBoolean())
{
event.disallow(Result.KICK_OTHER, "Server is temporarily open to admins only.");
return;
}
// Lockdown mode
if (TotalFreedomMod.lockdownEnabled)
{
event.disallow(Result.KICK_OTHER, "Server is currently in lockdown mode.");
return;
}
// Username already logged in
for (Player onlinePlayer : server.getOnlinePlayers())
{
if (onlinePlayer.getName().equalsIgnoreCase(username))
{
event.disallow(Result.KICK_OTHER, "Your username is already logged into this server.");
return;
}
}
// Whitelist
if (isWhitelisted())
{
if (!getWhitelisted().contains(username.toLowerCase()))
{
event.disallow(Result.KICK_OTHER, "You are not whitelisted on this server.");
return;
}
}
// UUID ban
if (TFM_BanManager.isUuidBanned(uuid))
{
final TFM_Ban ban = TFM_BanManager.getByUuid(uuid);
event.disallow(Result.KICK_OTHER, ban.getKickMessage());
return;
}
// IP ban
if (TFM_BanManager.isIpBanned(ip))
{
final TFM_Ban ban = TFM_BanManager.getByIp(ip);
event.disallow(Result.KICK_OTHER, ban.getKickMessage());
return;
}
// Permbanned IPs
for (String testIp : TFM_PermbanList.getPermbannedIps())
{
if (TFM_Util.fuzzyIpMatch(testIp, ip, 4))
{
event.disallow(Result.KICK_OTHER,
ChatColor.RED + "Your IP address is permanently banned from this server.\n"
+ "Release procedures are available at\n"
+ ChatColor.GOLD + TFM_ConfigEntry.SERVER_PERMBAN_URL.getString());
return;
}
}
// Permbanned usernames
for (String testPlayer : TFM_PermbanList.getPermbannedPlayers())
{
if (testPlayer.equalsIgnoreCase(username))
{
event.disallow(Result.KICK_OTHER,
ChatColor.RED + "Your username is permanently banned from this server.\n"
+ "Release procedures are available at\n"
+ ChatColor.GOLD + TFM_ConfigEntry.SERVER_PERMBAN_URL.getString());
return;
}
} }
} }
} }