Add temp banning, remove /ban clear, fix temp ban check

This commit is contained in:
MarioE 2013-11-10 23:03:12 -05:00
parent 6a4e7584a0
commit ebc36a5ada
4 changed files with 258 additions and 282 deletions

View file

@ -598,47 +598,36 @@ namespace TShockAPI
{
char c = str[i];
if (instr)
if (c == '\\' && ++i < str.Length)
{
if (c == '\\')
{
if (i + 1 >= str.Length)
break;
c = GetEscape(str[++i]);
}
else if (c == '"')
if (str[i] != '"' && str[i] != ' ' && str[i] != '\\')
sb.Append('\\');
sb.Append(str[i]);
}
else if (c == '"')
{
instr = !instr;
if (!instr)
{
ret.Add(sb.ToString());
sb.Clear();
}
else if (sb.Length > 0)
{
ret.Add(sb.ToString());
sb.Clear();
}
}
else if (IsWhiteSpace(c))
{
if (sb.Length > 0)
{
ret.Add(sb.ToString());
sb.Clear();
instr = false;
continue;
}
sb.Append(c);
}
else
{
if (IsWhiteSpace(c))
{
if (sb.Length > 0)
{
ret.Add(sb.ToString());
sb.Clear();
}
}
else if (c == '"')
{
if (sb.Length > 0)
{
ret.Add(sb.ToString());
sb.Clear();
}
instr = true;
}
else
{
sb.Append(c);
}
}
sb.Append(c);
}
if (sb.Length > 0)
ret.Add(sb.ToString());
@ -1091,260 +1080,200 @@ namespace TShockAPI
args.Player.SendInfoMessage("In addition, a reason may be provided for all new bans after the arguments.");
return;
}
if (args.Parameters[0].ToLower() == "list")
string subcmd = args.Parameters[0].ToLower();
switch (subcmd)
{
#region List bans
if (TShock.Bans.GetBans().Count == 0)
{
args.Player.SendErrorMessage("There are currently no players banned.");
return;
}
string banString = "";
foreach (Ban b in TShock.Bans.GetBans())
{
if (b.Name.Trim() == "")
case "add":
{
continue;
}
if (banString.Length == 0)
{
banString = b.Name;
}
else
{
int length = banString.Length;
while (length > 60)
#region Add ban
if (args.Parameters.Count < 2)
{
length = length - 60;
}
if (length + b.Name.Length >= 60)
{
banString += "|, " + b.Name;
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: /ban add <player> [reason]");
return;
}
List<TSPlayer> players = TShock.Utils.FindPlayer(args.Parameters[1]);
if (players.Count == 0)
args.Player.SendErrorMessage("Invalid player!");
else if (players.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
else
{
banString += ", " + b.Name;
string reason = args.Parameters.Count > 2
? String.Join(" ", args.Parameters.GetRange(2, args.Parameters.Count - 2))
: "Misbehavior.";
if (!TShock.Utils.Ban(players[0], reason, !args.Player.RealPlayer, args.Player.UserAccountName))
args.Player.SendErrorMessage("You can't ban {0}!", players[0].Name);
}
#endregion
}
}
String[] banStrings = banString.Split('|');
if (banStrings.Length == 0)
{
args.Player.SendErrorMessage("There are currently no players with valid names banned.");
return;
}
if (banStrings[0].Trim() == "")
{
args.Player.SendErrorMessage("There are currently no bans with valid names found.");
return;
}
args.Player.SendInfoMessage("List of banned players:");
foreach (string s in banStrings)
{
args.Player.SendInfoMessage(s);
}
return;
#endregion List bans
}
if (args.Parameters[0].ToLower() == "listip")
{
#region List ip bans
if (TShock.Bans.GetBans().Count == 0)
{
args.Player.SendWarningMessage("There are currently no players banned.");
return;
}
string banString = "";
foreach (Ban b in TShock.Bans.GetBans())
{
if (b.IP.Trim() == "")
case "addip":
{
continue;
}
if (banString.Length == 0)
{
banString = b.IP;
}
else
{
int length = banString.Length;
while (length > 60)
#region Add IP ban
if (args.Parameters.Count < 2)
{
length = length - 60;
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: /ban addip <ip> [reason]");
return;
}
if (length + b.Name.Length >= 60)
{
banString += "|, " + b.IP;
}
else
{
banString += ", " + b.IP;
}
}
}
String[] banStrings = banString.Split('|');
if (banStrings.Length == 0)
{
args.Player.SendErrorMessage("There are currently no players with valid IPs banned.");
return;
}
if (banStrings[0].Trim() == "")
{
args.Player.SendErrorMessage("There are currently no bans with valid IPs found.");
return;
}
args.Player.SendInfoMessage("List of IP banned players:");
foreach (string s in banStrings)
{
args.Player.SendInfoMessage(s);
}
return;
#endregion List ip bans
}
if (args.Parameters.Count >= 2)
{
if (args.Parameters[0].ToLower() == "add")
{
#region Add ban
string plStr = args.Parameters[1];
var players = TShock.Utils.FindPlayer(plStr);
if (players.Count == 0)
{
args.Player.SendErrorMessage("Invalid player!");
}
else if (players.Count > 1)
{
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
}
else
{
string ip = args.Parameters[1];
string reason = args.Parameters.Count > 2
? String.Join(" ", args.Parameters.GetRange(2, args.Parameters.Count - 2))
: "Misbehavior.";
if (!TShock.Utils.Ban(players[0], reason, !args.Player.RealPlayer, args.Player.UserAccountName))
: "Manually added IP address ban.";
TShock.Bans.AddBan(ip, "", "", reason, false, args.Player.UserAccountName);
args.Player.SendSuccessMessage("Banned IP {0}.", ip);
#endregion
}
return;
case "addtemp":
{
#region Add temp ban
if (args.Parameters.Count < 3)
{
args.Player.SendErrorMessage("You can't ban another admin!");
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: /ban addtemp <player> <time> [reason]");
return;
}
}
return;
#endregion Add ban
}
else if (args.Parameters[0].ToLower() == "addip")
{
#region Add ip ban
string ip = args.Parameters[1];
string reason = args.Parameters.Count > 2
? String.Join(" ", args.Parameters.GetRange(2, args.Parameters.Count - 2))
: "Manually added IP address ban.";
TShock.Bans.AddBan(ip, "", "", reason, false, args.Player.UserAccountName);
args.Player.SendSuccessMessage(ip + " banned.");
return;
#endregion Add ip ban
}
else if (args.Parameters[0].ToLower() == "delip")
{
#region Delete ip ban
var ip = args.Parameters[1];
var ban = TShock.Bans.GetBanByIp(ip);
if (ban != null)
{
if (TShock.Bans.RemoveBan(ban.IP))
args.Player.SendSuccessMessage(string.Format("Unbanned {0} ({1})!", ban.Name, ban.IP));
else
args.Player.SendErrorMessage(string.Format("Failed to unban {0} ({1})!", ban.Name, ban.IP));
}
else
{
args.Player.SendErrorMessage(string.Format("No bans for ip {0} exist", ip));
}
return;
#endregion Delete ip ban
}
else if (args.Parameters[0].ToLower() == "del")
{
#region Delete ban
string plStr = args.Parameters[1];
var ban = TShock.Bans.GetBanByName(plStr, false);
if (ban != null)
{
if (TShock.Bans.RemoveBan(ban.Name, true))
args.Player.SendSuccessMessage(string.Format("Unbanned {0} ({1})!", ban.Name, ban.IP));
else
args.Player.SendErrorMessage(string.Format("Failed to unban {0} ({1})!", ban.Name, ban.IP));
}
else
{
args.Player.SendErrorMessage(string.Format("No bans for player {0} exist", plStr));
}
return;
#endregion Delete ban
}
#region Clear bans
if (args.Parameters[0].ToLower() == "clear")
{
if (args.Parameters.Count < 1 && ClearBansCode == -1)
{
ClearBansCode = new Random().Next(0, short.MaxValue);
args.Player.SendInfoMessage("ClearBans Code: " + ClearBansCode);
return;
}
if (args.Parameters.Count < 1)
{
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: /ban clear <code>");
return;
}
int num;
if (!int.TryParse(args.Parameters[1], out num))
{
args.Player.SendErrorMessage("Invalid syntax! Expected a number, didn't get one.");
return;
}
if (num == ClearBansCode)
{
ClearBansCode = -1;
if (TShock.Bans.ClearBans())
{
Log.ConsoleInfo("Bans cleared.");
args.Player.SendSuccessMessage("Bans cleared.");
}
List<TSPlayer> players = TShock.Utils.FindPlayer(args.Parameters[1]);
if (players.Count == 0)
args.Player.SendErrorMessage("Invalid player!");
else if (players.Count > 1)
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
else
{
args.Player.SendErrorMessage("Failed to clear bans.");
int time;
if (!TShock.Utils.TryParseTime(args.Parameters[2], out time))
{
args.Player.SendErrorMessage("Invalid time string! Proper format: 0d0h0m0s, with at least one time specifier.");
return;
}
string reason = args.Parameters.Count > 3
? String.Join(" ", args.Parameters.GetRange(3, args.Parameters.Count - 3))
: "Misbehavior.";
if (args.Player.RealPlayer && players[0].Group.HasPermission(Permissions.immunetoban))
{
args.Player.SendErrorMessage("You can't ban {0}!", players[0].Name);
return;
}
if (TShock.Bans.AddBan(players[0].IP, players[0].Name, players[0].UUID, reason,
false, args.Player.Name, DateTime.UtcNow.AddSeconds(time).ToString("s")))
{
players[0].Disconnect(String.Format("Banned: {0}", reason));
Log.ConsoleInfo("Banned {0} for : '{1}'", players[0].Name, reason);
string verb = args.Player.RealPlayer ? "force " : "";
if (args.Player.RealPlayer)
TSPlayer.All.SendSuccessMessage("{0} {1}banned {2} for '{3}'", args.Player.Name, verb, players[0].Name, reason);
else
TSPlayer.All.SendSuccessMessage("{0} was {1}banned for '{2}'", players[0].Name, verb, reason);
}
else
args.Player.SendErrorMessage("Failed to ban {0}, check logs.", players[0].Name);
}
#endregion
}
else
return;
case "del":
{
args.Player.SendErrorMessage("Incorrect clear code.");
#region Delete ban
string plStr = args.Parameters[1];
Ban ban = TShock.Bans.GetBanByName(plStr, false);
if (ban != null)
{
if (TShock.Bans.RemoveBan(ban.Name, true))
args.Player.SendSuccessMessage("Unbanned {0} ({1}).", ban.Name, ban.IP);
else
args.Player.SendErrorMessage("Failed to unban {0} ({1}), check logs.", ban.Name, ban.IP);
}
else
args.Player.SendErrorMessage("No bans for {0} exist.", plStr);
#endregion
}
}
return;
#endregion Clear bans
return;
case "delip":
{
#region Delete IP ban
if (args.Parameters.Count != 2)
{
args.Player.SendErrorMessage("Invalid syntax! Proper syntax: /ban delip <ip>");
return;
}
string ip = args.Parameters[1];
Ban ban = TShock.Bans.GetBanByIp(ip);
if (ban != null)
{
if (TShock.Bans.RemoveBan(ban.IP, false))
args.Player.SendSuccessMessage("Unbanned IP {0} ({1}).", ban.IP, ban.Name);
else
args.Player.SendErrorMessage("Failed to unban IP {0} ({1}), check logs.", ban.IP, ban.Name);
}
else
args.Player.SendErrorMessage("IP {0} is not banned.", ip);
#endregion
}
return;
case "list":
{
#region List bans
int pageNumber;
if (!PaginationTools.TryParsePageNumber(args.Parameters, 1, args.Player, out pageNumber))
{
return;
}
List<Ban> bans = TShock.Bans.GetBans();
var nameBans = from ban in bans
where !String.IsNullOrEmpty(ban.Name)
select ban.Name;
PaginationTools.SendPage(args.Player, pageNumber, PaginationTools.BuildLinesFromTerms(nameBans),
new PaginationTools.Settings
{
HeaderFormat = "Bans ({0}/{1}):",
FooterFormat = "Type /ban list {0} for more.",
NothingToDisplayString = "There are currently no bans."
});
#endregion
}
return;
case "listip":
{
#region List IP bans
int pageNumber;
if (!PaginationTools.TryParsePageNumber(args.Parameters, 1, args.Player, out pageNumber))
{
return;
}
List<Ban> bans = TShock.Bans.GetBans();
var ipBans = from ban in bans
where String.IsNullOrEmpty(ban.Name)
select ban.IP;
PaginationTools.SendPage(args.Player, pageNumber, PaginationTools.BuildLinesFromTerms(ipBans),
new PaginationTools.Settings
{
HeaderFormat = "IP Bans ({0}/{1}):",
FooterFormat = "Type /ban listip {0} for more.",
NothingToDisplayString = "There are currently no IP bans."
});
#endregion
}
return;
default:
args.Player.SendErrorMessage("Invalid subcommand! Type /ban help for more information.");
return;
}
args.Player.SendErrorMessage("Invalid syntax or old command provided.");
args.Player.SendErrorMessage("Type /ban help for more information.");
}
private static int ClearBansCode = -1;
private static void Whitelist(CommandArgs args)
{
if (args.Parameters.Count == 1)

View file

@ -55,6 +55,11 @@ namespace TShockAPI.DB
}
}
/// <summary>
/// Gets a ban by IP.
/// </summary>
/// <param name="ip">The IP.</param>
/// <returns>The ban.</returns>
public Ban GetBanByIp(string ip)
{
try
@ -72,6 +77,9 @@ namespace TShockAPI.DB
return null;
}
/// <summary>
/// Gets a list of bans.
/// </summary>
public List<Ban> GetBans()
{
List<Ban> banlist = new List<Ban>();
@ -94,6 +102,12 @@ namespace TShockAPI.DB
return null;
}
/// <summary>
/// Gets a ban by name.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="casesensitive">Whether to check with case sensitivity.</param>
/// <returns>The ban.</returns>
public Ban GetBanByName(string name, bool casesensitive = true)
{
try
@ -114,6 +128,11 @@ namespace TShockAPI.DB
return null;
}
/// <summary>
/// Gets a ban by UUID.
/// </summary>
/// <param name="uuid">The UUID.</param>
/// <returns>The ban.</returns>
public Ban GetBanByUUID(string uuid)
{
try
@ -138,7 +157,7 @@ namespace TShockAPI.DB
return AddBan(ip, name, "", reason, false, "", "");
}
#endif
public bool AddBan(string ip, string name = "", string uuid = "", string reason = "", bool exceptions = false, string banner = "", string expiration = "")
public bool AddBan(string ip, string name = "", string uuid = "", string reason = "", bool exceptions = false, string banner = "", string expiration = "")
{
try
{

View file

@ -887,23 +887,6 @@ namespace TShockAPI
return;
}
var ipban = Bans.GetBanByIp(player.IP);
Ban ban = null;
if (ipban != null && Config.EnableIPBans)
ban = ipban;
if (ban != null)
{
if (!Utils.HasBanExpired(ban))
{
DateTime exp;
string duration = DateTime.TryParse(ban.Expiration, out exp) ? String.Format("until {0}", exp.ToString("G")) : "forever";
Utils.ForceKick(player, string.Format("You are banned {0}: {1}", duration, ban.Reason), true, false);
args.Handled = true;
return;
}
}
if (!FileTools.OnWhitelist(player.IP))
{
Utils.ForceKick(player, Config.WhitelistKickReason, true, false);
@ -939,7 +922,9 @@ namespace TShockAPI
if (Config.KickEmptyUUID && String.IsNullOrWhiteSpace(player.UUID))
{
Utils.ForceKick(player, "Your client did not send a UUID, this server is not configured to accept such a client");
Utils.ForceKick(player, "Your client did not send a UUID, this server is not configured to accept such a client.", true);
args.Handled = true;
return;
}
Ban ban = null;
@ -974,7 +959,6 @@ namespace TShockAPI
private void OnLeave(LeaveEventArgs args)
{
var tsplr = Players[args.Who];
Players[args.Who] = null;

View file

@ -698,7 +698,7 @@ namespace TShockAPI
bool expirationExists = DateTime.TryParse(ban.Expiration, out exp);
if (!string.IsNullOrWhiteSpace(ban.Expiration) && (expirationExists) &&
(DateTime.Now >= exp))
(DateTime.UtcNow >= exp))
{
if (byName)
{
@ -880,6 +880,50 @@ namespace TShockAPI
return true;
}
/// <summary>
/// Attempts to parse a string as a timespan (_d_m_h_s).
/// </summary>
/// <param name="time">The time string.</param>
/// <param name="seconds">The seconds.</param>
/// <returns>Whether the string was parsed successfully.</returns>
public bool TryParseTime(string str, out int seconds)
{
seconds = 0;
var sb = new StringBuilder(3);
for (int i = 0; i < str.Length; i++)
{
if (char.IsDigit(str[i]) || (str[i] == '-' || str[i] == '+'))
sb.Append(str[i]);
else
{
int num;
if (!int.TryParse(sb.ToString(), out num))
return false;
sb.Clear();
switch (str[i])
{
case 's':
seconds += num;
break;
case 'm':
seconds += num * 60;
break;
case 'h':
seconds += num * 60 * 60;
break;
case 'd':
seconds += num * 60 * 60 * 24;
break;
default:
return false;
}
}
}
return true;
}
/// <summary>
/// Searches for a projectile by identity and owner
/// </summary>