Create hook PlaceObject; move anti-hack to Bouncer

This commit is contained in:
Lucas Nicodemus 2017-12-07 21:43:33 -07:00
parent dbed5e3d5a
commit 914782ab9e
2 changed files with 179 additions and 89 deletions

View file

@ -27,6 +27,7 @@ using OTAPI.Tile;
using TShockAPI.Localization; using TShockAPI.Localization;
using static TShockAPI.GetDataHandlers; using static TShockAPI.GetDataHandlers;
using TerrariaApi.Server; using TerrariaApi.Server;
using Terraria.ObjectData;
namespace TShockAPI namespace TShockAPI
@ -40,11 +41,138 @@ namespace TShockAPI
{ {
// Setup hooks // Setup hooks
GetDataHandlers.PlaceObject.Register(OnPlaceObject);
GetDataHandlers.SendTileSquare.Register(OnSendTileSquare); GetDataHandlers.SendTileSquare.Register(OnSendTileSquare);
GetDataHandlers.HealOtherPlayer.Register(OnHealOtherPlayer); GetDataHandlers.HealOtherPlayer.Register(OnHealOtherPlayer);
GetDataHandlers.TileEdit.Register(OnTileEdit); GetDataHandlers.TileEdit.Register(OnTileEdit);
} }
internal void OnPlaceObject(object sender, GetDataHandlers.PlaceObjectEventArgs args)
{
short x = args.X;
short y = args.Y;
short type = args.Type;
short style = args.Style;
byte alternate = args.Alternate;
bool direction = args.Direction;
if (type < 0 || type >= Main.maxTileSets)
{
args.Handled = true;
return;
}
if (x < 0 || x >= Main.maxTilesX)
{
args.Handled = true;
return;
}
if (y < 0 || y >= Main.maxTilesY)
{
args.Handled = true;
return;
}
//style 52 and 53 are used by ItemID.Fake_newchest1 and ItemID.Fake_newchest2
//These two items cause localised lag and rendering issues
if (type == TileID.FakeContainers && (style == 52 || style == 53))
{
args.Player.SendTileSquare(x, y, 4);
args.Handled = true;
return;
}
if (TShock.TileBans.TileIsBanned(type, args.Player))
{
args.Player.SendTileSquare(x, y, 1);
args.Player.SendErrorMessage("You do not have permission to place this tile.");
args.Handled = true;
return;
}
if (!TShock.Utils.TilePlacementValid(x, y))
{
args.Handled = true;
return;
}
if (args.Player.Dead && TShock.Config.PreventDeadModification)
{
args.Handled = true;
return;
}
if (TShock.CheckIgnores(args.Player))
{
args.Player.SendTileSquare(x, y, 4);
args.Handled = true;
return;
}
// 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.Player.TPlayer.inventory[args.Player.TPlayer.selectedItem].createTile)
{
args.Player.SendTileSquare(x, y, 4);
args.Handled = true;
return;
}
TileObjectData tileData = TileObjectData.GetTileData(type, style, 0);
if (tileData == null)
{
args.Handled = true;
return;
}
x -= tileData.Origin.X;
y -= tileData.Origin.Y;
for (int i = x; i < x + tileData.Width; i++)
{
for (int j = y; j < y + tileData.Height; j++)
{
if (TShock.CheckTilePermission(args.Player, i, j, type, EditAction.PlaceTile))
{
args.Player.SendTileSquare(i, j, 4);
args.Handled = true;
return;
}
}
}
// Ignore rope placement range
if ((type != TileID.Rope
|| type != TileID.SilkRope
|| type != TileID.VineRope
|| type != TileID.WebRope)
&& TShock.CheckRangePermission(args.Player, x, y))
{
args.Player.SendTileSquare(x, y, 4);
args.Handled = true;
return;
}
if (args.Player.TilePlaceThreshold >= TShock.Config.TilePlaceThreshold)
{
args.Player.Disable("Reached TilePlace threshold.", DisableFlags.WriteToLogAndConsole);
args.Player.SendTileSquare(x, y, 4);
args.Handled = true;
return;
}
if (!args.Player.HasPermission(Permissions.ignoreplacetiledetection))
{
args.Player.TilePlaceThreshold++;
var coords = new Vector2(x, y);
lock (args.Player.TilesCreated)
if (!args.Player.TilesCreated.ContainsKey(coords))
args.Player.TilesCreated.Add(coords, Main.tile[x, y]);
}
}
internal void OnTileEdit(object sender, GetDataHandlers.TileEditEventArgs args) internal void OnTileEdit(object sender, GetDataHandlers.TileEditEventArgs args)
{ {
EditAction action = args.Action; EditAction action = args.Action;
@ -64,14 +192,22 @@ namespace TShockAPI
} }
if (!TShock.Utils.TilePlacementValid(tileX, tileY)) if (!TShock.Utils.TilePlacementValid(tileX, tileY))
{
args.Handled = true; args.Handled = true;
return; return;
}
if (action == EditAction.KillTile && Main.tile[tileX, tileY].type == TileID.MagicalIceBlock) if (action == EditAction.KillTile && Main.tile[tileX, tileY].type == TileID.MagicalIceBlock)
{
args.Handled = false; args.Handled = false;
return; return;
}
if (args.Player.Dead && TShock.Config.PreventDeadModification) if (args.Player.Dead && TShock.Config.PreventDeadModification)
{
args.Handled = true; args.Handled = true;
return; return;
}
if (args.Player.AwaitingName) if (args.Player.AwaitingName)
{ {

View file

@ -613,9 +613,51 @@ namespace TShockAPI
TileX = tilex, TileX = tilex,
TileY = tiley, TileY = tiley,
}; };
SendTileSquare.Invoke(null, args); SendTileSquare.Invoke(null, args);
return args.Handled; return args.Handled;
} }
public class PlaceObjectEventArgs : HandledEventArgs
{
public TSPlayer Player { get; set; }
public short X { get; set ; }
public short Y { get; set; }
public short Type { get; set; }
public short Style { get; set; }
public byte Alternate { get; set; }
public bool Direction { get; set; }
}
public static HandlerList<PlaceObjectEventArgs> PlaceObject;
private static bool OnPlaceObject(TSPlayer player, short x, short y, short type, short style, byte alternate, bool direction)
{
if (PlaceObject == null)
return false;
var args = new PlaceObjectEventArgs
{
Player = player,
X = x,
Y = y,
Type = type,
Style = style,
Alternate = alternate,
Direction = direction
};
PlaceObject.Invoke(null, args);
return args.Handled;
}
/// <summary> /// <summary>
/// For use in a NewProjectile event /// For use in a NewProjectile event
/// </summary> /// </summary>
@ -1826,7 +1868,6 @@ namespace TShockAPI
return false; return false;
} }
/// <summary> /// <summary>
/// Handle PlaceObject event /// Handle PlaceObject event
/// </summary> /// </summary>
@ -1839,96 +1880,9 @@ namespace TShockAPI
byte alternate = args.Data.ReadInt8(); byte alternate = args.Data.ReadInt8();
bool direction = args.Data.ReadBoolean(); bool direction = args.Data.ReadBoolean();
if (type < 0 || type >= Main.maxTileSets) if (OnPlaceObject(args.Player, x, y, type, style, alternate, direction))
return true; return true;
if (x < 0 || x >= Main.maxTilesX)
return true;
if (y < 0 || y >= Main.maxTilesY)
return true;
//style 52 and 53 are used by ItemID.Fake_newchest1 and ItemID.Fake_newchest2
//These two items cause localised lag and rendering issues
if (type == TileID.FakeContainers && (style == 52 || style == 53))
{
args.Player.SendTileSquare(x, y, 4);
return true;
}
if (TShock.TileBans.TileIsBanned(type, args.Player))
{
args.Player.SendTileSquare(x, y, 1);
args.Player.SendErrorMessage("You do not have permission to place this tile.");
return true;
}
if (!TShock.Utils.TilePlacementValid(x, y))
return true;
if (args.Player.Dead && TShock.Config.PreventDeadModification)
return true;
if (TShock.CheckIgnores(args.Player))
{
args.Player.SendTileSquare(x, y, 4);
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;
x -= tileData.Origin.X;
y -= tileData.Origin.Y;
for (int i = x; i < x + tileData.Width; i++)
{
for (int j = y; j < y + tileData.Height; j++)
{
if (TShock.CheckTilePermission(args.Player, i, j, type, EditAction.PlaceTile))
{
args.Player.SendTileSquare(i, j, 4);
return true;
}
}
}
// Ignore rope placement range
if ((type != TileID.Rope
|| type != TileID.SilkRope
|| type != TileID.VineRope
|| type != TileID.WebRope)
&& TShock.CheckRangePermission(args.Player, x, y))
{
args.Player.SendTileSquare(x, y, 4);
return true;
}
if (args.Player.TilePlaceThreshold >= TShock.Config.TilePlaceThreshold)
{
args.Player.Disable("Reached TilePlace threshold.", DisableFlags.WriteToLogAndConsole);
args.Player.SendTileSquare(x, y, 4);
return true;
}
if (!args.Player.HasPermission(Permissions.ignoreplacetiledetection))
{
args.Player.TilePlaceThreshold++;
var coords = new Vector2(x, y);
lock (args.Player.TilesCreated)
if (!args.Player.TilesCreated.ContainsKey(coords))
args.Player.TilesCreated.Add(coords, Main.tile[x, y]);
}
return false; return false;
} }