Aller au contenu

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.

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": "..."
}

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.
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);
});