From f0bf0ad82098e2cbdd818f4391368544e6f2a102 Mon Sep 17 00:00:00 2001 From: White Date: Mon, 1 Feb 2016 12:11:42 +1030 Subject: [PATCH] Added an ID property to Regions. Commented and simplified some RegionManager code --- TShockAPI/DB/RegionManager.cs | 281 +++++++++++++++++++++++++--------- 1 file changed, 209 insertions(+), 72 deletions(-) diff --git a/TShockAPI/DB/RegionManager.cs b/TShockAPI/DB/RegionManager.cs index 622b94e2..09862c9d 100755 --- a/TShockAPI/DB/RegionManager.cs +++ b/TShockAPI/DB/RegionManager.cs @@ -70,6 +70,7 @@ namespace TShockAPI.DB Regions.Clear(); while (reader.Read()) { + int id = reader.Get("Id"); int X1 = reader.Get("X1"); int Y1 = reader.Get("Y1"); int height = reader.Get("height"); @@ -83,16 +84,16 @@ namespace TShockAPI.DB string[] splitids = mergedids.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries); - Region r = new Region(new Rectangle(X1, Y1, width, height), name, owner, Protected != 0, Main.worldID.ToString(), z); + Region r = new Region(id, new Rectangle(X1, Y1, width, height), name, owner, Protected != 0, Main.worldID.ToString(), z); r.SetAllowedGroups(groups); try { for (int i = 0; i < splitids.Length; i++) { - int id; + int userid; - if (Int32.TryParse(splitids[i], out id)) // if unparsable, it's not an int, so silently skip - r.AllowedIDs.Add(id); + if (Int32.TryParse(splitids[i], out userid)) // if unparsable, it's not an int, so silently skip + r.AllowedIDs.Add(userid); else TShock.Log.Warn("One of your UserIDs is not a usable integer: " + splitids[i]); } @@ -138,7 +139,12 @@ namespace TShockAPI.DB database.Query( "INSERT INTO Regions (X1, Y1, width, height, RegionName, WorldID, UserIds, Protected, Groups, Owner, Z) VALUES (@0, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10);", tx, ty, width, height, regionname, worldid, "", 1, "", owner, z); - var region = new Region(new Rectangle(tx, ty, width, height), regionname, owner, true, worldid, z); + int id; + using (QueryResult res = database.QueryReader("SELECT Id FROM Regions WHERE RegionName = @0 AND WorldID = @1", regionname, worldid)) + { + id = res.Get("Id"); + } + var region = new Region(id, new Rectangle(tx, ty, width, height), regionname, owner, true, worldid, z); Regions.Add(region); Hooks.RegionHooks.OnRegionCreated(region); return true; @@ -150,6 +156,29 @@ namespace TShockAPI.DB return false; } + /// + /// Delets the region from this world with a given ID. + /// + /// The ID of the region to delete. + /// Whether the region was successfully deleted. + public bool DeleteRegion(int id) + { + try + { + database.Query("DELETE FROM Regions WHERE Id=@0 AND WorldID=@1", id, Main.worldID.ToString()); + var worldid = Main.worldID.ToString(); + var region = Regions.FirstOrDefault(r => r.ID == id && r.WorldID == worldid); + Regions.RemoveAll(r => r.ID == id && r.WorldID == worldid); + Hooks.RegionHooks.OnRegionDeleted(region); + return true; + } + catch (Exception ex) + { + TShock.Log.Error(ex.ToString()); + } + return false; + } + /// /// Deletes the region from this world with a given name. /// @@ -173,6 +202,38 @@ namespace TShockAPI.DB return false; } + /// + /// Sets the protected state of the region with a given ID. + /// + /// The ID of the region to change. + /// New protected state of the region. + /// Whether the region's state was successfully changed. + public bool SetRegionState(int id, bool state) + { + try + { + database.Query("UPDATE Regions SET Protected = @0 WHERE Id = @1 AND WorldID = @2", state ? 1 : 0, id, + Main.worldID.ToString()); + var region = GetRegionByID(id); + if (region != null) + { + region.DisableBuild = state; + } + return true; + } + catch (Exception ex) + { + TShock.Log.Error(ex.ToString()); + return false; + } + } + + /// + /// Sets the protected state of the region with a given name. + /// + /// The name of the region to change. + /// New protected state of the region. + /// Whether the region's state was successfully changed. public bool SetRegionState(string name, bool state) { try @@ -191,23 +252,13 @@ namespace TShockAPI.DB } } - public bool SetRegionStateTest(string name, string world, bool state) - { - try - { - database.Query("UPDATE Regions SET Protected=@0 WHERE RegionName=@1 AND WorldID=@2", state ? 1 : 0, name, world); - var region = GetRegionByName(name); - if (region != null) - region.DisableBuild = state; - return true; - } - catch (Exception ex) - { - TShock.Log.Error(ex.ToString()); - return false; - } - } - + /// + /// Checks if a given player can build in a region at the given (x, y) coordinate + /// + /// X coordinate + /// Y coordinate + /// Player to check permissions with + /// Whether the player can build at the given (x, y) coordinate public bool CanBuild(int x, int y, TSPlayer ply) { if (!ply.HasPermission(Permissions.canbuild)) @@ -227,52 +278,70 @@ namespace TShockAPI.DB return top == null || top.HasPermissionToBuildInRegion(ply); } + /// + /// Checks if any regions exist at the given (x, y) coordinate + /// + /// X coordinate + /// Y coordinate + /// Whether any regions exist at the given (x, y) coordinate public bool InArea(int x, int y) { - foreach (Region region in Regions.ToList()) - { - if (x >= region.Area.Left && x <= region.Area.Right && - y >= region.Area.Top && y <= region.Area.Bottom) - { - return true; - } - } - return false; + return Regions.Any(r => r.InArea(x, y)); } - public List InAreaRegionName(int x, int y) + /// + /// Checks if any regions exist at the given (x, y) coordinate + /// and returns an IEnumerable containing their names + /// + /// X coordinate + /// Y coordinate + /// The names of any regions that exist at the given (x, y) coordinate + public IEnumerable InAreaRegionName(int x, int y) { - List regions = new List() { }; - foreach (Region region in Regions.ToList()) - { - if (x >= region.Area.Left && x <= region.Area.Right && - y >= region.Area.Top && y <= region.Area.Bottom) - { - regions.Add(region.Name); - } - } - return regions; + return Regions.Where(r => r.InArea(x, y)).Select(r => r.Name); } - public List InAreaRegion(int x, int y) + /// + /// Checks if any regions exist at the given (x, y) coordinate + /// and returns an IEnumerable containing their IDs + /// + /// X coordinate + /// Y coordinate + /// The IDs of any regions that exist at the given (x, y) coordinate + public IEnumerable InAreaRegionID(int x, int y) { - List regions = new List() { }; - foreach (Region region in Regions.ToList()) - { - if (x >= region.Area.Left && x <= region.Area.Right && - y >= region.Area.Top && y <= region.Area.Bottom) - { - regions.Add(region); - } - } - return regions; + return Regions.Where(r => r.InArea(x, y)).Select(r => r.ID); } + /// + /// Checks if any regions exist at the given (x, y) coordinate + /// and returns an IEnumerable containing their objects + /// + /// X coordinate + /// Y coordinate + /// The objects of any regions that exist at the given (x, y) coordinate + public IEnumerable InAreaRegion(int x, int y) + { + return Regions.Where(r => r.InArea(x, y)); + } + + [Obsolete("Unused")] public static List ListIDs(string MergedIDs) { return MergedIDs.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).ToList(); } + /// + /// Changes the size of a given region + /// + /// Name of the region to resize + /// Amount to resize + /// Direction to resize in: + /// 0 = resize height and Y. + /// 1 = resize width. + /// 2 = resize height. + /// 3 = resize width and X. + /// public bool ResizeRegion(string regionName, int addAmount, int direction) { //0 = up @@ -448,11 +517,32 @@ namespace TShockAPI.DB return regions; } + /// + /// Returns a region with the given name + /// + /// Region name + /// The region with the given name, or null if not found public Region GetRegionByName(String name) { return Regions.FirstOrDefault(r => r.Name.Equals(name) && r.WorldID == Main.worldID.ToString()); } + /// + /// Returns a region with the given ID + /// + /// Region ID + /// The region with the given ID, or null if not found + public Region GetRegionByID(int id) + { + return Regions.FirstOrDefault(r => r.ID == id && r.WorldID == Main.worldID.ToString()); + } + + /// + /// Changes the owner of the region with the given name + /// + /// Region name + /// New owner's username + /// Whether the change was successfull public bool ChangeOwner(string regionName, string newOwner) { var region = GetRegionByName(regionName); @@ -467,6 +557,12 @@ namespace TShockAPI.DB return false; } + /// + /// Allows a group to use a region + /// + /// Region name + /// Group's name + /// Whether the change was successfull public bool AllowGroup(string regionName, string groupName) { string mergedGroups = ""; @@ -503,6 +599,12 @@ namespace TShockAPI.DB return q > 0; } + /// + /// Removes a group's access to a region + /// + /// Region name + /// Group name + /// Whether the change was successfull public bool RemoveGroup(string regionName, string group) { Region r = GetRegionByName(regionName); @@ -518,10 +620,15 @@ namespace TShockAPI.DB return false; } - public Region GetTopRegion( List regions ) + /// + /// Returns the with the highest Z index of the given list + /// + /// List of Regions to compare + /// + public Region GetTopRegion(IEnumerable regions) { Region ret = null; - foreach( Region r in regions) + foreach (Region r in regions) { if (ret == null) ret = r; @@ -534,7 +641,13 @@ namespace TShockAPI.DB return ret; } - public bool SetZ( string name, int z ) + /// + /// Sets the Z index of a given region + /// + /// Region name + /// New Z index + /// Whether the change was successfull + public bool SetZ(string name, int z) { try { @@ -556,6 +669,7 @@ namespace TShockAPI.DB public class Region { + public int ID { get; set; } public Rectangle Area { get; set; } public string Name { get; set; } public string Owner { get; set; } @@ -565,9 +679,10 @@ namespace TShockAPI.DB public List AllowedGroups { get; set; } public int Z { get; set; } - public Region(Rectangle region, string name, string owner, bool disablebuild, string RegionWorldIDz, int z) + public Region(int id, Rectangle region, string name, string owner, bool disablebuild, string RegionWorldIDz, int z) : this() { + ID = id; Area = region; Name = name; Owner = owner; @@ -587,27 +702,32 @@ namespace TShockAPI.DB Z = 0; } + /// + /// Checks if a given point is in the region's area + /// + /// Point to check + /// Whether the point exists in the region's area public bool InArea(Rectangle point) { - if (Area.Contains(point.X, point.Y)) - { - return true; - } - return false; + return Area.Contains(point.X, point.Y); } - + + /// + /// Checks if a given (x, y) coordinate is in the region's area + /// + /// X coordinate to check + /// Y coordinate to check + /// Whether the coordinate exists in the region's area public bool InArea(int x, int y) //overloaded with x,y { - - if (x >= Area.Left && x <= Area.Right && y >= Area.Top && y <= Area.Bottom) - { - return true; - } - - return false; + return Area.Contains(x, y); } - - + + /// + /// Checks if a given player has permission to build in the region + /// + /// Player to check permissions with + /// Whether the player has permission public bool HasPermissionToBuildInRegion(TSPlayer ply) { if (!DisableBuild) @@ -627,6 +747,10 @@ namespace TShockAPI.DB return AllowedIDs.Contains(ply.User.ID) || AllowedGroups.Contains(ply.Group.Name) || Owner == ply.User.Name; } + /// + /// Sets the user IDs which are allowed to use the region + /// + /// String of IDs to set public void SetAllowedIDs(String ids) { String[] id_arr = ids.Split(','); @@ -641,6 +765,10 @@ namespace TShockAPI.DB AllowedIDs = id_list; } + /// + /// Sets the group names which are allowed to use the region + /// + /// String of group names to set public void SetAllowedGroups(String groups) { // prevent null pointer exceptions @@ -655,6 +783,10 @@ namespace TShockAPI.DB } } + /// + /// Removes a user's access to the region + /// + /// User ID to remove public void RemoveID(int id) { var index = -1; @@ -669,6 +801,11 @@ namespace TShockAPI.DB AllowedIDs.RemoveAt(index); } + /// + /// Removes a group's access to the region + /// + /// Group name to remove + /// public bool RemoveGroup(string groupName) { return AllowedGroups.Remove(groupName);