mirror of
https://github.com/AtlasMediaGroup/TotalFreedomMod.git
synced 2024-11-27 01:05:38 +00:00
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:
parent
ef9ce2a9a7
commit
aca62caec1
@ -1,3 +1,3 @@
|
||||
#Build Number for ANT. Do not edit!
|
||||
#Sat Aug 02 16:25:24 CEST 2014
|
||||
build.number=920
|
||||
#Mon Aug 25 13:55:08 CEST 2014
|
||||
build.number=923
|
||||
|
@ -16,16 +16,16 @@ public class Command_rollback extends TFM_Command
|
||||
{
|
||||
if (args.length == 1)
|
||||
{
|
||||
if ("purgeall".equalsIgnoreCase(args[0]))
|
||||
if ("purgeall".equals(args[0]))
|
||||
{
|
||||
TFM_Util.adminAction(sender.getName(), "Purging all rollback history", false);
|
||||
playerMsg("Purged all rollback history for " + TFM_RollbackManager.purgeEntries() + " players.");
|
||||
}
|
||||
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.");
|
||||
return true;
|
||||
@ -45,9 +45,9 @@ public class Command_rollback extends TFM_Command
|
||||
{
|
||||
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.");
|
||||
return true;
|
||||
@ -57,9 +57,9 @@ public class Command_rollback extends TFM_Command
|
||||
}
|
||||
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.");
|
||||
return true;
|
||||
@ -80,23 +80,4 @@ public class Command_rollback extends TFM_Command
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,19 @@
|
||||
package me.StevenLawson.TotalFreedomMod;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import me.StevenLawson.TotalFreedomMod.Config.TFM_ConfigEntry;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
|
||||
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 UUID_BAN_REGEX;
|
||||
|
||||
@ -30,30 +35,37 @@ public class TFM_Ban
|
||||
+ ":(\\d+)"
|
||||
+ ":([\\s\\S]+)$");
|
||||
}
|
||||
private boolean complete;
|
||||
private final BanType type;
|
||||
private final boolean complete;
|
||||
private String subject; // uuid or IP
|
||||
private String lastLoginName;
|
||||
private String by;
|
||||
private long expireUnix;
|
||||
private String reason;
|
||||
|
||||
public TFM_Ban(UUID uuid, String lastLoginName)
|
||||
{
|
||||
this(uuid, lastLoginName, null, null, null);
|
||||
}
|
||||
|
||||
public TFM_Ban(String ip, String lastLoginName)
|
||||
{
|
||||
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.lastLoginName = (lastLoginName == null ? "none" : lastLoginName);
|
||||
this.by = (sender == null ? "none" : sender);
|
||||
@ -62,23 +74,15 @@ public class TFM_Ban
|
||||
complete = true;
|
||||
}
|
||||
|
||||
public TFM_Ban(String banString, boolean ip)
|
||||
public TFM_Ban(String banString, BanType type)
|
||||
{
|
||||
final Matcher matcher;
|
||||
this.type = type;
|
||||
|
||||
if (ip)
|
||||
{
|
||||
matcher = IP_BAN_REGEX.matcher(banString);
|
||||
}
|
||||
else
|
||||
{
|
||||
matcher = UUID_BAN_REGEX.matcher(banString);
|
||||
}
|
||||
|
||||
complete = false;
|
||||
final Matcher matcher = (type == BanType.IP ? IP_BAN_REGEX.matcher(banString) : UUID_BAN_REGEX.matcher(banString));
|
||||
|
||||
if (!matcher.find())
|
||||
{
|
||||
complete = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -87,10 +91,20 @@ public class TFM_Ban
|
||||
by = matcher.group(3);
|
||||
expireUnix = Long.valueOf(matcher.group(4));
|
||||
reason = TFM_Util.colorize(matcher.group(5));
|
||||
|
||||
complete = true;
|
||||
}
|
||||
|
||||
public static enum BanType
|
||||
{
|
||||
IP,
|
||||
UUID;
|
||||
}
|
||||
|
||||
public BanType getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getSubject()
|
||||
{
|
||||
return subject;
|
||||
@ -126,6 +140,26 @@ public class TFM_Ban
|
||||
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
|
||||
@Override
|
||||
public String toString()
|
||||
|
@ -7,6 +7,7 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
import me.StevenLawson.TotalFreedomMod.Config.TFM_Config;
|
||||
import me.StevenLawson.TotalFreedomMod.Config.TFM_ConfigEntry;
|
||||
import me.StevenLawson.TotalFreedomMod.TFM_Ban.BanType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -42,7 +43,7 @@ public class TFM_BanManager
|
||||
{
|
||||
try
|
||||
{
|
||||
addIpBan(new TFM_Ban(banString, true));
|
||||
addIpBan(new TFM_Ban(banString, BanType.IP));
|
||||
}
|
||||
catch (RuntimeException ex)
|
||||
{
|
||||
@ -54,7 +55,7 @@ public class TFM_BanManager
|
||||
{
|
||||
try
|
||||
{
|
||||
addUuidBan(new TFM_Ban(banString, false));
|
||||
addUuidBan(new TFM_Ban(banString, BanType.UUID));
|
||||
}
|
||||
catch (RuntimeException ex)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -13,7 +13,7 @@ import org.bukkit.entity.Player;
|
||||
|
||||
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()
|
||||
{
|
||||
@ -40,7 +40,7 @@ public class TFM_PlayerList
|
||||
|
||||
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()
|
||||
@ -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
|
||||
public static TFM_Player getEntry(UUID uuid)
|
||||
{
|
||||
|
@ -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()
|
||||
{
|
||||
Iterator<List<RollbackEntry>> it = PLAYER_HISTORY.values().iterator();
|
||||
@ -240,7 +264,7 @@ public class TFM_RollbackManager
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -18,7 +18,6 @@ public class TFM_ServerInterface
|
||||
{
|
||||
public static final String COMPILE_NMS_VERSION = "v1_7_R3";
|
||||
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)
|
||||
{
|
||||
@ -66,13 +65,12 @@ public class TFM_ServerInterface
|
||||
public static void handlePlayerLogin(PlayerLoginEvent event)
|
||||
{
|
||||
final Server server = TotalFreedomMod.server;
|
||||
|
||||
final Player player = event.getPlayer();
|
||||
|
||||
final String username = player.getName();
|
||||
final UUID uuid = TFM_Util.getUniqueId(username);
|
||||
final String ip = event.getAddress().getHostAddress().trim();
|
||||
|
||||
// Perform username checks
|
||||
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).");
|
||||
@ -81,11 +79,12 @@ public class TFM_ServerInterface
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
if (server.getOnlineMode())
|
||||
{
|
||||
@ -98,119 +97,9 @@ public class TFM_ServerInterface
|
||||
}
|
||||
|
||||
// Validation below this point
|
||||
if (!isAdmin) // If the player is not an admin
|
||||
if (isAdmin) // Player is superadmin
|
||||
{
|
||||
// UUID bans
|
||||
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
|
||||
// force-allow log in
|
||||
event.allow();
|
||||
|
||||
for (Player onlinePlayer : server.getOnlinePlayers())
|
||||
@ -241,10 +130,95 @@ public class TFM_ServerInterface
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user