diff --git a/CHANGELOG.md b/CHANGELOG.md
index ebac456e..54e5d06a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -60,8 +60,11 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin
* Added `TSPlayer.CheckIgnores()` and removed `TShock.CheckIgnores(TSPlayer)`. (@hakusaro)
* Hooks inside TShock can now be registered with their `Register` method and can be prioritized according to the TShock HandlerList system. (@hakusaro)
* Fix message requiring login not using the command specifier set in the config file. (@hakusaro)
+* Move `TShock.CheckRangePermission()` to `TSPlayer.IsInRange` which **returns the opposite** of what the previous method did (see updated docs). (@hakusaro)
* Move `TShock.CheckSpawn` to `Utils.IsInSpawn`. (@hakusaro)
+* Replace `TShock.CheckTilePermission` with `TSPlayer.HasBuildPermission`, `TSPlayer.HasPaintPermission`, and `TSPlayer.HasModifiedIceSuccessfully` respectively. (@hakusaro)
* Fix stack hack detection being inconsistent between two different check points. Moved `TShock.HackedInventory` to `TSPlayer.HasHackedItemStacks`. Added `GetDataHandlers.GetDataHandledEventArgs` which is where most hooks will inherit from in the future. (@hakusaro)
+* All `GetDataHandlers` hooks now inherit from `GetDataHandledEventArgs` which includes a `TSPlayer` and a `MemoryStream` of raw data. (@hakusaro)
## TShock 4.3.25
* Fixed a critical exploit in the Terraria protocol that could cause massive unpreventable world corruption as well as a number of other problems. Thanks to @bartico6 for reporting. Fixed by the efforts of @QuiCM, @hakusaro, and tips in the right directioon from @bartico6.
diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs
index 3f14e977..40e2c355 100644
--- a/TShockAPI/Bouncer.cs
+++ b/TShockAPI/Bouncer.cs
@@ -99,14 +99,14 @@ 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;
return;
}
- if (TShock.CheckRangePermission(args.Player, args.X, args.Y))
+ if (!args.Player.IsInRange(args.X, args.Y))
{
NetMessage.SendData((int)PacketTypes.UpdateTileEntity, -1, -1, NetworkText.Empty, args.ItemFrame.ID, 0, 1);
args.Handled = true;
@@ -137,7 +137,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;
@@ -155,13 +155,13 @@ namespace TShockAPI
return;
}
- if (TShock.CheckTilePermission(args.Player, args.X, args.Y))
+ if (!args.Player.HasBuildPermission(args.X, args.Y))
{
args.Handled = true;
return;
}
- if (TShock.CheckRangePermission(args.Player, args.X, args.Y))
+ if (!args.Player.IsInRange(args.X, args.Y))
{
args.Handled = true;
return;
@@ -206,7 +206,7 @@ namespace TShockAPI
return;
}
- if (TShock.CheckTilePermission(args.Player, x, y))
+ if (!args.Player.HasBuildPermission(x, y))
{
args.Handled = true;
return;
@@ -276,7 +276,7 @@ namespace TShockAPI
}
if (TShock.Config.RangeChecks &&
- TShock.CheckRangePermission(args.Player, (int)(Main.npc[id].position.X / 16f), (int)(Main.npc[id].position.Y / 16f), 128))
+ !args.Player.IsInRange((int)(Main.npc[id].position.X / 16f), (int)(Main.npc[id].position.Y / 16f), 128))
{
args.Player.SendData(PacketTypes.NpcUpdate, "", id);
args.Handled = true;
@@ -342,7 +342,7 @@ namespace TShockAPI
return;
}
- if (TShock.CheckRangePermission(args.Player, TShock.Players[id].TileX, TShock.Players[id].TileY, 100))
+ if (!args.Player.IsInRange(TShock.Players[id].TileX, TShock.Players[id].TileY, 100))
{
args.Player.SendData(PacketTypes.PlayerHp, "", id);
args.Player.SendData(PacketTypes.PlayerUpdate, "", id);
@@ -396,7 +396,7 @@ namespace TShockAPI
// client side (but only if it passed the range check) (i.e., return false)
if (type == 0)
{
- if (TShock.CheckRangePermission(args.Player, (int)(Main.item[id].position.X / 16f), (int)(Main.item[id].position.Y / 16f)))
+ if (!args.Player.IsInRange((int)(Main.item[id].position.X / 16f), (int)(Main.item[id].position.Y / 16f)))
{
// Causes item duplications. Will be re added if necessary
//args.Player.SendData(PacketTypes.ItemDrop, "", id);
@@ -408,7 +408,7 @@ namespace TShockAPI
return;
}
- if (TShock.CheckRangePermission(args.Player, (int)(pos.X / 16f), (int)(pos.Y / 16f)))
+ if (!args.Player.IsInRange((int)(pos.X / 16f), (int)(pos.Y / 16f)))
{
args.Player.SendData(PacketTypes.ItemDrop, "", id);
args.Handled = true;
@@ -488,7 +488,7 @@ namespace TShockAPI
return;
}
- if (TShock.CheckRangePermission(args.Player, TShock.Players[id].TileX, TShock.Players[id].TileY, 50))
+ if (!args.Player.IsInRange(TShock.Players[id].TileX, TShock.Players[id].TileY, 50))
{
args.Player.SendData(PacketTypes.PlayerAddBuff, "", id);
args.Handled = true;
@@ -533,13 +533,13 @@ 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;
}
- if (TShock.CheckRangePermission(args.Player, Main.chest[id].x, Main.chest[id].y))
+ if (!args.Player.IsInRange(Main.chest[id].x, Main.chest[id].y))
{
args.Handled = true;
return;
@@ -556,18 +556,15 @@ namespace TShockAPI
short y = args.Y;
byte homeless = args.Homeless;
- // 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,
Convert.ToByte(Main.npc[id].homeless));
args.Handled = true;
return;
}
- if (TShock.CheckRangePermission(args.Player, x, y))
+ if (!args.Player.IsInRange(x, y))
{
args.Player.SendData(PacketTypes.UpdateNPCHome, "", id, Main.npc[id].homeTileX, Main.npc[id].homeTileY,
Convert.ToByte(Main.npc[id].homeless));
@@ -587,13 +584,13 @@ namespace TShockAPI
return;
}
- if (TShock.CheckRangePermission(args.Player, args.X, args.Y))
+ if (!args.Player.IsInRange(args.X, args.Y))
{
args.Handled = true;
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;
@@ -648,14 +645,14 @@ namespace TShockAPI
}
}
- if (TShock.CheckTilePermission(args.Player, tileX, tileY))
+ if (!args.Player.HasBuildPermission(tileX, tileY))
{
args.Player.SendTileSquare(tileX, tileY, 3);
args.Handled = true;
return;
}
- if (TShock.CheckRangePermission(args.Player, tileX, tileY))
+ if (!args.Player.IsInRange(tileX, tileY))
{
args.Player.SendTileSquare(tileX, tileY, 3);
args.Handled = true;
@@ -781,14 +778,14 @@ namespace TShockAPI
}
}
- if (TShock.CheckTilePermission(args.Player, tileX, tileY))
+ if (!args.Player.HasBuildPermission(tileX, tileY))
{
args.Player.SendTileSquare(tileX, tileY, 1);
args.Handled = true;
return;
}
- if (TShock.CheckRangePermission(args.Player, tileX, tileY, 16))
+ if (!args.Player.IsInRange(tileX, tileY, 16))
{
args.Player.SendTileSquare(tileX, tileY, 1);
args.Handled = true;
@@ -1169,7 +1166,8 @@ namespace TShockAPI
{
for (int j = y; j < y + tileData.Height; j++)
{
- if (TShock.CheckTilePermission(args.Player, i, j, type, EditAction.PlaceTile))
+ if (!args.Player.HasModifiedIceSuccessfully(i, j, type, EditAction.PlaceTile)
+ && !args.Player.HasBuildPermission(i, j))
{
args.Player.SendTileSquare(i, j, 4);
args.Handled = true;
@@ -1183,7 +1181,7 @@ namespace TShockAPI
|| type != TileID.SilkRope
|| type != TileID.VineRope
|| type != TileID.WebRope)
- && TShock.CheckRangePermission(args.Player, x, y))
+ && !args.Player.IsInRange(x, y))
{
args.Player.SendTileSquare(x, y, 4);
args.Handled = true;
@@ -1500,14 +1498,15 @@ namespace TShockAPI
return;
}
- if (TShock.CheckTilePermission(args.Player, tileX, tileY, editData, action))
+ if (!args.Player.HasModifiedIceSuccessfully(tileX, tileY, editData, action)
+ && !args.Player.HasBuildPermission(tileX, tileY))
{
args.Player.SendTileSquare(tileX, tileY, 4);
args.Handled = true;
return;
}
- if (TShock.CheckRangePermission(args.Player, tileX, tileY))
+ if (!args.Player.IsInRange(tileX, tileY))
{
if (action == EditAction.PlaceTile && (editData == TileID.Rope || editData == TileID.SilkRope || editData == TileID.VineRope || editData == TileID.WebRope))
{
@@ -1683,8 +1682,8 @@ namespace TShockAPI
var tile = Main.tile[realx, realy];
var newtile = tiles[x, y];
- if (TShock.CheckTilePermission(args.Player, realx, realy) ||
- TShock.CheckRangePermission(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 83bcb26d..d5fafec5 100644
--- a/TShockAPI/GetDataHandlers.cs
+++ b/TShockAPI/GetDataHandlers.cs
@@ -80,13 +80,8 @@ namespace TShockAPI
///
/// Used when a TileEdit event is called.
///
- public class TileEditEventArgs : HandledEventArgs
+ public class TileEditEventArgs : GetDataHandledEventArgs
{
- ///
- /// The TSPlayer who made the tile edit
- ///
- public TSPlayer Player { get; set; }
-
///
/// The tile coordinate on the X plane
///
@@ -122,7 +117,7 @@ namespace TShockAPI
/// TileEdit - called when a tile is placed or destroyed
///
public static HandlerList TileEdit = new HandlerList();
- private static bool OnTileEdit(TSPlayer ply, int x, int y, EditAction action, EditType editDetail, short editData, byte style)
+ private static bool OnTileEdit(TSPlayer ply, MemoryStream data, int x, int y, EditAction action, EditType editDetail, short editData, byte style)
{
if (TileEdit == null)
return false;
@@ -130,6 +125,7 @@ namespace TShockAPI
var args = new TileEditEventArgs
{
Player = ply,
+ Data = data,
X = x,
Y = y,
Action = action,
@@ -143,7 +139,7 @@ namespace TShockAPI
///
/// For use in a TogglePvp event
///
- public class TogglePvpEventArgs : HandledEventArgs
+ public class TogglePvpEventArgs : GetDataHandledEventArgs
{
///
/// The Terraria player ID of the player
@@ -158,13 +154,15 @@ namespace TShockAPI
/// TogglePvp - called when a player toggles pvp
///
public static HandlerList TogglePvp = new HandlerList();
- private static bool OnPvpToggled(byte _id, bool _pvp)
+ private static bool OnPvpToggled(TSPlayer player, MemoryStream data, byte _id, bool _pvp)
{
if (TogglePvp == null)
return false;
var args = new TogglePvpEventArgs
{
+ Player = player,
+ Data = data,
PlayerId = _id,
Pvp = _pvp,
};
@@ -175,7 +173,7 @@ namespace TShockAPI
///
/// For use in a PlayerTeam event
///
- public class PlayerTeamEventArgs : HandledEventArgs
+ public class PlayerTeamEventArgs : GetDataHandledEventArgs
{
///
/// The Terraria player ID of the player
@@ -190,13 +188,15 @@ namespace TShockAPI
/// TogglePvp - called when a player toggles pvp
///
public static HandlerList PlayerTeam = new HandlerList();
- private static bool OnPlayerTeam(byte _id, byte _team)
+ private static bool OnPlayerTeam(TSPlayer player, MemoryStream data, byte _id, byte _team)
{
if (PlayerTeam == null)
return false;
var args = new PlayerTeamEventArgs
{
+ Player = player,
+ Data = data,
PlayerId = _id,
Team = _team,
};
@@ -207,7 +207,7 @@ namespace TShockAPI
///
/// For use in a PlayerSlot event
///
- public class PlayerSlotEventArgs : HandledEventArgs
+ public class PlayerSlotEventArgs : GetDataHandledEventArgs
{
///
/// The Terraria playerID
@@ -234,13 +234,15 @@ namespace TShockAPI
/// PlayerSlot - called at a PlayerSlot event
///
public static HandlerList PlayerSlot = new HandlerList();
- private static bool OnPlayerSlot(byte _plr, byte _slot, short _stack, byte _prefix, short _type)
+ private static bool OnPlayerSlot(TSPlayer player, MemoryStream data, byte _plr, byte _slot, short _stack, byte _prefix, short _type)
{
if (PlayerSlot == null)
return false;
var args = new PlayerSlotEventArgs
{
+ Player = player,
+ Data = data,
PlayerId = _plr,
Slot = _slot,
Stack = _stack,
@@ -254,7 +256,7 @@ namespace TShockAPI
///
/// For use in a PlayerHP event
///
- public class PlayerHPEventArgs : HandledEventArgs
+ public class PlayerHPEventArgs : GetDataHandledEventArgs
{
///
/// The Terraria playerID of the player
@@ -274,13 +276,15 @@ namespace TShockAPI
///
public static HandlerList PlayerHP = new HandlerList();
- private static bool OnPlayerHP(byte _plr, short _cur, short _max)
+ private static bool OnPlayerHP(TSPlayer player, MemoryStream data, byte _plr, short _cur, short _max)
{
if (PlayerHP == null)
return false;
var args = new PlayerHPEventArgs
{
+ Player = player,
+ Data = data,
PlayerId = _plr,
Current = _cur,
Max = _max,
@@ -292,7 +296,7 @@ namespace TShockAPI
///
/// For use in a PlayerMana event
///
- public class PlayerManaEventArgs : HandledEventArgs
+ public class PlayerManaEventArgs : GetDataHandledEventArgs
{
public byte PlayerId { get; set; }
public short Current { get; set; }
@@ -303,13 +307,15 @@ namespace TShockAPI
///
public static HandlerList PlayerMana = new HandlerList();
- private static bool OnPlayerMana(byte _plr, short _cur, short _max)
+ private static bool OnPlayerMana(TSPlayer player, MemoryStream data, byte _plr, short _cur, short _max)
{
if (PlayerMana == null)
return false;
var args = new PlayerManaEventArgs
{
+ Player = player,
+ Data = data,
PlayerId = _plr,
Current = _cur,
Max = _max,
@@ -318,7 +324,7 @@ namespace TShockAPI
return args.Handled;
}
- public class PlayerInfoEventArgs : HandledEventArgs
+ public class PlayerInfoEventArgs : GetDataHandledEventArgs
{
///
/// The Terraria playerID of the player
@@ -347,13 +353,15 @@ namespace TShockAPI
///
public static HandlerList PlayerInfo = new HandlerList();
- private static bool OnPlayerInfo(byte _plrid, byte _hair, int _style, byte _difficulty, string _name)
+ private static bool OnPlayerInfo(TSPlayer player, MemoryStream data, byte _plrid, byte _hair, int _style, byte _difficulty, string _name)
{
if (PlayerInfo == null)
return false;
var args = new PlayerInfoEventArgs
{
+ Player = player,
+ Data = data,
PlayerId = _plrid,
Hair = _hair,
Style = _style,
@@ -367,10 +375,8 @@ namespace TShockAPI
///
/// For use in a PlaceChest event
///
- public class PlaceChestEventArgs : HandledEventArgs
+ public class PlaceChestEventArgs : GetDataHandledEventArgs
{
- /// The TSPlayer that triggered the event
- public TSPlayer Player { get; set; }
/// What the packet is doing (see MP packet docs).
public int Flag { get; set; }
///
@@ -387,7 +393,7 @@ namespace TShockAPI
///
public static HandlerList PlaceChest = new HandlerList();
- private static bool OnPlaceChest(TSPlayer player, int flag, int tilex, int tiley)
+ private static bool OnPlaceChest(TSPlayer player, MemoryStream data, int flag, int tilex, int tiley)
{
if (PlaceChest == null)
return false;
@@ -395,6 +401,7 @@ namespace TShockAPI
var args = new PlaceChestEventArgs
{
Player = player,
+ Data = data,
Flag = flag,
TileX = tilex,
TileY = tiley,
@@ -404,10 +411,8 @@ namespace TShockAPI
}
/// The arguments to the ProjectileKill packet.
- public class ProjectileKillEventArgs : HandledEventArgs
+ public class ProjectileKillEventArgs : GetDataHandledEventArgs
{
- /// The TSPlayer that fired the event.
- public TSPlayer Player;
/// The projectile's identity...?
public int ProjectileIdentity;
/// The the player index of the projectile's owner (Main.players).
@@ -421,11 +426,12 @@ namespace TShockAPI
/// Fires the ProjectileKill event.
/// The TSPlayer that caused the event.
+ /// The MemoryStream containing the raw event data.
/// The projectile identity (from the packet).
/// The projectile's owner (from the packet).
/// The projectile's index (from Main.projectiles).
/// bool
- private static bool OnProjectileKill(TSPlayer player, int identity, byte owner, int index)
+ private static bool OnProjectileKill(TSPlayer player, MemoryStream data, int identity, byte owner, int index)
{
if (ProjectileKill == null)
return false;
@@ -433,6 +439,7 @@ namespace TShockAPI
var args = new ProjectileKillEventArgs
{
Player = player,
+ Data = data,
ProjectileIdentity = identity,
ProjectileOwner = owner,
ProjectileIndex = index,
@@ -445,10 +452,8 @@ namespace TShockAPI
///
/// For use in a KillMe event
///
- public class KillMeEventArgs : HandledEventArgs
+ public class KillMeEventArgs : GetDataHandledEventArgs
{
- /// The TSPlayer that triggered the event.
- public TSPlayer Player { get; set; }
///
/// The Terraria playerID of the player
///
@@ -473,7 +478,7 @@ namespace TShockAPI
///
public static HandlerList KillMe = new HandlerList();
- private static bool OnKillMe(TSPlayer player, byte plr, byte direction, short damage, bool pvp, PlayerDeathReason playerDeathReason)
+ private static bool OnKillMe(TSPlayer player, MemoryStream data, byte plr, byte direction, short damage, bool pvp, PlayerDeathReason playerDeathReason)
{
if (KillMe == null)
return false;
@@ -481,6 +486,7 @@ namespace TShockAPI
var args = new KillMeEventArgs
{
Player = player,
+ Data = data,
PlayerId = plr,
Direction = direction,
Damage = damage,
@@ -494,10 +500,8 @@ namespace TShockAPI
///
/// For use in a PlayerUpdate event
///
- public class PlayerUpdateEventArgs : HandledEventArgs
+ public class PlayerUpdateEventArgs : GetDataHandledEventArgs
{
- /// The TSPlayer object that triggered the event
- public TSPlayer Player { get; set; }
///
/// The Terraria playerID of the player
///
@@ -526,7 +530,7 @@ namespace TShockAPI
///
public static HandlerList PlayerUpdate = new HandlerList();
- private static bool OnPlayerUpdate(TSPlayer player, byte plr, byte control, byte item, Vector2 position, Vector2 velocity, byte pulley)
+ private static bool OnPlayerUpdate(TSPlayer player, MemoryStream data, byte plr, byte control, byte item, Vector2 position, Vector2 velocity, byte pulley)
{
if (PlayerUpdate == null)
return false;
@@ -534,6 +538,7 @@ namespace TShockAPI
var args = new PlayerUpdateEventArgs
{
Player = player,
+ Data = data,
PlayerId = plr,
Control = control,
Item = item,
@@ -544,6 +549,7 @@ namespace TShockAPI
PlayerUpdate.Invoke(null, args);
return args.Handled;
}
+
public static bool TSCheckNoclip(Vector2 Position, int Width, int Height)
{
int num = (int)(Position.X / 16f);
@@ -600,11 +606,8 @@ namespace TShockAPI
}
/// The event args object for the HealOtherPlayer event
- public class HealOtherPlayerEventArgs : HandledEventArgs
+ public class HealOtherPlayerEventArgs : GetDataHandledEventArgs
{
- /// The TSPlayer object that caused the event
- public TSPlayer Player { get; set; }
-
/// The Terraria player index of the target player
public byte TargetPlayerIndex { get; set; }
@@ -616,11 +619,12 @@ namespace TShockAPI
public static HandlerList HealOtherPlayer = new HandlerList();
/// Fires the HealOtherPlayer event
- /// The TSPlayer that started the event
+ /// The TSPlayer that caused the event.
+ /// The MemoryStream containing the raw event data.
/// The Terraria player index that the event targets
/// The amount to heal
/// bool
- private static bool OnHealOtherPlayer(TSPlayer player, byte targetPlayerIndex, short amount)
+ private static bool OnHealOtherPlayer(TSPlayer player, MemoryStream data, byte targetPlayerIndex, short amount)
{
if (HealOtherPlayer == null)
return false;
@@ -628,6 +632,7 @@ namespace TShockAPI
var args = new HealOtherPlayerEventArgs
{
Player = player,
+ Data = data,
TargetPlayerIndex = targetPlayerIndex,
Amount = amount,
};
@@ -639,14 +644,8 @@ namespace TShockAPI
///
/// For use in a SendTileSquare event
///
- public class SendTileSquareEventArgs : HandledEventArgs
+ public class SendTileSquareEventArgs : GetDataHandledEventArgs
{
- /// The TSPlayer that triggered the event.
- public TSPlayer Player { get; set; }
-
- /// The raw memory stream from the original event
- public MemoryStream Data { get; set; }
-
///
/// Size of the area
///
@@ -686,11 +685,8 @@ namespace TShockAPI
}
/// The arguments to the PlaceObject hook.
- public class PlaceObjectEventArgs : HandledEventArgs
+ public class PlaceObjectEventArgs : GetDataHandledEventArgs
{
- /// The calling Player.
- public TSPlayer Player { get; set; }
-
/// The X location where the object was placed.
public short X { get; set ; }
@@ -714,7 +710,8 @@ namespace TShockAPI
public static HandlerList PlaceObject = new HandlerList();
/// Fires the PlaceObject hook. To be called when an object is placed in the world.
- /// The originating player.
+ /// The TSPlayer that caused the event.
+ /// The MemoryStream containing the raw event data.
/// The x position where the object is placed.
/// The y position where the object is placed.
/// The type of object.
@@ -722,7 +719,7 @@ namespace TShockAPI
/// The object's alternate data.
/// The direction of the object.
/// bool
- private static bool OnPlaceObject(TSPlayer player, short x, short y, short type, short style, byte alternate, bool direction)
+ private static bool OnPlaceObject(TSPlayer player, MemoryStream data, short x, short y, short type, short style, byte alternate, bool direction)
{
if (PlaceObject == null)
return false;
@@ -730,6 +727,7 @@ namespace TShockAPI
var args = new PlaceObjectEventArgs
{
Player = player,
+ Data = data,
X = x,
Y = y,
Type = type,
@@ -746,10 +744,8 @@ namespace TShockAPI
///
/// For use in a NewProjectile event
///
- public class NewProjectileEventArgs : HandledEventArgs
+ public class NewProjectileEventArgs : GetDataHandledEventArgs
{
- /// The TSPlayer that triggered the new projectile.
- public TSPlayer Player { get; set; }
///
/// ???
///
@@ -788,13 +784,14 @@ namespace TShockAPI
///
public static HandlerList NewProjectile = new HandlerList();
- private static bool OnNewProjectile(short ident, Vector2 pos, Vector2 vel, float knockback, short dmg, byte owner, short type, int index, TSPlayer player)
+ private static bool OnNewProjectile(MemoryStream data, short ident, Vector2 pos, Vector2 vel, float knockback, short dmg, byte owner, short type, int index, TSPlayer player)
{
if (NewProjectile == null)
return false;
var args = new NewProjectileEventArgs
{
+ Data = data,
Identity = ident,
Position = pos,
Velocity = vel,
@@ -812,10 +809,8 @@ namespace TShockAPI
///
/// For use in a LiquidSet event
///
- public class LiquidSetEventArgs : HandledEventArgs
+ public class LiquidSetEventArgs : GetDataHandledEventArgs
{
- /// The TSPlayer that triggered the event.
- public TSPlayer Player { get; set; }
///
/// X location of the tile
///
@@ -838,7 +833,7 @@ namespace TShockAPI
///
public static HandlerList LiquidSet = new HandlerList();
- private static bool OnLiquidSet(TSPlayer player, int tilex, int tiley, byte amount, byte type)
+ private static bool OnLiquidSet(TSPlayer player, MemoryStream data, int tilex, int tiley, byte amount, byte type)
{
if (LiquidSet == null)
return false;
@@ -846,6 +841,7 @@ namespace TShockAPI
var args = new LiquidSetEventArgs
{
Player = player,
+ Data = data,
TileX = tilex,
TileY = tiley,
Amount = amount,
@@ -857,12 +853,12 @@ namespace TShockAPI
///
/// For use in a PlayerSpawn event
///
- public class SpawnEventArgs : HandledEventArgs
+ public class SpawnEventArgs : GetDataHandledEventArgs
{
///
/// The Terraria playerID of the player
///
- public byte Player { get; set; }
+ public byte PlayerID { get; set; }
///
/// X location of the player's spawn
///
@@ -877,7 +873,7 @@ namespace TShockAPI
///
public static HandlerList PlayerSpawn = new HandlerList();
- private static bool OnPlayerSpawn(byte player, int spawnX, int spawnY)
+ private static bool OnPlayerSpawn(TSPlayer player, MemoryStream data, byte pid, int spawnX, int spawnY)
{
if (PlayerSpawn == null)
return false;
@@ -885,6 +881,8 @@ namespace TShockAPI
var args = new SpawnEventArgs
{
Player = player,
+ Data = data,
+ PlayerID = pid,
SpawnX = spawnX,
SpawnY = spawnY,
};
@@ -894,7 +892,7 @@ namespace TShockAPI
///
/// For use with a ChestOpen event
///
- public class ChestOpenEventArgs : HandledEventArgs
+ public class ChestOpenEventArgs : GetDataHandledEventArgs
{
///
/// X location of said chest
@@ -904,24 +902,20 @@ namespace TShockAPI
/// Y location of said chest
///
public int Y { get; set; }
-
- ///
- /// The player opening the chest
- ///
- public TSPlayer Player { get; set; }
}
///
/// ChestOpen - Called when any chest is opened
///
public static HandlerList ChestOpen = new HandlerList();
- private static bool OnChestOpen(int x, int y, TSPlayer player)
+ private static bool OnChestOpen(MemoryStream data, int x, int y, TSPlayer player)
{
if (ChestOpen == null)
return false;
var args = new ChestOpenEventArgs
{
+ Data = data,
X = x,
Y = y,
Player = player,
@@ -933,10 +927,8 @@ namespace TShockAPI
///
/// For use in a ChestItemChange event
///
- public class ChestItemEventArgs : HandledEventArgs
+ public class ChestItemEventArgs : GetDataHandledEventArgs
{
- /// The TSPlayer that triggered the event.
- public TSPlayer Player { get; set; }
///
/// ChestID
///
@@ -963,7 +955,7 @@ namespace TShockAPI
///
public static HandlerList ChestItemChange = new HandlerList();
- private static bool OnChestItemChange(TSPlayer player, short id, byte slot, short stacks, byte prefix, short type)
+ private static bool OnChestItemChange(TSPlayer player, MemoryStream data, short id, byte slot, short stacks, byte prefix, short type)
{
if (ChestItemChange == null)
return false;
@@ -971,6 +963,7 @@ namespace TShockAPI
var args = new ChestItemEventArgs
{
Player = player,
+ Data = data,
ID = id,
Slot = slot,
Stacks = stacks,
@@ -984,7 +977,7 @@ namespace TShockAPI
///
/// For use in a Sign event
///
- public class SignEventArgs : HandledEventArgs
+ public class SignEventArgs : GetDataHandledEventArgs
{
///
/// The Terraria playerID of the player
@@ -1004,13 +997,15 @@ namespace TShockAPI
///
public static HandlerList Sign = new HandlerList();
- private static bool OnSignEvent(short id, int x, int y)
+ private static bool OnSignEvent(TSPlayer player, MemoryStream data, short id, int x, int y)
{
if (Sign == null)
return false;
var args = new SignEventArgs
{
+ Player = player,
+ Data = data,
ID = id,
X = x,
Y = y,
@@ -1022,10 +1017,8 @@ namespace TShockAPI
///
/// For use in a NPCHome event
///
- public class NPCHomeChangeEventArgs : HandledEventArgs
+ public class NPCHomeChangeEventArgs : GetDataHandledEventArgs
{
- /// The TSPlayer that caused the event.
- public TSPlayer Player { get; set; }
///
/// The Terraria playerID of the player
///
@@ -1048,7 +1041,7 @@ namespace TShockAPI
///
public static HandlerList NPCHome = new HandlerList();
- private static bool OnUpdateNPCHome(TSPlayer player, short id, short x, short y, byte homeless)
+ private static bool OnUpdateNPCHome(TSPlayer player, MemoryStream data, short id, short x, short y, byte homeless)
{
if (NPCHome == null)
return false;
@@ -1056,6 +1049,7 @@ namespace TShockAPI
var args = new NPCHomeChangeEventArgs
{
Player = player,
+ Data = data,
ID = id,
X = x,
Y = y,
@@ -1068,9 +1062,8 @@ namespace TShockAPI
///
/// For use in a PlayerBuff event
///
- public class PlayerBuffEventArgs : HandledEventArgs
+ public class PlayerBuffEventArgs : GetDataHandledEventArgs
{
- public TSPlayer Player { get; set; }
///
/// The Terraria playerID of the player
///
@@ -1089,7 +1082,7 @@ namespace TShockAPI
///
public static HandlerList PlayerBuff = new HandlerList();
- private static bool OnPlayerBuff(TSPlayer player, byte id, byte type, int time)
+ private static bool OnPlayerBuff(TSPlayer player, MemoryStream data, byte id, byte type, int time)
{
if (PlayerBuff == null)
return false;
@@ -1097,6 +1090,7 @@ namespace TShockAPI
var args = new PlayerBuffEventArgs
{
Player = player,
+ Data = data,
ID = id,
Type = type,
Time = time
@@ -1108,12 +1102,8 @@ namespace TShockAPI
///
/// For use in an ItemDrop event
///
- public class ItemDropEventArgs : HandledEventArgs
+ public class ItemDropEventArgs : GetDataHandledEventArgs
{
- ///
- /// The player who sent message
- ///
- public TSPlayer Player { get; set; }
///
/// ID of the item.
/// If below 400 and NetID(Type) is 0 Then Set Null. If ItemID is 400 Then New Item
@@ -1149,7 +1139,7 @@ namespace TShockAPI
///
public static HandlerList ItemDrop = new HandlerList();
- private static bool OnItemDrop(TSPlayer player, short id, Vector2 pos, Vector2 vel, short stacks, byte prefix, bool noDelay, short type)
+ private static bool OnItemDrop(TSPlayer player, MemoryStream data, short id, Vector2 pos, Vector2 vel, short stacks, byte prefix, bool noDelay, short type)
{
if (ItemDrop == null)
return false;
@@ -1157,6 +1147,7 @@ namespace TShockAPI
var args = new ItemDropEventArgs
{
Player = player,
+ Data = data,
ID = id,
Position = pos,
Velocity = vel,
@@ -1172,9 +1163,8 @@ namespace TShockAPI
///
/// For use in a PlayerDamage event
///
- public class PlayerDamageEventArgs : HandledEventArgs
+ public class PlayerDamageEventArgs : GetDataHandledEventArgs
{
- public TSPlayer Player { get; set; }
///
/// The Terraria playerID of the player
///
@@ -1203,7 +1193,7 @@ namespace TShockAPI
///
public static HandlerList PlayerDamage = new HandlerList();
- private static bool OnPlayerDamage(TSPlayer player, byte id, byte dir, short dmg, bool pvp, bool crit, PlayerDeathReason playerDeathReason)
+ private static bool OnPlayerDamage(TSPlayer player, MemoryStream data, byte id, byte dir, short dmg, bool pvp, bool crit, PlayerDeathReason playerDeathReason)
{
if (PlayerDamage == null)
return false;
@@ -1211,6 +1201,7 @@ namespace TShockAPI
var args = new PlayerDamageEventArgs
{
Player = player,
+ Data = data,
ID = id,
Direction = dir,
Damage = dmg,
@@ -1225,10 +1216,8 @@ namespace TShockAPI
///
/// For use with a NPCStrike event
///
- public class NPCStrikeEventArgs : HandledEventArgs
+ public class NPCStrikeEventArgs : GetDataHandledEventArgs
{
- /// The TSPlayer that triggered the event.
- public TSPlayer Player { get; set; }
///
/// ???
///
@@ -1255,7 +1244,7 @@ namespace TShockAPI
///
public static HandlerList NPCStrike = new HandlerList();
- private static bool OnNPCStrike(TSPlayer player, short id, byte dir, short dmg, float knockback, byte crit)
+ private static bool OnNPCStrike(TSPlayer player, MemoryStream data, short id, byte dir, short dmg, float knockback, byte crit)
{
if (NPCStrike == null)
return false;
@@ -1263,6 +1252,7 @@ namespace TShockAPI
var args = new NPCStrikeEventArgs
{
Player = player,
+ Data = data,
ID = id,
Direction = dir,
Damage = dmg,
@@ -1274,11 +1264,8 @@ namespace TShockAPI
}
/// The arguments to the MassWireOperation event.
- public class MassWireOperationEventArgs : HandledEventArgs
+ public class MassWireOperationEventArgs : GetDataHandledEventArgs
{
- /// The TSPlayer that triggered the event.
- public TSPlayer Player { get; set; }
-
/// The start X point in the operation.
public short StartX { get; set; }
@@ -1298,7 +1285,7 @@ namespace TShockAPI
/// Fired on a mass wire edit operation.
public static HandlerList MassWireOperation = new HandlerList();
- private static bool OnMassWireOperation(TSPlayer player, short startX, short startY, short endX, short endY, byte toolMode)
+ private static bool OnMassWireOperation(TSPlayer player, MemoryStream data, short startX, short startY, short endX, short endY, byte toolMode)
{
if (MassWireOperation == null)
return false;
@@ -1306,6 +1293,7 @@ namespace TShockAPI
var args = new MassWireOperationEventArgs
{
Player = player,
+ Data = data,
StartX = startX,
StartY = startY,
EndX = endX,
@@ -1318,11 +1306,8 @@ namespace TShockAPI
}
/// For use in a PlaceTileEntity event.
- public class PlaceTileEntityEventArgs : HandledEventArgs
+ public class PlaceTileEntityEventArgs : GetDataHandledEventArgs
{
- /// The TSPlayer that triggered the event.
- public TSPlayer Player { get; set; }
-
/// The X coordinate of the event.
public short X { get; set; }
@@ -1336,7 +1321,7 @@ namespace TShockAPI
/// Fired when a PlaceTileEntity event occurs.
public static HandlerList PlaceTileEntity = new HandlerList();
- private static bool OnPlaceTileEntity(TSPlayer player, short x, short y, byte type)
+ private static bool OnPlaceTileEntity(TSPlayer player, MemoryStream data, short x, short y, byte type)
{
if (PlaceTileEntity == null)
return false;
@@ -1344,6 +1329,7 @@ namespace TShockAPI
var args = new PlaceTileEntityEventArgs
{
Player = player,
+ Data = data,
X = x,
Y = y,
Type = type
@@ -1356,7 +1342,7 @@ namespace TShockAPI
///
/// For use with a NPCSpecial event
///
- public class NPCSpecialEventArgs : HandledEventArgs
+ public class NPCSpecialEventArgs : GetDataHandledEventArgs
{
///
/// ???
@@ -1372,13 +1358,15 @@ namespace TShockAPI
///
public static HandlerList NPCSpecial = new HandlerList();
- private static bool OnNPCSpecial(byte id, byte type)
+ private static bool OnNPCSpecial(TSPlayer player, MemoryStream data, byte id, byte type)
{
if (NPCSpecial == null)
return false;
var args = new NPCSpecialEventArgs
{
+ Player = player,
+ Data = data,
ID = id,
Type = type,
};
@@ -1389,18 +1377,14 @@ namespace TShockAPI
///
/// For use with a PlayerAnimation event
///
- public class PlayerAnimationEventArgs : HandledEventArgs
- {
- /// The TSPlayer that triggered the event.
- public TSPlayer Player { get; set; }
- }
+ public class PlayerAnimationEventArgs : GetDataHandledEventArgs { }
///
/// PlayerAnimation - Called when a player animates
///
public static HandlerList PlayerAnimation = new HandlerList();
- private static bool OnPlayerAnimation(TSPlayer player)
+ private static bool OnPlayerAnimation(TSPlayer player, MemoryStream data)
{
if (PlayerAnimation == null)
return false;
@@ -1408,6 +1392,7 @@ namespace TShockAPI
var args = new PlayerAnimationEventArgs
{
Player = player,
+ Data = data,
};
PlayerAnimation.Invoke(null, args);
return args.Handled;
@@ -1416,7 +1401,7 @@ namespace TShockAPI
///
/// For use in a PlayerBuffUpdate event
///
- public class PlayerBuffUpdateEventArgs : HandledEventArgs
+ public class PlayerBuffUpdateEventArgs : GetDataHandledEventArgs
{
///
/// The Terraria playerID of the player
@@ -1428,13 +1413,15 @@ namespace TShockAPI
///
public static HandlerList PlayerBuffUpdate = new HandlerList();
- private static bool OnPlayerBuffUpdate(byte id)
+ private static bool OnPlayerBuffUpdate(TSPlayer player, MemoryStream data, byte id)
{
if (PlayerBuffUpdate == null)
return false;
var args = new PlayerBuffUpdateEventArgs
{
+ Player = player,
+ Data = data,
ID = id,
};
PlayerBuffUpdate.Invoke(null, args);
@@ -1444,7 +1431,7 @@ namespace TShockAPI
///
/// For use with a NPCStrike event
///
- public class TeleportEventArgs : HandledEventArgs
+ public class TeleportEventArgs : GetDataHandledEventArgs
{
///
/// ???
@@ -1472,13 +1459,15 @@ namespace TShockAPI
///
public static HandlerList Teleport = new HandlerList();
- private static bool OnTeleport(Int16 id, byte f, float x, float y)
+ private static bool OnTeleport(TSPlayer player, MemoryStream data, Int16 id, byte f, float x, float y)
{
if (Teleport == null)
return false;
var args = new TeleportEventArgs
{
+ Player = player,
+ Data = data,
ID = id,
Flag = f,
X = x,
@@ -1581,7 +1570,7 @@ namespace TShockAPI
byte plr = args.Data.ReadInt8();
short amount = args.Data.ReadInt16();
- if (OnHealOtherPlayer(args.Player, plr, amount))
+ if (OnHealOtherPlayer(args.Player, args.Data, plr, amount))
return true;
return false;
@@ -1603,7 +1592,7 @@ namespace TShockAPI
bypassTrashCanCheck = true;
}
- if (OnPlayerSlot(plr, slot, stack, prefix, type) || plr != args.Player.Index || slot < 0 ||
+ if (OnPlayerSlot(args.Player, args.Data, plr, slot, stack, prefix, type) || plr != args.Player.Index || slot < 0 ||
slot > NetItem.MaxInventory)
return true;
if (args.Player.IgnoreSSCPackets)
@@ -1643,7 +1632,7 @@ namespace TShockAPI
var cur = args.Data.ReadInt16();
var max = args.Data.ReadInt16();
- if (OnPlayerHP(plr, cur, max) || cur <= 0 || max <= 0 || args.Player.IgnoreSSCPackets)
+ if (OnPlayerHP(args.Player, args.Data, plr, cur, max) || cur <= 0 || max <= 0 || args.Player.IgnoreSSCPackets)
return true;
if (max > TShock.Config.MaxHP && !args.Player.HasPermission(Permissions.ignorehp))
@@ -1672,7 +1661,7 @@ namespace TShockAPI
var cur = args.Data.ReadInt16();
var max = args.Data.ReadInt16();
- if (OnPlayerMana(plr, cur, max) || cur < 0 || max < 0 || args.Player.IgnoreSSCPackets)
+ if (OnPlayerMana(args.Player, args.Data, plr, cur, max) || cur < 0 || max < 0 || args.Player.IgnoreSSCPackets)
return true;
if (max > TShock.Config.MaxMP && !args.Player.HasPermission(Permissions.ignoremp))
@@ -1724,7 +1713,7 @@ namespace TShockAPI
bool extraSlot = extra[2];
- if (OnPlayerInfo(playerid, hair, skinVariant, difficulty, name))
+ if (OnPlayerInfo(args.Player, args.Data, playerid, hair, skinVariant, difficulty, name))
{
TShock.Utils.ForceKick(args.Player, "A plugin cancelled the event.", true);
return true;
@@ -2077,7 +2066,7 @@ namespace TShockAPI
var style = args.Data.ReadInt8();
- if (OnTileEdit(args.Player, tileX, tileY, action, type, editData, style))
+ if (OnTileEdit(args.Player, args.Data, tileX, tileY, action, type, editData, style))
return true;
return false;
@@ -2095,7 +2084,7 @@ namespace TShockAPI
byte alternate = args.Data.ReadInt8();
bool direction = args.Data.ReadBoolean();
- if (OnPlaceObject(args.Player, x, y, type, style, alternate, direction))
+ if (OnPlaceObject(args.Player, args.Data, x, y, type, style, alternate, direction))
return true;
return false;
@@ -2104,7 +2093,7 @@ namespace TShockAPI
///
/// For use with a PaintTile event
///
- public class PaintTileEventArgs : HandledEventArgs
+ public class PaintTileEventArgs : GetDataHandledEventArgs
{
///
/// X Location
@@ -2124,13 +2113,15 @@ namespace TShockAPI
///
public static HandlerList PaintTile = new HandlerList();
- private static bool OnPaintTile(Int32 x, Int32 y, byte t)
+ private static bool OnPaintTile(TSPlayer player, MemoryStream data, Int32 x, Int32 y, byte t)
{
if (PaintTile == null)
return false;
var args = new PaintTileEventArgs
{
+ Player = player,
+ Data = data,
X = x,
Y = y,
type = t
@@ -2143,7 +2134,7 @@ namespace TShockAPI
///
/// For use with a PaintWall event
///
- public class PaintWallEventArgs : HandledEventArgs
+ public class PaintWallEventArgs : GetDataHandledEventArgs
{
///
/// X Location
@@ -2163,13 +2154,15 @@ namespace TShockAPI
///
public static HandlerList PaintWall = new HandlerList();
- private static bool OnPaintWall(Int32 x, Int32 y, byte t)
+ private static bool OnPaintWall(TSPlayer player, MemoryStream data, Int32 x, Int32 y, byte t)
{
if (PaintWall == null)
return false;
var args = new PaintWallEventArgs
{
+ Player = player,
+ Data = data,
X = x,
Y = y,
type = t
@@ -2182,7 +2175,7 @@ namespace TShockAPI
{
byte id = args.Data.ReadInt8();
bool pvp = args.Data.ReadBoolean();
- if (OnPvpToggled(id, pvp))
+ if (OnPvpToggled(args.Player, args.Data, id, pvp))
return true;
if (id != args.Player.Index)
@@ -2203,7 +2196,7 @@ namespace TShockAPI
{
byte id = args.Data.ReadInt8();
byte team = args.Data.ReadInt8();
- if (OnPlayerTeam(id, team))
+ if (OnPlayerTeam(args.Player, args.Data, id, team))
return true;
if (id != args.Player.Index)
@@ -2235,7 +2228,7 @@ namespace TShockAPI
if (pulley[2])
vel = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle());
- if (OnPlayerUpdate(args.Player, plr, control, item, pos, vel, pulley))
+ if (OnPlayerUpdate(args.Player, args.Data, plr, control, item, pos, vel, pulley))
return true;
if (control[5])
@@ -2383,7 +2376,7 @@ namespace TShockAPI
var index = TShock.Utils.SearchProjectile(ident, owner);
- if (OnNewProjectile(ident, pos, vel, knockback, dmg, owner, type, index, args.Player))
+ if (OnNewProjectile(args.Data, ident, pos, vel, knockback, dmg, owner, type, index, args.Player))
return true;
return false;
@@ -2396,7 +2389,7 @@ namespace TShockAPI
owner = (byte)args.Player.Index;
var index = TShock.Utils.SearchProjectile(ident, owner);
- if (OnProjectileKill(args.Player, ident, owner, index))
+ if (OnProjectileKill(args.Player, args.Data, ident, owner, index))
{
return true;
}
@@ -2425,7 +2418,7 @@ namespace TShockAPI
BitsByte bits = (BitsByte)args.Data.ReadByte();
bool pvp = bits[0];
- if (OnKillMe(args.Player, id, direction, dmg, pvp, playerDeathReason))
+ if (OnKillMe(args.Player, args.Data, id, direction, dmg, pvp, playerDeathReason))
return true;
args.Player.Dead = true;
@@ -2473,7 +2466,7 @@ namespace TShockAPI
byte amount = args.Data.ReadInt8();
byte type = args.Data.ReadInt8();
- if (OnLiquidSet(args.Player, tileX, tileY, amount, type))
+ if (OnLiquidSet(args.Player, args.Data, tileX, tileY, amount, type))
return true;
return false;
@@ -2486,7 +2479,7 @@ namespace TShockAPI
int tileY = args.Data.ReadInt16();
args.Data.ReadInt16(); // Ignore style
- if (OnPlaceChest(args.Player, flag, tileX, tileY))
+ if (OnPlaceChest(args.Player, args.Data, flag, tileX, tileY))
return true;
return false;
@@ -2498,7 +2491,7 @@ namespace TShockAPI
var spawnx = args.Data.ReadInt16();
var spawny = args.Data.ReadInt16();
- if (OnPlayerSpawn(player, spawnx, spawny))
+ if (OnPlayerSpawn(args.Player, args.Data, player, spawnx, spawny))
return true;
if (args.Player.InitSpawn && args.TPlayer.inventory[args.TPlayer.selectedItem].type != 50)
@@ -2548,7 +2541,7 @@ namespace TShockAPI
var x = args.Data.ReadInt16();
var y = args.Data.ReadInt16();
- if (OnChestOpen(x, y, args.Player))
+ if (OnChestOpen(args.Data, x, y, args.Player))
return true;
return false;
@@ -2570,7 +2563,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;
@@ -2587,7 +2580,7 @@ namespace TShockAPI
var prefix = args.Data.ReadInt8();
var type = args.Data.ReadInt16();
- if (OnChestItemChange(args.Player, id, slot, stacks, prefix, type))
+ if (OnChestItemChange(args.Player, args.Data, id, slot, stacks, prefix, type))
return true;
Item item = new Item();
@@ -2607,16 +2600,16 @@ namespace TShockAPI
var y = args.Data.ReadInt16();
args.Data.ReadString(); // Ignore sign text
- if (OnSignEvent(id, x, y))
+ if (OnSignEvent(args.Player, args.Data, 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;
}
- if (TShock.CheckRangePermission(args.Player, x, y))
+ if (!args.Player.IsInRange(x, y))
{
args.Player.SendData(PacketTypes.SignNew, "", id);
return true;
@@ -2631,7 +2624,7 @@ namespace TShockAPI
var y = args.Data.ReadInt16();
var homeless = args.Data.ReadInt8();
- if (OnUpdateNPCHome(args.Player, id, x, y, homeless))
+ if (OnUpdateNPCHome(args.Player, args.Data, id, x, y, homeless))
return true;
if (!args.Player.HasPermission(Permissions.movenpc))
@@ -2650,7 +2643,7 @@ namespace TShockAPI
var type = args.Data.ReadInt8();
var time = args.Data.ReadInt32();
- if (OnPlayerBuff(args.Player, id, type, time))
+ if (OnPlayerBuff(args.Player, args.Data, id, type, time))
return true;
args.Player.SendData(PacketTypes.PlayerAddBuff, "", id);
@@ -2667,7 +2660,7 @@ namespace TShockAPI
var noDelay = args.Data.ReadInt8() == 1;
var type = args.Data.ReadInt16();
- if (OnItemDrop(args.Player, id, pos, vel, stacks, prefix, noDelay, type))
+ if (OnItemDrop(args.Player, args.Data, id, pos, vel, stacks, prefix, noDelay, type))
return true;
return false;
@@ -2700,7 +2693,7 @@ namespace TShockAPI
var crit = bits[0];
var pvp = bits[1];
- if (OnPlayerDamage(args.Player, id, direction, dmg, pvp, crit, playerDeathReason))
+ if (OnPlayerDamage(args.Player, args.Data, id, direction, dmg, pvp, crit, playerDeathReason))
return true;
if (TShock.Players[id].GodMode)
@@ -2719,7 +2712,7 @@ namespace TShockAPI
var direction = (byte)(args.Data.ReadInt8() - 1);
var crit = args.Data.ReadInt8();
- if (OnNPCStrike(args.Player, id, direction, dmg, knockback, crit))
+ if (OnNPCStrike(args.Player, args.Data, id, direction, dmg, knockback, crit))
return true;
if (Main.npc[id].townNPC && !args.Player.HasPermission(Permissions.hurttownnpc))
@@ -2737,7 +2730,7 @@ namespace TShockAPI
var id = args.Data.ReadInt8();
var type = args.Data.ReadInt8();
- if (OnNPCSpecial(id, type))
+ if (OnNPCSpecial(args.Player, args.Data, id, type))
return true;
if (type == 1 && TShock.Config.DisableDungeonGuardian)
@@ -2758,7 +2751,7 @@ namespace TShockAPI
private static bool HandlePlayerAnimation(GetDataHandlerArgs args)
{
- if (OnPlayerAnimation(args.Player))
+ if (OnPlayerAnimation(args.Player, args.Data))
return true;
return false;
@@ -2768,7 +2761,7 @@ namespace TShockAPI
{
var id = args.Data.ReadInt8();
- if (OnPlayerBuffUpdate(id))
+ if (OnPlayerBuffUpdate(args.Player, args.Data, id))
return true;
for (int i = 0; i < Terraria.Player.maxBuffs; i++)
@@ -2915,7 +2908,7 @@ namespace TShockAPI
{
return true;
}
- if (OnPaintTile(x, y, t))
+ if (OnPaintTile(args.Player, args.Data, x, y, t))
{
return true;
}
@@ -2935,8 +2928,8 @@ namespace TShockAPI
}
if (args.Player.IsBouncerThrottled() ||
- TShock.CheckTilePermission(args.Player, x, y, true) ||
- TShock.CheckRangePermission(args.Player, x, y))
+ !args.Player.HasPaintPermission(x, y) ||
+ !args.Player.IsInRange(x, y))
{
args.Player.SendData(PacketTypes.PaintTile, "", x, y, Main.tile[x, y].color());
return true;
@@ -2959,7 +2952,7 @@ namespace TShockAPI
{
return true;
}
- if (OnPaintWall(x, y, t))
+ if (OnPaintWall(args.Player, args.Data, x, y, t))
{
return true;
}
@@ -2979,8 +2972,8 @@ namespace TShockAPI
}
if (args.Player.IsBouncerThrottled() ||
- TShock.CheckTilePermission(args.Player, x, y, true) ||
- TShock.CheckRangePermission(args.Player, x, y))
+ !args.Player.HasPaintPermission(x, y) ||
+ !args.Player.IsInRange(x, y))
{
args.Player.SendData(PacketTypes.PaintWall, "", x, y, Main.tile[x, y].wallColor());
return true;
@@ -3000,7 +2993,7 @@ namespace TShockAPI
var x = args.Data.ReadSingle();
var y = args.Data.ReadSingle();
- if (OnTeleport(id, flag, x, y))
+ if (OnTeleport(args.Player, args.Data, id, flag, x, y))
return true;
int type = 0;
@@ -3107,18 +3100,15 @@ namespace TShockAPI
short endY = args.Data.ReadInt16();
byte toolMode = (byte) args.Data.ReadByte();
- if (OnMassWireOperation(args.Player, startX, startY, endX, endY, toolMode))
+ if (OnMassWireOperation(args.Player, args.Data, startX, startY, endX, endY, toolMode))
return true;
return false;
}
/// The arguments to the PlaceItemFrame event.
- public class PlaceItemFrameEventArgs : HandledEventArgs
+ public class PlaceItemFrameEventArgs : GetDataHandledEventArgs
{
- /// The TSPlayer that triggered the event.
- public TSPlayer Player { get; set; }
-
/// The X coordinate of the item frame.
public short X { get; set; }
@@ -3141,7 +3131,7 @@ namespace TShockAPI
/// Fired when an ItemFrame is placed.
public static HandlerList PlaceItemFrame = new HandlerList();
- private static bool OnPlaceItemFrame(TSPlayer player, short x, short y, short itemID, byte prefix, short stack, TEItemFrame itemFrame)
+ private static bool OnPlaceItemFrame(TSPlayer player, MemoryStream data, short x, short y, short itemID, byte prefix, short stack, TEItemFrame itemFrame)
{
if (PlaceItemFrame == null)
return false;
@@ -3149,6 +3139,7 @@ namespace TShockAPI
var args = new PlaceItemFrameEventArgs
{
Player = player,
+ Data = data,
X = x,
Y = y,
ItemID = itemID,
@@ -3164,10 +3155,8 @@ namespace TShockAPI
///
/// For use with a ToggleGemLock event
///
- public class GemLockToggleEventArgs : HandledEventArgs
+ public class GemLockToggleEventArgs : GetDataHandledEventArgs
{
- /// The TSPlayer that triggered the event.
- public TSPlayer Player { get; set; }
///
/// X Location
///
@@ -3187,13 +3176,15 @@ namespace TShockAPI
///
public static HandlerList GemLockToggle = new HandlerList();
- private static bool OnGemLockToggle(short x, short y, bool on)
+ private static bool OnGemLockToggle(TSPlayer player, MemoryStream data, short x, short y, bool on)
{
if (GemLockToggle == null)
return false;
var args = new GemLockToggleEventArgs
{
+ Player = player,
+ Data = data,
X = x,
Y = y,
On = on
@@ -3208,7 +3199,7 @@ namespace TShockAPI
var y = args.Data.ReadInt16();
var on = args.Data.ReadBoolean();
- if (OnGemLockToggle(x, y, on))
+ if (OnGemLockToggle(args.Player, args.Data, x, y, on))
{
return true;
}
@@ -3281,7 +3272,7 @@ namespace TShockAPI
var y = args.Data.ReadInt16();
var type = (byte) args.Data.ReadByte();
- if (OnPlaceTileEntity(args.Player, x, y, type))
+ if (OnPlaceTileEntity(args.Player, args.Data, x, y, type))
{
return true;
}
@@ -3307,7 +3298,7 @@ namespace TShockAPI
var stack = args.Data.ReadInt16();
var itemFrame = (TEItemFrame)TileEntity.ByID[TEItemFrame.Find(x, y)];
- if (OnPlaceItemFrame(args.Player, x, y, itemID, prefix, stack, itemFrame))
+ if (OnPlaceItemFrame(args.Player, args.Data, x, y, itemID, prefix, stack, itemFrame))
{
return true;
}
@@ -3331,7 +3322,7 @@ namespace TShockAPI
return true;
}
- if (TShock.CheckRangePermission(args.Player, (int)position.X, (int)position.Y))
+ if (!args.Player.IsInRange((int)position.X, (int)position.Y))
{
return true;
}
diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs
index 89bf758c..3c747b9d 100644
--- a/TShockAPI/TSPlayer.cs
+++ b/TShockAPI/TSPlayer.cs
@@ -530,30 +530,147 @@ namespace TShockAPI
public bool SilentJoinInProgress;
+ /// Checks if a player is in range of a given tile if range checks are enabled.
+ /// The x coordinate of the tile.
+ /// The y coordinate of the tile.
+ /// The range to check for.
+ /// True if the player is in range of a tile or if range checks are off. False if not.
+ public bool IsInRange(int x, int y, int range = 32)
+ {
+ if (TShock.Config.RangeChecks && ((Math.Abs(TileX - x) > range) || (Math.Abs(TileY - y) > range)))
+ {
+ return false;
+ }
+ 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, bool shouldWarnPlayer = true)
+ {
+ 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))
+ {
+ failure = BuildPermissionFailPoint.SpawnProtect;
+ // 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))
+ {
+ failure = BuildPermissionFailPoint.Regions;
+ // If they have build permission in this region, then they're allowed to continue
+ if (TShock.Regions.CanBuild(x, y, this))
+ {
+ return true;
+ }
+ }
+ }
+ // 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.
+
+ // If they shouldn't be warned, exit early.
+ if (!shouldWarnPlayer)
+ return false;
+
+ // Space out warnings by 2 seconds so that they don't get spammed.
+ if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - lastPermissionWarning) < 2000)
+ {
+ return false;
+ }
+
+ // If they should be warned, warn them.
+ switch (failure)
+ {
+ case BuildPermissionFailPoint.GeneralBuild:
+ SendErrorMessage("You lack permission to build on this server.");
+ break;
+ case BuildPermissionFailPoint.SpawnProtect:
+ SendErrorMessage("You lack permission to build in the spawn point.");
+ break;
+ case BuildPermissionFailPoint.Regions:
+ SendErrorMessage("You lack permission to build in this region.");
+ break;
+ }
+
+ // Set the last warning time to now.
+ lastPermissionWarning = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
+
+ 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);
+ }
+
+ /// Checks if a player can place ice, and if they can, tracks ice placements and removals.
+ /// The x coordinate of the suspected ice block.
+ /// The y coordinate of the suspected ice block.
+ /// The tile type of the suspected ice block.
+ /// The EditAction on the suspected ice block.
+ /// True if a player successfully places an ice tile or removes one of their past ice tiles.
+ public bool HasModifiedIceSuccessfully(int x, int y, short tileType, GetDataHandlers.EditAction editAction)
+ {
+ // The goal is to short circuit ASAP.
+ // A subsequent call to HasBuildPermission can figure this out if not explicitly ice.
+ if (!TShock.Config.AllowIce)
+ {
+ return false;
+ }
+
+ // They've placed some ice. Horrible!
+ if (editAction == GetDataHandlers.EditAction.PlaceTile && tileType == TileID.MagicalIceBlock)
+ {
+ IceTiles.Add(new Point(x, y));
+ return true;
+ }
+
+ // The edit wasn't an add, so we check to see if the position matches any of the known ice tiles
+ if (editAction == GetDataHandlers.EditAction.KillTile)
+ {
+ foreach (Point p in IceTiles)
+ {
+ // If they're trying to kill ice or dirt, and the tile was in the list, we allow it.
+ if (p.X == x && p.Y == y && (Main.tile[p.X, p.Y].type == TileID.Dirt || Main.tile[p.X, p.Y].type == TileID.MagicalIceBlock))
+ {
+ IceTiles.Remove(p);
+ return true;
+ }
+ }
+ }
+
+ // Only a small number of cases let this happen.
+ return false;
+ }
+
///
/// A list of points where ice tiles have been placed.
///
public List IceTiles;
///
- /// Unused, can be removed.
+ /// The last time the player was warned for build permissions.
+ /// In MS, defaults to 1 (so it will warn on the first attempt).
///
- public long RPm = 1;
-
- ///
- /// World protection message cool down.
- ///
- public long WPm = 1;
-
- ///
- /// Spawn protection message cool down.
- ///
- public long SPm = 1;
-
- ///
- /// Permission to build message cool down.
- ///
- public long BPm = 1;
+ public long lastPermissionWarning = 1;
///
/// The time in ms when the player has logged in.
diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs
index 0996c9a9..d534d67e 100644
--- a/TShockAPI/TShock.cs
+++ b/TShockAPI/TShock.cs
@@ -576,7 +576,7 @@ namespace TShockAPI
return;
}
- if (CheckRangePermission(tsplr, args.Chest.x, args.Chest.y))
+ if (!tsplr.IsInRange(args.Chest.x, args.Chest.y))
{
args.Handled = true;
return;
@@ -1726,178 +1726,6 @@ namespace TShockAPI
e.Handled = true;
}
-
-
-
- /// CheckRangePermission - Checks if a player has permission to modify a tile dependent on range checks.
- /// player - The TSPlayer object.
- /// x - The x coordinate of the tile.
- /// y - The y coordinate of the tile.
- /// range - The range to check for.
- /// bool - True if the player should not be able to place the tile. False if they can, or if range checks are off.
- public static bool CheckRangePermission(TSPlayer player, int x, int y, int range = 32)
- {
- if (Config.RangeChecks && ((Math.Abs(player.TileX - x) > range) || (Math.Abs(player.TileY - y) > range)))
- {
- return true;
- }
- return false;
- }
-
- /// CheckTilePermission - Checks to see if a player has permission to modify a tile in general.
- /// player - The TSPlayer object.
- /// tileX - The x coordinate of the tile.
- /// tileY - The y coordinate of the tile.
- /// tileType - The tile type.
- /// actionType - The type of edit that took place.
- /// bool - True if the player should not be able to modify a tile.
- public static bool CheckTilePermission(TSPlayer player, int tileX, int tileY, short tileType, GetDataHandlers.EditAction actionType)
- {
- if (!player.HasPermission(Permissions.canbuild))
- {
- if (TShock.Config.AllowIce && actionType != GetDataHandlers.EditAction.PlaceTile)
- {
- foreach (Point p in player.IceTiles)
- {
- if (p.X == tileX && p.Y == tileY && (Main.tile[p.X, p.Y].type == 0 || Main.tile[p.X, p.Y].type == 127))
- {
- player.IceTiles.Remove(p);
- return false;
- }
- }
-
- if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.BPm) > 2000)
- {
- player.SendErrorMessage("You do not have permission to build!");
- player.BPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
- }
- return true;
- }
-
- if (TShock.Config.AllowIce && actionType == GetDataHandlers.EditAction.PlaceTile && tileType == 127)
- {
- player.IceTiles.Add(new Point(tileX, tileY));
- return false;
- }
-
- if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.BPm) > 2000)
- {
- 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) > 2000)
- {
- player.SendErrorMessage("Spawn is protected from changes.");
- player.SPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
- }
- return true;
- }
- }
- }
- 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.