diff --git a/CommonClient.py b/CommonClient.py index 9d08c2d9..93c68319 100644 --- a/CommonClient.py +++ b/CommonClient.py @@ -397,6 +397,9 @@ async def process_server_cmd(ctx: CommonContext, args: dict): elif cmd == 'InvalidPacket': logger.warning(f"Invalid Packet of {args['type']}: {args['text']}") + elif cmd == "Bounced": + pass + else: logger.debug(f"unknown command {cmd}") diff --git a/MultiServer.py b/MultiServer.py index 95f28516..38cda876 100644 --- a/MultiServer.py +++ b/MultiServer.py @@ -1118,13 +1118,26 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict): elif cmd == 'StatusUpdate': update_client_status(ctx, client, args["status"]) - if cmd == 'Say': + elif cmd == 'Say': if "text" not in args or type(args["text"]) is not str or not args["text"].isprintable(): await ctx.send_msgs(client, [{'cmd': 'InvalidPacket', "type": "arguments", "text": 'Say'}]) return client.messageprocessor(args["text"]) + elif cmd == "Bounce": + games = set(args.get("games", [])) + tags = set(args.get("tags", [])) + slots = set(args.get("slots", [])) + args["cmd"] = "Bounced" + msg = ctx.dumper([args]) + + for bounceclient in ctx.endpoints: + if client.team == bounceclient.team and (ctx.games[bounceclient.slot] in games or + set(bounceclient.tags) & tags or + bounceclient.slot in slots): + await ctx.send_encoded_msgs(bounceclient, msg) + def update_client_status(ctx: Context, client: Client, new_status: ClientStatus): current = ctx.client_game_state[client.team, client.slot] diff --git a/docs/network protocol.md b/docs/network protocol.md index a39524e7..fdc6c8cd 100644 --- a/docs/network protocol.md +++ b/docs/network protocol.md @@ -43,6 +43,7 @@ These packets are are sent from the multiworld server to the client. They are no * [Print](#Print) * [PrintJSON](#PrintJSON) * [DataPackage](#DataPackage) +* [Bounced](#Bounced) ### RoomInfo Sent to clients when they connect to an Archipelago server. @@ -148,6 +149,15 @@ Sent to clients to provide what is known as a 'data package' which contains info | ---- | ---- | ----- | | data | DataPackageObject | The data package as a JSON object. More details on its contents may be found at [Data Package Contents](#Data-Package-Contents) | +### Bounced +Sent to clients after a client requested this message be sent to them, more info in the Bounce package. + +#### Arguments +| Name | Type | Notes | +| ---- | ---- | ----- | +| Any | Any | The data in the Bounce package copied | + + ## (Client -> Server) These packets are sent purely from client to server. They are not accepted by clients. @@ -158,6 +168,7 @@ These packets are sent purely from client to server. They are not accepted by cl * [StatusUpdate](#StatusUpdate) * [Say](#Say) * [GetDataPackage](#GetDataPackage) +* [Bounce](#Bounce) ### Connect Sent by the client to initiate a connection to an Archipelago game session. @@ -220,6 +231,19 @@ Requests the data package from the server. Does not require client authenticatio | ------ | ----- | ------ | | exlusions | list[str] | Optional. If specified, will not send back the specified data. Such as, ["Factorio"] -> Datapackage without Factorio data.| +### Bounce +Send this message to the server, tell it which clients should receive the message and +the server will forward the message to all those targets to which any one requirement applies. + +#### Arguments +| Name | Type | Notes | +| ------ | ----- | ------ | +| games | list[str] | Optional. Game names that should receive this message | +| slots | list[int] | Optional. Player IDs that should receive this message | +| tags | list[str] | Optional. Client tags that should receive this message | +| Any | Any | Any data you want to send | + + ## Appendix ### NetworkPlayer A list of objects. Each object denotes one player. Each object has four fields about the player, in this order: `team`, `slot`, `alias`, and `name`. `team` and `slot` are ints, `alias` and `name` are strs.