diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index e7a2c032..d9495f94 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -166,7 +166,7 @@ namespace TShockAPI ChatCommands.Add(new Command(PasswordUser, "password") { DoLog = false }); ChatCommands.Add(new Command(RegisterUser, "register") { DoLog = false }); ChatCommands.Add(new Command("root-only", ManageUsers, "user") { DoLog = false }); - ChatCommands.Add(new Command("root-only", GrabUserIP, "ip")); + ChatCommands.Add(new Command("root-only", GrabUserUserInfo, "userinfo", "ui")); ChatCommands.Add(new Command("root-only", AuthVerify, "auth-verify")); ChatCommands.Add(new Command(AttemptLogin, "login") { DoLog = false }); ChatCommands.Add(new Command("cfg", Broadcast, "broadcast", "bc")); @@ -316,28 +316,31 @@ namespace TShockAPI try { string encrPass = Tools.HashPassword(args.Parameters[1]); - string[] exr = TShock.Users.FetchHashedPasswordAndGroup(args.Parameters[0]); - if (exr[0].ToUpper() == encrPass.ToUpper()) + var user = TShock.Users.GetUserByName(args.Parameters[0]); + if (user == null) { - args.Player.Group = Tools.GetGroup(exr[1]); + args.Player.SendMessage("User by that name does not exist"); + } + else if (user.Password.ToUpper() == encrPass.ToUpper()) + { + args.Player.Group = Tools.GetGroup(user.Group); args.Player.UserAccountName = args.Parameters[0]; args.Player.UserID = TShock.Users.GetUserID(args.Player.UserAccountName); args.Player.IsLoggedIn = true; args.Player.SendMessage("Authenticated as " + args.Parameters[0] + " successfully.", Color.LimeGreen); Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user: " + args.Parameters[0]); - return; } else { + args.Player.SendMessage("Incorrect password", Color.LimeGreen); Log.Warn(args.Player.IP + " failed to authenticate as user: " + args.Parameters[0]); args.Player.LoginAttempts++; - return; } } - catch (Exception) + catch (Exception ex) { - args.Player.SendMessage("There was an error processing your request. Maybe your account doesn't exist?", Color.Red); - return; + args.Player.SendMessage("There was an error processing your request.", Color.Red); + Log.Error(ex.ToString()); } } @@ -351,8 +354,7 @@ namespace TShockAPI { var user = TShock.Users.GetUserByName(args.Player.UserAccountName); string encrPass = Tools.HashPassword(args.Parameters[0]); - string[] exr = TShock.Users.FetchHashedPasswordAndGroup(args.Player.UserAccountName); - if (exr[0].ToUpper() == encrPass.ToUpper()) + if (user.Password.ToUpper() == encrPass.ToUpper()) { args.Player.SendMessage("You changed your password!", Color.Green); TShock.Users.SetUserPassword(user, args.Parameters[1]); // SetUserPassword will hash it for you. @@ -383,7 +385,7 @@ namespace TShockAPI if (args.Parameters.Count == 2) { var user = new User(); - user.Name = args.Parameters[0].ToLower(); + user.Name = args.Parameters[0]; user.Password = args.Parameters[1]; user.Group = TShock.Config.DefaultRegistrationGroupName; // FIXME -- we should get this from the DB. @@ -439,7 +441,7 @@ namespace TShockAPI { if (namepass.Length == 2) { - user.Name = namepass[0].ToLower(); + user.Name = namepass[0]; user.Password = namepass[1]; user.Group = args.Parameters[2]; } @@ -577,11 +579,11 @@ namespace TShockAPI #region Player Management Commands - private static void GrabUserIP(CommandArgs args) + private static void GrabUserUserInfo(CommandArgs args) { if (args.Parameters.Count < 1) { - args.Player.SendMessage("Invalid syntax! Proper syntax: /ip ", Color.Red); + args.Player.SendMessage("Invalid syntax! Proper syntax: /userinfo ", Color.Red); return; } @@ -593,7 +595,7 @@ namespace TShockAPI } try { - args.Player.SendMessage(players[0].IP, Color.Green); + args.Player.SendMessage("IP Address: " + players[0].IP + " Logged In As: " + players[0].UserAccountName, Color.Green); } catch (Exception) { @@ -797,9 +799,10 @@ namespace TShockAPI { if (args.Parameters.Count == 1) { - TextWriter tw = new StreamWriter(FileTools.WhitelistPath, true); - tw.WriteLine(args.Parameters[0]); - tw.Close(); + using (var tw = new StreamWriter(FileTools.WhitelistPath, true)) + { + tw.WriteLine(args.Parameters[0]); + } args.Player.SendMessage("Added " + args.Parameters[0] + " to the whitelist."); } } @@ -862,31 +865,38 @@ namespace TShockAPI ThreadPool.QueueUserWorkItem(UpdateManager.CheckUpdate); } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] private static void UpdateNow(CommandArgs args) { Process TServer = Process.GetCurrentProcess(); - StreamWriter sw = new StreamWriter("pid"); - sw.Write(TServer.Id); - sw.Close(); + using (var sw = new StreamWriter("pid")) + { + sw.Write(TServer.Id); + } - sw = new StreamWriter("pn"); - sw.Write(TServer.ProcessName + " " + Environment.CommandLine); - sw.Close(); + using (var sw = new StreamWriter("pn")) + { + sw.Write(TServer.ProcessName + " " + Environment.CommandLine); + } - WebClient client = new WebClient(); - client.Headers.Add("user-agent", "TShock"); - byte[] updatefile = client.DownloadData("http://tsupdate.shankshock.com/UpdateTShock.exe"); + using (var client = new WebClient()) + { + client.Headers.Add("user-agent", "TShock"); + byte[] updatefile = client.DownloadData("http://tsupdate.shankshock.com/UpdateTShock.exe"); - BinaryWriter bw = new BinaryWriter(new FileStream("UpdateTShock.exe", FileMode.Create)); - bw.Write(updatefile); - bw.Close(); + using (var bw = new BinaryWriter(new FileStream("UpdateTShock.exe", FileMode.Create))) + { + bw.Write(updatefile); + } + } Process.Start(new ProcessStartInfo("UpdateTShock.exe")); Tools.ForceKickAll("Server shutting down for update!"); WorldGen.saveWorld(); Netplay.disconnect = true; + } #endregion Server Maintenence Commands @@ -1237,7 +1247,7 @@ namespace TShockAPI args.Player.SendMessage("Could not find specified warp", Color.Red); } else - args.Player.SendMessage("Invalid syntax! Proper syntax: /hidewarp [name] ", Color.Red); + args.Player.SendMessage("Invalid syntax! Proper syntax: /hidewarp [name] ", Color.Red); } else args.Player.SendMessage("Invalid syntax! Proper syntax: /hidewarp [name] ", Color.Red); @@ -1286,7 +1296,7 @@ namespace TShockAPI //Add up to pagelimit names to a list var nameslist = new List(); - for (int i = 0; i < pagelimit && i + (page * pagelimit) < warps.Count; i++) + for (int i = (page * pagelimit); (i < ((page * pagelimit) + pagelimit)) && i < warps.Count; i++) { nameslist.Add(warps[i].WarpName); } @@ -1300,7 +1310,7 @@ namespace TShockAPI if (page < pagecount) { - args.Player.SendMessage(string.Format("Type /warp list {0} for more warps.", (page + 1)), Color.Yellow); + args.Player.SendMessage(string.Format("Type /warp list {0} for more warps.", (page + 2)), Color.Yellow); } } else @@ -1330,10 +1340,10 @@ namespace TShockAPI { String groupname = args.Parameters[0]; args.Parameters.RemoveAt(0); - String permissions = String.Join(",", args.Parameters ); + String permissions = String.Join(",", args.Parameters); String response = TShock.Groups.AddGroup(groupname, permissions); - if( response.Length > 0 ) + if (response.Length > 0) args.Player.SendMessage(response, Color.Green); } else @@ -1389,7 +1399,7 @@ namespace TShockAPI #endregion Group Management #region Item Management - + private static void AddItem(CommandArgs args) { if (args.Parameters.Count > 0) @@ -1495,7 +1505,8 @@ namespace TShockAPI private static void Reload(CommandArgs args) { FileTools.SetupConfig(); - args.Player.SendMessage("Configuration reload complete. Some changes may require server restart."); + TShock.Groups.LoadPermisions(); + args.Player.SendMessage("Configuration & Permissions reload complete. Some changes may require server restart."); } private static void ServerPassword(CommandArgs args) @@ -1673,25 +1684,25 @@ namespace TShockAPI { if (args.Parameters[1] == "1") { - args.Player.TempArea.X = args.Player.TileX; - args.Player.TempArea.Y = args.Player.TileY; - args.Player.SendMessage("Set Temp Point 1", Color.Yellow); + if (!args.Player.AwaitingTemp2) + { + args.Player.SendMessage("Hit a block to Set Point 1", Color.Yellow); + args.Player.AwaitingTemp1 = true; + } + else + args.Player.SendMessage("Awaiting you to Set Point 2", Color.Yellow); } else if (args.Parameters[1] == "2") { if (args.Player.TempArea.X != 0) { - if (args.Player.TileX > args.Player.TempArea.X && args.Player.TileY > args.Player.TempArea.Y) + if (!args.Player.AwaitingTemp1) { - args.Player.TempArea.Width = args.Player.TileX - args.Player.TempArea.X; - args.Player.TempArea.Height = (args.Player.TileY + 3) - args.Player.TempArea.Y; - args.Player.SendMessage("Set Temp Point 2", Color.Yellow); + args.Player.SendMessage("Hit a block to Set Point 2", Color.Yellow); + args.Player.AwaitingTemp2 = true; } else - { - args.Player.SendMessage("Point 2 must be below and right of Point 1", Color.Yellow); - args.Player.SendMessage("Use /region clear to start again", Color.Yellow); - } + args.Player.SendMessage("Awaiting you to Set Point 1", Color.Yellow); } else { @@ -1775,6 +1786,8 @@ namespace TShockAPI { args.Player.TempArea = Rectangle.Empty; args.Player.SendMessage("Cleared temp area", Color.Yellow); + args.Player.AwaitingTemp1 = false; + args.Player.AwaitingTemp2 = false; break; } case "allow": @@ -1856,7 +1869,7 @@ namespace TShockAPI //Add up to pagelimit names to a list var nameslist = new List(); - for (int i = 0; i < pagelimit && i + (page * pagelimit) < regions.Count; i++) + for (int i = (page * pagelimit); (i < ((page * pagelimit) + pagelimit)) && i < regions.Count; i++) { nameslist.Add(regions[i].Name); } @@ -1870,7 +1883,7 @@ namespace TShockAPI if (page < pagecount) { - args.Player.SendMessage(string.Format("Type /region list {0} for more regions.", (page + 1)), Color.Yellow); + args.Player.SendMessage(string.Format("Type /region list {0} for more regions.", (page + 2)), Color.Yellow); } break; @@ -2231,9 +2244,9 @@ namespace TShockAPI args.Parameters.RemoveAt(0); string plStr = args.Parameters[0]; args.Parameters.RemoveAt(0); - if( args.Parameters.Count > 0 ) + if (args.Parameters.Count > 0) int.TryParse(args.Parameters[args.Parameters.Count - 1], out itemAmount); - + if (items.Count == 0) { diff --git a/TShockAPI/DB/GroupManager.cs b/TShockAPI/DB/GroupManager.cs index b086822c..1486a5f7 100644 --- a/TShockAPI/DB/GroupManager.cs +++ b/TShockAPI/DB/GroupManager.cs @@ -166,7 +166,7 @@ namespace TShockAPI.DB try { - using (var reader = database.QueryReader("SELECT * FROM Grouplist")) + using (var reader = database.QueryReader("SELECT * FROM GroupList")) { while (reader.Read()) { diff --git a/TShockAPI/DB/IQueryBuilder.cs b/TShockAPI/DB/IQueryBuilder.cs index 9080b289..e88d7c9c 100644 --- a/TShockAPI/DB/IQueryBuilder.cs +++ b/TShockAPI/DB/IQueryBuilder.cs @@ -16,6 +16,7 @@ namespace TShockAPI.DB string UpdateValue(string table, List values, List wheres); string InsertValues(string table, List values); string ReadColumn(string table, List wheres); + string DeleteRow(string table, List wheres); } public class SqliteQueryCreator : IQueryBuilder @@ -51,6 +52,22 @@ namespace TShockAPI.DB * Twitchy - Oh. I get it! */ } + public string DeleteRow(string table, List wheres) + { + var sbwheres = new StringBuilder(); + int count = 0; + foreach (SqlValue where in wheres) + { + sbwheres.Append(where.Name + "=" + where.Value.ToString()); + if (count != wheres.Count - 1) + sbwheres.Append(" AND "); + count++; + } + if (wheres.Count > 0) + return "DELETE FROM '{0}' WHERE {1} ".SFormat(table, sbwheres.ToString()); + else + return "DELETE FROM '{0}'".SFormat(table, sbwheres.ToString()); + } public string UpdateValue(string table, List values, List wheres) { var sbvalues = new StringBuilder(); @@ -68,7 +85,7 @@ namespace TShockAPI.DB { sbwheres.Append(where.Name + "=" + where.Value.ToString()); if (count != wheres.Count - 1) - sbvalues.Append(" AND "); + sbwheres.Append(" AND "); count++; } @@ -99,7 +116,6 @@ namespace TShockAPI.DB sbvalues.Append(", "); count++; } - return "INSERT INTO '{0}' ({1}) VALUES ({2})".SFormat(table, sbnames.ToString(), sbvalues.ToString()); } public string ReadColumn(string table, List wheres) @@ -165,6 +181,22 @@ namespace TShockAPI.DB var drop = "DROP TABLE {0}_{1}".SFormat(rstr, from.Name); return "{0}; {1}; {2}; {3};".SFormat(alter, create, insert, drop); } + public string DeleteRow(string table, List wheres) + { + var sbwheres = new StringBuilder(); + int count = 0; + foreach (SqlValue where in wheres) + { + sbwheres.Append(where.Name + "=" + where.Value.ToString()); + if (count != wheres.Count - 1) + sbwheres.Append(" AND "); + count++; + } + if (wheres.Count > 0) + return "DELETE FROM {0} WHERE {1} ".SFormat(table, sbwheres.ToString()); + else + return "DELETE FROM {0}".SFormat(table, sbwheres.ToString()); + } public string UpdateValue(string table, List values, List wheres) { var sbvalues = new StringBuilder(); @@ -182,7 +214,7 @@ namespace TShockAPI.DB { sbwheres.Append(where.Name + "=" + where.Value.ToString()); if (count != wheres.Count - 1) - sbvalues.Append(" AND "); + sbwheres.Append(" AND "); count++; } diff --git a/TShockAPI/DB/RegionManager.cs b/TShockAPI/DB/RegionManager.cs index 76048d83..3e9ebf77 100644 --- a/TShockAPI/DB/RegionManager.cs +++ b/TShockAPI/DB/RegionManager.cs @@ -20,6 +20,7 @@ using System; using System.Collections.Generic; using System.Data; using System.IO; +using System.Linq; using System.Xml; using Microsoft.Xna.Framework; using MySql.Data.MySqlClient; @@ -54,6 +55,7 @@ namespace TShockAPI.DB } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] public void ImportOld() { String file = Path.Combine(TShock.SavePath, "regions.xml"); @@ -62,77 +64,74 @@ namespace TShockAPI.DB Region region; Rectangle rect; - using (var sr = new StreamReader(file)) + + using (var reader = XmlReader.Create(new StreamReader(file), new XmlReaderSettings { CloseInput = true })) { - using (var reader = XmlReader.Create(sr)) + // Parse the file and display each of the nodes. + while (reader.Read()) { - // Parse the file and display each of the nodes. - while (reader.Read()) + if (reader.NodeType != XmlNodeType.Element || reader.Name != "ProtectedRegion") + continue; + + region = new Region(); + rect = new Rectangle(); + + bool endregion = false; + while (reader.Read() && !endregion) { - if (reader.NodeType != XmlNodeType.Element || reader.Name != "ProtectedRegion") + if (reader.NodeType != XmlNodeType.Element) continue; - region = new Region(); - rect = new Rectangle(); + string name = reader.Name; - bool endregion = false; - while (reader.Read() && !endregion) + while (reader.Read() && reader.NodeType != XmlNodeType.Text) ; + + switch (name) { - if (reader.NodeType != XmlNodeType.Element) - continue; - - string name = reader.Name; - - while (reader.Read() && reader.NodeType != XmlNodeType.Text) ; - - switch (name) - { - case "RegionName": - region.Name = reader.Value; - break; - case "Point1X": - int.TryParse(reader.Value, out rect.X); - break; - case "Point1Y": - int.TryParse(reader.Value, out rect.Y); - break; - case "Point2X": - int.TryParse(reader.Value, out rect.Width); - break; - case "Point2Y": - int.TryParse(reader.Value, out rect.Height); - break; - case "Protected": - region.DisableBuild = reader.Value.ToLower().Equals("true"); - break; - case "WorldName": - region.WorldID = reader.Value; - break; - case "AllowedUserCount": - break; - case "IP": - region.AllowedIDs.Add(int.Parse(reader.Value)); - break; - default: - endregion = true; - break; - } - } - - region.Area = rect; - using (var com = database.CreateCommand()) - { - string query = (TShock.Config.StorageType.ToLower() == "sqlite") ? - "INSERT OR IGNORE INTO Regions VALUES (@0, @1, @2, @3, @4, @5, @6, @7);" : - "INSERT IGNORE INTO Regions SET X1=@0, Y1=@1, height=@2, width=@3, RegionName=@4, WorldID=@5, UserIds=@6, Protected=@7;"; - database.Query(query, region.Area.X, region.Area.Y, region.Area.Width, region.Area.Height, region.Name, region.WorldID, "", region.DisableBuild); - - //Todo: What should this be? We don't really have a way to go from ips to userids - /*string.Join(",", region.AllowedIDs)*/ + case "RegionName": + region.Name = reader.Value; + break; + case "Point1X": + int.TryParse(reader.Value, out rect.X); + break; + case "Point1Y": + int.TryParse(reader.Value, out rect.Y); + break; + case "Point2X": + int.TryParse(reader.Value, out rect.Width); + break; + case "Point2Y": + int.TryParse(reader.Value, out rect.Height); + break; + case "Protected": + region.DisableBuild = reader.Value.ToLower().Equals("true"); + break; + case "WorldName": + region.WorldID = reader.Value; + break; + case "AllowedUserCount": + break; + case "IP": + region.AllowedIDs.Add(int.Parse(reader.Value)); + break; + default: + endregion = true; + break; } } + + region.Area = rect; + string query = (TShock.Config.StorageType.ToLower() == "sqlite") ? + "INSERT OR IGNORE INTO Regions VALUES (@0, @1, @2, @3, @4, @5, @6, @7);" : + "INSERT IGNORE INTO Regions SET X1=@0, Y1=@1, height=@2, width=@3, RegionName=@4, WorldID=@5, UserIds=@6, Protected=@7;"; + database.Query(query, region.Area.X, region.Area.Y, region.Area.Width, region.Area.Height, region.Name, region.WorldID, "", region.DisableBuild); + + //Todo: What should this be? We don't really have a way to go from ips to userids + /*string.Join(",", region.AllowedIDs)*/ + } } + String path = Path.Combine(TShock.SavePath, "old_configs"); String file2 = Path.Combine(path, "regions.xml"); if (!Directory.Exists(path)) @@ -171,31 +170,30 @@ namespace TShockAPI.DB int height = reader.Get("height"); int width = reader.Get("width"); int Protected = reader.Get("Protected"); - string MergedIDs = reader.Get("UserIds"); + string mergedids = reader.Get("UserIds"); string name = reader.Get("RegionName"); - string[] SplitIDs = MergedIDs.Split(','); + string[] splitids = mergedids.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries); Region r = new Region(new Rectangle(X1, Y1, width, height), name, Protected != 0, Main.worldID.ToString()); try { - for (int i = 0; i < SplitIDs.Length; i++) + for (int i = 0; i < splitids.Length; i++) { int id; - if (Int32.TryParse(SplitIDs[i], out id)) // if unparsable, it's not an int, so silently skip + if (Int32.TryParse(splitids[i], out id)) // if unparsable, it's not an int, so silently skip r.AllowedIDs.Add(id); - else if (SplitIDs[i] == "") // Split gotcha, can return an empty string with certain conditions - // but we only want to let the user know if it's really a nonparsable integer. - Log.Warn("One of your UserIDs is not a usable integer: " + SplitIDs[i]); + else + Log.Warn("One of your UserIDs is not a usable integer: " + splitids[i]); } } catch (Exception e) { Log.Error("Your database contains invalid UserIDs (they should be ints)."); Log.Error("A lot of things will fail because of this. You must manually delete and re-create the allowed field."); - Log.Error(e.Message); + Log.Error(e.ToString()); Log.Error(e.StackTrace); } @@ -346,29 +344,7 @@ namespace TShockAPI.DB public static List ListIDs(string MergedIDs) { - List SplitIDs = new List(); - /*var sb = new StringBuilder(); - for (int i = 0; i < MergedIDs.Length; i++) - { - char c = MergedIDs[i]; - - if (c != ',') - { - sb.Append(c); - } - else if (sb.Length > 0) - { - SplitIDs.Add(sb.ToString()); - sb.Clear(); - } - }*/ - String[] s = MergedIDs.Split(','); - for (int i = 0; i < s.Length; i++) - { - if (!s[i].Equals("")) - SplitIDs.Add(s[i]); - } - return SplitIDs; + return MergedIDs.Split(new []{','}, StringSplitOptions.RemoveEmptyEntries).ToList(); } public bool AddNewUser(string regionName, String userName) @@ -382,7 +358,7 @@ namespace TShockAPI.DB MergedIDs = reader.Get("UserIds"); } - if (MergedIDs == string.Empty) + if (string.IsNullOrEmpty(MergedIDs)) MergedIDs = Convert.ToString(TShock.Users.GetUserID(userName)); else MergedIDs = MergedIDs + "," + Convert.ToString(TShock.Users.GetUserID(userName)); diff --git a/TShockAPI/DB/SqlTable.cs b/TShockAPI/DB/SqlTable.cs index 3ccca4c4..21d289e1 100644 --- a/TShockAPI/DB/SqlTable.cs +++ b/TShockAPI/DB/SqlTable.cs @@ -76,5 +76,10 @@ namespace TShockAPI.DB return ret; } + + public void DeleteRow(string table, List wheres) + { + database.Query(creator.DeleteRow(table, wheres)); + } } } diff --git a/TShockAPI/DB/UserManager.cs b/TShockAPI/DB/UserManager.cs index de943668..ea875cb0 100644 --- a/TShockAPI/DB/UserManager.cs +++ b/TShockAPI/DB/UserManager.cs @@ -35,9 +35,9 @@ namespace TShockAPI.DB var table = new SqlTable("Users", new SqlColumn("ID", MySqlDbType.Int32) { Primary = true, AutoIncrement = true }, new SqlColumn("Username", MySqlDbType.VarChar, 32) { Unique = true }, - new SqlColumn("Password", MySqlDbType.VarChar, 64), + new SqlColumn("Password", MySqlDbType.VarChar, 128), new SqlColumn("Usergroup", MySqlDbType.Text), - new SqlColumn("IP", MySqlDbType.VarChar, 32) + new SqlColumn("IP", MySqlDbType.VarChar, 16) ); var creator = new SqlTableCreator(db, db.GetSqlType() == SqlType.Sqlite ? (IQueryBuilder)new SqliteQueryCreator() : new MysqlQueryCreator()); creator.EnsureExists(table); @@ -178,34 +178,6 @@ namespace TShockAPI.DB } } - - /// - /// Fetches the hashed password and group for a given username - /// - /// string username - /// string[] {password, group} - public string[] FetchHashedPasswordAndGroup(string username) - { - string[] returndata = new string[2]; - try - { - using (var reader = database.QueryReader("SELECT * FROM Users WHERE Username=@0", username)) - { - if (reader.Read()) - { - returndata[0] = reader.Get("Password"); - returndata[1] = reader.Get("UserGroup"); - return returndata; - } - } - } - catch (Exception ex) - { - Log.ConsoleError("FetchHashedPasswordAndGroup SQL returned an error: " + ex); - } - return returndata; - } - public int GetUserID(string username) { try @@ -314,6 +286,9 @@ namespace TShockAPI.DB { 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; } } @@ -350,6 +325,7 @@ namespace TShockAPI.DB } } + [Serializable] public class UserManagerException : Exception { public UserManagerException(string message) @@ -363,6 +339,7 @@ namespace TShockAPI.DB } } + [Serializable] public class UserExistsException : UserManagerException { public UserExistsException(string name) @@ -370,6 +347,7 @@ namespace TShockAPI.DB { } } + [Serializable] public class UserNotExistException : UserManagerException { public UserNotExistException(string name) @@ -377,7 +355,7 @@ namespace TShockAPI.DB { } } - + [Serializable] public class GroupNotExistsException : UserManagerException { public GroupNotExistsException(string group) diff --git a/TShockAPI/DB/WarpsManager.cs b/TShockAPI/DB/WarpsManager.cs index 8b320149..a6f6c615 100644 --- a/TShockAPI/DB/WarpsManager.cs +++ b/TShockAPI/DB/WarpsManager.cs @@ -31,12 +31,13 @@ namespace TShockAPI.DB { private IDbConnection database; + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] public WarpManager(IDbConnection db) { database = db; var table = new SqlTable("Warps", - new SqlColumn("WarpName", MySqlDbType.VarChar, 50) { Primary = true}, + new SqlColumn("WarpName", MySqlDbType.VarChar, 50) { Primary = true }, new SqlColumn("X", MySqlDbType.Int32), new SqlColumn("Y", MySqlDbType.Int32), new SqlColumn("WorldID", MySqlDbType.Text), @@ -50,78 +51,76 @@ namespace TShockAPI.DB String world = ""; int x1 = 0; int y1 = 0; - if (File.Exists(file)) + if (!File.Exists(file)) + return; + + using (var reader = XmlReader.Create(new StreamReader(file), new XmlReaderSettings { CloseInput = true })) { - XmlReader reader; - using (reader = XmlReader.Create(new StreamReader(file))) + // Parse the file and display each of the nodes. + while (reader.Read()) { - // Parse the file and display each of the nodes. - while (reader.Read()) + switch (reader.NodeType) { - switch (reader.NodeType) - { - case XmlNodeType.Element: - switch (reader.Name) - { - case "Warp": - name = ""; - world = ""; - x1 = 0; - y1 = 0; - break; - case "WarpName": - while (reader.NodeType != XmlNodeType.Text) - reader.Read(); - name = reader.Value; - break; - case "X": - while (reader.NodeType != XmlNodeType.Text) - reader.Read(); - int.TryParse(reader.Value, out x1); - break; - case "Y": - while (reader.NodeType != XmlNodeType.Text) - reader.Read(); - int.TryParse(reader.Value, out y1); - break; - case "WorldName": - while (reader.NodeType != XmlNodeType.Text) - reader.Read(); - world = reader.Value; - break; - } - break; - case XmlNodeType.Text: + case XmlNodeType.Element: + switch (reader.Name) + { + case "Warp": + name = ""; + world = ""; + x1 = 0; + y1 = 0; + break; + case "WarpName": + while (reader.NodeType != XmlNodeType.Text) + reader.Read(); + name = reader.Value; + break; + case "X": + while (reader.NodeType != XmlNodeType.Text) + reader.Read(); + int.TryParse(reader.Value, out x1); + break; + case "Y": + while (reader.NodeType != XmlNodeType.Text) + reader.Read(); + int.TryParse(reader.Value, out y1); + break; + case "WorldName": + while (reader.NodeType != XmlNodeType.Text) + reader.Read(); + world = reader.Value; + break; + } + break; + case XmlNodeType.Text: - break; - case XmlNodeType.XmlDeclaration: - case XmlNodeType.ProcessingInstruction: - break; - case XmlNodeType.Comment: - break; - case XmlNodeType.EndElement: - if (reader.Name.Equals("Warp")) - { - string query = (TShock.Config.StorageType.ToLower() == "sqlite") ? - "INSERT OR IGNORE INTO Warps VALUES (@0, @1,@2, @3);" : - "INSERT IGNORE INTO Warps SET X=@0, Y=@1, WarpName=@2, WorldID=@3;"; - database.Query(query, x1, y1, name, world); - } - break; - } + break; + case XmlNodeType.XmlDeclaration: + case XmlNodeType.ProcessingInstruction: + break; + case XmlNodeType.Comment: + break; + case XmlNodeType.EndElement: + if (reader.Name.Equals("Warp")) + { + string query = (TShock.Config.StorageType.ToLower() == "sqlite") + ? "INSERT OR IGNORE INTO Warps VALUES (@0, @1,@2, @3);" + : "INSERT IGNORE INTO Warps SET X=@0, Y=@1, WarpName=@2, WorldID=@3;"; + database.Query(query, x1, y1, name, world); + } + break; } - } - reader.Close(); - String path = Path.Combine(TShock.SavePath, "old_configs"); - String file2 = Path.Combine(path, "warps.xml"); - if (!Directory.Exists(path)) - Directory.CreateDirectory(path); - if (File.Exists(file2)) - File.Delete(file2); - //File.Move(file, file2); + } + String path = Path.Combine(TShock.SavePath, "old_configs"); + String file2 = Path.Combine(path, "warps.xml"); + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); + if (File.Exists(file2)) + File.Delete(file2); + File.Move(file, file2); } public void ConvertDB() diff --git a/TShockAPI/Extensions/DbExt.cs b/TShockAPI/Extensions/DbExt.cs index 00fe20bd..52f5c011 100644 --- a/TShockAPI/Extensions/DbExt.cs +++ b/TShockAPI/Extensions/DbExt.cs @@ -14,6 +14,7 @@ namespace TShockAPI.DB /// Query string with parameters as @0, @1, etc. /// Parameters to be put in the query /// Rows affected by query + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2100:Review SQL queries for security vulnerabilities")] public static int Query(this IDbConnection olddb, string query, params object[] args) { using (var db = olddb.CloneEx()) @@ -36,6 +37,7 @@ namespace TShockAPI.DB /// Query string with parameters as @0, @1, etc. /// Parameters to be put in the query /// Query result as IDataReader + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2100:Review SQL queries for security vulnerabilities")] public static QueryResult QueryReader(this IDbConnection olddb, string query, params object[] args) { var db = olddb.CloneEx(); @@ -125,10 +127,32 @@ namespace TShockAPI.DB Reader = reader; } + ~QueryResult() + { + Dispose(false); + } + public void Dispose() { - Reader.Dispose(); - Connection.Dispose(); + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + if (Reader != null) + { + Reader.Dispose(); + Reader = null; + } + if (Connection != null) + { + Connection.Dispose(); + Connection = null; + } + } } public bool Read() diff --git a/TShockAPI/FileTools.cs b/TShockAPI/FileTools.cs index 4ca142f1..282eda95 100644 --- a/TShockAPI/FileTools.cs +++ b/TShockAPI/FileTools.cs @@ -73,7 +73,7 @@ namespace TShockAPI Log.Error(ex.ToString()); } - + } /// @@ -88,26 +88,25 @@ namespace TShockAPI return true; } CreateIfNot(WhitelistPath, "127.0.0.1"); - TextReader tr = new StreamReader(WhitelistPath); - string whitelist = tr.ReadToEnd(); - ip = Tools.GetRealIP(ip); - bool contains = whitelist.Contains(ip); - if (!contains) + using (var tr = new StreamReader(WhitelistPath)) { - var char2 = Environment.NewLine.ToCharArray(); - var array = whitelist.Split(Environment.NewLine.ToCharArray()); - foreach (var line in whitelist.Split(Environment.NewLine.ToCharArray())) + string whitelist = tr.ReadToEnd(); + ip = Tools.GetRealIP(ip); + bool contains = whitelist.Contains(ip); + if (!contains) { - if (string.IsNullOrWhiteSpace(line)) - continue; - contains = Tools.GetIPv4Address(line).Equals(ip); - if (contains) - return true; + foreach (var line in whitelist.Split(Environment.NewLine.ToCharArray())) + { + if (string.IsNullOrWhiteSpace(line)) + continue; + contains = Tools.GetIPv4Address(line).Equals(ip); + if (contains) + return true; + } + return false; } - return false; - } - else return true; + } } } } \ No newline at end of file diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index c6be4ace..9f5163ed 100755 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -256,6 +256,37 @@ namespace TShockAPI int x = args.Data.ReadInt32(); int y = args.Data.ReadInt32(); byte tiletype = args.Data.ReadInt8(); + + if (args.Player.AwaitingTemp1) + { + args.Player.TempArea.X = x; + args.Player.TempArea.Y = y; + args.Player.SendMessage("Set Temp Point 1", Color.Yellow); + args.Player.SendTileSquare(x, y); + args.Player.AwaitingTemp1 = false; + return true; + } + + if (args.Player.AwaitingTemp2) + { + if (x > args.Player.TempArea.X && y > args.Player.TempArea.Y) + { + args.Player.TempArea.Width = x - args.Player.TempArea.X; + args.Player.TempArea.Height = y - args.Player.TempArea.Y; + args.Player.SendMessage("Set Temp Point 2", Color.Yellow); + args.Player.SendTileSquare(x, y); + args.Player.AwaitingTemp2 = false; + } + else + { + args.Player.SendMessage("Point 2 must be below and right of Point 1", Color.Yellow); + args.Player.SendMessage("Use /region clear to start again", Color.Yellow); + args.Player.SendTileSquare(x, y); + args.Player.AwaitingTemp2 = false; + } + return true; + } + if (!args.Player.Group.HasPermission("canbuild")) { if (!args.Player.HasBeenSpammedWithBuildMessage) @@ -547,6 +578,36 @@ namespace TShockAPI if (tilex < 0 || tilex >= Main.maxTilesX || tiley < 0 || tiley >= Main.maxTilesY) return false; + if (args.Player.AwaitingTemp1) + { + args.Player.TempArea.X = tilex; + args.Player.TempArea.Y = tiley; + args.Player.SendMessage("Set Temp Point 1", Color.Yellow); + args.Player.SendTileSquare(tilex, tiley); + args.Player.AwaitingTemp1 = false; + return true; + } + + if (args.Player.AwaitingTemp2) + { + if (tilex > args.Player.TempArea.X && tiley > args.Player.TempArea.Y) + { + args.Player.TempArea.Width = tilex - args.Player.TempArea.X; + args.Player.TempArea.Height = tiley - args.Player.TempArea.Y; + args.Player.SendMessage("Set Temp Point 2", Color.Yellow); + args.Player.SendTileSquare(tilex, tiley); + args.Player.AwaitingTemp2 = false; + } + else + { + args.Player.SendMessage("Point 2 must be below and right of Point 1", Color.Yellow); + args.Player.SendMessage("Use /region clear to start again", Color.Yellow); + args.Player.SendTileSquare(tilex, tiley); + args.Player.AwaitingTemp2 = false; + } + return true; + } + if (Main.tile[tilex, tiley].type != 0x15 && (!Tools.MaxChests() && Main.tile[tilex, tiley].type != 0)) //Chest { Log.Debug(string.Format("TileKill(TileXY:{0}_{1}, Type:{2})", diff --git a/TShockAPI/PacketBufferer.cs b/TShockAPI/PacketBufferer.cs index ac309bb5..be00dd72 100644 --- a/TShockAPI/PacketBufferer.cs +++ b/TShockAPI/PacketBufferer.cs @@ -24,8 +24,10 @@ namespace TShockAPI int[] Packets = new int[52]; int[] Compressed = new int[52]; +#if DEBUG_NET Command dump; Command flush; +#endif public PacketBufferer() { @@ -45,15 +47,29 @@ namespace TShockAPI GameHooks.PostUpdate += GameHooks_Update; } + ~PacketBufferer() + { + Dispose(false); + } + public void Dispose() { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { #if DEBUG_NET - Commands.ChatCommands.Remove(dump); - Commands.ChatCommands.Remove(flush); + Commands.ChatCommands.Remove(dump); + Commands.ChatCommands.Remove(flush); #endif NetHooks.SendBytes -= ServerHooks_SendBytes; ServerHooks.SocketReset -= ServerHooks_SocketReset; GameHooks.PostUpdate -= GameHooks_Update; + } } void Dump(CommandArgs args) @@ -120,7 +136,10 @@ namespace TShockAPI Bytes[pt] += size; Compressed[pt] += Compress(buffer, offset, count); #endif - buffers[socket.whoAmI].AddRange(new MemoryStream(buffer, offset, count).ToArray()); + using (var ms = new MemoryStream(buffer, offset, count)) + { + buffers[socket.whoAmI].AddRange(ms.ToArray()); + } } } #if DEBUG_NET diff --git a/TShockAPI/RconHandler.cs b/TShockAPI/RconHandler.cs index 4240b8ed..ec34f563 100644 --- a/TShockAPI/RconHandler.cs +++ b/TShockAPI/RconHandler.cs @@ -24,6 +24,7 @@ using System.Net.Sockets; using System.Text; using System.Threading; using Terraria; +using XNAHelpers; namespace TShockAPI { @@ -116,11 +117,13 @@ namespace TShockAPI try { var EP = new IPEndPoint(IPAddress.Any, port); - UdpClient client = new UdpClient(); - client.Connect(hostname, port); - client.Client.ReceiveTimeout = 500; - client.Send(bytes, bytes.Length); - response = Encoding.UTF8.GetString(client.Receive(ref EP)); + using (var client = new UdpClient()) + { + client.Connect(hostname, port); + client.Client.ReceiveTimeout = 500; + client.Send(bytes, bytes.Length); + response = Encoding.UTF8.GetString(client.Receive(ref EP)); + } } catch (Exception e) { @@ -244,7 +247,7 @@ namespace TShockAPI if (player != null && player.Active) { count++; - TSPlayer.Server.SendMessage(string.Format("{0} ({1}) [{2}]", player.Name, player.IP, player.Group.Name)); + TSPlayer.Server.SendMessage(string.Format("{0} ({1}) [{2}] <{3}>", player.Name, player.IP, player.Group.Name, player.UserAccountName)); } } TSPlayer.Server.SendMessage(string.Format("{0} players connected.", count)); @@ -259,7 +262,7 @@ namespace TShockAPI if (player != null && player.Active) { count++; - Response += (string.Format("{0} 0 0 {1}({2}) {3} {4} 0 0", count, player.Name, player.Group.Name, Netplay.serverSock[player.Index].tcpClient.Client.RemoteEndPoint)) + "\n"; + Response += (string.Format("{0} 0 0 {1}({2}) {3} {4} 0 0", count, player.Name, player.Group.Name, Netplay.serverSock[player.Index].tcpClient.Client.RemoteEndPoint, "")) + "\n"; } } } @@ -288,17 +291,18 @@ namespace TShockAPI private static byte[] ConstructPacket(string response, bool print) { var oob = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF }; - MemoryStream stream = new MemoryStream(); - BinaryWriter writer = new BinaryWriter(stream); - writer.Write(oob); - if (print) - writer.Write(Encoding.UTF8.GetBytes(string.Format("print\n{0}", response))); - else - writer.Write(Encoding.UTF8.GetBytes(response)); - var trimmedpacket = new byte[(int)stream.Length]; - var packet = stream.GetBuffer(); - Array.Copy(packet, trimmedpacket, (int)stream.Length); - return trimmedpacket; + using (var stream = new MemoryStream()) + { + stream.WriteBytes(oob); + if (print) + stream.WriteBytes(Encoding.UTF8.GetBytes(string.Format("print\n{0}", response))); + else + stream.WriteBytes(Encoding.UTF8.GetBytes(response)); + var trimmedpacket = new byte[(int)stream.Length]; + var packet = stream.GetBuffer(); + Array.Copy(packet, trimmedpacket, (int)stream.Length); + return trimmedpacket; + } } private static byte[] PadPacket(byte[] packet) diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 33cf3bbe..077eff5a 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -39,6 +39,8 @@ namespace TShockAPI public int Index { get; protected set; } public DateTime LastPvpChange { get; protected set; } public Rectangle TempArea; + public bool AwaitingTemp1 { get; set; } + public bool AwaitingTemp2 { get; set; } public DateTime LastExplosive { get; set; } public DateTime LastTileChangeNotify { get; set; } public bool InitSpawn; @@ -178,9 +180,11 @@ namespace TShockAPI }; - var ms = new MemoryStream(); - msg.PackFull(ms); - SendRawData(ms.ToArray()); + using (var ms = new MemoryStream()) + { + msg.PackFull(ms); + SendRawData(ms.ToArray()); + } } public bool Teleport(int tilex, int tiley) diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs old mode 100755 new mode 100644 index 07ad2dcc..a3e9b07a --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -94,6 +94,7 @@ namespace TShockAPI Order = 0; } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] public override void Initialize() { if (!Directory.Exists(SavePath)) @@ -315,15 +316,17 @@ namespace TShockAPI Console.WriteLine("This token will display until disabled by verification. (/auth-verify)"); Console.ForegroundColor = ConsoleColor.Gray; FileTools.CreateFile(Path.Combine(SavePath, "authcode.txt")); - TextWriter tw = new StreamWriter(Path.Combine(SavePath, "authcode.txt")); - tw.WriteLine(AuthToken); - tw.Close(); + using (var tw = new StreamWriter(Path.Combine(SavePath, "authcode.txt"))) + { + tw.WriteLine(AuthToken); + } } else if (File.Exists(Path.Combine(SavePath, "authcode.txt"))) { - TextReader tr = new StreamReader(Path.Combine(SavePath, "authcode.txt")); - AuthToken = Convert.ToInt32(tr.ReadLine()); - tr.Close(); + using (var tr = new StreamReader(Path.Combine(SavePath, "authcode.txt"))) + { + AuthToken = Convert.ToInt32(tr.ReadLine()); + } Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine( "TShock Notice: authcode.txt is still present, and the AuthToken located in that file will be used."); @@ -445,6 +448,9 @@ namespace TShockAPI private void OnChat(messageBuffer msg, int ply, string text, HandledEventArgs e) { + if (e.Handled) + return; + var tsplr = Players[msg.whoAmI]; if (tsplr == null) { @@ -528,8 +534,8 @@ namespace TShockAPI if (player != null && player.Active) { count++; - TSPlayer.Server.SendMessage(string.Format("{0} ({1}) [{2}]", player.Name, player.IP, - player.Group.Name)); + TSPlayer.Server.SendMessage(string.Format("{0} ({1}) [{2}] <{3}>", player.Name, player.IP, + player.Group.Name, player.UserAccountName)); } } TSPlayer.Server.SendMessage(string.Format("{0} players connected.", count)); @@ -554,6 +560,9 @@ namespace TShockAPI private void GetData(GetDataEventArgs e) { + if (e.Handled) + return; + PacketTypes type = e.MsgID; var player = Players[e.Msg.whoAmI]; if (player == null) diff --git a/TShockAPI/Tools.cs b/TShockAPI/Tools.cs index 241ca1a3..58eb74d2 100755 --- a/TShockAPI/Tools.cs +++ b/TShockAPI/Tools.cs @@ -428,34 +428,36 @@ namespace TShockAPI public static void ShowFileToUser(TSPlayer player, string file) { string foo = ""; - TextReader tr = new StreamReader(Path.Combine(TShock.SavePath, file)); - while ((foo = tr.ReadLine()) != null) + using (var tr = new StreamReader(Path.Combine(TShock.SavePath, file))) { - foo = foo.Replace("%map%", Main.worldName); - foo = foo.Replace("%players%", GetPlayers()); - if (foo.Substring(0, 1) == "%" && foo.Substring(12, 1) == "%") //Look for a beginning color code. + while ((foo = tr.ReadLine()) != null) { - string possibleColor = foo.Substring(0, 13); - foo = foo.Remove(0, 13); - float[] pC = { 0, 0, 0 }; - possibleColor = possibleColor.Replace("%", ""); - string[] pCc = possibleColor.Split(','); - if (pCc.Length == 3) + foo = foo.Replace("%map%", Main.worldName); + foo = foo.Replace("%players%", GetPlayers()); + if (foo.Substring(0, 1) == "%" && foo.Substring(12, 1) == "%") //Look for a beginning color code. { - try + string possibleColor = foo.Substring(0, 13); + foo = foo.Remove(0, 13); + float[] pC = {0, 0, 0}; + possibleColor = possibleColor.Replace("%", ""); + string[] pCc = possibleColor.Split(','); + if (pCc.Length == 3) { - player.SendMessage(foo, (byte)Convert.ToInt32(pCc[0]), (byte)Convert.ToInt32(pCc[1]), (byte)Convert.ToInt32(pCc[2])); - continue; - } - catch (Exception e) - { - Log.Error(e.ToString()); + try + { + player.SendMessage(foo, (byte) Convert.ToInt32(pCc[0]), (byte) Convert.ToInt32(pCc[1]), + (byte) Convert.ToInt32(pCc[2])); + continue; + } + catch (Exception e) + { + Log.Error(e.ToString()); + } } } + player.SendMessage(foo); } - player.SendMessage(foo); } - tr.Close(); } /// diff --git a/TShockAPI/UpdateManager.cs b/TShockAPI/UpdateManager.cs index 8d86d3c5..6f20816b 100644 --- a/TShockAPI/UpdateManager.cs +++ b/TShockAPI/UpdateManager.cs @@ -55,26 +55,28 @@ namespace TShockAPI /// private static bool ServerIsOutOfDate() { - WebClient client = new WebClient(); - client.Headers.Add("user-agent", - "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705;)"); - try + using (var client = new WebClient()) { - string updateString = client.DownloadString(updateUrl); - string[] changes = updateString.Split(','); - Version updateVersion = new Version(Convert.ToInt32(changes[0]), Convert.ToInt32(changes[1]), - Convert.ToInt32(changes[2]), Convert.ToInt32(changes[3])); - if (TShock.VersionNum.CompareTo(updateVersion) < 0) + client.Headers.Add("user-agent", + "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705;)"); + try { - globalChanges = changes; - return true; + string updateString = client.DownloadString(updateUrl); + string[] changes = updateString.Split(','); + Version updateVersion = new Version(Convert.ToInt32(changes[0]), Convert.ToInt32(changes[1]), + Convert.ToInt32(changes[2]), Convert.ToInt32(changes[3])); + if (TShock.VersionNum.CompareTo(updateVersion) < 0) + { + globalChanges = changes; + return true; + } } + catch (Exception e) + { + Log.Error(e.ToString()); + } + return false; } - catch (Exception e) - { - Log.Error(e.ToString()); - } - return false; } private static void NotifyAdministrators(string[] changes) diff --git a/UnitTests/BanManagerTest.cs b/UnitTests/BanManagerTest.cs index e7c206c4..d18ca714 100644 --- a/UnitTests/BanManagerTest.cs +++ b/UnitTests/BanManagerTest.cs @@ -29,7 +29,7 @@ namespace UnitTests } [TestMethod] - public void TestDBNotNull() + public void TestBansDBNotNull() { Assert.IsNotNull(Bans); } diff --git a/UnitTests/BanManagerTest.orderedtest b/UnitTests/BanManagerTest.orderedtest index 1d93a5b5..646da342 100644 --- a/UnitTests/BanManagerTest.orderedtest +++ b/UnitTests/BanManagerTest.orderedtest @@ -1,7 +1,7 @@  - + - + diff --git a/UnitTests/GroupManagerTest.cs b/UnitTests/GroupManagerTest.cs new file mode 100644 index 00000000..b38eb2ae --- /dev/null +++ b/UnitTests/GroupManagerTest.cs @@ -0,0 +1,63 @@ +using System; +using System.Data; +using System.Text; +using System.Collections.Generic; +using System.Linq; +using Community.CsharpSqlite.SQLiteClient; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using TShockAPI; +using TShockAPI.DB; + +namespace UnitTests +{ + [TestClass] + public class GroupManagerTest + { + public static IDbConnection DB; + private GroupManager Groups; + + [TestInitialize] + public void Initialize() + { + TShock.Config = new ConfigFile(); + TShock.Config.StorageType = "sqlite"; + + DB = new SqliteConnection(string.Format("uri=file://{0},Version=3", "tshock.test.sqlite")); + DB.Open(); + + Groups = new GroupManager(DB); + TShock.Groups = this.Groups; + } + + [TestMethod] + public void TestGroupsDBNotNull() + { + Assert.IsNotNull(Groups); + } + + [TestMethod] + public void CreateGroup() + { + Assert.IsTrue(Groups.AddGroup("test1", "heal") != ""); + Assert.IsTrue(Groups.GroupExists("test1")); + Assert.IsTrue(Tools.GetGroup("test1").HasPermission("heal")); + } + + [TestMethod] + public void DeleteGroup() + { + Assert.IsTrue(Groups.AddGroup("test1", "heal") != ""); + Assert.IsTrue(Groups.GroupExists("test1")); + Assert.IsTrue(Groups.DeleteGroup("test1") != ""); + Assert.IsFalse( Groups.GroupExists( "test1") ); + } + + /*[TestMethod] + public void CreateGroup() + { + Assert.IsTrue(Groups.AddGroup("test1", "heal") != ""); + Assert.IsTrue(Groups.GroupExists("test1")); + Assert.IsTrue(Tools.GetGroup("test1").HasPermission("heal")); + }*/ + } +} diff --git a/UnitTests/GroupManagerTest.orderedtest b/UnitTests/GroupManagerTest.orderedtest new file mode 100644 index 00000000..b7c5c255 --- /dev/null +++ b/UnitTests/GroupManagerTest.orderedtest @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/UnitTests/UnitTests.csproj b/UnitTests/UnitTests.csproj index 86f31eec..6ece350a 100644 --- a/UnitTests/UnitTests.csproj +++ b/UnitTests/UnitTests.csproj @@ -87,6 +87,7 @@ + @@ -104,6 +105,9 @@ Always + + Always + Always