From 4e1eb78163f9008f0812b8da3a0478c9a61dbfd7 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sat, 26 Jul 2025 19:30:38 +0200 Subject: [PATCH] MultiServer: Fix LocationScouts with "only_new" broadcasting hints for found locations over and over (#4482) * Hints PR number 42069 * Make it explicit * clarify * oops * Port the change to CreateHints --- MultiServer.py | 11 ++++++----- docs/network protocol.md | 3 ++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/MultiServer.py b/MultiServer.py index 108795d8..1f421aaa 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -752,7 +752,7 @@ class Context: return self.player_names[team, slot] def notify_hints(self, team: int, hints: typing.List[Hint], only_new: bool = False, - recipients: typing.Sequence[int] = None): + persist_even_if_found: bool = False, recipients: typing.Sequence[int] = None): """Send and remember hints.""" if only_new: hints = [hint for hint in hints if hint not in self.hints[team, hint.finding_player]] @@ -767,8 +767,9 @@ class Context: if not hint.local and data not in concerns[hint.finding_player]: concerns[hint.finding_player].append(data) - # only remember hints that were not already found at the time of creation - if not hint.found: + # For !hint use cases, only hints that were not already found at the time of creation should be remembered + # For LocationScouts use-cases, all hints should be remembered + if not hint.found or persist_even_if_found: # since hints are bidirectional, finding player and receiving player, # we can check once if hint already exists if hint not in self.hints[team, hint.finding_player]: @@ -1946,7 +1947,7 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): hints.extend(collect_hint_location_id(ctx, client.team, client.slot, location, HintStatus.HINT_UNSPECIFIED)) locs.append(NetworkItem(target_item, location, target_player, flags)) - ctx.notify_hints(client.team, hints, only_new=create_as_hint == 2) + ctx.notify_hints(client.team, hints, only_new=create_as_hint == 2, persist_even_if_found=True) if locs and create_as_hint: ctx.save() await ctx.send_msgs(client, [{'cmd': 'LocationInfo', 'locations': locs}]) @@ -1990,7 +1991,7 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): hints += collect_hint_location_id(ctx, client.team, location_player, location, status) # As of writing this code, only_new=True does not update status for existing hints - ctx.notify_hints(client.team, hints, only_new=True) + ctx.notify_hints(client.team, hints, only_new=True, persist_even_if_found=True) ctx.save() elif cmd == 'UpdateHint': diff --git a/docs/network protocol.md b/docs/network protocol.md index 4b66b7b1..b40cf31b 100644 --- a/docs/network protocol.md +++ b/docs/network protocol.md @@ -340,7 +340,8 @@ Sent to the server to retrieve the items that are on a specified list of locatio Fully remote clients without a patch file may use this to "place" items onto their in-game locations, most commonly to display their names or item classifications before/upon pickup. LocationScouts can also be used to inform the server of locations the client has seen, but not checked. This creates a hint as if the player had run `!hint_location` on a location, but without deducting hint points. -This is useful in cases where an item appears in the game world, such as 'ledge items' in _A Link to the Past_. To do this, set the `create_as_hint` parameter to a non-zero value. +This is useful in cases where an item appears in the game world, such as 'ledge items' in _A Link to the Past_. To do this, set the `create_as_hint` parameter to a non-zero value. +Note that LocationScouts with a non-zero `create_as_hint` value will _always_ create a **persistent** hint (listed in the Hints tab of concerning players' TextClients), even if the location was already found. If this is not desired behavior, you need to prevent sending LocationScouts with `create_as_hint` for already found locations in your client-side code. #### Arguments | Name | Type | Notes |