-
Notifications
You must be signed in to change notification settings - Fork 107
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
Encounter command API #231
Comments
Experimenting with the DM view, it looks like the server and client don't sync the actual encounter state (i.e. two DM views controlling the same encounter ID can have two different encounters running, and a PlayerView will display the last one that changed). Would it be possible to have a DM view reflect changes to an encounter made by a different client? My thought was that both third-party applications would be able to manage adding and modifying combatants, tags, etc. to an encounter programmatically, or an end user over the web GUI. |
It is true that the Tracker view doesn't sync encounter state with the server. This is because the encounter state is mastered in the Tracker view client; changes in encounter state never flow back to the DM view. #149 contains some notes about to this architecture. I don't have plans to change this architecture for the foreseeable future. This means that any API calls to update the encounter would need to flow through the Tracker view client the same way that Damage Suggest does. To implement this without requiring an 'Accept' dialog on the tracker view for any given action, it may require introducing something like a 'secret encounter key' at mentioned in #149 that allows anyone with the key to freely push actions. |
Got it. To address the concerns brought up in #149, maybe a POST endpoint to start an encounter that would return such a secret could be used, although that wouldn't allow for third-party apps to issue encounter commands to a web-initiated encounter. This key could then be supplied in either websocket payloads or HTTP requests to update the encounter. As for third-party clients receiving updates about encounter state from II, |
You can GET the current SavedEncounter through the app.get("/playerviews/:id") endpoint without having to wait on a socket update. The PlayerView makes a request to this endpoint when it first connects in order to get the current encounter state. Since it's accessible to anyone with the encounter ID, this is not a good place to expose a secret key. One approach might be to add a Connect to Avrae button somewhere in the II menus that posts a secret key to your app. Then you could use that secret key to send commands to a POST endpoint. |
It appears as though the A "Connect to Avrae" button would probably be unnecessary (my comment was in case you wanted this API to be for a more general use case), since the main flow would be:
From there, the two apps would continue to send the other updates, either via socket, webhooks, or some other implementation. Does that sound realistic? |
This could work. Have you taken a look at the /importencounter/ endpoint that's used by Kobold Fight Club? This is the ideal way to set up an initial encounter state, and the endpoint could be updated to return a key that can be used to issue other encounter commands. |
That endpoint is designed for the user's browser to post the encounter from another domain, which is why it responds with a redirect, so maybe there ought to be a new endpoint that you'd hit if you wanted to initialize a remotely-run encounter. |
I'm thinking the latter would probably be the better option, since Avrae would initialize the encounter without combatants, then a user could either add them on Avrae (which would send the update to II), or on II (which would send the update to Avrae). Maybe something like this? POST /integratedencounter/ HTTP/1.1
Content-Type: application/json
{
"webhook_url": "https://avrae.io/api/combat/...",
"origin": "avrae"
} Which would return something like this (plus any other metadata, if needed): {
"encounter_secret": "...",
"encounter_id": "..."
} |
This proposal looks great. Did you find out if it's possible to make a cross-origin socket connection? I imagine that using socket.io is a bit more efficient than hitting a webhook on every encounter update. Maybe that's too much of a pre-optimization. If the cross-origin socket is not trivial, having II hit the supplied webhook on every encounter update seems reasonable. I can see how the webhooks approach makes it overall easier for other apps like yours to integrate. |
While it looks like it's possible to make cross-origin socket connections, there isn't really a robust socket.io client library for Python (which Avrae is programmed in), meaning that if I were to use that method, I'd likely have to build one from the lower-level socket connection. Since Avrae's load isn't too large (relatively speaking), using webhooks seems like the best approach for now. In the future, that can be optimized if it needs to be. |
There is some precedent for commands being passed through the socket, see https://github.com/cynicaloptimist/improved-initiative/blob/master/server/sockets.ts#L31 for an example. That command comes from a PlayerView that's connected to the socket, so its corresponding client call is at https://github.com/cynicaloptimist/improved-initiative/blob/master/client/Player/PlayerViewClient.ts#L12 .
Sockets may be accessible cross-domain. I haven't researched or experimented with this yet, but I'm guessing this requires some configuration to achieve. It might possibly be better to build a POST endpoint that accepts encounter commands, then forwards them to the appropriate socket channel.
The text was updated successfully, but these errors were encountered: