From 6468ed756279166fd7514177af8c8a2529d64ae9 Mon Sep 17 00:00:00 2001 From: high Date: Wed, 13 Jul 2011 14:14:39 -0400 Subject: [PATCH] This is not C, stop doing return codes especially without doing an enum. Databases can store other things besides strings. If you do not like changes from this commit feel free to revert it. Just giving some last insight on this branch. --- TShockAPI/Commands.cs | 136 ++++++++++++--------- TShockAPI/ConfigFile.cs | 3 +- TShockAPI/DB/RegionManager.cs | 20 ++- TShockAPI/DB/UserManager.cs | 221 +++++++++++++++++++++------------- TShockAPI/GetDataHandlers.cs | 4 +- TShockAPI/TShock.cs | 14 ++- 6 files changed, 235 insertions(+), 163 deletions(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 1d966e79..99cb7bbc 100755 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -323,6 +323,8 @@ namespace TShockAPI } } + //Todo: Add separate help text for '/user add' and '/user del'. Also add '/user addip' and '/user delip' + private static void ManageUsers(CommandArgs args) { if (args.Parameters.Count < 2) @@ -331,66 +333,76 @@ namespace TShockAPI args.Player.SendMessage("Note: Passwords are stored with SHA512 hashing. To reset a user's password, remove and re-add them."); return; } - if (args.Parameters[0] == "add" && args.Parameters.Count > 2) + + string subcmd = args.Parameters[0]; + + if (subcmd == "add") + { + var namepass = args.Parameters[1].Split(':'); + var user = new User(); + + try { - int returnval = 0; - if (args.Parameters[1].Split(':').Length == 2) + if (args.Parameters.Count > 2) { - if ((returnval = TShock.Users.AddUser("", args.Parameters[1].Split(':')[0], args.Parameters[1].Split(':')[1], args.Parameters[2])) == 1) + if (namepass.Length == 2) { - args.Player.SendMessage("Account " + args.Parameters[1].Split(':')[0] + " has been added to group " + args.Parameters[2] + "!", Color.Green); - Log.ConsoleInfo(args.Player.Name + " added Account " + args.Parameters[1].Split(':')[0] + " to group " + args.Parameters[2]); + user.Name = namepass[0]; + user.Password = namepass[1]; + user.Group = args.Parameters[2]; } - else if (returnval == 2) - args.Player.SendMessage("Invalid Group", Color.Green); - else - args.Player.SendMessage("Could not add user", Color.Green); - return; - } - else if (args.Parameters[1].Split(':').Length == 1) - { - if ((returnval = TShock.Users.AddUser(args.Parameters[1], args.Parameters[1], "null", args.Parameters[2])) == 1) + else if (namepass.Length == 1) + { + user.Address = namepass[0]; + user.Group = args.Parameters[2]; + } + if (!string.IsNullOrEmpty(user.Address)) { args.Player.SendMessage("IP address admin added. If they're logged in, tell them to rejoin.", Color.Green); args.Player.SendMessage("WARNING: This is insecure! It would be better to use a user account instead.", Color.Red); - Log.ConsoleInfo(args.Player.Name + " added IP " + args.Parameters[1] + " to group " + args.Parameters[2]); + Log.ConsoleInfo(args.Player.Name + " added IP " + user.Address + " to group " + user.Group); } - else if (returnval == 2) - args.Player.SendMessage("Invalid Group", Color.Green); else - args.Player.SendMessage("Could not add user", Color.Green); - return; + { + args.Player.SendMessage("Account " + user.Name + " has been added to group " + user.Group + "!", Color.Green); + Log.ConsoleInfo(args.Player.Name + " added Account " + user.Name + " to group " + user.Group); + } } - args.Player.SendMessage("Invalid syntax. Try /user help.", Color.Red); - }else if (args.Parameters[0] == "del" && args.Parameters.Count == 2) - { - if (args.Parameters[1].Contains(".")) + else { - //If this isn't an IP, well... - if (TShock.Users.RemoveUser(args.Parameters[1], true) == 1) - { - args.Player.SendMessage("IP removed successfully.", Color.Green); - Log.ConsoleInfo(args.Player.Name + " successfully deleted ip: " + args.Parameters[1]); - } - else - { - args.Player.SendMessage("IP wasn't removed. Was it invalid?", Color.Red); - Log.ConsoleInfo(args.Player.Name + " failed deleting invalid ip: " + args.Parameters[1]); - } - } else - { - if (TShock.Users.RemoveUser(args.Parameters[1], false) == 1) - { - args.Player.SendMessage("Account removed successfully.", Color.Green); - Log.ConsoleInfo(args.Player.Name + " successfully deleted account: " + args.Parameters[1]); - } - else - { - args.Player.SendMessage("Account wasn't removed. Was it invalid?", Color.Red); - Log.ConsoleInfo(args.Player.Name + " failed deleting invalid account: " + args.Parameters[1]); - } + args.Player.SendMessage("Invalid syntax. Try /user help.", Color.Red); } } + catch (UserManagerException ex) + { + args.Player.SendMessage(ex.Message, Color.Green); + Log.ConsoleError(ex.ToString()); + } + } + else if (subcmd == "del" && args.Parameters.Count == 2) + { + var user = new User(); + if (args.Parameters[1].Contains(".")) + user.Address = args.Parameters[1]; + else + user.Name = args.Parameters[1]; + + try + { + TShock.Users.RemoveUser(user); + args.Player.SendMessage("Account removed successfully.", Color.Green); + Log.ConsoleInfo(args.Player.Name + " successfully deleted account: " + args.Parameters[1]); + } + catch (UserManagerException ex) + { + args.Player.SendMessage(ex.Message, Color.Red); + Log.ConsoleError(ex.ToString()); + } + } + else + { + args.Player.SendMessage("Invalid syntax. Try /user help.", Color.Red); + } } #endregion @@ -418,7 +430,7 @@ namespace TShockAPI { args.Player.SendMessage("Invalid player.", Color.Red); } - } + } private static void Kick(CommandArgs args) { @@ -1383,7 +1395,7 @@ namespace TShockAPI { string playerName = args.Parameters[1]; string regionName = ""; - string playerID = "0"; + User playerID; for (int i = 2; i < args.Parameters.Count; i++) { @@ -1396,7 +1408,7 @@ namespace TShockAPI regionName = regionName + " " + args.Parameters[i]; } } - if ((playerID = TShock.Users.GetUserID(Tools.FindPlayer(playerName)[0].UserName)) != "0") + if ((playerID = TShock.Users.GetUserByName(Tools.FindPlayer(playerName)[0].UserName)) != null) { if (TShock.Regions.AddNewUser(regionName, playerID)) { @@ -1405,7 +1417,7 @@ namespace TShockAPI else args.Player.SendMessage("Region " + regionName + " not found", Color.Red); } - else if ((playerID = TShock.Users.GetUserID("",Tools.FindPlayer(playerName)[0].IP)) != "0") + else if ((playerID = TShock.Users.GetUserByIP(Tools.FindPlayer(playerName)[0].IP)) != null) { if (TShock.Regions.AddNewUser(regionName, playerID)) { @@ -1534,13 +1546,21 @@ namespace TShockAPI int givenCode = Convert.ToInt32(args.Parameters[0]); if (givenCode == TShock.AuthToken && args.Player.Group.Name != "superadmin") { - TShock.Users.AddUser(args.Player.IP,"","","superadmin"); - args.Player.Group = Tools.GetGroup("superadmin"); - args.Player.SendMessage("This IP address is now superadmin. Please perform the following command:"); - args.Player.SendMessage("/user add : superadmin"); - args.Player.SendMessage("Creates: with the password as part of the superadmin group."); - args.Player.SendMessage("Please use /login to login from now on."); - args.Player.SendMessage("If you understand, please /login now, and type /auth-verify"); + try + { + TShock.Users.AddUser(new User(args.Player.IP, "", "", "superadmin")); + args.Player.Group = Tools.GetGroup("superadmin"); + args.Player.SendMessage("This IP address is now superadmin. Please perform the following command:"); + args.Player.SendMessage("/user add : superadmin"); + args.Player.SendMessage("Creates: with the password as part of the superadmin group."); + args.Player.SendMessage("Please use /login to login from now on."); + args.Player.SendMessage("If you understand, please /login now, and type /auth-verify"); + } + catch (UserManagerException ex) + { + Log.ConsoleError(ex.ToString()); + args.Player.SendMessage(ex.Message); + } return; } diff --git a/TShockAPI/ConfigFile.cs b/TShockAPI/ConfigFile.cs index 3125a4df..9c93f6b0 100644 --- a/TShockAPI/ConfigFile.cs +++ b/TShockAPI/ConfigFile.cs @@ -77,9 +77,8 @@ namespace TShockAPI /// public string StorageType = "sqlite"; - public string MySqlHost = "localhost"; + public string MySqlHost = "localhost:3306"; public string MySqlDbName = ""; - public string MySqlPort = "3306"; public string MySqlUsername = ""; public string MySqlPassword = ""; diff --git a/TShockAPI/DB/RegionManager.cs b/TShockAPI/DB/RegionManager.cs index 7810f6ff..9fc37278 100644 --- a/TShockAPI/DB/RegionManager.cs +++ b/TShockAPI/DB/RegionManager.cs @@ -109,7 +109,7 @@ namespace TShockAPI.DB { com.CommandText = "UPDATE Regions SET Protected=@bool WHERE RegionName=@name WorldID=@worldid"; com.AddParameter("@name", name); - if (state) + if (state) com.AddParameter("@bool", 1); else com.AddParameter("@bool", 0); @@ -127,7 +127,7 @@ namespace TShockAPI.DB } } - public bool InProtectedArea(int X, int Y, string ID) + public bool InProtectedArea(int X, int Y, User user) { try { @@ -154,7 +154,7 @@ namespace TShockAPI.DB Y <= Y2 && Protected == 1) { - if (!SplitIDs.Contains(ID)) + if (!SplitIDs.Contains(user.ID.ToString())) return true; } } @@ -191,7 +191,7 @@ namespace TShockAPI.DB return SplitIDs; } - public bool AddNewUser(string regionName, string ID) + public bool AddNewUser(string regionName, User user) { string MergedIDs = string.Empty; @@ -206,23 +206,17 @@ namespace TShockAPI.DB using (var reader = com.ExecuteReader()) { if (reader.Read()) - { MergedIDs = reader.Get("UserIds"); - } - reader.Close(); } if (MergedIDs == string.Empty) - MergedIDs = ID; + MergedIDs = user.ID.ToString(); else - MergedIDs = MergedIDs + "," + ID; + MergedIDs = MergedIDs + "," + user.ID; com.CommandText = "UPDATE Regions SET UserIds=@ids"; com.AddParameter("@ids", MergedIDs); - if (com.ExecuteNonQuery() > 0) - return true; - else - return false; + return (com.ExecuteNonQuery() > 0); } } catch (Exception ex) diff --git a/TShockAPI/DB/UserManager.cs b/TShockAPI/DB/UserManager.cs index a1ca1d09..14af0682 100644 --- a/TShockAPI/DB/UserManager.cs +++ b/TShockAPI/DB/UserManager.cs @@ -27,7 +27,7 @@ using Community.CsharpSqlite.SQLiteClient; namespace TShockAPI.DB { public class UserManager - { + { private IDbConnection database; public UserManager(IDbConnection db) @@ -38,94 +38,72 @@ namespace TShockAPI.DB { if (TShock.Config.StorageType.ToLower() == "sqlite") com.CommandText = - "CREATE TABLE IF NOT EXISTS 'Users' ('Username' TEXT PRIMARY KEY, 'Password' TEXT, 'UserGroup' TEXT, 'IP' TEXT);"; + "CREATE TABLE IF NOT EXISTS 'Users' ('ID' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, 'Username' VARCHAR(32) UNIQUE, 'Password' VARCHAR(64), 'Usergroup' TEXT, 'IP' VARCHAR(15));"; else if (TShock.Config.StorageType.ToLower() == "mysql") com.CommandText = - "CREATE TABLE IF NOT EXISTS Users (Username VARCHAR(255) PRIMARY, Password VARCHAR(255), UserGroup VARCHAR(255), IP VARCHAR(255));"; - + "CREATE TABLE IF NOT EXISTS Users (ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, Username VARCHAR(32) UNIQUE, Password VARCHAR(64), Usergroup VARCHAR(255), IP VARCHAR(15));"; + com.ExecuteNonQuery(); } } - public int AddUser(string ip = "" , string name = "", string password = "", string group = "default") //I LOVE HOW THIS IS COMPLETELY NOT THE FORMAT FOR, YOU KNOW, THE DB + + public void AddUser(User user) { try { using (var com = database.CreateCommand()) { com.CommandText = "INSERT INTO Users (Username, Password, UserGroup, IP) VALUES (@name, @password, @group, @ip);"; - com.AddParameter("@name", name.ToLower()); - com.AddParameter("@password", Tools.HashPassword(password)); + com.AddParameter("@name", user.Name); + com.AddParameter("@password", Tools.HashPassword(user.Password)); - if(TShock.Groups.GroupExists(group)) - com.AddParameter("@group", group); - else - //Return code 2 (Group not exist) - return 2; + if (!TShock.Groups.GroupExists(user.Group)) + throw new GroupNotExistsException(user.Group); - com.AddParameter("@ip", ip); + com.AddParameter("@group", user.Group); + com.AddParameter("@ip", user.Address); using (var reader = com.ExecuteReader()) { - if (reader.RecordsAffected > 0) - { - //Return code 1 (User added) - return 1; - } - else - { - //Return code 0 (Add failed) - return 0; - } - } - } - } - catch (Exception ex) - { - //Return code 0 (Add failed) - Log.ConsoleError("AddUser SQL returned an error: " + ex.ToString()); - return 0; - } - } - - public int RemoveUser(string inputUser, bool ip) - { - try - { - using (var com = database.CreateCommand()) - { - if (ip) - { - com.CommandText = "DELETE FROM Users WHERE IP=@ip"; - com.AddParameter("@ip", inputUser.ToLower()); - } else - { - com.CommandText = "DELETE FROM Users WHERE Username=@name"; - com.AddParameter("@name", inputUser.ToLower()); - } - - using (var reader = com.ExecuteReader()) - { - if (reader.RecordsAffected > 0) - { - //Return code 1 (User removed) - reader.Close(); - return 1; - } - else - { - //Return code 0 (Remove failed) - reader.Close(); - return 0; - } + if (reader.RecordsAffected < 1) + throw new UserExistsException(user.Name); } } } catch (Exception ex) { - //Return code 0 (Remove failed) - Log.ConsoleError("RemoveUser SQL returned an error: " + ex.ToString()); - return 0; + throw new UserManagerException("AddUser SQL returned an error", ex); + } + } + + public void RemoveUser(User user) + { + try + { + using (var com = database.CreateCommand()) + { + if (!string.IsNullOrEmpty(user.Address)) + { + com.CommandText = "DELETE FROM Users WHERE IP=@ip"; + com.AddParameter("@ip", user.Address); + } + else + { + com.CommandText = "DELETE FROM Users WHERE Username=@name"; + com.AddParameter("@name", user.Name); + } + + using (var reader = com.ExecuteReader()) + { + if (reader.RecordsAffected < 1) + throw new UserNotExistException(string.IsNullOrEmpty(user.Address) ? user.Name : user.Address); + } + } + } + catch (Exception ex) + { + throw new UserManagerException("RemoveUser SQL returned an error", ex); } } @@ -183,7 +161,6 @@ namespace TShockAPI.DB string group = reader.Get("UserGroup"); return Tools.GetGroup(group); } - reader.Close(); } } } @@ -193,42 +170,122 @@ namespace TShockAPI.DB } return Tools.GetGroup("default"); } + public User GetUserByName(string name) + { + try + { + return GetUser(new User { Name = name }); + } + catch (UserManagerException) + { + return null; + } + } + public User GetUserByIP(string ip) + { + try + { + return GetUser(new User { Address = ip }); + } + catch (UserManagerException) + { + return null; + } + } - public string GetUserID(string username = "", string IP = "") + public User GetUser(User user) { try { using (var com = database.CreateCommand()) { - if (username != "" && username != null) + if (string.IsNullOrEmpty(user.Address)) { com.CommandText = "SELECT * FROM Users WHERE Username=@name"; - com.AddParameter("@name", username); - } - else if (IP != "" && IP != null) - { - com.CommandText = "SELECT * FROM Users WHERE IP=@ip"; - com.AddParameter("@ip", IP); + com.AddParameter("@name", user.Name); } else - return "0"; + { + com.CommandText = "SELECT * FROM Users WHERE IP=@ip"; + com.AddParameter("@ip", user.Address); + } using (var reader = com.ExecuteReader()) { if (reader.Read()) { - string ID = reader.Get("ID"); - return ID; + user.ID = reader.Get("ID"); + user.Group = reader.Get("Usergroup"); + return user; } - reader.Close(); } } } catch (Exception ex) { - Log.ConsoleError("GetUserID SQL returned an error: " + ex.ToString()); + throw new UserManagerException("GetUserID SQL returned an error", ex); } - return "0"; + throw new UserNotExistException(string.IsNullOrEmpty(user.Address) ? user.Name : user.Address); + } + } + + public class User + { + public int ID { get; set; } + public string Name { get; set; } + public string Password { get; set; } + public string Group { get; set; } + public string Address { get; set; } + + public User(string ip, string name, string pass, string group) + { + Address = ip; + Name = name; + Password = pass; + Group = group; + } + public User() + { + Address = ""; + Name = ""; + Password = ""; + Group = ""; + } + } + + public class UserManagerException : Exception + { + public UserManagerException(string message) + : base(message) + { + + } + public UserManagerException(string message, Exception inner) + : base(message, inner) + { + + } + } + public class UserExistsException : UserManagerException + { + public UserExistsException(string name) + : base("User '" + name + "' already exists") + { + } + } + public class UserNotExistException : UserManagerException + { + public UserNotExistException(string name) + : base("User '" + name + "' does not exist") + { + } + } + + public class GroupNotExistsException : UserManagerException + { + public GroupNotExistsException(string group) + : base("Group '" + group + "' does not exist") + { } } } diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index c6f8295d..632d81e1 100755 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -278,7 +278,7 @@ namespace TShockAPI return true; } } - if (!args.Player.Group.HasPermission("editspawn") && TShock.Regions.InProtectedArea(x, y, TShock.Users.GetUserID(args.Player.UserName,args.Player.IP))) + if (!args.Player.Group.HasPermission("editspawn") && TShock.Regions.InProtectedArea(x, y, TShock.Users.GetUserByIP(args.Player.IP))) { if ((DateTime.UtcNow - args.Player.LastTileChangeNotify).TotalMilliseconds > 1000) { @@ -537,7 +537,7 @@ namespace TShockAPI args.Player.SendTileSquare(tilex, tiley); return true; } - if (!args.Player.Group.HasPermission("editspawn") && TShock.Regions.InProtectedArea(tilex, tiley, Tools.GetPlayerIP(args.Player.Name))) + if (!args.Player.Group.HasPermission("editspawn") && TShock.Regions.InProtectedArea(tilex, tiley, TShock.Users.GetUserByName(args.Player.Name))) { args.Player.SendMessage("Region protected from changes.", Color.Red); args.Player.SendTileSquare(tilex, tiley); diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 0aa05e28..b14ca2c5 100755 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -143,13 +143,15 @@ namespace TShockAPI { try { + var hostport = Config.MySqlHost.Split(':'); DB = new MySqlConnection(); - DB.ConnectionString = - "Server='" + Config.MySqlHost + - "';Port='" + Config.MySqlPort + - "';Database='" + Config.MySqlDbName + - "';Uid='" + Config.MySqlUsername + - "';Pwd='" + Config.MySqlPassword + "';"; + DB.ConnectionString = String.Format("Server='{0}'; Port='{1}'; Database='{2}'; Uid='{3}'; Pwd='{4}';", + hostport[0], + hostport.Length > 1 ? hostport[1] : "3306", + Config.MySqlDbName, + Config.MySqlUsername, + Config.MySqlPassword + ); DB.Open(); } catch (MySqlException ex)