diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index a8908ace..5be36054 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -1346,7 +1346,7 @@ namespace TShockAPI void DisplayBanDetails(Ban ban) { - args.Player.SendMessage($"{"Ban Details".Color(Utils.BoldHighlight)} - Unique ID: {ban.UniqueId.Color(Utils.GreenHighlight)}", Color.White); + args.Player.SendMessage($"{"Ban Details".Color(Utils.BoldHighlight)} - Ticket Number: {ban.TicketNumber.Color(Utils.GreenHighlight)}", Color.White); args.Player.SendMessage($"{"Identifier:".Color(Utils.BoldHighlight)} {ban.Identifier}", Color.White); args.Player.SendMessage($"{"Reason:".Color(Utils.BoldHighlight)} {ban.Reason}", Color.White); args.Player.SendMessage($"{"Banned by:".Color(Utils.BoldHighlight)} {ban.BanningUser.Color(Utils.GreenHighlight)} on {ban.BanDateTime.ToString("yyyy/MM/dd").Color(Utils.RedHighlight)} ({ban.GetPrettyTimeSinceBanString().Color(Utils.YellowHighlight)} ago)", Color.White); @@ -1426,7 +1426,7 @@ namespace TShockAPI banResult = TShock.Bans.InsertBan(target, reason ?? "Banned", args.Player.Account.Name, DateTime.UtcNow, expiration); if (banResult.Ban != null) { - args.Player.SendSuccessMessage($"Ban ID {banResult.Ban.UniqueId} added."); + args.Player.SendSuccessMessage($"Ban added. Ticket Number: {banResult.Ban.TicketNumber}."); DisplayBanDetails(banResult.Ban); } else @@ -1458,7 +1458,7 @@ namespace TShockAPI banResult = TShock.Bans.InsertBan(ident, reason, args.Player.Account.Name, DateTime.UtcNow, expiration); if (banResult.Ban != null) { - args.Player.SendSuccessMessage($"Ban ID {banResult.Ban.UniqueId} added for identifier {ident}."); + args.Player.SendSuccessMessage($"Ban Ticket Number {banResult.Ban.TicketNumber.Color(Utils.GreenHighlight)} created for identifier {ident}."); banReason = banResult.Ban.Reason; } else @@ -1587,7 +1587,7 @@ namespace TShockAPI args.Player.SendWarningMessage($"If you are sure you wish to proceed, please execute {"ban-convert-confirm".Color(Utils.WhiteHighlight)} to continue."); args.Player.AddResponse("ban-convert-confirm", (obj) => { - TShock.Bans.ConvertBans(); + TShock.Bans.TryConvertBans(); var cmdArgs = (CommandArgs)obj; cmdArgs.Player.SendSuccessMessage("Bans have been converted."); diff --git a/TShockAPI/DB/BanManager.cs b/TShockAPI/DB/BanManager.cs index fe15b92e..2ecd4766 100644 --- a/TShockAPI/DB/BanManager.cs +++ b/TShockAPI/DB/BanManager.cs @@ -34,7 +34,7 @@ namespace TShockAPI.DB private Dictionary _bans; /// - /// Dictionary of Bans, keyed on unique ban ID + /// Dictionary of Bans, keyed on ban ticket number /// public Dictionary Bans { @@ -42,7 +42,7 @@ namespace TShockAPI.DB { if (_bans == null) { - _bans = RetrieveAllBans().ToDictionary(b => b.UniqueId); + _bans = RetrieveAllBans().ToDictionary(b => b.TicketNumber); } return _bans; @@ -92,6 +92,8 @@ namespace TShockAPI.DB throw new Exception("Could not find a database library (probably Sqlite3.dll)"); } + TryConvertBans(); + OnBanValidate += BanValidateCheck; OnBanPreAdd += BanAddedCheck; } @@ -99,45 +101,60 @@ namespace TShockAPI.DB /// /// Converts bans from the old ban system to the new. /// - public void ConvertBans() + public void TryConvertBans() { - using (var reader = database.QueryReader("SELECT * FROM Bans")) + int res; + if (database.GetSqlType() == SqlType.Mysql) { - while (reader.Read()) + res = database.QueryScalar("SELECT COUNT(name) FROM information_schema.tables WHERE table_schema = @0 and table_name = 'Bans'", TShock.Config.MySqlDbName); + } + else + { + res = database.QueryScalar("SELECT COUNT(name) FROM sqlite_master WHERE type='table' AND name = 'Bans'"); + } + + if (res != 0) + { + using (var reader = database.QueryReader("SELECT * FROM Bans")) { - var ip = reader.Get("IP"); - var uuid = reader.Get("UUID"); - var account = reader.Get("AccountName"); - var reason = reader.Get("Reason"); - var banningUser = reader.Get("BanningUser"); - var date = reader.Get("Date"); - var expiration = reader.Get("Expiration"); - - if (!DateTime.TryParse(date, out DateTime start)) + while (reader.Read()) { - start = DateTime.UtcNow; - } + var ip = reader.Get("IP"); + var uuid = reader.Get("UUID"); + var account = reader.Get("AccountName"); + var reason = reader.Get("Reason"); + var banningUser = reader.Get("BanningUser"); + var date = reader.Get("Date"); + var expiration = reader.Get("Expiration"); - if (!DateTime.TryParse(expiration, out DateTime end)) - { - end = DateTime.MaxValue; - } + if (!DateTime.TryParse(date, out DateTime start)) + { + start = DateTime.UtcNow; + } - if (!string.IsNullOrWhiteSpace(ip)) - { - InsertBan($"{Identifier.IP}{ip}", reason, banningUser, start, end); - } + if (!DateTime.TryParse(expiration, out DateTime end)) + { + end = DateTime.MaxValue; + } - if (!string.IsNullOrWhiteSpace(account)) - { - InsertBan($"{Identifier.Account}{account}", reason, banningUser, start, end); - } + if (!string.IsNullOrWhiteSpace(ip)) + { + InsertBan($"{Identifier.IP}{ip}", reason, banningUser, start, end); + } - if (!string.IsNullOrWhiteSpace(uuid)) - { - InsertBan($"{Identifier.UUID}{uuid}", reason, banningUser, start, end); + if (!string.IsNullOrWhiteSpace(account)) + { + InsertBan($"{Identifier.Account}{account}", reason, banningUser, start, end); + } + + if (!string.IsNullOrWhiteSpace(uuid)) + { + InsertBan($"{Identifier.UUID}{uuid}", reason, banningUser, start, end); + } } } + + database.Query("DROP TABLE 'Bans'"); } } @@ -222,15 +239,15 @@ namespace TShockAPI.DB query += "SELECT CAST(last_insert_rowid() as INT);"; } - int uniqueId = database.QueryScalar(query, identifier, reason, banningUser, fromDate.Ticks, toDate.Ticks); + int ticketId = database.QueryScalar(query, identifier, reason, banningUser, fromDate.Ticks, toDate.Ticks); - if (uniqueId == 0) + if (ticketId == 0) { return new AddBanResult { Message = "Database insert failed." }; } - Ban b = new Ban(uniqueId, identifier, reason, banningUser, fromDate, toDate); - _bans.Add(uniqueId, b); + Ban b = new Ban(ticketId, identifier, reason, banningUser, fromDate, toDate); + _bans.Add(ticketId, b); OnBanPostAdd?.Invoke(this, new BanEventArgs { Ban = b }); @@ -240,28 +257,28 @@ namespace TShockAPI.DB /// /// Attempts to remove a ban. Returns true if the ban was removed or expired. False if the ban could not be removed or expired /// - /// The unique ID of the ban to change + /// The ticket number of the ban to change /// If true, deletes the ban from the database. If false, marks the expiration time as now, rendering the ban expired. Defaults to false /// - public bool RemoveBan(int uniqueId, bool fullDelete = false) + public bool RemoveBan(int ticketNumber, bool fullDelete = false) { int rowsModified; if (fullDelete) { - rowsModified = database.Query("DELETE FROM PlayerBans WHERE TicketNumber=@0", uniqueId); - _bans.Remove(uniqueId); + rowsModified = database.Query("DELETE FROM PlayerBans WHERE TicketNumber=@0", ticketNumber); + _bans.Remove(ticketNumber); } else { - rowsModified = database.Query("UPDATE PlayerBans SET Expiration=@0 WHERE TicketNumber=@1", DateTime.UtcNow.Ticks, uniqueId); - _bans[uniqueId].ExpirationDateTime = DateTime.UtcNow; + rowsModified = database.Query("UPDATE PlayerBans SET Expiration=@0 WHERE TicketNumber=@1", DateTime.UtcNow.Ticks, ticketNumber); + _bans[ticketNumber].ExpirationDateTime = DateTime.UtcNow; } return rowsModified > 0; } /// - /// Retrieves a single ban from a unique ban ID + /// Retrieves a single ban from a ban's ticket number /// /// /// @@ -276,14 +293,14 @@ namespace TShockAPI.DB { if (reader.Read()) { - var uniqueId = reader.Get("TicketNumber"); + var ticketNumber = reader.Get("TicketNumber"); var identifier = reader.Get("Identifier"); var reason = reader.Get("Reason"); var banningUser = reader.Get("BanningUser"); var date = reader.Get("Date"); var expiration = reader.Get("Expiration"); - return new Ban(uniqueId, identifier, reason, banningUser, date, expiration); + return new Ban(ticketNumber, identifier, reason, banningUser, date, expiration); } } @@ -308,7 +325,7 @@ namespace TShockAPI.DB { while (reader.Read()) { - var uniqueId = reader.Get("TicketNumber"); + var ticketNumber = reader.Get("TicketNumber"); var ident = reader.Get("Identifier"); var id = reader.Get("Identifier"); var reason = reader.Get("Reason"); @@ -316,7 +333,7 @@ namespace TShockAPI.DB var date = reader.Get("Date"); var expiration = reader.Get("Expiration"); - yield return new Ban(uniqueId, ident, reason, banningUser, date, expiration); + yield return new Ban(ticketNumber, ident, reason, banningUser, date, expiration); } } } @@ -342,14 +359,14 @@ namespace TShockAPI.DB { while (reader.Read()) { - var uniqueId = reader.Get("TicketNumber"); + var ticketNumber = reader.Get("TicketNumber"); var identifier = reader.Get("Identifier"); var reason = reader.Get("Reason"); var banningUser = reader.Get("BanningUser"); var date = reader.Get("Date"); var expiration = reader.Get("Expiration"); - yield return new Ban(uniqueId, identifier, reason, banningUser, date, expiration); + yield return new Ban(ticketNumber, identifier, reason, banningUser, date, expiration); } } } @@ -374,14 +391,14 @@ namespace TShockAPI.DB { while (reader.Read()) { - var uniqueId = reader.Get("TicketNumber"); + var ticketNumber = reader.Get("TicketNumber"); var identifier = reader.Get("Identifier"); var reason = reader.Get("Reason"); var banningUser = reader.Get("BanningUser"); var date = reader.Get("Date"); var expiration = reader.Get("Expiration"); - var ban = new Ban(uniqueId, identifier, reason, banningUser, date, expiration); + var ban = new Ban(ticketNumber, identifier, reason, banningUser, date, expiration); banlist.Add(ban); } } @@ -443,9 +460,9 @@ namespace TShockAPI.DB /// AddedOldestToNewest, /// - /// Bans will be sorted by their unique ID + /// Bans will be sorted by their ticket number /// - UniqueId + TicketNumber } /// @@ -600,7 +617,7 @@ namespace TShockAPI.DB /// /// A unique ID assigned to this ban /// - public int UniqueId { get; set; } + public int TicketNumber { get; set; } /// /// An identifiable piece of information to ban @@ -658,14 +675,14 @@ namespace TShockAPI.DB /// /// Initializes a new instance of the class. /// - /// Unique ID assigned to the ban + /// Unique ID assigned to the ban /// Identifier to apply the ban to /// Reason for the ban /// Account name that executed the ban /// System ticks at which the ban began /// System ticks at which the ban will end - public Ban(int uniqueId, string identifier, string reason, string banningUser, long start, long end) - : this(uniqueId, identifier, reason, banningUser, new DateTime(start), new DateTime(end)) + public Ban(int ticketNumber, string identifier, string reason, string banningUser, long start, long end) + : this(ticketNumber, identifier, reason, banningUser, new DateTime(start), new DateTime(end)) { } @@ -673,15 +690,15 @@ namespace TShockAPI.DB /// /// Initializes a new instance of the class. /// - /// Unique ID assigned to the ban + /// Unique ID assigned to the ban /// Identifier to apply the ban to /// Reason for the ban /// Account name that executed the ban /// DateTime at which the ban will start /// DateTime at which the ban will end - public Ban(int uniqueId, string identifier, string reason, string banningUser, DateTime start, DateTime end) + public Ban(int ticketNumber, string identifier, string reason, string banningUser, DateTime start, DateTime end) { - UniqueId = uniqueId; + TicketNumber = ticketNumber; Identifier = identifier; Reason = reason; BanningUser = banningUser; diff --git a/TShockAPI/Rest/RestManager.cs b/TShockAPI/Rest/RestManager.cs index 45a3d03d..b90749e2 100644 --- a/TShockAPI/Rest/RestManager.cs +++ b/TShockAPI/Rest/RestManager.cs @@ -635,28 +635,29 @@ namespace TShockAPI if (!DateTime.TryParse(args.Parameters["end"], out DateTime endDate)) endDate = DateTime.MaxValue; - if (TShock.Bans.InsertBan(identifier, reason, args.TokenData.Username, startDate, endDate) != null) + AddBanResult banResult = TShock.Bans.InsertBan(identifier, reason, args.TokenData.Username, startDate, endDate); + if (banResult.Ban != null) { TSPlayer player = null; - if (identifier.StartsWith(Identifiers.IP)) + if (identifier.StartsWith(Identifier.IP.Prefix)) { - player = TShock.Players.FirstOrDefault(p => p.IP == identifier.Substring(Identifiers.IP.Length)); + player = TShock.Players.FirstOrDefault(p => p.IP == identifier.Substring(Identifier.IP.Prefix.Length)); } - else if (identifier.StartsWith(Identifiers.Name)) + else if (identifier.StartsWith(Identifier.Name.Prefix)) { //Character names may not necessarily be unique, so kick all matches - foreach (var ply in TShock.Players.Where(p => p.Name == identifier.Substring(Identifiers.Name.Length))) + foreach (var ply in TShock.Players.Where(p => p.Name == identifier.Substring(Identifier.Name.Prefix.Length))) { ply.Kick(reason, true); } } - else if (identifier.StartsWith(Identifiers.Account)) + else if (identifier.StartsWith(Identifier.Account.Prefix)) { - player = TShock.Players.FirstOrDefault(p => p.Account?.Name == identifier.Substring(Identifiers.Account.Length)); + player = TShock.Players.FirstOrDefault(p => p.Account?.Name == identifier.Substring(Identifier.Account.Prefix.Length)); } - else if (identifier.StartsWith(Identifiers.UUID)) + else if (identifier.StartsWith(Identifier.UUID.Prefix)) { - player = TShock.Players.FirstOrDefault(p => p.UUID == identifier.Substring(Identifiers.UUID.Length)); + player = TShock.Players.FirstOrDefault(p => p.UUID == identifier.Substring(Identifier.UUID.Prefix.Length)); } if (player != null) @@ -664,32 +665,32 @@ namespace TShockAPI player.Kick(reason, true); } - return RestResponse("Ban added."); + return RestResponse($"Ban added. Ticket number: {banResult.Ban.TicketNumber}"); } - return RestError("Failed to add ban.", status: "500"); + return RestError($"Failed to add ban. {banResult.Message}", status: "500"); } [Description("Delete an existing ban entry.")] [Route("/v3/bans/destroy")] [Permission(RestPermissions.restmanagebans)] - [Noun("uniqueId", true, "The unique ID of the ban to delete.", typeof(String))] + [Noun("ticketNumber", true, "The ticket number of the ban to delete.", typeof(String))] [Noun("fullDelete", false, "Whether or not to completely remove the ban from the system.", typeof(bool))] [Token] private object BanDestroyV3(RestRequestArgs args) { - string id = args.Parameters["uniqueId"]; + string id = args.Parameters["ticketNumber"]; if (string.IsNullOrWhiteSpace(id)) - return RestMissingParam("uniqueId"); + return RestMissingParam("ticketNumber"); - if (!int.TryParse(id, out int uniqueId)) + if (!int.TryParse(id, out int ticketNumber)) { - return RestInvalidParam("uniqueId"); + return RestInvalidParam("ticketNumber"); } bool.TryParse(args.Parameters["fullDelete"], out bool fullDelete); - if (TShock.Bans.RemoveBan(uniqueId, fullDelete)) + if (TShock.Bans.RemoveBan(ticketNumber, fullDelete)) { return RestResponse("Ban removed."); } @@ -700,20 +701,20 @@ namespace TShockAPI [Description("View the details of a specific ban.")] [Route("/v3/bans/read")] [Permission(RestPermissions.restviewbans)] - [Noun("uniqueId", true, "The unique ID to search for.", typeof(String))] + [Noun("ticketNumber", true, "The ticket number to search for.", typeof(String))] [Token] private object BanInfoV3(RestRequestArgs args) { - string id = args.Parameters["uniqueId"]; + string id = args.Parameters["ticketNumber"]; if (string.IsNullOrWhiteSpace(id)) - return RestMissingParam("uniqueId"); + return RestMissingParam("ticketNumber"); - if (!int.TryParse(id, out int uniqueId)) + if (!int.TryParse(id, out int ticketNumber)) { - return RestInvalidParam("uniqueId"); + return RestInvalidParam("ticketNumber"); } - Ban ban = TShock.Bans.GetBanById(uniqueId); + Ban ban = TShock.Bans.GetBanById(ticketNumber); if (ban == null) { @@ -722,11 +723,12 @@ namespace TShockAPI return new RestObject { - {"identifier", ban.Identifier }, - {"reason", ban.Reason }, - {"banning_user", ban.BanningUser }, - {"fromDate", ban.BanDateTime.ToString("s") }, - {"toDate", ban.ExpirationDateTime.ToString("s") }, + { "ticket_number", ban.TicketNumber }, + { "identifier", ban.Identifier }, + { "reason", ban.Reason }, + { "banning_user", ban.BanningUser }, + { "start_date_ticks", ban.BanDateTime.Ticks }, + { "end_date_ticks", ban.ExpirationDateTime.Ticks }, }; } @@ -742,13 +744,14 @@ namespace TShockAPI foreach (var ban in bans) { banList.Add( - new Dictionary + new Dictionary { - {"identifier", ban.Identifier }, - {"reason", ban.Reason }, - {"banning_user", ban.BanningUser }, - {"fromDate", ban.BanDateTime.ToString("s") }, - {"toDate", ban.ExpirationDateTime.ToString("s") }, + { "ticket_number", ban.TicketNumber }, + { "identifier", ban.Identifier }, + { "reason", ban.Reason }, + { "banning_user", ban.BanningUser }, + { "start_date_ticks", ban.BanDateTime.Ticks }, + { "end_date_ticks", ban.ExpirationDateTime.Ticks }, } ); } diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 449dfc14..ac7b774f 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -479,7 +479,7 @@ namespace TShockAPI UserAccounts.UpdateLogin(args.Player.Account); //Check if this user has a recorded ban on their account - var ban = Bans.Bans.FirstOrDefault(b => b.Value.Identifier == $"{Identifiers.Account}{args.Player.Account.Name}" && Bans.IsValidBan(b.Value, args.Player)).Value; + var ban = Bans.Bans.FirstOrDefault(b => b.Value.Identifier == $"{Identifier.Account}{args.Player.Account.Name}" && Bans.IsValidBan(b.Value, args.Player)).Value; //If they do and the ban is still valid, kick them if (ban != null && !args.Player.HasPermission(Permissions.immunetoban)) @@ -1206,9 +1206,9 @@ namespace TShockAPI List identifiers = new List { - $"{Identifiers.UUID}{player.UUID}", - $"{Identifiers.Name}{player.Name}", - $"{Identifiers.IP}{player.IP}" + $"{Identifier.UUID}{player.UUID}", + $"{Identifier.Name}{player.Name}", + $"{Identifier.IP}{player.IP}" }; Ban ban = Bans.Bans.FirstOrDefault(b => identifiers.Contains(b.Value.Identifier) && Bans.IsValidBan(b.Value, player)).Value;