Merge pull request from GHSA-q776-cv3j-4q6m
Patch SendTileRectangle mass-griefing exploit
This commit is contained in:
commit
914cdb1046
3 changed files with 91 additions and 57 deletions
|
|
@ -1,12 +1,15 @@
|
|||
using OTAPI.Tile;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Terraria;
|
||||
using Terraria.DataStructures;
|
||||
using Terraria.GameContent.Tile_Entities;
|
||||
using Terraria.ID;
|
||||
using Terraria.ObjectData;
|
||||
|
||||
using TShockAPI.Net;
|
||||
|
||||
namespace TShockAPI.Handlers
|
||||
|
|
@ -198,7 +201,7 @@ namespace TShockAPI.Handlers
|
|||
TShock.Log.ConsoleDebug("Bouncer / SendTileRect rejected from no permission for tile object from {0}", args.Player.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (TShock.TileBans.TileIsBanned((short)tileType))
|
||||
{
|
||||
TShock.Log.ConsoleDebug("Bouncer / SendTileRect rejected for banned tile");
|
||||
|
|
@ -238,12 +241,12 @@ namespace TShockAPI.Handlers
|
|||
|
||||
if (tile.type == TileID.LandMine && !newTile.Active)
|
||||
{
|
||||
UpdateServerTileState(tile, newTile);
|
||||
UpdateServerTileState(tile, newTile, TileDataType.Tile);
|
||||
}
|
||||
|
||||
if (tile.type == TileID.WirePipe)
|
||||
{
|
||||
UpdateServerTileState(tile, newTile);
|
||||
UpdateServerTileState(tile, newTile, TileDataType.Tile);
|
||||
}
|
||||
|
||||
ProcessConversionSpreads(Main.tile[realX, realY], newTile);
|
||||
|
|
@ -274,7 +277,7 @@ namespace TShockAPI.Handlers
|
|||
return;
|
||||
}
|
||||
|
||||
UpdateServerTileState(Main.tile[realX, realY], newTile);
|
||||
UpdateServerTileState(Main.tile[realX, realY], newTile, TileDataType.Tile);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -295,8 +298,14 @@ namespace TShockAPI.Handlers
|
|||
TileID.Sets.Conversion.HardenedSand[tile.type] && TileID.Sets.Conversion.HardenedSand[newTile.Type] ||
|
||||
TileID.Sets.Conversion.Thorn[tile.type] && TileID.Sets.Conversion.Thorn[newTile.Type] ||
|
||||
TileID.Sets.Conversion.Moss[tile.type] && TileID.Sets.Conversion.Moss[newTile.Type] ||
|
||||
TileID.Sets.Conversion.MossBrick[tile.type] && TileID.Sets.Conversion.MossBrick[newTile.Type] ||
|
||||
WallID.Sets.Conversion.Stone[tile.wall] && WallID.Sets.Conversion.Stone[newTile.Wall] ||
|
||||
TileID.Sets.Conversion.MossBrick[tile.type] && TileID.Sets.Conversion.MossBrick[newTile.Type]
|
||||
)
|
||||
{
|
||||
TShock.Log.ConsoleDebug("Bouncer / SendTileRect processing a tile conversion update - [{0}] -> [{1}]", tile.type, newTile.Type);
|
||||
UpdateServerTileState(tile, newTile, TileDataType.Tile);
|
||||
}
|
||||
|
||||
if (WallID.Sets.Conversion.Stone[tile.wall] && WallID.Sets.Conversion.Stone[newTile.Wall] ||
|
||||
WallID.Sets.Conversion.Grass[tile.wall] && WallID.Sets.Conversion.Grass[newTile.Wall] ||
|
||||
WallID.Sets.Conversion.Sandstone[tile.wall] && WallID.Sets.Conversion.Sandstone[newTile.Wall] ||
|
||||
WallID.Sets.Conversion.HardenedSand[tile.wall] && WallID.Sets.Conversion.HardenedSand[newTile.Wall] ||
|
||||
|
|
@ -307,76 +316,84 @@ namespace TShockAPI.Handlers
|
|||
WallID.Sets.Conversion.NewWall4[tile.wall] && WallID.Sets.Conversion.NewWall4[newTile.Wall]
|
||||
)
|
||||
{
|
||||
TShock.Log.ConsoleDebug("Bouncer / SendTileRect processing a conversion update - [{0}|{1}] -> [{2}|{3}]", tile.type, tile.wall, newTile.Type, newTile.Wall);
|
||||
UpdateServerTileState(tile, newTile);
|
||||
TShock.Log.ConsoleDebug("Bouncer / SendTileRect processing a wall conversion update - [{0}] -> [{1}]", tile.wall, newTile.Wall);
|
||||
UpdateServerTileState(tile, newTile, TileDataType.Wall);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates a single tile's world state with a change from the tile rect packet
|
||||
/// Updates a single tile's world state with a set of changes from the networked tile state
|
||||
/// </summary>
|
||||
/// <param name="tile">The tile to update</param>
|
||||
/// <param name="newTile">The NetTile containing the change</param>
|
||||
public static void UpdateServerTileState(ITile tile, NetTile newTile)
|
||||
/// <param name="updateType">The type of data to merge into world state</param>
|
||||
public static void UpdateServerTileState(ITile tile, NetTile newTile, TileDataType updateType)
|
||||
{
|
||||
tile.active(newTile.Active);
|
||||
tile.type = newTile.Type;
|
||||
//This logic (updateType & TDT.Tile) != 0 is the way Terraria does it (see: Tile.cs/Clear(TileDataType))
|
||||
//& is not a typo - we're performing a binary AND test to see if a given flag is set.
|
||||
|
||||
if (newTile.FrameImportant)
|
||||
if ((updateType & TileDataType.Tile) != 0)
|
||||
{
|
||||
tile.frameX = newTile.FrameX;
|
||||
tile.frameY = newTile.FrameY;
|
||||
tile.active(newTile.Active);
|
||||
tile.type = newTile.Type;
|
||||
|
||||
if (newTile.FrameImportant)
|
||||
{
|
||||
tile.frameX = newTile.FrameX;
|
||||
tile.frameY = newTile.FrameY;
|
||||
}
|
||||
else if (tile.type != newTile.Type || !tile.active())
|
||||
{
|
||||
//This is vanilla logic - if the tile changed types (or wasn't active) the frame values might not be valid - so we reset them to -1.
|
||||
tile.frameX = -1;
|
||||
tile.frameY = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (newTile.HasWall)
|
||||
if ((updateType & TileDataType.Wall) != 0)
|
||||
{
|
||||
tile.wall = newTile.Wall;
|
||||
}
|
||||
|
||||
if (newTile.HasLiquid)
|
||||
if ((updateType & TileDataType.TilePaint) != 0)
|
||||
{
|
||||
tile.color(newTile.TileColor);
|
||||
}
|
||||
|
||||
if ((updateType & TileDataType.WallPaint) != 0)
|
||||
{
|
||||
tile.wallColor(newTile.WallColor);
|
||||
}
|
||||
|
||||
if ((updateType & TileDataType.Liquid) != 0)
|
||||
{
|
||||
tile.liquid = newTile.Liquid;
|
||||
tile.liquidType(newTile.LiquidType);
|
||||
}
|
||||
|
||||
tile.wire(newTile.Wire);
|
||||
tile.wire2(newTile.Wire2);
|
||||
tile.wire3(newTile.Wire3);
|
||||
tile.wire4(newTile.Wire4);
|
||||
|
||||
tile.halfBrick(newTile.IsHalf);
|
||||
|
||||
if (newTile.HasColor)
|
||||
if ((updateType & TileDataType.Slope) != 0)
|
||||
{
|
||||
tile.color(newTile.TileColor);
|
||||
tile.halfBrick(newTile.IsHalf);
|
||||
tile.slope(newTile.Slope);
|
||||
}
|
||||
|
||||
if (newTile.HasWallColor)
|
||||
if ((updateType & TileDataType.Wiring) != 0)
|
||||
{
|
||||
tile.wallColor(newTile.WallColor);
|
||||
tile.wire(newTile.Wire);
|
||||
tile.wire2(newTile.Wire2);
|
||||
tile.wire3(newTile.Wire3);
|
||||
tile.wire4(newTile.Wire4);
|
||||
}
|
||||
|
||||
byte slope = 0;
|
||||
if (newTile.Slope)
|
||||
if ((updateType & TileDataType.Actuator) != 0)
|
||||
{
|
||||
slope += 1;
|
||||
tile.actuator(newTile.IsActuator);
|
||||
tile.inActive(newTile.Inactive);
|
||||
}
|
||||
if (newTile.Slope2)
|
||||
{
|
||||
slope += 2;
|
||||
}
|
||||
if (newTile.Slope3)
|
||||
{
|
||||
slope += 4;
|
||||
}
|
||||
|
||||
tile.slope(slope);
|
||||
|
||||
TShock.Log.ConsoleDebug("Bouncer / SendTileRect updated a tile from type {0} to {1}", tile.type, newTile.Type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs <see cref="UpdateServerTileState(ITile, NetTile)"/> on multiple tiles
|
||||
/// Performs <see cref="UpdateServerTileState(ITile, NetTile, TileDataType)"/> on multiple tiles
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
|
|
@ -389,7 +406,7 @@ namespace TShockAPI.Handlers
|
|||
{
|
||||
for (int j = 0; j < height; j++)
|
||||
{
|
||||
UpdateServerTileState(Main.tile[x + i, y + j], newTiles[i, j]);
|
||||
UpdateServerTileState(Main.tile[x + i, y + j], newTiles[i, j], TileDataType.Tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -550,10 +567,10 @@ namespace TShockAPI.Handlers
|
|||
{
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
UpdateServerTileState(Main.tile[tileX + x, tileY + y], newTiles[x, y]);
|
||||
UpdateServerTileState(Main.tile[tileX + x, tileY + y], newTiles[x, y], TileDataType.All);
|
||||
}
|
||||
//Add a line of dirt blocks at the bottom for safety
|
||||
UpdateServerTileState(Main.tile[tileX + x, tileY + height], new NetTile { Active = true, Type = 0 });
|
||||
UpdateServerTileState(Main.tile[tileX + x, tileY + height], new NetTile { Active = true, Type = 0 }, TileDataType.All);
|
||||
}
|
||||
|
||||
player.SendTileRect(tileX, tileY, width, height);
|
||||
|
|
|
|||
|
|
@ -37,17 +37,34 @@ namespace TShockAPI.Net
|
|||
public bool Wire2 { get; set; }
|
||||
public bool Wire3 { get; set; }
|
||||
public bool Wire4 { get; set; }
|
||||
public byte HalfBrick { get; set; }
|
||||
public byte Actuator { get; set; }
|
||||
public bool Inactive { get; set; }
|
||||
public bool IsHalf { get; set; }
|
||||
public bool IsActuator { get; set; }
|
||||
public byte TileColor { get; set; }
|
||||
public byte WallColor { get; set; }
|
||||
public bool Slope { get; set; }
|
||||
public bool Slope1 { get; set; }
|
||||
public bool Slope2 { get; set; }
|
||||
public bool Slope3 { get; set; }
|
||||
|
||||
public byte Slope
|
||||
{
|
||||
get
|
||||
{
|
||||
byte sl = 0;
|
||||
|
||||
if (Slope1)
|
||||
sl += 1;
|
||||
|
||||
if (Slope2)
|
||||
sl += 2;
|
||||
|
||||
if (Slope3)
|
||||
sl += 4;
|
||||
|
||||
return sl;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasColor
|
||||
{
|
||||
get { return TileColor > 0; }
|
||||
|
|
@ -85,14 +102,13 @@ namespace TShockAPI.Net
|
|||
Wire2 = false;
|
||||
Wire3 = false;
|
||||
Wire4 = false;
|
||||
HalfBrick = 0;
|
||||
Actuator = 0;
|
||||
Inactive = false;
|
||||
TileColor = 0;
|
||||
WallColor = 0;
|
||||
Lighted = false;
|
||||
Slope = false;
|
||||
Slope1 = false;
|
||||
Slope2 = false;
|
||||
Slope3 = false;
|
||||
}
|
||||
|
||||
public NetTile(Stream stream)
|
||||
|
|
@ -124,9 +140,7 @@ namespace TShockAPI.Net
|
|||
bits[6] = true;
|
||||
|
||||
if (Inactive)
|
||||
{
|
||||
bits[7] = true;
|
||||
}
|
||||
|
||||
stream.WriteInt8((byte) bits);
|
||||
|
||||
|
|
@ -144,7 +158,7 @@ namespace TShockAPI.Net
|
|||
if (HasWallColor)
|
||||
bits[3] = true;
|
||||
|
||||
if (Slope)
|
||||
if (Slope1)
|
||||
bits[4] = true;
|
||||
|
||||
if (Slope2)
|
||||
|
|
@ -195,7 +209,7 @@ namespace TShockAPI.Net
|
|||
|
||||
Wire2 = flags2[0];
|
||||
Wire3 = flags2[1];
|
||||
Slope = flags2[4];
|
||||
Slope1 = flags2[4];
|
||||
Slope2 = flags2[5];
|
||||
Slope3 = flags2[6];
|
||||
Wire4 = flags2[7];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue