From f99b7ec359e1da3fe904ff4c657fd561cd33d495 Mon Sep 17 00:00:00 2001 From: Chris <2648373+QuiCM@users.noreply.github.com> Date: Tue, 22 May 2018 10:10:22 +0930 Subject: [PATCH 1/8] Allow time parser to take spaces So you can pass in `10h 5m 2s` instead of `10h+5m+2s`. Works for things like `10h +5m -2s` as well --- TShockAPI/Utils.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TShockAPI/Utils.cs b/TShockAPI/Utils.cs index 1c4d681f..1ac60283 100644 --- a/TShockAPI/Utils.cs +++ b/TShockAPI/Utils.cs @@ -534,7 +534,7 @@ namespace TShockAPI var sb = new StringBuilder(3); for (int i = 0; i < str.Length; i++) { - if (Char.IsDigit(str[i]) || (str[i] == '-' || str[i] == '+')) + if (Char.IsDigit(str[i]) || (str[i] == '-' || str[i] == '+' || str[i] == ' ')) sb.Append(str[i]); else { From 1d306994fef3d84ca14e848d5e643c3737dae60d Mon Sep 17 00:00:00 2001 From: Chris <2648373+QuiCM@users.noreply.github.com> Date: Tue, 22 May 2018 10:24:14 +0930 Subject: [PATCH 2/8] Minor adjustments to the ban add subcommand Should fix #1609 --- TShockAPI/Commands.cs | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index bf814190..840ee72e 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -1309,16 +1309,20 @@ namespace TShockAPI // Effective ban target assignment List players = TSPlayer.FindByNameOrID(args.Parameters[1]); + + // Bad case: Players contains more than 1 person so we can't ban them + if (players.Count > 1) + { + //Fail fast + args.Player.SendMultipleMatchError(players.Select(p => p.Name)); + return; + } + UserAccount offlineUserAccount = TShock.UserAccounts.GetUserAccountByName(args.Parameters[1]); // Storage variable to determine if the command executor is the server console // If it is, we assume they have full control and let them override permission checks - bool callerIsServerConsole = false; - - if (args.Player is TSServerPlayer) - { - callerIsServerConsole = true; - } + bool callerIsServerConsole = args.Player is TSServerPlayer; // The ban reason the ban is going to have string banReason = "Unknown."; @@ -1331,16 +1335,18 @@ namespace TShockAPI if (args.Parameters.Count >= 3) { bool parsedOkay = false; - if (!(args.Parameters[2] == "0")) + if (args.Parameters[2] != "0") { parsedOkay = TShock.Utils.TryParseTime(args.Parameters[2], out banLengthInSeconds); - } else { + } + else + { parsedOkay = true; } if (!parsedOkay) { - args.Player.SendErrorMessage("Invalid time format. Example: 10d+5h+3m-2s."); + args.Player.SendErrorMessage("Invalid time format. Example: 10d 5h 3m 2s."); args.Player.SendErrorMessage("Use 0 (zero) for a permanent ban."); return; } @@ -1352,13 +1358,6 @@ namespace TShockAPI banReason = String.Join(" ", args.Parameters.Skip(3)); } - // Bad case: Players contains more than 1 person so we can't ban them - if (players.Count > 1) - { - args.Player.SendMultipleMatchError(players.Select(p => p.Name)); - return; - } - // Good case: Online ban for matching character. if (players.Count == 1) { @@ -1371,7 +1370,7 @@ namespace TShockAPI } targetGeneralizedName = target.Name; - success = TShock.Bans.AddBan(target.IP, target.Name, target.UUID, target.Account.Name, banReason, false, args.Player.Account.Name, + success = TShock.Bans.AddBan(target.IP, target.Name, target.UUID, target.Account?.Name ?? "", banReason, false, args.Player.Account.Name, banLengthInSeconds == 0 ? "" : DateTime.UtcNow.AddSeconds(banLengthInSeconds).ToString("s")); // Since this is an online ban, we need to dc the player and tell them now. @@ -1399,7 +1398,8 @@ namespace TShockAPI // If the target is a valid IP... string pattern = @"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"; Regex r = new Regex(pattern, RegexOptions.IgnoreCase); - if (r.IsMatch(args.Parameters[1])) { + if (r.IsMatch(args.Parameters[1])) + { targetGeneralizedName = "IP: " + args.Parameters[1]; success = TShock.Bans.AddBan(args.Parameters[1], "", "", "", banReason, false, args.Player.Account.Name, banLengthInSeconds == 0 ? "" : DateTime.UtcNow.AddSeconds(banLengthInSeconds).ToString("s")); @@ -1409,7 +1409,9 @@ namespace TShockAPI args.Player.SendErrorMessage("Note: An account named with this IP address also exists."); args.Player.SendErrorMessage("Note: It will also be banned."); } - } else { + } + else + { // Apparently there is no way to not IP ban someone // This means that where we would normally just ban a "character name" here // We can't because it requires some IP as a primary key. From ae5d508989ec23921bd4f0777ff19bf6974799b0 Mon Sep 17 00:00:00 2001 From: Chris <2648373+QuiCM@users.noreply.github.com> Date: Tue, 22 May 2018 18:54:28 +0930 Subject: [PATCH 3/8] Add filtering for packet 96. Fixes #1605 --- TShockAPI/Bouncer.cs | 31 ++++++++++++++++- TShockAPI/GetDataHandlers.cs | 64 +++++++++++++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs index f1ce0005..223de05b 100644 --- a/TShockAPI/Bouncer.cs +++ b/TShockAPI/Bouncer.cs @@ -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; + } + } + /// /// Tile IDs that can be oriented: /// Cannon, @@ -1762,4 +1791,4 @@ namespace TShockAPI }; } -} \ No newline at end of file +} diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index d8c47b3b..e42f688c 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -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; } + /// The event args object for the HealOtherPlayer event + public class TeleportThroughPortalEventArgs : GetDataHandledEventArgs + { + /// The Terraria player index of the target player + public byte TargetPlayerIndex { get; set; } + + /// + /// The position the target player will be at after going through the portal + /// + public Vector2 NewPosition { get; set; } + + /// + /// The velocity the target player will have after going through the portal + /// + public Vector2 NewVelocity { get; set; } + + /// + /// Index of the portal's color (for use with ) + /// + public int PortalColorIndex { get; set; } + } + + /// When a player passes through a portal + public static HandlerList PortalTeleport = new HandlerList(); + + 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(); From 9222d8112a7699b54bec672724906a67d8dd0831 Mon Sep 17 00:00:00 2001 From: Chris <2648373+QuiCM@users.noreply.github.com> Date: Tue, 22 May 2018 18:55:59 +0930 Subject: [PATCH 4/8] Copy pasting is hard --- TShockAPI/GetDataHandlers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index e42f688c..c59ce1a7 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -1511,7 +1511,7 @@ namespace TShockAPI return false; } - /// The event args object for the HealOtherPlayer event + /// The event args object for the PortalTeleport event public class TeleportThroughPortalEventArgs : GetDataHandledEventArgs { /// The Terraria player index of the target player From eabb0a34bb0ab5c985bdc7a451e0e01e390f60a0 Mon Sep 17 00:00:00 2001 From: Chris <2648373+QuiCM@users.noreply.github.com> Date: Tue, 22 May 2018 18:58:13 +0930 Subject: [PATCH 5/8] Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3ad3bfa..2e18f284 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -84,6 +84,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Fixed erroneous kicks and bans when using `KickOnMediumcoreDeath` and `BanOnMediumcoreDeath` options. (@DankRank) * Removed `TSPlayer.InitSpawn` field. (@DankRank) * `OnPlayerSpawn`'s player ID field is now `PlayerId`. (@DankRank) +* 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. From dcb6f23771ba36579e9d1721fb6f4ecf04f7e8c0 Mon Sep 17 00:00:00 2001 From: Chris <2648373+QuiCM@users.noreply.github.com> Date: Wed, 23 May 2018 11:53:05 +0930 Subject: [PATCH 6/8] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3ad3bfa..cf397188 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -84,6 +84,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Fixed erroneous kicks and bans when using `KickOnMediumcoreDeath` and `BanOnMediumcoreDeath` options. (@DankRank) * Removed `TSPlayer.InitSpawn` field. (@DankRank) * `OnPlayerSpawn`'s player ID field is now `PlayerId`. (@DankRank) +* Enabled banning unregistered users (@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. From dd00d74effdebe958412f4b24d0d996701183172 Mon Sep 17 00:00:00 2001 From: Chris <2648373+QuiCM@users.noreply.github.com> Date: Wed, 23 May 2018 11:54:25 +0930 Subject: [PATCH 7/8] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3ad3bfa..d954e7b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -84,6 +84,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Fixed erroneous kicks and bans when using `KickOnMediumcoreDeath` and `BanOnMediumcoreDeath` options. (@DankRank) * 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) ## 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. From 28e35fda648405c00167f77c790b0f32c6ee0292 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Wed, 6 Jun 2018 12:57:59 -0600 Subject: [PATCH 8/8] Unix build steps cover where to put nuget --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ffadf1a..8261fadc 100644 --- a/README.md +++ b/README.md @@ -155,9 +155,10 @@ You need to re-run the patcher any time `OTAPI` updates. You need to rebuild `Te 1. You need to get NuGet. Download the latest `nuget.exe` from [NuGet](https://www.nuget.org/downloads). -1. Make a `~/bin` folder if you don't have one. +1. Make a `~/bin` folder if you don't have one. Then, put `nuget.exe` inside it. $ mkdir ~/bin/ + $ cp ~/downloads/nuget.exe ~/bin/ 1. Set an environment variable to store if you plan to build in debug or release.