From 09fe254f17e25d3f570dce1edc8cf4960d37012e Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Tue, 25 May 2021 18:34:33 -0700 Subject: [PATCH 1/2] Change TSPlayer.FindByNameOrID to keep searching Currently, the TSPlayer FindbyNameOrID method aborts if it finds an "exact match" based on this criteria: 1. If the player ID is on the server, it must be the thing we're looking for. Therefore, return that. 2. If the case sensitive "exact match" is on the server that isn't an ID, that must be what we're looking for. Therefore, return that. 3. Just yolo and downcase everything and return any number of matching players next. This commit changes the behavior because some players have been joining servers with ambiguous names, like `1`. In the current system, this player is difficult to query because they're an "ID" and therefore an exact match will be returned even if a player name exists that matches the criteria. This also alleviates the issue of a case exact match falling down the same trap. It's ambiguous enough in all of these situations that an admin should just be using a player ID instead.` --- CHANGELOG.md | 1 + TShockAPI/TSPlayer.cs | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 246db4f5..c9369eea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Fixed torchgod settings to include whether or not torchgod has been fought by the player before and respect `usingBiomeTorches` setting. (@Quinci135) * Fixed /worldmode not synchronising data to players after updating the world state (@bartico6, @Arthri) * Added `OnSendNetData` hook to TSAPI, which enables developers to intercept traffic being sent from the server to clients. (@Stealownz) +* Changed `TSPlayer.FindByNameOrID` so that it will continue searching for players and return a list of many players whem ambiguous matches exist in all cases. Specifically, this avoids a scenario where a griefer names themselves `1` and is difficult to enact justice on, because their name will not be found by the matching system used to kick players. (@hakusaro, @Onusai) ## TShock 4.5.3 * Added permissions for using Teleportation Potions, Magic Conch, and Demon Conch. (@drunderscore) diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 8b20dfd3..12fb2d69 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -92,7 +92,7 @@ namespace TShockAPI TSPlayer player = TShock.Players[plrID]; if (player != null && player.Active) { - return new List { player }; + found.Add(player); } } @@ -101,9 +101,6 @@ namespace TShockAPI { if (player != null) { - // Must be an EXACT match - if (player.Name == plr) - return new List { player }; if (player.Name.ToLower().StartsWith(plrLower)) found.Add(player); } From e73ce17130f0c0567c2bfe74ecbe2ddba6ae6725 Mon Sep 17 00:00:00 2001 From: Lucas Nicodemus Date: Tue, 25 May 2021 19:19:01 -0700 Subject: [PATCH 2/2] Add fallback for finding players using tsi & tsn This commit adds a fallback to address problems with FindByNameOrID potentially returning ambiguous results. Now, in response to a multiple match error, a player can specify tsi:[number] or tsn:[exact name] to match a user ID or name exactly. This behaves analogous to the old behavior of the search method. --- CHANGELOG.md | 2 +- TShockAPI/GetDataHandlers.cs | 8 ++++++++ TShockAPI/TSPlayer.cs | 38 +++++++++++++++++++++++++++--------- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9369eea..8f3e103c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Fixed torchgod settings to include whether or not torchgod has been fought by the player before and respect `usingBiomeTorches` setting. (@Quinci135) * Fixed /worldmode not synchronising data to players after updating the world state (@bartico6, @Arthri) * Added `OnSendNetData` hook to TSAPI, which enables developers to intercept traffic being sent from the server to clients. (@Stealownz) -* Changed `TSPlayer.FindByNameOrID` so that it will continue searching for players and return a list of many players whem ambiguous matches exist in all cases. Specifically, this avoids a scenario where a griefer names themselves `1` and is difficult to enact justice on, because their name will not be found by the matching system used to kick players. (@hakusaro, @Onusai) +* Changed `TSPlayer.FindByNameOrID` so that it will continue searching for players and return a list of many players whem ambiguous matches exist in all cases. Specifically, this avoids a scenario where a griefer names themselves `1` and is difficult to enact justice on, because their name will not be found by the matching system used to kick players. To help with ambiguity, this method now processes requests with prefixes `tsi:` and `tsn:`. `tsi:[number]` will process the search as looking for an exact player by ID. `tsn:` will process the search as looking for an exact name, case sensitive. In both cases, the system will return an exact result in the "old-style" result, i.e., a `List` with exactly one result. For example, `/kick tsid:1` will match the player with the ID `1`. `/kick tsn:1` will match the username `1`. In addition, players who attempt to join the server with the name prefixes `tsn:` and `tsi:` will be rejected for having invalid names. (@hakusaro, @Onusai) ## TShock 4.5.3 * Added permissions for using Teleportation Potions, Magic Conch, and Demon Conch. (@drunderscore) diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 1cab65dc..27173d4a 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -2282,6 +2282,14 @@ namespace TShockAPI args.Player.Kick("You have been Bounced.", true, true); return true; } + + if (name.Trim().StartsWith("tsi:") || name.Trim().StartsWith("tsn:")) + { + TShock.Log.ConsoleDebug("GetDataHandlers / rejecting player for name prefix starting with tsi: or tsn:."); + args.Player.Kick("Illegal name: prefixes tsi: and tsn: are forbidden.", true, true); + return true; + } + if (args.Player.ReceivedInfo) { // Since Terraria 1.2.3 these character properties can change ingame. diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 12fb2d69..aeaf17b3 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -75,33 +75,52 @@ namespace TShockAPI public static readonly TSPlayer All = new TSPlayer("All"); /// - /// Finds a TSPlayer based on name or ID + /// Finds a TSPlayer based on name or ID. + /// If the string comes with tsi: or tsn:, we'll only return a list with one element, + /// either the player with the matching ID or name, respectively. /// /// Player name or ID /// A list of matching players - public static List FindByNameOrID(string plr) + public static List FindByNameOrID(string search) { var found = new List(); + + search = search.Trim(); + + // tsi: and tsn: are used to disambiguate between usernames and not + // and are also both 3 characters to remove them from the search + // (the goal was to pick prefixes unlikely to be used by names) + // (and not to collide with other prefixes used by other commands) + var exactIndexOnly = search.StartsWith("tsi:"); + var exactNameOnly = search.StartsWith("tsn:"); + + if (exactNameOnly || exactIndexOnly) + search = search.Remove(0, 4); + // Avoid errors caused by null search - if (plr == null) + if (search == null || search == "") return found; - byte plrID; - if (byte.TryParse(plr, out plrID) && plrID < Main.maxPlayers) + byte searchID; + if (byte.TryParse(search, out searchID) && searchID < Main.maxPlayers) { - TSPlayer player = TShock.Players[plrID]; + TSPlayer player = TShock.Players[searchID]; if (player != null && player.Active) { + if (exactIndexOnly) + return new List { player }; found.Add(player); } } - string plrLower = plr.ToLower(); + string searchLower = search.ToLower(); foreach (TSPlayer player in TShock.Players) { if (player != null) { - if (player.Name.ToLower().StartsWith(plrLower)) + if ((search == player.Name) && exactNameOnly) + return new List { player }; + if (player.Name.ToLower().StartsWith(searchLower)) found.Add(player); } } @@ -1664,12 +1683,13 @@ namespace TShockAPI /// An enumerable list with the matches public void SendMultipleMatchError(IEnumerable matches) { - SendErrorMessage("More than one match found: "); + SendErrorMessage("More than one match found -- unable to decide which is correct: "); var lines = PaginationTools.BuildLinesFromTerms(matches.ToArray()); lines.ForEach(SendInfoMessage); SendErrorMessage("Use \"my query\" for items with spaces."); + SendErrorMessage("Use tsi:[number] or tsn:[username] to distinguish between user IDs and usernames."); } [Conditional("DEBUG")]