Merge branch 'general-devel' into general-devel
This commit is contained in:
commit
531ec1376c
4 changed files with 97 additions and 33 deletions
|
|
@ -504,6 +504,14 @@ namespace TShockAPI
|
||||||
return;
|
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)
|
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));
|
TShock.Log.ConsoleDebug(GetString("Bouncer / OnPlayerUpdate rejected from (position check) {0}", args.Player.Name));
|
||||||
|
|
@ -1072,6 +1080,22 @@ namespace TShockAPI
|
||||||
bool noDelay = args.NoDelay;
|
bool noDelay = args.NoDelay;
|
||||||
short type = args.Type;
|
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
|
// player is attempting to crash clients
|
||||||
if (type < -48 || type >= Terraria.ID.ItemID.Count)
|
if (type < -48 || type >= Terraria.ID.ItemID.Count)
|
||||||
{
|
{
|
||||||
|
|
@ -1175,6 +1199,22 @@ namespace TShockAPI
|
||||||
int index = args.Index;
|
int index = args.Index;
|
||||||
float[] ai = args.Ai;
|
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)
|
if (index > Main.maxProjectiles)
|
||||||
{
|
{
|
||||||
TShock.Log.ConsoleDebug(GetString("Bouncer / OnNewProjectile rejected from above projectile limit from {0}", args.Player.Name));
|
TShock.Log.ConsoleDebug(GetString("Bouncer / OnNewProjectile rejected from above projectile limit from {0}", args.Player.Name));
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ namespace TShockAPI
|
||||||
{ PacketTypes.TileSendSquare, HandleSendTileRect },
|
{ PacketTypes.TileSendSquare, HandleSendTileRect },
|
||||||
{ PacketTypes.ItemDrop, HandleItemDrop },
|
{ PacketTypes.ItemDrop, HandleItemDrop },
|
||||||
{ PacketTypes.ItemOwner, HandleItemOwner },
|
{ PacketTypes.ItemOwner, HandleItemOwner },
|
||||||
|
{ PacketTypes.NpcItemStrike, HandleNpcItemStrike },
|
||||||
{ PacketTypes.ProjectileNew, HandleProjectileNew },
|
{ PacketTypes.ProjectileNew, HandleProjectileNew },
|
||||||
{ PacketTypes.NpcStrike, HandleNpcStrike },
|
{ PacketTypes.NpcStrike, HandleNpcStrike },
|
||||||
{ PacketTypes.ProjectileDestroy, HandleProjectileKill },
|
{ PacketTypes.ProjectileDestroy, HandleProjectileKill },
|
||||||
|
|
@ -2964,6 +2965,13 @@ namespace TShockAPI
|
||||||
return false;
|
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)
|
private static bool HandleProjectileNew(GetDataHandlerArgs args)
|
||||||
{
|
{
|
||||||
short ident = args.Data.ReadInt16();
|
short ident = args.Data.ReadInt16();
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,13 @@ namespace TShockAPI.Handlers
|
||||||
Removal,
|
Removal,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum MatchResult
|
||||||
|
{
|
||||||
|
NotMatched,
|
||||||
|
RejectChanges,
|
||||||
|
BroadcastChanges,
|
||||||
|
}
|
||||||
|
|
||||||
private readonly int Width;
|
private readonly int Width;
|
||||||
private readonly int Height;
|
private readonly int Height;
|
||||||
|
|
||||||
|
|
@ -179,11 +186,11 @@ namespace TShockAPI.Handlers
|
||||||
/// <param name="player">The player the operation originates from.</param>
|
/// <param name="player">The player the operation originates from.</param>
|
||||||
/// <param name="rect">The tile rectangle of the operation.</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>
|
/// <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)
|
if (rect.Width != Width || rect.Height != Height)
|
||||||
{
|
{
|
||||||
return false;
|
return MatchResult.NotMatched;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int x = 0; x < rect.Width; x++)
|
for (int x = 0; x < rect.Width; x++)
|
||||||
|
|
@ -195,7 +202,7 @@ namespace TShockAPI.Handlers
|
||||||
{
|
{
|
||||||
if (tile.Type != TileType)
|
if (tile.Type != TileType)
|
||||||
{
|
{
|
||||||
return false;
|
return MatchResult.NotMatched;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Type is MatchType.Placement or MatchType.StateChange)
|
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)
|
if (tile.FrameX < 0 || tile.FrameX > MaxFrameX || tile.FrameX % FrameXStep != 0)
|
||||||
{
|
{
|
||||||
return false;
|
return MatchResult.NotMatched;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (MaxFrameY != IGNORE_FRAME)
|
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)
|
// 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))
|
if (!(TileType == TileID.LunarMonolith && tile.FrameY % FrameYStep == 2))
|
||||||
{
|
{
|
||||||
return false;
|
return MatchResult.NotMatched;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -223,7 +230,7 @@ namespace TShockAPI.Handlers
|
||||||
{
|
{
|
||||||
if (tile.Active)
|
if (tile.Active)
|
||||||
{
|
{
|
||||||
return false;
|
return MatchResult.NotMatched;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -236,7 +243,7 @@ namespace TShockAPI.Handlers
|
||||||
if (!player.HasBuildPermission(x, y))
|
if (!player.HasBuildPermission(x, y))
|
||||||
{
|
{
|
||||||
// for simplicity, let's pretend that the edit was valid, but do not execute it
|
// 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++)
|
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
|
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))
|
if (TShock.TileBans.TileIsBanned((short)TileType, player))
|
||||||
{
|
{
|
||||||
// for simplicity, let's pretend that the edit was valid, but do not execute it
|
// 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++)
|
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++)
|
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)
|
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++)
|
for (int y = rect.Y; y < rect.Y + rect.Height; y++)
|
||||||
{
|
{
|
||||||
if (!Main.tile[x, y].active() || Main.tile[x, y].type != TileType)
|
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(2, 3, TileID.TargetDummy, 54, 36, 18, 18),
|
||||||
TileRectMatch.Placement(3, 4, TileID.TeleportationPylon, 468, 54, 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.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(2, 2, TileID.ItemFrame, 162, 18, 18, 18),
|
||||||
TileRectMatch.Placement(3, 3, TileID.WeaponsRack2, 90, 36, 18, 18),
|
TileRectMatch.Placement(3, 3, TileID.WeaponsRack2, 90, 36, 18, 18),
|
||||||
TileRectMatch.Placement(1, 1, TileID.FoodPlatter, 18, 0, 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}"));
|
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect rejected from throttle from {args.Player.Name}"));
|
||||||
|
|
||||||
// send correcting data
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -446,7 +453,7 @@ namespace TShockAPI.Handlers
|
||||||
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect rejected from being disabled from {args.Player.Name}"));
|
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect rejected from being disabled from {args.Player.Name}"));
|
||||||
|
|
||||||
// send correcting data
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -468,7 +475,7 @@ namespace TShockAPI.Handlers
|
||||||
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect reimplemented from {args.Player.Name}"));
|
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect reimplemented from {args.Player.Name}"));
|
||||||
|
|
||||||
// send correcting data
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -478,7 +485,7 @@ namespace TShockAPI.Handlers
|
||||||
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect rejected from out of range from {args.Player.Name}"));
|
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect rejected from out of range from {args.Player.Name}"));
|
||||||
|
|
||||||
// send correcting data
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -488,19 +495,23 @@ namespace TShockAPI.Handlers
|
||||||
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect reimplemented from {args.Player.Name}"));
|
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect reimplemented from {args.Player.Name}"));
|
||||||
|
|
||||||
// send correcting data
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the rect matches any valid operation
|
// check if the rect matches any valid operation
|
||||||
foreach (TileRectMatch match in Matches)
|
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}"));
|
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect reimplemented from {args.Player.Name}"));
|
||||||
|
|
||||||
// send correcting data
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -511,14 +522,14 @@ namespace TShockAPI.Handlers
|
||||||
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect reimplemented from {args.Player.Name}"));
|
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect reimplemented from {args.Player.Name}"));
|
||||||
|
|
||||||
// send correcting data
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect rejected from matches from {args.Player.Name}"));
|
TShock.Log.ConsoleDebug(GetString($"Bouncer / SendTileRect rejected from matches from {args.Player.Name}"));
|
||||||
|
|
||||||
// send correcting data
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -94,10 +94,15 @@ Use past tense when adding new entries; sign your name off when you add or chang
|
||||||
* Added a hook `AccountHooks.AccountGroupUpdate`, which is called when you change the user group. (@AgaSpace)
|
* Added a hook `AccountHooks.AccountGroupUpdate`, which is called when you change the user group. (@AgaSpace)
|
||||||
* * Ensured `TSPlayer.PlayerData` is non-null whilst syncing loadouts. (@drunderscore)
|
* * Ensured `TSPlayer.PlayerData` is non-null whilst syncing loadouts. (@drunderscore)
|
||||||
* * Detected invalid installations, by checking for a file named `TerrariaServer.exe`. (@drunderscore)
|
* * Detected invalid installations, by checking for a file named `TerrariaServer.exe`. (@drunderscore)
|
||||||
* This made the two most common installation mistakes (extracting into the Terraria client directory, and extracting TShock 5 or newer into a TShock 4 or older install) prompt the user with a more useful diagnostic, rather than (likely) crashing moments later.
|
* This made the two most common installation mistakes (extracting into the Terraria client directory, and extracting TShock 5 or newer into a TShock 4 or older install) prompt the user with a more useful diagnostic, rather than (likely) crashing moments later. Rewrote bed spawning for SSC. (@PotatoCider)
|
||||||
* Rewrote bed spawning for SSC. (@PotatoCider)
|
|
||||||
* Removed `TSPlayer.s{X,Y}` in favour of using desyncing client and server spawnpoint values (`Terraria.Player.Spawn{X,Y}`) until the player has changed their spawnpoint per session.
|
* Removed `TSPlayer.s{X,Y}` in favour of using desyncing client and server spawnpoint values (`Terraria.Player.Spawn{X,Y}`) until the player has changed their spawnpoint per session.
|
||||||
* Partially fixed the bed spawning bug when SSC is enabled. Players would need to spawn at their beds at least once to tell TShock that the player's spawnpoint has changed.
|
* Partially fixed the bed spawning bug when SSC is enabled. Players would need to spawn at their beds at least once to tell TShock that the player's spawnpoint has changed.
|
||||||
|
* Changed Bouncer to block updates which set the following fields to infinity or NaN: player position, projectile position, projectile velocity, item position, and item velocity. (@Arthri)
|
||||||
|
* Updated `TShockAPI.Handlers.SendTileRectHandler` (@LaoSparrow):
|
||||||
|
* Fixed incorrect validating range in `TileRectMatch.MatchRemoval`.
|
||||||
|
* Fixed tile rect changes (e.g. turning on and off campfires) are not synced between clients.
|
||||||
|
* Fixed unable to place Hat Rack without permission `tshock.ignore.sendtilesquare`.
|
||||||
|
* Updated `GetDataHandlers` to ignore `NpcItemStrike(msgid 24)`, which should never be sent by a vanilla client. (@LaoSparrow)
|
||||||
|
|
||||||
## TShock 5.2.1
|
## TShock 5.2.1
|
||||||
* Updated `TSPlayer.GodMode`. (@AgaSpace)
|
* Updated `TSPlayer.GodMode`. (@AgaSpace)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue