diff --git a/CHANGELOG.md b/CHANGELOG.md
index aa42a2aa..d7ab5308 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,15 @@
This is the rolling changelog for TShock for Terraria. Use past tense when adding new entries; sign your name off when you add or change something. This should primarily be things like user changes, not necessarily codebase changes unless it's really relevant or large.
## Upcoming Changes
+* API: Added hooks for item, projectile and tile bans (@deadsurgeon42)
+* API: New WorldGrassSpread hook which shold allow corruption/crimson/hallow creep config options to work (@DeathCradle)
+* Fixed saving when one player is one the server and another one joins (@MarioE)
+* Fixed /spawnmob not spawning negative IDs (@MarioE)
+* Validated tile placement on PlaceObject; clients can no longer place frames, paintings etc with dirt blocks (@bartico6, @ProfessorXZ)
+* Updated to new stat tracking system with more data so we can actually make informed software decisions (Jordan Coulam)
+## TShock 4.3.24
+* API: Changed `PlayerHooks` permission hook mechanisms to allow negation from hooks (@deadsurgeon42)
* Updated OpenTerraria API to 1.3.5.3 (@DeathCradle)
* Updated Terraria Server API to 1.3.5.3 (@WhiteXZ, @hakusaro)
* Updated TShock core components to 1.3.5.3 (@hakusaro)
diff --git a/README.md b/README.md
index 2d024912..2ad38b13 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-
+
diff --git a/TShockAPI/DB/ItemManager.cs b/TShockAPI/DB/ItemManager.cs
index 0ff89b40..c3d92840 100644
--- a/TShockAPI/DB/ItemManager.cs
+++ b/TShockAPI/DB/ItemManager.cs
@@ -201,8 +201,9 @@ namespace TShockAPI.DB
if (ply.HasPermission(Permissions.usebanneditem))
return true;
- if (PlayerHooks.OnPlayerItembanPermission(ply, this))
- return true;
+ PermissionHookResult hookResult = PlayerHooks.OnPlayerItembanPermission(ply, this);
+ if (hookResult != PermissionHookResult.Unhandled)
+ return hookResult == PermissionHookResult.Granted;
var cur = ply.Group;
var traversed = new List();
diff --git a/TShockAPI/DB/ProjectileManager.cs b/TShockAPI/DB/ProjectileManager.cs
index 79bf9a37..4214fce6 100644
--- a/TShockAPI/DB/ProjectileManager.cs
+++ b/TShockAPI/DB/ProjectileManager.cs
@@ -206,8 +206,9 @@ namespace TShockAPI.DB
if (ply.HasPermission(Permissions.canusebannedprojectiles))
return true;
- if (PlayerHooks.OnPlayerProjbanPermission(ply, this))
- return true;
+ PermissionHookResult hookResult = PlayerHooks.OnPlayerProjbanPermission(ply, this);
+ if (hookResult != PermissionHookResult.Unhandled)
+ return hookResult == PermissionHookResult.Granted;
var cur = ply.Group;
var traversed = new List();
diff --git a/TShockAPI/DB/TileManager.cs b/TShockAPI/DB/TileManager.cs
index 90a235f8..c291b21a 100644
--- a/TShockAPI/DB/TileManager.cs
+++ b/TShockAPI/DB/TileManager.cs
@@ -206,8 +206,9 @@ namespace TShockAPI.DB
if (ply.HasPermission(Permissions.canusebannedtiles))
return true;
- if (PlayerHooks.OnPlayerTilebanPermission(ply, this))
- return true;
+ PermissionHookResult hookResult = PlayerHooks.OnPlayerTilebanPermission(ply, this);
+ if (hookResult != PermissionHookResult.Unhandled)
+ return hookResult == PermissionHookResult.Granted;
var cur = ply.Group;
var traversed = new List();
diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs
index 2a7ddd00..77e37c03 100644
--- a/TShockAPI/GetDataHandlers.cs
+++ b/TShockAPI/GetDataHandlers.cs
@@ -2350,6 +2350,15 @@ namespace TShockAPI
return true;
}
+ // This is neccessary to check in order to prevent special tiles such as
+ // queen bee larva, paintings etc that use this packet from being placed
+ // without selecting the right item.
+ if (type != args.TPlayer.inventory[args.TPlayer.selectedItem].createTile)
+ {
+ args.Player.SendTileSquare(x, y, 4);
+ return true;
+ }
+
TileObjectData tileData = TileObjectData.GetTileData(type, style, 0);
if (tileData == null)
return true;
diff --git a/TShockAPI/Hooks/PlayerHooks.cs b/TShockAPI/Hooks/PlayerHooks.cs
index 062a78b8..91f9612c 100644
--- a/TShockAPI/Hooks/PlayerHooks.cs
+++ b/TShockAPI/Hooks/PlayerHooks.cs
@@ -143,7 +143,7 @@ namespace TShockAPI.Hooks
///
/// EventArgs used for the event.
///
- public class PlayerPermissionEventArgs : HandledEventArgs
+ public class PlayerPermissionEventArgs
{
///
/// The player who fired the event.
@@ -155,6 +155,11 @@ namespace TShockAPI.Hooks
///
public string Permission { get; set; }
+ ///
+ /// of the hook.
+ ///
+ public PermissionHookResult Result { get; set; }
+
///
/// Initializes a new instance of the PlayerPermissionEventArgs class.
///
@@ -164,13 +169,14 @@ namespace TShockAPI.Hooks
{
Player = player;
Permission = permission;
+ Result = PermissionHookResult.Unhandled;
}
}
///
/// EventArgs used for the event.
///
- public class PlayerItembanPermissionEventArgs : HandledEventArgs
+ public class PlayerItembanPermissionEventArgs
{
///
/// The player who fired the event.
@@ -182,22 +188,28 @@ namespace TShockAPI.Hooks
///
public ItemBan BannedItem { get; set; }
+ ///
+ /// of the hook.
+ ///
+ public PermissionHookResult Result { get; set; }
+
///
/// Initializes a new instance of the PlayerItembanPermissionEventArgs class.
///
/// The player who fired the event.
- /// The permission being checked.
+ /// The banned item being checked.
public PlayerItembanPermissionEventArgs(TSPlayer player, ItemBan bannedItem)
{
Player = player;
BannedItem = bannedItem;
+ Result = PermissionHookResult.Unhandled;
}
}
///
/// EventArgs used for the event.
///
- public class PlayerProjbanPermissionEventArgs : HandledEventArgs
+ public class PlayerProjbanPermissionEventArgs
{
///
/// The player who fired the event.
@@ -209,6 +221,11 @@ namespace TShockAPI.Hooks
///
public ProjectileBan BannedProjectile { get; set; }
+ ///
+ /// of the hook.
+ ///
+ public PermissionHookResult Result { get; set; }
+
///
/// Initializes a new instance of the PlayerProjbanPermissionEventArgs class.
///
@@ -218,13 +235,14 @@ namespace TShockAPI.Hooks
{
Player = player;
BannedProjectile = checkedProjectile;
+ Result = PermissionHookResult.Unhandled;
}
}
///
/// EventArgs used for the event.
///
- public class PlayerTilebanPermissionEventArgs : HandledEventArgs
+ public class PlayerTilebanPermissionEventArgs
{
///
/// The player who fired the event.
@@ -236,6 +254,11 @@ namespace TShockAPI.Hooks
///
public TileBan BannedTile { get; set; }
+ ///
+ /// of the hook.
+ ///
+ public PermissionHookResult Result { get; set; }
+
///
/// Initializes a new instance of the PlayerTilebanPermissionEventArgs class.
///
@@ -245,6 +268,7 @@ namespace TShockAPI.Hooks
{
Player = player;
BannedTile = checkedTile;
+ Result = PermissionHookResult.Unhandled;
}
}
@@ -439,60 +463,79 @@ namespace TShockAPI.Hooks
/// Fires the event.
///
/// The player firing the event.
- /// True if the event has been handled.
- public static bool OnPlayerPermission(TSPlayer player, string permission)
+ /// Event result if the event has been handled, otherwise .
+ public static PermissionHookResult OnPlayerPermission(TSPlayer player, string permission)
{
if (PlayerPermission == null)
- return false;
+ return PermissionHookResult.Unhandled;
var args = new PlayerPermissionEventArgs(player, permission);
PlayerPermission(args);
- return args.Handled;
+
+ return args.Result;
}
///
/// Fires the event.
///
/// The player firing the event.
- /// True if the event has been handled.
- public static bool OnPlayerItembanPermission(TSPlayer player, ItemBan bannedItem)
+ /// Event result if the event has been handled, otherwise .
+ public static PermissionHookResult OnPlayerItembanPermission(TSPlayer player, ItemBan bannedItem)
{
if (PlayerItembanPermission == null)
- return false;
+ return PermissionHookResult.Unhandled;
var args = new PlayerItembanPermissionEventArgs(player, bannedItem);
PlayerItembanPermission(args);
- return args.Handled;
+
+ return args.Result;
}
///
/// Fires the event.
///
/// The player firing the event.
- /// True if the event has been handled.
- public static bool OnPlayerProjbanPermission(TSPlayer player, ProjectileBan bannedProj)
+ /// Event result if the event has been handled, otherwise .
+ public static PermissionHookResult OnPlayerProjbanPermission(TSPlayer player, ProjectileBan bannedProj)
{
if (PlayerProjbanPermission == null)
- return false;
+ return PermissionHookResult.Unhandled;
var args = new PlayerProjbanPermissionEventArgs(player, bannedProj);
PlayerProjbanPermission(args);
- return args.Handled;
+
+ return args.Result;
}
///
/// Fires the event.
///
/// The player firing the event.
- /// True if the event has been handled.
- public static bool OnPlayerTilebanPermission(TSPlayer player, TileBan bannedTile)
+ /// Event result if the event has been handled, otherwise .
+ public static PermissionHookResult OnPlayerTilebanPermission(TSPlayer player, TileBan bannedTile)
{
if (PlayerTilebanPermission == null)
- return false;
+ return PermissionHookResult.Unhandled;
var args = new PlayerTilebanPermissionEventArgs(player, bannedTile);
PlayerTilebanPermission(args);
- return args.Handled;
+
+ return args.Result;
}
+
}
+
+ ///
+ /// Defines the possible outcomes of handlers.
+ ///
+ public enum PermissionHookResult
+ {
+ /// Hook doesn't return a result on the permission check.
+ Unhandled,
+ /// Permission is explicitly denied by a hook.
+ Denied,
+ /// Permission is explicitly granted by a hook.
+ Granted
+ }
+
}
diff --git a/TShockAPI/Sockets/LinuxTcpSocket.cs b/TShockAPI/Sockets/LinuxTcpSocket.cs
index 98df1674..86381237 100644
--- a/TShockAPI/Sockets/LinuxTcpSocket.cs
+++ b/TShockAPI/Sockets/LinuxTcpSocket.cs
@@ -12,23 +12,23 @@ namespace TShockAPI.Sockets
{
public class LinuxTcpSocket : ISocket
{
- private byte[] _packetBuffer = new byte[1024];
+ public byte[] _packetBuffer = new byte[1024];
- private int _packetBufferLength;
+ public int _packetBufferLength;
- private List