Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UpdateHint: create_if_not_exists (Allows clients to hint own items in other worlds) #4316

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 74 additions & 17 deletions MultiServer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1903,27 +1903,29 @@ 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"]
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) \
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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would move the try/catch for status = HintStatus(status_int) above the hint = ctx.get_hint(client.team, location_player, location) as it breaks the flow that there is a check for if hint is None right below it

except ValueError:
await ctx.send_msgs(client,
[{'cmd': 'InvalidPacket', "type": "arguments",
Expand All @@ -1934,7 +1936,62 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict):
[{'cmd': 'InvalidPacket', "type": "arguments",
"text": 'UpdateHint: Cannot manually update status to "HINT_FOUND"', "original_cmd": cmd}])
return
new_hint = new_hint.re_prioritize(ctx, status)

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. '
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would remove already from this scentence

'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.
# 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.',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for items for other players is a bit odd, as its items send by other players. not items for those other players

"original_cmd": cmd
}],
)
return

if client.slot != location_player:
await ctx.send_msgs(
client,
[{
"cmd": "InvalidPacket",
"type": "arguments",
"text": "UpdateHint: No Permission",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No Permission Might be on purpose but this gives no information on why your getting this response, and if its as part of an implementation error by the client, then it might not help the dev to understand what went wrong

"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.re_prioritize(ctx, status)
if hint == new_hint:
return
ctx.replace_hint(client.team, hint.finding_player, hint, new_hint)
Expand Down
2 changes: 2 additions & 0 deletions docs/network protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -345,13 +345,15 @@ 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 |
| ---- | ---- | ----- |
| 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. Cannot set `HINT_FOUND`, or change the status from `HINT_FOUND`. |
| 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.
Expand Down
Loading