Merge branch 'general-devel' into general-devel

This commit is contained in:
Lucas Nicodemus 2025-03-10 00:20:50 +09:00 committed by GitHub
commit 531ec1376c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 97 additions and 33 deletions

View file

@ -504,6 +504,14 @@ namespace TShockAPI
return;
}
if (!float.IsFinite(pos.X) || !float.IsFinite(pos.Y))
{
TShock.Log.ConsoleInfo(GetString("Bouncer / OnPlayerUpdate force kicked (attempted to set position to infinity or NaN) from {0}", args.Player.Name));
args.Player.Kick(GetString("Detected DOOM set to ON position."), true, true);
args.Handled = true;
return;
}
if (pos.X < 0 || pos.Y < 0 || pos.X >= Main.maxTilesX * 16 - 16 || pos.Y >= Main.maxTilesY * 16 - 16)
{
TShock.Log.ConsoleDebug(GetString("Bouncer / OnPlayerUpdate rejected from (position check) {0}", args.Player.Name));
@ -1072,6 +1080,22 @@ namespace TShockAPI
bool noDelay = args.NoDelay;
short type = args.Type;
if (!float.IsFinite(pos.X) || !float.IsFinite(pos.Y))
{
TShock.Log.ConsoleInfo(GetString("Bouncer / OnItemDrop force kicked (attempted to set position to infinity or NaN) from {0}", args.Player.Name));
args.Player.Kick(GetString("Detected DOOM set to ON position."), true, true);
args.Handled = true;
return;
}
if (!float.IsFinite(vel.X) || !float.IsFinite(vel.Y))
{
TShock.Log.ConsoleInfo(GetString("Bouncer / OnItemDrop force kicked (attempted to set velocity to infinity or NaN) from {0}", args.Player.Name));
args.Player.Kick(GetString("Detected DOOM set to ON position."), true, true);
args.Handled = true;
return;
}
// player is attempting to crash clients
if (type < -48 || type >= Terraria.ID.ItemID.Count)
{
@ -1175,6 +1199,22 @@ namespace TShockAPI
int index = args.Index;
float[] ai = args.Ai;
if (!float.IsFinite(pos.X) || !float.IsFinite(pos.Y))
{
TShock.Log.ConsoleInfo(GetString("Bouncer / OnNewProjectile force kicked (attempted to set position to infinity or NaN) from {0}", args.Player.Name));
args.Player.Kick(GetString("Detected DOOM set to ON position."), true, true);
args.Handled = true;
return;
}
if (!float.IsFinite(vel.X) || !float.IsFinite(vel.Y))
{
TShock.Log.ConsoleInfo(GetString("Bouncer / OnNewProjectile force kicked (attempted to set velocity to infinity or NaN) from {0}", args.Player.Name));
args.Player.Kick(GetString("Detected DOOM set to ON position."), true, true);
args.Handled = true;
return;
}
if (index > Main.maxProjectiles)
{
TShock.Log.ConsoleDebug(GetString("Bouncer / OnNewProjectile rejected from above projectile limit from {0}", args.Player.Name));

View file

@ -95,6 +95,7 @@ namespace TShockAPI
{ PacketTypes.TileSendSquare, HandleSendTileRect },
{ PacketTypes.ItemDrop, HandleItemDrop },
{ PacketTypes.ItemOwner, HandleItemOwner },
{ PacketTypes.NpcItemStrike, HandleNpcItemStrike },
{ PacketTypes.ProjectileNew, HandleProjectileNew },
{ PacketTypes.NpcStrike, HandleNpcStrike },
{ PacketTypes.ProjectileDestroy, HandleProjectileKill },
@ -2964,6 +2965,13 @@ namespace TShockAPI
return false;
}
private static bool HandleNpcItemStrike(GetDataHandlerArgs args)
{
// Never sent by vanilla client, ignore this
TShock.Log.ConsoleDebug(GetString("GetDataHandlers / HandleNpcItemStrike surprise packet! Someone tell the TShock team! {0}", args.Player.Name));
return true;
}
private static bool HandleProjectileNew(GetDataHandlerArgs args)
{
short ident = args.Data.ReadInt16();

View file

@ -78,6 +78,13 @@ namespace TShockAPI.Handlers
Removal,
}
public enum MatchResult
{
NotMatched,
RejectChanges,
BroadcastChanges,
}
private readonly int Width;
private readonly int Height;
@ -179,11 +186,11 @@ namespace TShockAPI.Handlers
/// <param name="player">The player the operation originates from.</param>
/// <param name="rect">The tile rectangle of the operation.</param>
/// <returns><see langword="true"/>, if the rect matches this operation and the changes have been applied, otherwise <see langword="false"/>.</returns>
public bool Matches(TSPlayer player, TileRect rect)
public MatchResult Matches(TSPlayer player, TileRect rect)
{
if (rect.Width != Width || rect.Height != Height)
{
return false;
return MatchResult.NotMatched;
}
for (int x = 0; x < rect.Width; x++)
@ -195,7 +202,7 @@ namespace TShockAPI.Handlers
{
if (tile.Type != TileType)
{
return false;
return MatchResult.NotMatched;
}
}
if (Type is MatchType.Placement or MatchType.StateChange)
@ -204,7 +211,7 @@ namespace TShockAPI.Handlers
{
if (tile.FrameX < 0 || tile.FrameX > MaxFrameX || tile.FrameX % FrameXStep != 0)
{
return false;
return MatchResult.NotMatched;
}
}
if (MaxFrameY != IGNORE_FRAME)
@ -214,7 +221,7 @@ namespace TShockAPI.Handlers
// this is the only tile type sent in a tile rect where the frame have a different pattern (56, 74, 92 instead of 54, 72, 90)
if (!(TileType == TileID.LunarMonolith && tile.FrameY % FrameYStep == 2))
{
return false;
return MatchResult.NotMatched;
}
}
}
@ -223,7 +230,7 @@ namespace TShockAPI.Handlers
{
if (tile.Active)
{
return false;
return MatchResult.NotMatched;
}
}
}
@ -236,7 +243,7 @@ namespace TShockAPI.Handlers
if (!player.HasBuildPermission(x, y))
{
// for simplicity, let's pretend that the edit was valid, but do not execute it
return true;
return MatchResult.RejectChanges;
}
}
}
@ -257,10 +264,10 @@ namespace TShockAPI.Handlers
}
}
return false;
return MatchResult.NotMatched;
}
private bool MatchPlacement(TSPlayer player, TileRect rect)
private MatchResult MatchPlacement(TSPlayer player, TileRect rect)
{
for (int x = rect.X; x < rect.Y + rect.Width; x++)
{
@ -268,7 +275,7 @@ namespace TShockAPI.Handlers
{
if (Main.tile[x, y].active()) // the client will kill tiles that auto break before placing the object
{
return false;
return MatchResult.NotMatched;
}
}
}
@ -277,7 +284,7 @@ namespace TShockAPI.Handlers
if (TShock.TileBans.TileIsBanned((short)TileType, player))
{
// for simplicity, let's pretend that the edit was valid, but do not execute it
return true;
return MatchResult.RejectChanges;
}
for (int x = 0; x < rect.Width; x++)
@ -291,10 +298,10 @@ namespace TShockAPI.Handlers
}
}
return true;
return MatchResult.BroadcastChanges;
}
private bool MatchStateChange(TSPlayer player, TileRect rect)
private MatchResult MatchStateChange(TSPlayer player, TileRect rect)
{
for (int x = rect.X; x < rect.Y + rect.Width; x++)
{
@ -302,7 +309,7 @@ namespace TShockAPI.Handlers
{
if (!Main.tile[x, y].active() || Main.tile[x, y].type != TileType)
{
return false;
return MatchResult.NotMatched;
}
}
}
@ -322,18 +329,18 @@ namespace TShockAPI.Handlers
}
}
return true;
return MatchResult.BroadcastChanges;
}
private bool MatchRemoval(TSPlayer player, TileRect rect)
private MatchResult MatchRemoval(TSPlayer player, TileRect rect)
{
for (int x = rect.X; x < rect.Y + rect.Width; x++)
for (int x = rect.X; x < rect.X + rect.Width; x++)
{
for (int y = rect.Y; y < rect.Y + rect.Height; y++)
{
if (!Main.tile[x, y].active() || Main.tile[x, y].type != TileType)
{
return false;
return MatchResult.NotMatched;
}
}
}
@ -348,7 +355,7 @@ namespace TShockAPI.Handlers
}
}
return true;
return MatchResult.BroadcastChanges;
}
}
@ -364,7 +371,7 @@ namespace TShockAPI.Handlers
TileRectMatch.Placement(2, 3, TileID.TargetDummy, 54, 36, 18, 18),
TileRectMatch.Placement(3, 4, TileID.TeleportationPylon, 468, 54, 18, 18),
TileRectMatch.Placement(2, 3, TileID.DisplayDoll, 126, 36, 18, 18),
TileRectMatch.Placement(2, 3, TileID.HatRack, 90, 54, 18, 18),
TileRectMatch.Placement(3, 4, TileID.HatRack, 90, 54, 18, 18),
TileRectMatch.Placement(2, 2, TileID.ItemFrame, 162, 18, 18, 18),
TileRectMatch.Placement(3, 3, TileID.WeaponsRack2, 90, 36, 18, 18),
TileRectMatch.Placement(1, 1, TileID.FoodPlatter, 18, 0, 18, 18),
@ -436,7 +443,7 @@ namespace TShockAPI.Handlers
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect rejected from throttle from {args.Player.Name}"));
// send correcting data
args.Player.SendTileRect(args.TileX, args.TileY, args.Length, args.Width);
args.Player.SendTileRect(args.TileX, args.TileY, args.Width, args.Length);
return;
}
@ -446,7 +453,7 @@ namespace TShockAPI.Handlers
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect rejected from being disabled from {args.Player.Name}"));
// send correcting data
args.Player.SendTileRect(args.TileX, args.TileY, args.Length, args.Width);
args.Player.SendTileRect(args.TileX, args.TileY, args.Width, args.Length);
return;
}
@ -468,7 +475,7 @@ namespace TShockAPI.Handlers
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect reimplemented from {args.Player.Name}"));
// send correcting data
args.Player.SendTileRect(args.TileX, args.TileY, args.Length, args.Width);
args.Player.SendTileRect(args.TileX, args.TileY, args.Width, args.Length);
return;
}
@ -478,7 +485,7 @@ namespace TShockAPI.Handlers
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect rejected from out of range from {args.Player.Name}"));
// send correcting data
args.Player.SendTileRect(args.TileX, args.TileY, args.Length, args.Width);
args.Player.SendTileRect(args.TileX, args.TileY, args.Width, args.Length);
return;
}
@ -488,19 +495,23 @@ namespace TShockAPI.Handlers
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect reimplemented from {args.Player.Name}"));
// send correcting data
args.Player.SendTileRect(args.TileX, args.TileY, args.Length, args.Width);
args.Player.SendTileRect(args.TileX, args.TileY, args.Width, args.Length);
return;
}
// check if the rect matches any valid operation
foreach (TileRectMatch match in Matches)
{
if (match.Matches(args.Player, rect))
var result = match.Matches(args.Player, rect);
if (result != TileRectMatch.MatchResult.NotMatched)
{
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect reimplemented from {args.Player.Name}"));
// send correcting data
args.Player.SendTileRect(args.TileX, args.TileY, args.Length, args.Width);
if (result == TileRectMatch.MatchResult.RejectChanges)
args.Player.SendTileRect(args.TileX, args.TileY, args.Width, args.Length);
if (result == TileRectMatch.MatchResult.BroadcastChanges)
TSPlayer.All.SendTileRect(args.TileX, args.TileY, args.Width, args.Length);
return;
}
}
@ -511,14 +522,14 @@ namespace TShockAPI.Handlers
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect reimplemented from {args.Player.Name}"));
// send correcting data
args.Player.SendTileRect(args.TileX, args.TileY, args.Length, args.Width);
args.Player.SendTileRect(args.TileX, args.TileY, args.Width, args.Length);
return;
}
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect rejected from matches from {args.Player.Name}"));
// send correcting data
args.Player.SendTileRect(args.TileX, args.TileY, args.Length, args.Width);
args.Player.SendTileRect(args.TileX, args.TileY, args.Width, args.Length);
return;
}
@ -910,7 +921,7 @@ namespace TShockAPI.Handlers
}
}
/*
/*
* This is a copy of the `WorldGen.Convert` method with the following precise changes:
* - Added a `MockTile tile` parameter
* - Changed the `i` and `j` parameters to `k` and `l`
@ -921,7 +932,7 @@ namespace TShockAPI.Handlers
* - Removed the ifs checking the bounds of the tile and wall types
* - Removed branches that would call `WorldGen.KillTile`
* - Changed branches depending on randomness to instead set the property to both values after one another
*
*
* This overall leads to a method that can be called on a MockTile and real-world coordinates and will spit out the proper conversion changes into the MockTile.
*/