diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs
index d4727962..0bbf77e5 100644
--- a/TShockAPI/Bouncer.cs
+++ b/TShockAPI/Bouncer.cs
@@ -76,7 +76,7 @@ namespace TShockAPI
return;
}
- if (TShock.CheckTilePermission(args.Player, args.X, args.Y))
+ if (!args.Player.HasBuildPermission(args.X, args.Y))
{
NetMessage.SendData((int)PacketTypes.UpdateTileEntity, -1, -1, NetworkText.Empty, args.ItemFrame.ID, 0, 1);
args.Handled = true;
@@ -114,7 +114,7 @@ namespace TShockAPI
return;
}
- if (TShock.CheckTilePermission(args.Player, args.X, args.Y))
+ if (!args.Player.HasBuildPermission(args.X, args.Y))
{
args.Handled = true;
return;
@@ -132,7 +132,7 @@ namespace TShockAPI
return;
}
- if (TShock.CheckTilePermission(args.Player, args.X, args.Y))
+ if (!args.Player.HasBuildPermission(args.X, args.Y))
{
args.Handled = true;
return;
@@ -183,7 +183,7 @@ namespace TShockAPI
return;
}
- if (TShock.CheckTilePermission(args.Player, x, y))
+ if (!args.Player.HasBuildPermission(x, y))
{
args.Handled = true;
return;
@@ -510,7 +510,7 @@ namespace TShockAPI
return;
}
- if (TShock.CheckTilePermission(args.Player, Main.chest[id].x, Main.chest[id].y) && TShock.Config.RegionProtectChests)
+ if (!args.Player.HasBuildPermission(Main.chest[id].x, Main.chest[id].y) && TShock.Config.RegionProtectChests)
{
args.Handled = true;
return;
@@ -535,7 +535,7 @@ namespace TShockAPI
// Calls to TShock.CheckTilePermission need to be broken up into different subsystems
// In particular, this handles both regions and other things. Ouch.
- if (TShock.CheckTilePermission(args.Player, x, y))
+ if (!args.Player.HasBuildPermission(x, y))
{
args.Player.SendErrorMessage("You do not have access to modify this area.");
args.Player.SendData(PacketTypes.UpdateNPCHome, "", id, Main.npc[id].homeTileX, Main.npc[id].homeTileY,
@@ -570,7 +570,7 @@ namespace TShockAPI
return;
}
- if (TShock.CheckTilePermission(args.Player, args.X, args.Y) && TShock.Config.RegionProtectChests)
+ if (!args.Player.HasBuildPermission(args.X, args.Y) && TShock.Config.RegionProtectChests)
{
args.Handled = true;
return;
@@ -625,7 +625,7 @@ namespace TShockAPI
}
}
- if (TShock.CheckTilePermission(args.Player, tileX, tileY))
+ if (!args.Player.HasBuildPermission(tileX, tileY))
{
args.Player.SendTileSquare(tileX, tileY, 3);
args.Handled = true;
@@ -758,7 +758,7 @@ namespace TShockAPI
}
}
- if (TShock.CheckTilePermission(args.Player, tileX, tileY))
+ if (!args.Player.HasBuildPermission(tileX, tileY))
{
args.Player.SendTileSquare(tileX, tileY, 1);
args.Handled = true;
@@ -1660,7 +1660,7 @@ namespace TShockAPI
var tile = Main.tile[realx, realy];
var newtile = tiles[x, y];
- if (TShock.CheckTilePermission(args.Player, realx, realy) ||
+ if (!args.Player.HasBuildPermission(realx, realy) ||
!args.Player.IsInRange(realx, realy))
{
continue;
diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs
index 310a3b64..6d7000a1 100644
--- a/TShockAPI/GetDataHandlers.cs
+++ b/TShockAPI/GetDataHandlers.cs
@@ -2532,7 +2532,7 @@ namespace TShockAPI
args.Player.ActiveChest = id;
- if (TShock.CheckTilePermission(args.Player, x, y) && TShock.Config.RegionProtectChests)
+ if (!args.Player.HasBuildPermission(x, y) && TShock.Config.RegionProtectChests)
{
args.Player.SendData(PacketTypes.ChestOpen, "", -1);
return true;
@@ -2572,7 +2572,7 @@ namespace TShockAPI
if (OnSignEvent(id, x, y))
return true;
- if (TShock.CheckTilePermission(args.Player, x, y))
+ if (!args.Player.HasBuildPermission(x, y))
{
args.Player.SendData(PacketTypes.SignNew, "", id);
return true;
@@ -2897,7 +2897,7 @@ namespace TShockAPI
}
if (args.Player.IsBouncerThrottled() ||
- TShock.CheckTilePermission(args.Player, x, y, true) ||
+ !args.Player.HasPaintPermission(x, y) ||
!args.Player.IsInRange(x, y))
{
args.Player.SendData(PacketTypes.PaintTile, "", x, y, Main.tile[x, y].color());
@@ -2941,7 +2941,7 @@ namespace TShockAPI
}
if (args.Player.IsBouncerThrottled() ||
- TShock.CheckTilePermission(args.Player, x, y, true) ||
+ !args.Player.HasPaintPermission(x, y) ||
!args.Player.IsInRange(x, y))
{
args.Player.SendData(PacketTypes.PaintWall, "", x, y, Main.tile[x, y].wallColor());
diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs
index 8071ea37..05d9844c 100644
--- a/TShockAPI/TSPlayer.cs
+++ b/TShockAPI/TSPlayer.cs
@@ -335,6 +335,56 @@ namespace TShockAPI
return true;
}
+ private enum BuildPermissionFailPoint
+ {
+ GeneralBuild,
+ SpawnProtect,
+ Regions
+ }
+
+ /// Determines if the player can build on a given point.
+ /// The x coordinate they want to build at.
+ /// The y coordinate they want to paint at.
+ /// True if the player can build at the given point from build, spawn, and region protection.
+ public bool HasBuildPermission(int x, int y)
+ {
+ BuildPermissionFailPoint failure = BuildPermissionFailPoint.GeneralBuild;
+ // The goal is to short circuit on easy stuff as much as possible.
+ // Don't compute permissions unless needed, and don't compute taxing stuff unless needed.
+
+ // If the player has bypass on build protection or building is enabled; continue
+ // (General build protection takes precedence over spawn protection)
+ if (!TShock.Config.DisableBuild || HasPermission(Permissions.antibuild))
+ {
+ // If they have spawn protect bypass, or it isn't spawn, or it isn't in spawn; continue
+ // (If they have spawn protect bypass, we don't care if it's spawn or not)
+ if (!TShock.Config.SpawnProtection || HasPermission(Permissions.editspawn) || !Utils.IsInSpawn(x, y))
+ {
+ // If they have build permission in this region, then they're allowed to continue
+ if (TShock.Regions.CanBuild(x, y, this))
+ {
+ return true;
+ }
+ }
+ }
+
+ // TODO: Implement warning system.
+
+ // If they lack build permission, they end up here.
+ // If they have build permission but lack the ability to edit spawn and it's spawn, they end up here.
+ // If they have build, it isn't spawn, or they can edit spawn, but they fail the region check, they end up here.
+ return false;
+ }
+
+ /// Determines if the player can paint on a given point. Checks general build permissions, then paint.
+ /// The x coordinate they want to paint at.
+ /// The y coordinate they want to paint at.
+ /// True if they can paint.
+ public bool HasPaintPermission(int x, int y)
+ {
+ return HasBuildPermission(x, y) || HasPermission(Permissions.canpaint);
+ }
+
///
/// A list of points where ice tiles have been placed.
///
diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs
index 1cc17e37..f35efda8 100644
--- a/TShockAPI/TShock.cs
+++ b/TShockAPI/TShock.cs
@@ -1842,75 +1842,6 @@ namespace TShockAPI
return false;
}
- /// CheckTilePermission - Checks to see if a player has the ability to modify a tile at a given position.
- /// player - The TSPlayer object.
- /// tileX - The x coordinate of the tile.
- /// tileY - The y coordinate of the tile.
- /// paint - Whether or not the tile is paint.
- /// bool - True if the player should not be able to modify the tile.
- public static bool CheckTilePermission(TSPlayer player, int tileX, int tileY, bool paint = false)
- {
- if ((!paint && !player.HasPermission(Permissions.canbuild)) ||
- (paint && !player.HasPermission(Permissions.canpaint)))
- {
- if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.BPm) > 2000)
- {
- if (paint)
- {
- player.SendErrorMessage("You do not have permission to paint!");
- }
- else
- {
- player.SendErrorMessage("You do not have permission to build!");
- }
- player.BPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
- }
- return true;
- }
-
- if (!Regions.CanBuild(tileX, tileY, player))
- {
- if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.RPm) > 2000)
- {
- player.SendErrorMessage("This region is protected from changes.");
- player.RPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
- }
- return true;
- }
-
- if (Config.DisableBuild)
- {
- if (!player.HasPermission(Permissions.antibuild))
- {
- if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.WPm) > 2000)
- {
- player.SendErrorMessage("The world is protected from changes.");
- player.WPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
- }
- return true;
- }
- }
-
- if (Config.SpawnProtection)
- {
- if (!player.HasPermission(Permissions.editspawn))
- {
- if (Utils.IsInSpawn(tileX, tileY))
- {
- if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.SPm) > 1000)
- {
- player.SendErrorMessage("Spawn is protected from changes.");
- player.SPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
- }
- return true;
- }
- }
- }
- return false;
- }
-
-
-
/// Distance - Determines the distance between two vectors.
/// value1 - The first vector location.
/// value2 - The second vector location.