From d4466f64c6ff6f20819d3bda7c2e2035be65d6d8 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sun, 1 Dec 2024 14:33:12 +0100 Subject: [PATCH 1/5] Allow creating new hints with UpdateHint --- MultiServer.py | 77 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 61 insertions(+), 16 deletions(-) diff --git a/MultiServer.py b/MultiServer.py index 80fcd32fd1e3..573be51b71a5 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -1903,32 +1903,77 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): elif cmd == 'UpdateHint': location = args["location"] - player = args["player"] - status = args["status"] - if not isinstance(player, int) or not isinstance(location, int) \ - or (status is not None and not isinstance(status, int)): + location_player = args["player"] + status_int = args.get("status") + + if not isinstance(location_player, int) or not isinstance(location, int) \ + or (status_int is not None and not isinstance(status_int, int)): await ctx.send_msgs(client, [{'cmd': 'InvalidPacket', "type": "arguments", "text": 'UpdateHint', "original_cmd": cmd}]) return - hint = ctx.get_hint(client.team, player, location) - if not hint: - return # Ignored safely - if hint.receiving_player != client.slot: - await ctx.send_msgs(client, - [{'cmd': 'InvalidPacket', "type": "arguments", "text": 'UpdateHint: No Permission', - "original_cmd": cmd}]) - return - new_hint = hint - if status is None: - return + + hint = ctx.get_hint(client.team, location_player, location) + + if status_int is None: + if hint is None: + # New hints are created with unspecified by default + status_int = HintStatus.HINT_UNSPECIFIED + else: + # If the hint already exists and no status was provided, there is no point to the packet + return + try: - status = HintStatus(status) + status = HintStatus(status_int) except ValueError: await ctx.send_msgs(client, [{'cmd': 'InvalidPacket', "type": "arguments", "text": 'UpdateHint: Invalid Status', "original_cmd": cmd}]) return + + if hint is None: + # UpdateHint can be used as an "Upsert", creating a new hint. + # The newly created hint must either be for a location in the requesting slot's world, + # or a location containing an item for the requesting slot (including item links). + + target_item, item_player, flags = ctx.locations[location_player][location] + + if client.slot not in ctx.slot_set(item_player): + if status != HintStatus.HINT_UNSPECIFIED: + await ctx.send_msgs( + client, + [{ + "cmd": "InvalidPacket", + "type": "arguments", + "text": 'UpdateHint: Must use "unspecified"/None status for items for other players.', + "original_cmd": cmd + }], + ) + return + + if client.slot != location_player: + await ctx.send_msgs( + client, + [{ + "cmd": "InvalidPacket", + "type": "arguments", + "text": "UpdateHint: No Permission", + "original_cmd": cmd + }], + ) + return + + new_hint = collect_hint_location_id(ctx, client.team, location_player, location, status) + ctx.notify_hints(client.team, new_hint) + ctx.save() + return + + if hint.receiving_player != client.slot: + await ctx.send_msgs(client, + [{'cmd': 'InvalidPacket', "type": "arguments", "text": 'UpdateHint: No Permission', + "original_cmd": cmd}]) + return + new_hint = hint new_hint = new_hint.re_prioritize(ctx, status) if hint == new_hint: return From e283910c1d234a239a1ef65b6427acb180e222c2 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sun, 1 Dec 2024 14:36:03 +0100 Subject: [PATCH 2/5] Make that behavior optional --- MultiServer.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MultiServer.py b/MultiServer.py index 573be51b71a5..af0f9101c623 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -1904,6 +1904,7 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): elif cmd == 'UpdateHint': location = args["location"] location_player = args["player"] + create_if_not_exists = args.get("create_if_not_exists", False) status_int = args.get("status") if not isinstance(location_player, int) or not isinstance(location, int) \ @@ -1932,6 +1933,9 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): return if hint is None: + if not create_if_not_exists: + return + # UpdateHint can be used as an "Upsert", creating a new hint. # The newly created hint must either be for a location in the requesting slot's world, # or a location containing an item for the requesting slot (including item links). From 48782d1f74ca75e9ba3169b6363cb47adf9fa3ba Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sun, 1 Dec 2024 14:38:07 +0100 Subject: [PATCH 3/5] InvalidPacket if hint doesn't exist and create as hint is not on --- MultiServer.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MultiServer.py b/MultiServer.py index af0f9101c623..5be78d321e20 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -1934,6 +1934,15 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): if hint is None: if not create_if_not_exists: + await ctx.send_msgs(client, + [{ + "cmd": "InvalidPacket", + "type": "arguments", + "text": 'UpdateHint: Desired hint does not already exist. ' + 'Use with create_if_not_exists = True if the hint should be created.', + "original_cmd": cmd + }], + ) return # UpdateHint can be used as an "Upsert", creating a new hint. From b53f9ae1008bfabec67939d9d461d903f8c5d016 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sun, 1 Dec 2024 14:44:20 +0100 Subject: [PATCH 4/5] docs update --- docs/network protocol.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/network protocol.md b/docs/network protocol.md index 1c5b2e002289..5dff9ff09aef 100644 --- a/docs/network protocol.md +++ b/docs/network protocol.md @@ -345,6 +345,7 @@ This is useful in cases where an item appears in the game world, such as 'ledge ### UpdateHint Sent to the server to update the status of a Hint. The client must be the 'receiving_player' of the Hint, or the update fails. +Alternatively, if `create_if_not_exists` is set to true, the client can also be the 'finding_player' of the hint. In this case, the `status` must be `None` or 1 (unspecified). ### Arguments | Name | Type | Notes | @@ -352,6 +353,7 @@ Sent to the server to update the status of a Hint. The client must be the 'recei | player | int | The ID of the player whose location is being hinted for. | | location | int | The ID of the location to update the hint for. If no hint exists for this location, the packet is ignored. | | status | [HintStatus](#HintStatus) | Optional. If included, sets the status of the hint to this status. | +| create_if_not_exists | bool | If true, a new hint will be created if the hint doesn't already exist. Defaults to false. | #### HintStatus An enumeration containing the possible hint states. From 925e5dae2e3ef2203ad76991d62749e5b6393792 Mon Sep 17 00:00:00 2001 From: NewSoupVi <57900059+NewSoupVi@users.noreply.github.com> Date: Sun, 1 Dec 2024 15:27:07 +0100 Subject: [PATCH 5/5] remove an unnecessary line --- MultiServer.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MultiServer.py b/MultiServer.py index 5be78d321e20..e3f53ec6c3cc 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -1986,8 +1986,7 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): [{'cmd': 'InvalidPacket', "type": "arguments", "text": 'UpdateHint: No Permission', "original_cmd": cmd}]) return - new_hint = hint - new_hint = new_hint.re_prioritize(ctx, status) + new_hint = hint.re_prioritize(ctx, status) if hint == new_hint: return ctx.replace_hint(client.team, hint.finding_player, hint, new_hint)