Protocole du connecteur
Un connecteur est un programme (plugin, addon ou mod de jeu) qui tient Inari informé de la position des joueurs. Il dialogue avec Inari via le même endpoint WebSocket que les navigateurs : /ws.
Messages
Section intitulée « Messages »Chaque message est une trame texte JSON avec la même enveloppe :
{ "kind": "auth", "data": {}, "transaction_uuid": "6f1c0a9e-3a8b-4c53-a9a1-5e2c0f2d1b77"}| Champ | Description |
|---|---|
kind |
Type de message, en snake_case. |
data |
Contenu, dépend de kind. |
transaction_uuid |
Choisi par vous. La réponse à une requête porte la même valeur, ce qui permet de les associer. |
Les JSON invalides et les messages inconnus sont ignorés silencieusement.
Doit être le premier message. Il ne peut être envoyé qu’une fois par connexion.
Requête
{ "kind": "auth", "data": { "is_connector": true, "auth_key": "<API_KEY>", "channel": "default" }, "transaction_uuid": "..."}| Champ | Type | Description |
|---|---|---|
is_connector |
boolean |
true pour un connecteur. |
auth_key |
string |
L’API_KEY du serveur. |
channel |
string |
Channel à gérer. |
Réponse
{ "kind": "auth", "data": { "max_distance": 20, "app_version": "1.0.0" }, "transaction_uuid": "..."}sync_connector_state
Section intitulée « sync_connector_state »Envoyez la liste complète des joueurs de votre serveur de jeu. Appelez-le régulièrement, environ toutes les 300 ms : c’est lui qui détermine qui entend qui. Les joueurs du channel absents de la liste ne sont pas liés à un personnage.
Requête
{ "kind": "sync_connector_state", "data": { "clients": [ { "code": "a1b2c3d4", "display_name": "Steve", "position": [120.5, 64.0, -30.2], "head": [1, 0, 0], "is_force_muted": false, "group": "team-red", "actions": { "toggle_muted": false, "toggle_deafened": false } } ] }, "transaction_uuid": "..."}| Champ | Type | Requis | Description |
|---|---|---|---|
code |
string |
oui | Le code utilisé par le joueur pour rejoindre. |
position |
[x, y, z] |
oui | Position du personnage, dans les unités de votre jeu. Comparée à MAX_DISTANCE. |
head |
[x, y, z] |
oui | Direction dans laquelle regarde le joueur, utilisée pour placer les voix autour de l’auditeur. Doit être un vecteur unitaire (longueur 1, chaque composante entre -1 et 1), comme getViewDirection() de Minecraft Bedrock. Par exemple, [1, 0, 0] regarde le long de l’axe X. |
is_force_muted |
boolean |
oui | Si true, personne n’entend ce joueur. |
display_name |
string |
non | Nom affiché sur la page web. |
group |
string |
non | Seuls les joueurs du même groupe s’entendent. default par défaut. |
actions.toggle_muted |
boolean |
non | true bascule l’état muet du joueur. |
actions.toggle_deafened |
boolean |
non | true bascule l’état sourdine du joueur. |
Réponse
{ "kind": "sync_connector_state", "data": { "connections": [ { "code": "a1b2c3d4", "display_name": "Steve", "is_connector": false, "is_force_muted": false, "is_muted": false, "is_deafened": false } ] }, "transaction_uuid": "..."}connections liste toutes les personnes connectées au channel, ce qui vous permet d’afficher en jeu l’état muet/sourdine d’un joueur.
Les erreurs utilisent le kind error et le transaction_uuid de la requête en échec.
{ "kind": "error", "data": { "message": "UNAUTHORIZED", "details": "The API key provided is invalid.", "code": 401 }, "transaction_uuid": "..."}| Code | message |
Cause |
|---|---|---|
400 |
BAD_REQUEST |
Code client invalide (moins de 6 caractères ou déjà utilisé). |
401 |
UNAUTHORIZED |
Clé d’API invalide, ou un non-connecteur a envoyé un message de connecteur. |
409 |
ALREADY_CONNECTED |
auth a déjà été envoyé sur cette connexion. |
Exemple minimal
Section intitulée « Exemple minimal »import { WebSocket } from "ws";import { v4 as uuid } from "uuid";
const ws = new WebSocket("wss://inari.example.com/ws");const send = (kind: string, data: unknown) => ws.send(JSON.stringify({ kind, data, transaction_uuid: uuid() }));
ws.on("open", () => { send("auth", { is_connector: true, auth_key: process.env.INARI_API_KEY, channel: "default" });
setInterval(() => { send("sync_connector_state", { clients: getPlayers() }); // vos données de jeu }, 300);});