Skip to content

General Extension Protocol

Chasm edited this page Dec 15, 2013 · 22 revisions

The General Extension Protocol(GEP) is the recommended mechanism for extending spyd functionality for your particular deployment. GEP aims to be interface, transport, and packing agnostic.

The goal would be to allow GEP to listen on TCP, UDS, etc; read packed data which transported as a netstring, newline terminated, etc; and unpacked using json, edn, etc. See GEP Interface, Transport, and Packing for information about how each is implemented and which are currently available.

After all that, the protocol is implemented as hashes of key value pairs henceforth identied as GEP Messages.

  • GEP Messages have one required field "msgtype".
  • If a "reqid" field is included it will be echoed back with the response "respid" field. If no response would normally be given for a message type but a reqid is sent, then a status ok message will come back.
  • Clients must honor this "reqid" "respid" pattern as well.

Example authentication exchange

{"msgtype": "connect", "username": "bob", "domain": "example.com"}
{"msgtype": "challenge", "challenge": "+b09192498c05502ed8eb11a113d3dcd09251970a42fdb88a"}
{"msgtype": "answer", "answer": "81a838d411f32284ce4d9bfee2af62d62db0308fa73a6b2f"}
{"msgtype": "status", "status": "success"}
{"msgtype": "error", "message": "Good bye"}

Event subscription api

Even though spyd is the server in this protocol, either party may subscribe to events from the other.

{"msgtype": "subscribe", "event_stream": "spyd.game.player.chat", "reqid": 352}
{"msgtype": "status", "status": "success", "respid": 352}
{"msgtype": "error", "message": "Unknown event stream.", "respid": 352}

Messages like the following would then begin to be transmitted as the events occur;

{"msgtype": "event", "event_stream": "spyd.game.player.chat", "event_data": {"player": "3F2504E0-4F89-11D3-9A0C-0305E82C3301", "room": "lobby", "scope": "team", "text": "Hello world! Why won't you talk to me!" }}

Examples of all the different events;

{"event_stream": "spyd.game.player.connect", "msgtype": "event", "event_data": {"player": "50d2d9b7-d288-4910-aa01-737f2d2fb14e", "room": "lobby"}}
{"event_stream": "spyd.game.player.chat", "msgtype": "event", "event_data": {"player": "50d2d9b7-d288-4910-aa01-737f2d2fb14e", "text": "Hello room.", "room": "lobby", "scope": "room"}}
{"event_stream": "spyd.game.player.chat", "msgtype": "event", "event_data": {"player": "50d2d9b7-d288-4910-aa01-737f2d2fb14e", "text": "Hello team.", "room": "lobby", "scope": "team"}}
{"event_stream": "spyd.game.player.disconnect", "msgtype": "event", "event_data": {"player": "50d2d9b7-d288-4910-aa01-737f2d2fb14e", "room": "lobby"}}

Ping message

Either party can ping eachother. The times are in microseconds since epoch.

{"reqid": 4, "msgtype": "ping", "time": 1382822552519713}
{"client_time": 1382822512312759, "msgtype": "pong", "server_time": 1382822512313339, "respid": 4}

Get player info

{"player": "babcf40d-141e-4542-9eec-ac48c5796122", "reqid": 5, "msgtype": "get_player_info"}
{"player": "babcf40d-141e-4542-9eec-ac48c5796122", "respid": 5, "msgtype": "player_info", "player_info": {"game_state": {"is_spectator": false, "frags": 0, "teamkills": 0, "armour": 50, "deaths": 0, "has_quad": false, "armourtype": 0, "maxhealth": 100, "damage_dealt": 0, "flags": 0, "damage_spent": 0, "suicides": 0, "health": 100, "flag_returns": 0, "gunselect": 6, "is_alive": true, "ammo": [1, 0, 0, 0, 0, 1, 40, 0, 0, 0, 0, 0]}, "room": "lobby", "isai": false, "name": "[FD]Chasm", "host": "127.0.0.1", "groups": ["local.client"], "team": "good", "model": 0, "cn": 0}}

Move player between rooms

{"player": "a8e7d89c-7c4e-49c6-a93f-b700a9e4d0f6", "message": "get used to it.", "msgtype": "set_player_room", "room": "xyz", "reqid": 7}
{"msgtype": "status", "status": "success", "respid": 7}

Pause or resume the game

{"message": "Told you guys to get used to it.", "pause": true, "msgtype": "set_room_paused", "room": "xyz", "reqid": 9}
{"status": "success", "respid": 9, "msgtype": "status"}