Merge branch 'general-devel' into fix-time

This commit is contained in:
Hussein Farran 2018-05-28 21:25:46 -04:00 committed by GitHub
commit 851cc7b34c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 2 deletions

View file

@ -85,6 +85,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin
* Removed `TSPlayer.InitSpawn` field. (@DankRank)
* `OnPlayerSpawn`'s player ID field is now `PlayerId`. (@DankRank)
* `Utils.TryParseTime` can now take spaces (e.g., `3d 5h 2m 3s`) (@QuiCM)
* Added filtering and validation on packet 96 (Teleport player through portal) (@QuiCM)
## TShock 4.3.25
* Fixed a critical exploit in the Terraria protocol that could cause massive unpreventable world corruption as well as a number of other problems. Thanks to @bartico6 for reporting. Fixed by the efforts of @QuiCM, @hakusaro, and tips in the right directioon from @bartico6.

View file

@ -64,6 +64,7 @@ namespace TShockAPI
GetDataHandlers.HealOtherPlayer += OnHealOtherPlayer;
GetDataHandlers.TileEdit += OnTileEdit;
GetDataHandlers.MassWireOperation += OnMassWireOperation;
GetDataHandlers.PortalTeleport += OnPlayerPortalTeleport;
}
internal void OnGetSection(object sender, GetDataHandlers.GetSectionEventArgs args)
@ -1721,6 +1722,34 @@ namespace TShockAPI
args.Handled = true;
}
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
//belongs to the player who sent the packet.
if (args.Player.Index != args.TargetPlayerIndex)
{
//If the player who sent the packet is not the player being teleported, cancel this packet
args.Player.Disable("Malicious portal attempt.", DisableFlags.WriteToLogAndConsole); //Todo: this message is not particularly clear - suggestions wanted
args.Handled = true;
return;
}
//Generic bounds checking, though I'm not sure if anyone would willingly hack themselves outside the map?
if (args.NewPosition.X > Main.maxTilesX || args.NewPosition.X < 0
|| args.NewPosition.Y > Main.maxTilesY || args.NewPosition.Y < 0)
{
args.Handled = true;
return;
}
//May as well reject teleport attempts if the player is being throttled
if (args.Player.IsBeingDisabled() || args.Player.IsBouncerThrottled())
{
args.Handled = true;
return;
}
}
/// <summary>
/// Tile IDs that can be oriented:
/// Cannon,
@ -1762,4 +1791,4 @@ namespace TShockAPI
};
}
}
}

View file

@ -1488,7 +1488,8 @@ namespace TShockAPI
{ PacketTypes.PlayerHealOther, HandleHealOther },
{ PacketTypes.CrystalInvasionStart, HandleOldOnesArmy },
{ PacketTypes.PlayerHurtV2, HandlePlayerDamageV2 },
{ PacketTypes.PlayerDeathV2, HandlePlayerKillMeV2 }
{ PacketTypes.PlayerDeathV2, HandlePlayerKillMeV2 },
{ PacketTypes.PlayerTeleportPortal, HandlePlayerPortalTeleport }
};
}
@ -1510,6 +1511,67 @@ namespace TShockAPI
return false;
}
/// <summary>The event args object for the PortalTeleport event</summary>
public class TeleportThroughPortalEventArgs : GetDataHandledEventArgs
{
/// <summary>The Terraria player index of the target player</summary>
public byte TargetPlayerIndex { get; set; }
/// <summary>
/// The position the target player will be at after going through the portal
/// </summary>
public Vector2 NewPosition { get; set; }
/// <summary>
/// The velocity the target player will have after going through the portal
/// </summary>
public Vector2 NewVelocity { get; set; }
/// <summary>
/// Index of the portal's color (for use with <see cref="Terraria.GameContent.PortalHelper.GetPortalColor(int)"/>)
/// </summary>
public int PortalColorIndex { get; set; }
}
/// <summary>When a player passes through a portal</summary>
public static HandlerList<TeleportThroughPortalEventArgs> PortalTeleport = new HandlerList<TeleportThroughPortalEventArgs>();
private static bool OnPlayerTeleportThroughPortal(TSPlayer sender, byte targetPlayerIndex, MemoryStream data, Vector2 position, Vector2 velocity, int colorIndex)
{
TeleportThroughPortalEventArgs args = new TeleportThroughPortalEventArgs
{
TargetPlayerIndex = targetPlayerIndex,
Data = data,
Player = sender,
NewPosition = position,
NewVelocity = velocity,
PortalColorIndex = colorIndex
};
PortalTeleport.Invoke(null, args);
return args.Handled;
}
private static bool HandlePlayerPortalTeleport(GetDataHandlerArgs args)
{
byte plr = args.Data.ReadInt8();
short portalColorIndex = args.Data.ReadInt16();
float newPositionX = args.Data.ReadSingle();
float newPositionY = args.Data.ReadSingle();
float newVelocityX = args.Data.ReadSingle();
float newVelocityY = args.Data.ReadSingle();
return OnPlayerTeleportThroughPortal(
args.Player,
plr,
args.Data,
new Vector2(newPositionX, newPositionY),
new Vector2(newVelocityX, newVelocityY),
portalColorIndex
);
}
private static bool HandleHealOther(GetDataHandlerArgs args)
{
byte plr = args.Data.ReadInt8();