Skip to content
43 changes: 43 additions & 0 deletions TShockAPI/Bouncer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ internal Bouncer()
GetDataHandlers.PlaceObject += OnPlaceObject;
GetDataHandlers.PlaceTileEntity += OnPlaceTileEntity;
GetDataHandlers.PlaceItemFrame += OnPlaceItemFrame;
GetDataHandlers.WeaponsRackTryPlacing += OnWeaponsRackTryPlacing;
GetDataHandlers.PortalTeleport += OnPlayerPortalTeleport;
GetDataHandlers.GemLockToggle += OnGemLockToggle;
GetDataHandlers.MassWireOperation += OnMassWireOperation;
Expand Down Expand Up @@ -2696,6 +2697,48 @@ internal void OnPlaceItemFrame(object sender, GetDataHandlers.PlaceItemFrameEven
}
}

/// <summary>Fired when an weapon rack is placed for anti-cheat detection.</summary>
/// <param name="sender">The object that triggered the event.</param>
/// <param name="args">The packet arguments that the event has.</param>
internal void OnWeaponsRackTryPlacing(object sender, GetDataHandlers.WeaponsRackTryPlacingEventArgs args)
{
if (!TShock.Utils.TilePlacementValid(args.X, args.Y))
{
TShock.Log.ConsoleDebug(GetString("Bouncer / OnWeaponsRackTryPlacing rejected tile placement valid from {0}", args.Player.Name));
args.Handled = true;
return;
}

if (args.Player.IsBeingDisabled())
{
TShock.Log.ConsoleDebug(GetString("Bouncer / OnWeaponsRackTryPlacing rejected disabled from {0}", args.Player.Name));
NetMessage.SendData((int)PacketTypes.UpdateTileEntity, -1, -1, NetworkText.Empty, args.WeaponRack.ID, 0, 1);
args.Handled = true;
return;
}

if (!args.Player.HasBuildPermission(args.X, args.Y))
{
int num = Item.NewItem(null, (args.X * 16) + 8, (args.Y * 16) + 8, args.Player.TPlayer.width, args.Player.TPlayer.height, args.ItemID, args.Stack, noBroadcast: true, args.Prefix, noGrabDelay: true);
Main.item[num].playerIndexTheItemIsReservedFor = args.Player.Index;
NetMessage.SendData((int)PacketTypes.ItemDrop, args.Player.Index, -1, NetworkText.Empty, num, 1f);
NetMessage.SendData((int)PacketTypes.ItemOwner, args.Player.Index, -1, NetworkText.Empty, num);

TShock.Log.ConsoleDebug(GetString("Bouncer / OnWeaponsRackTryPlacing rejected permissions from {0}", args.Player.Name));
NetMessage.SendData((int)PacketTypes.UpdateTileEntity, -1, -1, NetworkText.Empty, args.WeaponRack.ID, 0, 1);
args.Handled = true;
return;
}

if (!args.Player.IsInRange(args.X, args.Y))
{
TShock.Log.ConsoleDebug(GetString("Bouncer / OnWeaponsRackTryPlacing rejected range checks from {0}", args.Player.Name));
NetMessage.SendData((int)PacketTypes.UpdateTileEntity, -1, -1, NetworkText.Empty, args.WeaponRack.ID, 0, 1);
args.Handled = true;
return;
}
}

internal void OnPlayerPortalTeleport(object sender, GetDataHandlers.TeleportThroughPortalEventArgs args)
{
//Packet 96 (player teleport through portal) has no validation on whether or not the player id provided
Expand Down
69 changes: 66 additions & 3 deletions TShockAPI/GetDataHandlers.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
TShock, a server mod for Terraria
Copyright (C) 2011-2019 Pryaxis & TShock Contributors

Expand All @@ -16,20 +16,21 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

using Microsoft.Xna.Framework;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.IO.Streams;
using System.Linq;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.DataStructures;
using Terraria.GameContent.Tile_Entities;
using Terraria.ID;
using Terraria.Localization;
using TShockAPI.Models.PlayerUpdate;
using TShockAPI.Configuration;
using TShockAPI.Models.PlayerUpdate;

namespace TShockAPI
{
Expand Down Expand Up @@ -136,6 +137,7 @@ public static void InitGetDataHandler()
{ PacketTypes.Emoji, HandleEmoji },
{ PacketTypes.TileEntityDisplayDollItemSync, HandleTileEntityDisplayDollItemSync },
{ PacketTypes.RequestTileEntityInteraction, HandleRequestTileEntityInteraction },
{ PacketTypes.WeaponsRackTryPlacing, HandleWeaponsRackTryPlacing },
{ PacketTypes.SyncTilePicking, HandleSyncTilePicking },
{ PacketTypes.SyncRevengeMarker, HandleSyncRevengeMarker },
{ PacketTypes.LandGolfBallInCup, HandleLandGolfBallInCup },
Expand Down Expand Up @@ -2321,6 +2323,50 @@ private static bool OnRequestTileEntityInteraction(TSPlayer player, MemoryStream
RequestTileEntityInteraction.Invoke(null, args);
return args.Handled;
}
/// <summary>
/// For use in an OnWeaponsRackTryPlacing event.
/// </summary>
public class WeaponsRackTryPlacingEventArgs : GetDataHandledEventArgs
{
/// <summary>The X coordinate of the weapon rack.</summary>
public short X { get; set; }

/// <summary>The Y coordinate of the weapon rack.</summary>
public short Y { get; set; }

/// <summary>The ItemID of the weapon rack.</summary>
public short ItemID { get; set; }

/// <summary>The prefix.</summary>
public byte Prefix { get; set; }

/// <summary>The stack.</summary>
public short Stack { get; set; }

/// <summary>The ItemFrame object associated with this event.</summary>
public TEWeaponsRack WeaponRack { get; set; }
}
/// <summary>Fired when an WeaponRack is placed.</summary>
public static HandlerList<WeaponsRackTryPlacingEventArgs> WeaponsRackTryPlacing = new HandlerList<WeaponsRackTryPlacingEventArgs>();
private static bool OnWeaponsRackTryPlacing(TSPlayer player, MemoryStream data, short x, short y, short itemID, byte prefix, short stack, TEWeaponsRack weaponRack)
{
if (WeaponsRackTryPlacing == null)
return false;

var args = new WeaponsRackTryPlacingEventArgs
{
Player = player,
Data = data,
X = x,
Y = y,
ItemID = itemID,
Prefix = prefix,
Stack = stack,
WeaponRack = weaponRack
};
WeaponsRackTryPlacing.Invoke(null, args);
return args.Handled;
}

/// <summary>
/// For use in a SyncTilePicking event.
Expand Down Expand Up @@ -4803,6 +4849,23 @@ private static bool HandleRequestTileEntityInteraction(GetDataHandlerArgs args)
return false;
}

private static bool HandleWeaponsRackTryPlacing(GetDataHandlerArgs args)
{
short x = args.Data.ReadInt16();
short y = args.Data.ReadInt16();
short itemID = args.Data.ReadInt16();
byte prefix = args.Data.ReadInt8();
short stack = args.Data.ReadInt16();
TEWeaponsRack WeaponRack = (TEWeaponsRack)TileEntity.ByID[TEWeaponsRack.Find(x, y)];

if (OnWeaponsRackTryPlacing(args.Player, args.Data, x, y, itemID, prefix, stack, WeaponRack))
{
return true;
}

return false;
}

private static bool HandleSyncTilePicking(GetDataHandlerArgs args)
{
byte playerIndex = args.Data.ReadInt8();
Expand Down
Loading