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.