Added an ID property to Regions. Commented and simplified some RegionManager code

This commit is contained in:
White 2016-02-01 12:11:42 +10:30
parent d665474278
commit f0bf0ad820

View file

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