diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d75548a..955407d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -16,5 +16,5 @@ jobs:
- run: npm run format:check
- run: npm run typecheck
- run: npm run lint
- - run: npm run build && git diff --exit-code
+ - run: npm run build:clean && git diff --exit-code
- run: npm test
diff --git a/docs/schema/game.md b/docs/schema/game.md
deleted file mode 100644
index e9c473d..0000000
--- a/docs/schema/game.md
+++ /dev/null
@@ -1,90 +0,0 @@
-
-
-# Game
-
-- [launch](#launch)
----
-
-## Launch
-
-When a user client receives this response it should launch the game (spring.exe) with the start script.
-
-- Endpoint Type: **Event**
-- Source: **Server**
-- Target: **User**
-- Requires Role: `tachyon.lobby`
-
-### Event
-
-
-JSONSchema
-
-```json
-{
- "$id": "game/launch/event",
- "scopes": [
- "tachyon.lobby"
- ],
- "type": "object",
- "properties": {
- "type": {
- "const": "event",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "game/launch",
- "type": "string"
- },
- "data": {
- "type": "object",
- "properties": {
- "script": {
- "type": "string"
- }
- },
- "required": [
- "script"
- ]
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "data"
- ]
-}
-```
-
-
-
-
-Example
-
-```json
-{
- "type": "event",
- "messageId": "labore",
- "commandId": "game/launch",
- "data": {
- "script": "labore"
- }
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface GameLaunchEvent {
- type: "event";
- messageId: string;
- commandId: "game/launch";
- data: {
- script: string;
- };
-}
-
-```
diff --git a/docs/schema/lobby.md b/docs/schema/lobby.md
deleted file mode 100644
index 07aed13..0000000
--- a/docs/schema/lobby.md
+++ /dev/null
@@ -1,3325 +0,0 @@
-
-
-# Lobby
-
-These commands relate to custom battles.
-
----
-- [close](#close)
-- [create](#create)
-- [join](#join)
-- [joined](#joined)
-- [leave](#leave)
-- [left](#left)
-- [list](#list)
-- [receiveMessage](#receivemessage)
-- [sendMessage](#sendmessage)
-- [subscribe](#subscribe)
-- [unsubscribe](#unsubscribe)
-- [updated](#updated)
----
-
-## Close
-
-Close an existing lobby.
-
-- Endpoint Type: **Request** -> **Response**
-- Source: **User**
-- Target: **Server**
-- Requires Role: `tachyon.lobby`
-
-### Request
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.close.request",
- "scopes": [
- "tachyon.lobby"
- ],
- "type": "object",
- "properties": {
- "type": {
- "const": "request",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/close",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId"
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "request",
- "messageId": "Ut",
- "commandId": "lobby/close"
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface LobbyCloseRequest {
- type: "request";
- messageId: string;
- commandId: "lobby/close";
-}
-```
-### Response
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.close.response",
- "scopes": [
- "tachyon.lobby"
- ],
- "anyOf": [
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/close",
- "type": "string"
- },
- "status": {
- "const": "success",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/close",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "internal_error",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/close",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "unauthorized",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/close",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "invalid_request",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/close",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "command_unimplemented",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- }
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "response",
- "messageId": "dolore",
- "commandId": "lobby/close",
- "status": "success"
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface LobbyCloseResponse {
- type: "response";
- messageId: string;
- commandId: "lobby/close";
- status: "success";
-}
-```
-Possible Failed Reasons: `internal_error`, `unauthorized`, `invalid_request`, `command_unimplemented`
-
----
-
-## Create
-
-Create a new lobby - intended for player clients to summon a dedicated host.
-
-- Endpoint Type: **Request** -> **Response**
-- Source: **User**
-- Target: **Server**
-- Requires Role: `tachyon.lobby`
-
-### Request
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.create.request",
- "scopes": [
- "tachyon.lobby"
- ],
- "type": "object",
- "properties": {
- "type": {
- "const": "request",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/create",
- "type": "string"
- },
- "data": {
- "examples": [
- {
- "title": "8v8 | All Welcome",
- "private": false,
- "region": "EU",
- "maxPlayers": 16
- }
- ],
- "type": "object",
- "properties": {
- "title": {
- "minLength": 2,
- "maxLength": 30,
- "type": "string"
- },
- "private": {
- "default": true,
- "type": "boolean"
- },
- "region": {
- "type": "string"
- },
- "maxPlayers": {
- "minimum": 0,
- "default": 16,
- "type": "integer"
- }
- },
- "required": [
- "title",
- "private",
- "region",
- "maxPlayers"
- ]
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "data"
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "request",
- "messageId": "labore",
- "commandId": "lobby/create",
- "data": {
- "title": "8v8 | All Welcome",
- "private": false,
- "region": "EU",
- "maxPlayers": 16
- }
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface LobbyCreateRequest {
- type: "request";
- messageId: string;
- commandId: "lobby/create";
- data: {
- title: string;
- private: boolean;
- region: string;
- maxPlayers: number;
- };
-}
-```
-### Response
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.create.response",
- "scopes": [
- "tachyon.lobby"
- ],
- "anyOf": [
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/create",
- "type": "string"
- },
- "status": {
- "const": "success",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/create",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "no_hosts_available",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/create",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "invalid_region",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/create",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "internal_error",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/create",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "unauthorized",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/create",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "invalid_request",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/create",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "command_unimplemented",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- }
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "response",
- "messageId": "incididunt",
- "commandId": "lobby/create",
- "status": "success"
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface LobbyCreateResponse {
- type: "response";
- messageId: string;
- commandId: "lobby/create";
- status: "success";
-}
-```
-Possible Failed Reasons: `no_hosts_available`, `invalid_region`, `internal_error`, `unauthorized`, `invalid_request`, `command_unimplemented`
-
----
-
-## Join
-
-Join a custom lobby. Server will send a [joined](#joined) response containing the joined lobby's data.
-These commands are split because the server may want to force the client to join a battle without them explicitly requesting it.
-
-- Endpoint Type: **Request** -> **Response**
-- Source: **User**
-- Target: **Server**
-- Requires Role: `tachyon.lobby`
-
-### Request
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.join.request",
- "scopes": [
- "tachyon.lobby"
- ],
- "type": "object",
- "properties": {
- "type": {
- "const": "request",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/join",
- "type": "string"
- },
- "data": {
- "examples": [
- {
- "lobbyId": 27,
- "password": "fish"
- }
- ],
- "type": "object",
- "properties": {
- "lobbyId": {
- "type": "string"
- },
- "password": {
- "type": "string"
- }
- },
- "required": [
- "lobbyId"
- ]
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "data"
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "request",
- "messageId": "tempor",
- "commandId": "lobby/join",
- "data": {
- "lobbyId": 27,
- "password": "fish"
- }
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface LobbyJoinRequest {
- type: "request";
- messageId: string;
- commandId: "lobby/join";
- data: {
- lobbyId: string;
- password?: string;
- };
-}
-```
-### Response
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.join.response",
- "scopes": [
- "tachyon.lobby"
- ],
- "anyOf": [
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/join",
- "type": "string"
- },
- "status": {
- "const": "success",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/join",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "locked",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/join",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "requires_password",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/join",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "invalid_password",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/join",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "max_participants_reached",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/join",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "rank_too_low",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/join",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "rank_too_high",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/join",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "banned",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/join",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "internal_error",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/join",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "unauthorized",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/join",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "invalid_request",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/join",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "command_unimplemented",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- }
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "response",
- "messageId": "eiusmod",
- "commandId": "lobby/join",
- "status": "success"
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface LobbyJoinResponse {
- type: "response";
- messageId: string;
- commandId: "lobby/join";
- status: "success";
-}
-```
-Possible Failed Reasons: `locked`, `requires_password`, `invalid_password`, `max_participants_reached`, `rank_too_low`, `rank_too_high`, `banned`, `internal_error`, `unauthorized`, `invalid_request`, `command_unimplemented`
-
----
-
-## Joined
-
-Sent when the client successfully joins a lobby. Can also be sent at any time by the server to forcibly make the client join a lobby.
-
-- Endpoint Type: **Event**
-- Source: **Server**
-- Target: **User**
-- Requires Role: `tachyon.lobby`
-
-### Event
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.joined.event",
- "scopes": [
- "tachyon.lobby"
- ],
- "type": "object",
- "properties": {
- "type": {
- "const": "event",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/joined",
- "type": "string"
- },
- "data": {
- "$ref": "battle"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "data"
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "event",
- "messageId": "do",
- "commandId": "lobby/joined",
- "data": {
- "battleId": 27,
- "hostId": 822,
- "engine": "105.1.1-1821-gaca6f20 BAR105",
- "game": "Beyond All Reason test-23561-0abff7c",
- "map": "Red Comet Remake 1.8",
- "startPosType": 2,
- "startAreas": {
- "0": {
- "x": 0,
- "y": 0,
- "width": 1,
- "height": 0.3
- },
- "1": {
- "x": 0,
- "y": 0.7,
- "width": 1,
- "height": 0.3
- }
- },
- "startTime": 1705432698,
- "ip": "121.32.201.76",
- "port": 41403,
- "scriptPassword": "10sdfi90sid0sjkdf",
- "modOptions": {
- "emprework": 0
- },
- "bots": [],
- "users": []
- }
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export type StartPosType = 0 | 1 | 2;
-export type UnixTime = number | null;
-export type Bot = BattleContender & {
- isSpectator: false;
- isBot: true;
- ownerId: string;
- aiShortName: string;
- name: string;
- aiOptions: {
- [k: string]: unknown;
- };
- faction: string;
-};
-export type UserStatus = "offline" | "menu" | "playing" | "lobby";
-export type BattleStatus =
- | ({
- battleId: string;
- } & (BattlePlayer | BattleSpectator))
- | null;
-export type BattlePlayer = BattleContender & {
- isSpectator: false;
- isBot: false;
- ready: boolean;
- sync: {
- engine: number;
- game: number;
- map: number;
- };
-};
-
-export interface LobbyJoinedEvent {
- type: "event";
- messageId: string;
- commandId: "lobby/joined";
- data: Battle;
-}
-export interface Battle {
- battleId: string;
- hostId: string;
- engine: string;
- game: string;
- map: string;
- startPosType: StartPosType;
- startAreas: {
- [k: string]: Rect;
- };
- startTime: UnixTime;
- ip: string | null;
- port: number | null;
- scriptPassword: string | null;
- modOptions: {
- [k: string]: unknown;
- };
- bots: Bot[];
- users: User[];
-}
-export interface Rect {
- x: number;
- y: number;
- width: number;
- height: number;
-}
-export interface BattleContender {
- playerId: number;
- teamId: number;
- color: string;
- bonus: number;
- inGame: boolean;
-}
-export interface User {
- userId: string;
- username: string;
- displayName: string;
- clanId: string | null;
- partyId: string | null;
- scopes: string[];
- countryCode?: string;
- status: UserStatus;
- battleStatus: BattleStatus;
-}
-export interface BattleSpectator {
- isSpectator: true;
- isBot: false;
-}
-```
----
-
-## Leave
-
-Leave the current lobby.
-
-- Endpoint Type: **Request** -> **Response**
-- Source: **User**
-- Target: **Server**
-- Requires Role: `tachyon.lobby`
-
-### Request
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.leave.request",
- "scopes": [
- "tachyon.lobby"
- ],
- "type": "object",
- "properties": {
- "type": {
- "const": "request",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/leave",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId"
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "request",
- "messageId": "id",
- "commandId": "lobby/leave"
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface LobbyLeaveRequest {
- type: "request";
- messageId: string;
- commandId: "lobby/leave";
-}
-```
-### Response
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.leave.response",
- "scopes": [
- "tachyon.lobby"
- ],
- "anyOf": [
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/leave",
- "type": "string"
- },
- "status": {
- "const": "success",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/leave",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "no_lobby",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/leave",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "internal_error",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/leave",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "unauthorized",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/leave",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "invalid_request",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/leave",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "command_unimplemented",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- }
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "response",
- "messageId": "sint",
- "commandId": "lobby/leave",
- "status": "success"
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface LobbyLeaveResponse {
- type: "response";
- messageId: string;
- commandId: "lobby/leave";
- status: "success";
-}
-```
-Possible Failed Reasons: `no_lobby`, `internal_error`, `unauthorized`, `invalid_request`, `command_unimplemented`
-
----
-
-## Left
-
-Sent when the server removes the client from a lobby.
-
-- Endpoint Type: **Event**
-- Source: **Server**
-- Target: **User**
-- Requires Role: `tachyon.lobby`
-
-### Event
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.left.event",
- "scopes": [
- "tachyon.lobby"
- ],
- "type": "object",
- "properties": {
- "type": {
- "const": "event",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/left",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId"
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "event",
- "messageId": "nulla",
- "commandId": "lobby/left"
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface LobbyLeftEvent {
- type: "event";
- messageId: string;
- commandId: "lobby/left";
-}
-```
----
-
-## List
-
-Returns all custom lobbies.
-
-- Endpoint Type: **Request** -> **Response**
-- Source: **User**
-- Target: **Server**
-- Requires Role: `tachyon.lobby`
-
-### Request
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.list.request",
- "scopes": [
- "tachyon.lobby"
- ],
- "type": "object",
- "properties": {
- "type": {
- "const": "request",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/list",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId"
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "request",
- "messageId": "dolor",
- "commandId": "lobby/list"
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface LobbyListRequest {
- type: "request";
- messageId: string;
- commandId: "lobby/list";
-}
-```
-### Response
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.list.response",
- "scopes": [
- "tachyon.lobby"
- ],
- "anyOf": [
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/list",
- "type": "string"
- },
- "status": {
- "const": "success",
- "type": "string"
- },
- "data": {
- "type": "object",
- "properties": {
- "battles": {
- "type": "array",
- "items": {
- "$ref": "customBattle"
- }
- }
- },
- "required": [
- "battles"
- ]
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "data"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/list",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "internal_error",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/list",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "unauthorized",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/list",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "invalid_request",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/list",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "command_unimplemented",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- }
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "response",
- "messageId": "aute",
- "commandId": "lobby/list",
- "status": "success",
- "data": {
- "battles": [
- {
- "battleId": 27,
- "hostId": 822,
- "engine": "105.1.1-1821-gaca6f20 BAR105",
- "game": "Beyond All Reason test-23561-0abff7c",
- "map": "Red Comet Remake 1.8",
- "startPosType": 2,
- "startAreas": {
- "0": {
- "x": 0,
- "y": 0,
- "width": 1,
- "height": 0.3
- },
- "1": {
- "x": 0,
- "y": 0.7,
- "width": 1,
- "height": 0.3
- }
- },
- "startTime": 1705432698,
- "ip": "121.32.201.76",
- "port": 41403,
- "scriptPassword": "10sdfi90sid0sjkdf",
- "modOptions": {
- "emprework": 0
- },
- "bots": [],
- "users": [],
- "title": "8v8 | All Welcome",
- "bossIds": [
- 123,
- 456
- ],
- "locked": false,
- "passworded": false,
- "spectatorIds": [
- 88
- ],
- "limits": {
- "minTeamsize": 3,
- "maxTeamsize": 3,
- "minRating": null,
- "maxRating": 25
- }
- }
- ]
- }
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export type CustomBattle = Battle & {
- title: string;
- locked: boolean;
- passworded: boolean;
- bossIds: string[];
- joinQueueIds: string[];
- limits: {
- minTeamsize: number | null;
- maxTeamsize: number | null;
- minRating: number | null;
- maxRating: number | null;
- };
-};
-export type StartPosType = 0 | 1 | 2;
-export type UnixTime = number | null;
-export type Bot = BattleContender & {
- isSpectator: false;
- isBot: true;
- ownerId: string;
- aiShortName: string;
- name: string;
- aiOptions: {
- [k: string]: unknown;
- };
- faction: string;
-};
-export type UserStatus = "offline" | "menu" | "playing" | "lobby";
-export type BattleStatus =
- | ({
- battleId: string;
- } & (BattlePlayer | BattleSpectator))
- | null;
-export type BattlePlayer = BattleContender & {
- isSpectator: false;
- isBot: false;
- ready: boolean;
- sync: {
- engine: number;
- game: number;
- map: number;
- };
-};
-
-export interface LobbyListResponse {
- type: "response";
- messageId: string;
- commandId: "lobby/list";
- status: "success";
- data: {
- battles: CustomBattle[];
- };
-}
-export interface Battle {
- battleId: string;
- hostId: string;
- engine: string;
- game: string;
- map: string;
- startPosType: StartPosType;
- startAreas: {
- [k: string]: Rect;
- };
- startTime: UnixTime;
- ip: string | null;
- port: number | null;
- scriptPassword: string | null;
- modOptions: {
- [k: string]: unknown;
- };
- bots: Bot[];
- users: User[];
-}
-export interface Rect {
- x: number;
- y: number;
- width: number;
- height: number;
-}
-export interface BattleContender {
- playerId: number;
- teamId: number;
- color: string;
- bonus: number;
- inGame: boolean;
-}
-export interface User {
- userId: string;
- username: string;
- displayName: string;
- clanId: string | null;
- partyId: string | null;
- scopes: string[];
- countryCode?: string;
- status: UserStatus;
- battleStatus: BattleStatus;
-}
-export interface BattleSpectator {
- isSpectator: true;
- isBot: false;
-}
-```
-Possible Failed Reasons: `internal_error`, `unauthorized`, `invalid_request`, `command_unimplemented`
-
----
-
-## ReceiveMessage
-
-Receive a lobby message. See [sendMessage](#sendmessage) for outgoing messages.
-
-- Endpoint Type: **Event**
-- Source: **Server**
-- Target: **User**
-- Requires Role: `tachyon.lobby`
-
-### Event
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.receiveMessage.event",
- "scopes": [
- "tachyon.lobby"
- ],
- "type": "object",
- "properties": {
- "type": {
- "const": "event",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/receiveMessage",
- "type": "string"
- },
- "data": {
- "examples": [
- {
- "userId": 27,
- "message": "Hello lobby!"
- }
- ],
- "type": "object",
- "properties": {
- "userId": {
- "type": "string"
- },
- "message": {
- "type": "string"
- }
- },
- "required": [
- "userId",
- "message"
- ]
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "data"
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "event",
- "messageId": "nisi",
- "commandId": "lobby/receiveMessage",
- "data": {
- "userId": 27,
- "message": "Hello lobby!"
- }
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface LobbyReceiveMessageEvent {
- type: "event";
- messageId: string;
- commandId: "lobby/receiveMessage";
- data: {
- userId: string;
- message: string;
- };
-}
-```
----
-
-## SendMessage
-
-Send a lobby message. See [receiveMessage](#receivemessage) for incoming messages.
-
-- Endpoint Type: **Request** -> **Response**
-- Source: **User**
-- Target: **Server**
-- Requires Role: `tachyon.lobby`
-
-### Request
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.sendMessage.request",
- "scopes": [
- "tachyon.lobby"
- ],
- "type": "object",
- "properties": {
- "type": {
- "const": "request",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/sendMessage",
- "type": "string"
- },
- "data": {
- "examples": [
- {
- "message": "Hello lobby!"
- }
- ],
- "type": "object",
- "properties": {
- "message": {
- "maxLength": 300,
- "type": "string"
- }
- },
- "required": [
- "message"
- ]
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "data"
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "request",
- "messageId": "ullamco",
- "commandId": "lobby/sendMessage",
- "data": {
- "message": "Hello lobby!"
- }
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface LobbySendMessageRequest {
- type: "request";
- messageId: string;
- commandId: "lobby/sendMessage";
- data: {
- message: string;
- };
-}
-```
-### Response
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.sendMessage.response",
- "scopes": [
- "tachyon.lobby"
- ],
- "anyOf": [
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/sendMessage",
- "type": "string"
- },
- "status": {
- "const": "success",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/sendMessage",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "not_in_lobby",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/sendMessage",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "muted",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/sendMessage",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "internal_error",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/sendMessage",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "unauthorized",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/sendMessage",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "invalid_request",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/sendMessage",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "command_unimplemented",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- }
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "response",
- "messageId": "exercitation",
- "commandId": "lobby/sendMessage",
- "status": "success"
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface LobbySendMessageResponse {
- type: "response";
- messageId: string;
- commandId: "lobby/sendMessage";
- status: "success";
-}
-```
-Possible Failed Reasons: `not_in_lobby`, `muted`, `internal_error`, `unauthorized`, `invalid_request`, `command_unimplemented`
-
----
-
-## Subscribe
-
-Subscribe to custom battle updates. By default, updates for the user's own battle will always be subscribed to. If successful, the Tachyon server should respond with full data about the subscribed battles, and then continue to send partial (stateful) updates via the [updated](#updated) response.
-
-- Endpoint Type: **Request** -> **Response**
-- Source: **User**
-- Target: **Server**
-- Requires Role: `tachyon.lobby`
-
-### Request
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.subscribe.request",
- "scopes": [
- "tachyon.lobby"
- ],
- "type": "object",
- "properties": {
- "type": {
- "const": "request",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/subscribe",
- "type": "string"
- },
- "data": {
- "type": "object",
- "properties": {
- "battleIds": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- },
- "required": [
- "battleIds"
- ]
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "data"
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "request",
- "messageId": "Ut velit",
- "commandId": "lobby/subscribe",
- "data": {
- "battleIds": [
- "Ut velit",
- "Ut velit"
- ]
- }
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface LobbySubscribeRequest {
- type: "request";
- messageId: string;
- commandId: "lobby/subscribe";
- data: {
- battleIds: string[];
- };
-}
-```
-### Response
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.subscribe.response",
- "scopes": [
- "tachyon.lobby"
- ],
- "anyOf": [
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/subscribe",
- "type": "string"
- },
- "status": {
- "const": "success",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/subscribe",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "internal_error",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/subscribe",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "unauthorized",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/subscribe",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "invalid_request",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/subscribe",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "command_unimplemented",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- }
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "response",
- "messageId": "Ut in",
- "commandId": "lobby/subscribe",
- "status": "success"
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface LobbySubscribeResponse {
- type: "response";
- messageId: string;
- commandId: "lobby/subscribe";
- status: "success";
-}
-```
-Possible Failed Reasons: `internal_error`, `unauthorized`, `invalid_request`, `command_unimplemented`
-
----
-
-## Unsubscribe
-
-Unsubscribe from custom battle updates. If battleIds is passed only updates to those battles will be stopped, otherwise this will stop updates for all battles.
-
-- Endpoint Type: **Request** -> **Response**
-- Source: **User**
-- Target: **Server**
-- Requires Role: `tachyon.lobby`
-
-### Request
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.unsubscribe.request",
- "scopes": [
- "tachyon.lobby"
- ],
- "type": "object",
- "properties": {
- "type": {
- "const": "request",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/unsubscribe",
- "type": "string"
- },
- "data": {
- "type": "object",
- "properties": {
- "battleIds": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- }
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "data"
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "request",
- "messageId": "aliqua in",
- "commandId": "lobby/unsubscribe",
- "data": {
- "aliquac": -56000000
- }
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface LobbyUnsubscribeRequest {
- type: "request";
- messageId: string;
- commandId: "lobby/unsubscribe";
- data: {
- battleIds?: string[];
- };
-}
-```
-### Response
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.unsubscribe.response",
- "scopes": [
- "tachyon.lobby"
- ],
- "anyOf": [
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/unsubscribe",
- "type": "string"
- },
- "status": {
- "const": "success",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/unsubscribe",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "cannot_unsub_own_battle",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/unsubscribe",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "internal_error",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/unsubscribe",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "unauthorized",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/unsubscribe",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "invalid_request",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- },
- {
- "type": "object",
- "properties": {
- "type": {
- "const": "response",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/unsubscribe",
- "type": "string"
- },
- "status": {
- "const": "failed",
- "type": "string"
- },
- "reason": {
- "const": "command_unimplemented",
- "type": "string"
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "status",
- "reason"
- ]
- }
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "response",
- "messageId": "magna commodo",
- "commandId": "lobby/unsubscribe",
- "status": "success"
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface LobbyUnsubscribeResponse {
- type: "response";
- messageId: string;
- commandId: "lobby/unsubscribe";
- status: "success";
-}
-```
-Possible Failed Reasons: `cannot_unsub_own_battle`, `internal_error`, `unauthorized`, `invalid_request`, `command_unimplemented`
-
----
-
-## Updated
-
-Server sends an array of partial battle objects whenever a subscribed battle changes in some way.
-
-- Endpoint Type: **Event**
-- Source: **Server**
-- Target: **User**
-- Requires Role: `tachyon.lobby`
-
-### Event
-
-
-JSONSchema
-
-```json
-{
- "$id": "lobby.updated.event",
- "scopes": [
- "tachyon.lobby"
- ],
- "type": "object",
- "properties": {
- "type": {
- "const": "event",
- "type": "string"
- },
- "messageId": {
- "type": "string"
- },
- "commandId": {
- "const": "lobby/updated",
- "type": "string"
- },
- "data": {
- "type": "object",
- "properties": {
- "battles": {
- "type": "array",
- "items": {
- "examples": [
- {
- "title": "3v3 | Newbies only",
- "limits": {
- "minTeamsize": 3,
- "maxTeamsize": 3,
- "minRating": null,
- "maxRating": 25
- }
- }
- ],
- "allOf": [
- {
- "type": "object",
- "properties": {}
- },
- {
- "type": "object",
- "properties": {
- "title": {
- "type": "string"
- },
- "locked": {
- "type": "boolean"
- },
- "passworded": {
- "type": "boolean"
- },
- "bossIds": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "joinQueueIds": {
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "limits": {
- "type": "object",
- "properties": {
- "minTeamsize": {
- "anyOf": [
- {
- "type": "integer"
- },
- {
- "type": "null"
- }
- ]
- },
- "maxTeamsize": {
- "anyOf": [
- {
- "type": "integer"
- },
- {
- "type": "null"
- }
- ]
- },
- "minRating": {
- "anyOf": [
- {
- "type": "integer"
- },
- {
- "type": "null"
- }
- ]
- },
- "maxRating": {
- "anyOf": [
- {
- "type": "integer"
- },
- {
- "type": "null"
- }
- ]
- }
- },
- "required": [
- "minTeamsize",
- "maxTeamsize",
- "minRating",
- "maxRating"
- ]
- }
- }
- }
- ],
- "type": "object"
- }
- }
- },
- "required": [
- "battles"
- ]
- }
- },
- "required": [
- "type",
- "messageId",
- "commandId",
- "data"
- ]
-}
-```
-
-
-
-Example
-
-```json
-{
- "type": "event",
- "messageId": "id ea",
- "commandId": "lobby/updated",
- "data": {
- "battles": [
- {
- "title": "3v3 | Newbies only",
- "limits": {
- "minTeamsize": 3,
- "maxTeamsize": 3,
- "minRating": null,
- "maxRating": 25
- }
- },
- {
- "title": "3v3 | Newbies only",
- "limits": {
- "minTeamsize": 3,
- "maxTeamsize": 3,
- "minRating": null,
- "maxRating": 25
- }
- }
- ]
- }
-}
-```
-
-
-#### TypeScript Definition
-```ts
-export interface LobbyUpdatedEvent {
- type: "event";
- messageId: string;
- commandId: "lobby/updated";
- data: {
- battles: ({} & {
- title?: string;
- locked?: boolean;
- passworded?: boolean;
- bossIds?: string[];
- joinQueueIds?: string[];
- limits?: {
- minTeamsize: number | null;
- maxTeamsize: number | null;
- minRating: number | null;
- maxRating: number | null;
- };
- })[];
- };
-}
-```
diff --git a/package.json b/package.json
index fd65403..62b8e4d 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,7 @@
"scripts": {
"dev": "nodemon --watch src/** --ext ts --ignore src/meta.ts --exec npm run build",
"build": "npx tsx src/index.ts",
+ "build:clean": "rm -rf dist schema docs/schema && npm run build",
"tidy": "npm run lint && npm run format",
"lint": "eslint . --ext .ts --fix",
"format": "prettier --write .",