diff --git a/TShockAPI/DB/BanManager.cs b/TShockAPI/DB/BanManager.cs index 082e5a41..65ab171a 100644 --- a/TShockAPI/DB/BanManager.cs +++ b/TShockAPI/DB/BanManager.cs @@ -92,10 +92,6 @@ throw new Exception("Could not find a database library (probably Sqlite3.dll)"); public Ban GetBanByName(string name, bool casesensitive = true) { - if (!TShock.Config.EnableBanOnUsernames) - { - return null; - } try { var namecol = casesensitive ? "Name" : "UPPER(Name)"; @@ -127,11 +123,15 @@ throw new Exception("Could not find a database library (probably Sqlite3.dll)"); return false; } - public bool RemoveBan(string ip) + public bool RemoveBan(string match, bool byName = false, bool casesensitive = true) { try { - return database.Query("DELETE FROM Bans WHERE IP=@0", ip) != 0; + if (!byName) + return database.Query("DELETE FROM Bans WHERE IP=@0", match) != 0; + + var namecol = casesensitive ? "Name" : "UPPER(Name)"; + return database.Query("DELETE FROM Bans WHERE " + namecol + "=@0", casesensitive ? match : match.ToUpper()) != 0; } catch (Exception ex) { diff --git a/TShockAPI/DB/GroupManager.cs b/TShockAPI/DB/GroupManager.cs index da3ce79f..27fee59a 100644 --- a/TShockAPI/DB/GroupManager.cs +++ b/TShockAPI/DB/GroupManager.cs @@ -16,6 +16,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ using System; +using System.Collections; using System.Collections.Generic; using System.Data; using System.IO; @@ -24,7 +25,7 @@ using MySql.Data.MySqlClient; namespace TShockAPI.DB { - public class GroupManager + public class GroupManager : IEnumerable { private IDbConnection database; @@ -64,21 +65,42 @@ namespace TShockAPI.DB if (group == "superadmin") return true; - return groups.Any(g => g.Name.Equals(group)); } + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public IEnumerator GetEnumerator() + { + return groups.GetEnumerator(); + } + + public Group GetGroupByName(string name) + { + var ret = groups.Where(g => g.Name == name); + return 1 == ret.Count() ? ret.ElementAt(0) : null; + } + /// /// Adds group with name and permissions if it does not exist. /// /// name of group /// parent of group /// permissions - public String AddGroup(String name, string parentname, String permissions, String chatcolor) + /// chatcolor + /// exceptions true indicates use exceptions for errors false otherwise + public String AddGroup(String name, string parentname, String permissions, String chatcolor, bool exceptions = false) { String message = ""; if (GroupExists(name)) + { + if (exceptions) + throw new GroupExistsException(name); return "Error: Group already exists. Use /modGroup to change permissions."; + } var group = new Group(name, null, chatcolor); group.permissions.Add(permissions); @@ -88,6 +110,8 @@ namespace TShockAPI.DB if (parent == null) { var error = "Invalid parent {0} for group {1}".SFormat(group.Name, parentname); + if (exceptions) + throw new GroupManagerException(error); Log.ConsoleError(error); return error; } @@ -98,9 +122,12 @@ namespace TShockAPI.DB ? "INSERT OR IGNORE INTO GroupList (GroupName, Parent, Commands, ChatColor) VALUES (@0, @1, @2, @3);" : "INSERT IGNORE INTO GroupList SET GroupName=@0, Parent=@1, Commands=@2, ChatColor=@3"; if (database.Query(query, name, parentname, permissions, chatcolor) == 1) + { message = "Group " + name + " has been created successfully."; - - groups.Add(group); + groups.Add(group); + } + else if (exceptions) + throw new GroupManagerException("Failed to add group '" + name + "'"); return message; } @@ -115,15 +142,23 @@ namespace TShockAPI.DB return AddGroup(name, parent, permissions, "255,255,255"); } - public String DeleteGroup(String name) + public String DeleteGroup(String name, bool exceptions = false) { String message = ""; if (!GroupExists(name)) + { + if (exceptions) + throw new GroupNotExistException(name); return "Error: Group doesn't exists."; + } if (database.Query("DELETE FROM GroupList WHERE GroupName=@0", name) == 1) + { message = "Group " + name + " has been deleted successfully."; - groups.Remove(TShock.Utils.GetGroup(name)); + groups.Remove(TShock.Utils.GetGroup(name)); + } + else if (exceptions) + throw new GroupManagerException("Failed to delete group '" + name + "'"); return message; } @@ -239,4 +274,36 @@ namespace TShockAPI.DB } } } -} \ No newline at end of file + + [Serializable] + public class GroupManagerException : Exception + { + public GroupManagerException(string message) + : base(message) + { + } + + public GroupManagerException(string message, Exception inner) + : base(message, inner) + { + } + } + + [Serializable] + public class GroupExistsException : GroupManagerException + { + public GroupExistsException(string name) + : base("Group '" + name + "' already exists") + { + } + } + + [Serializable] + public class GroupNotExistException : GroupManagerException + { + public GroupNotExistException(string name) + : base("Group '" + name + "' does not exist") + { + } + } +} diff --git a/TShockAPI/DB/IQueryBuilder.cs b/TShockAPI/DB/IQueryBuilder.cs index 107375da..9157e645 100644 --- a/TShockAPI/DB/IQueryBuilder.cs +++ b/TShockAPI/DB/IQueryBuilder.cs @@ -42,7 +42,7 @@ namespace TShockAPI.DB var columns = table.Columns.Select( c => - "'{0}' {1} {2} {3} {4}".SFormat(c.Name, DbTypeToString(c.Type, c.Length), c.Primary ? "PRIMARY KEY" : "", + "'{0}' {1} {2} {3} {4} {5}".SFormat(c.Name, DbTypeToString(c.Type, c.Length), c.Primary ? "PRIMARY KEY" : "", c.AutoIncrement ? "AUTOINCREMENT" : "", c.NotNull ? "NOT NULL" : "", c.Unique ? "UNIQUE" : "")); return "CREATE TABLE '{0}' ({1})".SFormat(table.Name, string.Join(", ", columns)); @@ -198,7 +198,7 @@ namespace TShockAPI.DB var columns = table.Columns.Select( c => - "{0} {1} {2} {3}".SFormat(c.Name, DbTypeToString(c.Type, c.Length), c.Primary ? "PRIMARY KEY" : "", + "{0} {1} {2} {3} {4}".SFormat(c.Name, DbTypeToString(c.Type, c.Length), c.Primary ? "PRIMARY KEY" : "", c.AutoIncrement ? "AUTO_INCREMENT" : "", c.NotNull ? "NOT NULL" : "")); var uniques = table.Columns.Where(c => c.Unique).Select(c => c.Name); return "CREATE TABLE {0} ({1} {2})".SFormat(table.Name, string.Join(", ", columns), diff --git a/TShockAPI/DB/UserManager.cs b/TShockAPI/DB/UserManager.cs index 70423dfb..7ea6c63a 100644 --- a/TShockAPI/DB/UserManager.cs +++ b/TShockAPI/DB/UserManager.cs @@ -18,6 +18,7 @@ along with this program. If not, see . using System; using System.Data; using System.IO; +using System.Collections.Generic; using MySql.Data.MySqlClient; namespace TShockAPI.DB @@ -50,20 +51,22 @@ namespace TShockAPI.DB /// User user public void AddUser(User user) { + if (!TShock.Groups.GroupExists(user.Group)) + throw new GroupNotExistsException(user.Group); + + int ret; try { - if (!TShock.Groups.GroupExists(user.Group)) - throw new GroupNotExistsException(user.Group); - - if ( - database.Query("INSERT INTO Users (Username, Password, UserGroup, IP) VALUES (@0, @1, @2, @3);", user.Name, - TShock.Utils.HashPassword(user.Password), user.Group, user.Address) < 1) - throw new UserExistsException(user.Name); + ret = database.Query("INSERT INTO Users (Username, Password, UserGroup, IP) VALUES (@0, @1, @2, @3);", user.Name, + TShock.Utils.HashPassword(user.Password), user.Group, user.Address); } catch (Exception ex) { - throw new UserManagerException("AddUser SQL returned an error", ex); + throw new UserManagerException("AddUser SQL returned an error (" + ex.Message + ")", ex); } + + if (1 > ret) + throw new UserExistsException(user.Name); } /// @@ -254,14 +257,7 @@ namespace TShockAPI.DB using (var reader = result) { if (reader.Read()) - { - user.ID = reader.Get("ID"); - user.Group = reader.Get("Usergroup"); - user.Password = reader.Get("Password"); - user.Name = reader.Get("Username"); - user.Address = reader.Get("IP"); - return user; - } + return LoadUserFromResult(user, result); } } catch (Exception ex) @@ -270,6 +266,37 @@ namespace TShockAPI.DB } throw new UserNotExistException(string.IsNullOrEmpty(user.Address) ? user.Name : user.Address); } + + public List GetUsers() + { + try + { + List users = new List(); + using (var reader = database.QueryReader("SELECT * FROM Users")) + { + while (reader.Read()) + { + users.Add(LoadUserFromResult(new User(), reader)); + } + return users; + } + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + return null; + } + + private User LoadUserFromResult(User user, QueryResult result) + { + user.ID = result.Get("ID"); + user.Group = result.Get("Usergroup"); + user.Password = result.Get("Password"); + user.Name = result.Get("Username"); + user.Address = result.Get("IP"); + return user; + } } public class User diff --git a/TShockAPI/Group.cs b/TShockAPI/Group.cs index 01131a5e..16448677 100644 --- a/TShockAPI/Group.cs +++ b/TShockAPI/Group.cs @@ -44,6 +44,11 @@ namespace TShockAPI byte.TryParse(chatcolor.Split(',')[2], out B); } + public string ChatColor() + { + return string.Format("{0}{1}{2}", R.ToString("X2"), G.ToString("X2"), B.ToString("X2")); + } + public virtual bool HasPermission(string permission) { var cur = this; diff --git a/TShockAPI/Rest/RestObject.cs b/TShockAPI/Rest/RestObject.cs index 6b99d1cc..e63233dc 100644 --- a/TShockAPI/Rest/RestObject.cs +++ b/TShockAPI/Rest/RestObject.cs @@ -41,7 +41,7 @@ namespace Rests set { this["response"] = value; } } - public RestObject(string status) + public RestObject(string status = "200") { Status = status; } diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 2c50bf97..0c697c24 100755 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -210,6 +210,9 @@ namespace TShockAPI Commands.InitCommands(); //RconHandler.StartThread(); + if (Config.RestApiEnabled) + RestApi.Start(); + if (Config.BufferPackets) PacketBuffer = new PacketBufferer(); @@ -434,8 +437,6 @@ namespace TShockAPI AuthToken = 0; } Regions.ReloadAllRegions(); - if (Config.RestApiEnabled) - RestApi.Start(); StatTracker.CheckIn(); FixChestStacks(); diff --git a/TShockAPI/Utils.cs b/TShockAPI/Utils.cs index d5c723b9..df5c7207 100644 --- a/TShockAPI/Utils.cs +++ b/TShockAPI/Utils.cs @@ -205,6 +205,9 @@ namespace TShockAPI public List FindPlayer(string ply) { var found = new List(); + // Avoid errors caused by null search + if (null == ply) + return found; ply = ply.ToLower(); foreach (TSPlayer player in TShock.Players) {