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]; char c = str[i];
if (instr) if (c == '\\' && ++i < str.Length)
{ {
if (c == '\\') if (str[i] != '"' && str[i] != ' ' && str[i] != '\\')
{ sb.Append('\\');
if (i + 1 >= str.Length) sb.Append(str[i]);
break; }
c = GetEscape(str[++i]); else if (c == '"')
} {
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()); ret.Add(sb.ToString());
sb.Clear(); sb.Clear();
instr = false;
continue;
} }
sb.Append(c);
} }
else else
{ sb.Append(c);
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);
}
}
} }
if (sb.Length > 0) if (sb.Length > 0)
ret.Add(sb.ToString()); 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."); args.Player.SendInfoMessage("In addition, a reason may be provided for all new bans after the arguments.");
return; return;
} }
if (args.Parameters[0].ToLower() == "list")
string subcmd = args.Parameters[0].ToLower();
switch (subcmd)
{ {
#region List bans case "add":
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() == "")
{ {
continue; #region Add ban
} if (args.Parameters.Count < 2)
if (banString.Length == 0)
{
banString = b.Name;
}
else
{
int length = banString.Length;
while (length > 60)
{ {
length = length - 60; args.Player.SendErrorMessage("Invalid syntax! Proper syntax: /ban add <player> [reason]");
} return;
if (length + b.Name.Length >= 60)
{
banString += "|, " + b.Name;
} }
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 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; return;
} case "addip":
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() == "")
{ {
continue; #region Add IP ban
} if (args.Parameters.Count < 2)
if (banString.Length == 0)
{
banString = b.IP;
}
else
{
int length = banString.Length;
while (length > 60)
{ {
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('|'); string ip = args.Parameters[1];
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 reason = args.Parameters.Count > 2 string reason = args.Parameters.Count > 2
? String.Join(" ", args.Parameters.GetRange(2, args.Parameters.Count - 2)) ? String.Join(" ", args.Parameters.GetRange(2, args.Parameters.Count - 2))
: "Misbehavior."; : "Manually added IP address ban.";
if (!TShock.Utils.Ban(players[0], reason, !args.Player.RealPlayer, args.Player.UserAccountName)) 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 List<TSPlayer> players = TShock.Utils.FindPlayer(args.Parameters[1]);
if (args.Parameters[0].ToLower() == "clear") if (players.Count == 0)
{ args.Player.SendErrorMessage("Invalid player!");
if (args.Parameters.Count < 1 && ClearBansCode == -1) else if (players.Count > 1)
{ TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
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.");
}
else 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;
return; case "delip":
#endregion Clear bans {
#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) private static void Whitelist(CommandArgs args)
{ {
if (args.Parameters.Count == 1) 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) public Ban GetBanByIp(string ip)
{ {
try try
@ -72,6 +77,9 @@ namespace TShockAPI.DB
return null; return null;
} }
/// <summary>
/// Gets a list of bans.
/// </summary>
public List<Ban> GetBans() public List<Ban> GetBans()
{ {
List<Ban> banlist = new List<Ban>(); List<Ban> banlist = new List<Ban>();
@ -94,6 +102,12 @@ namespace TShockAPI.DB
return null; 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) public Ban GetBanByName(string name, bool casesensitive = true)
{ {
try try
@ -114,6 +128,11 @@ namespace TShockAPI.DB
return null; return null;
} }
/// <summary>
/// Gets a ban by UUID.
/// </summary>
/// <param name="uuid">The UUID.</param>
/// <returns>The ban.</returns>
public Ban GetBanByUUID(string uuid) public Ban GetBanByUUID(string uuid)
{ {
try try
@ -138,7 +157,7 @@ namespace TShockAPI.DB
return AddBan(ip, name, "", reason, false, "", ""); return AddBan(ip, name, "", reason, false, "", "");
} }
#endif #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 try
{ {

View file

@ -887,23 +887,6 @@ namespace TShockAPI
return; 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)) if (!FileTools.OnWhitelist(player.IP))
{ {
Utils.ForceKick(player, Config.WhitelistKickReason, true, false); Utils.ForceKick(player, Config.WhitelistKickReason, true, false);
@ -939,7 +922,9 @@ namespace TShockAPI
if (Config.KickEmptyUUID && String.IsNullOrWhiteSpace(player.UUID)) 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; Ban ban = null;
@ -974,7 +959,6 @@ namespace TShockAPI
private void OnLeave(LeaveEventArgs args) private void OnLeave(LeaveEventArgs args)
{ {
var tsplr = Players[args.Who]; var tsplr = Players[args.Who];
Players[args.Who] = null; Players[args.Who] = null;

View file

@ -698,7 +698,7 @@ namespace TShockAPI
bool expirationExists = DateTime.TryParse(ban.Expiration, out exp); bool expirationExists = DateTime.TryParse(ban.Expiration, out exp);
if (!string.IsNullOrWhiteSpace(ban.Expiration) && (expirationExists) && if (!string.IsNullOrWhiteSpace(ban.Expiration) && (expirationExists) &&
(DateTime.Now >= exp)) (DateTime.UtcNow >= exp))
{ {
if (byName) if (byName)
{ {
@ -880,6 +880,50 @@ namespace TShockAPI
return true; 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> /// <summary>
/// Searches for a projectile by identity and owner /// Searches for a projectile by identity and owner
/// </summary> /// </summary>