@game-vir/multiplayer
Version:
Client side definitions and types for @game-vir/multiplayer-server
214 lines (213 loc) • 8.78 kB
TypeScript
import { type JsonCompatibleValue, type MaybePromise, type PartialWithUndefined, type Uuid } from '@augment-vir/common';
import { type RequireExactlyOne } from 'type-fest';
import { ListenTarget } from 'typed-event-target';
import { type MultiplayerApi } from '../multiplayer-service/multiplayer-api.js';
import { type MultiplayerService } from '../multiplayer-service/multiplayer-service.js';
import { MultiplayerWebSocketMessageType } from './web-rtc-communication.js';
declare const WebrtcMultiplayerMessageEvent_base: (new (eventInitDict: {
bubbles?: boolean;
cancelable?: boolean;
composed?: boolean;
detail: any;
}) => import("typed-event-target").TypedCustomEvent<any, "webrtc-multiplayer-message">) & Pick<{
new (type: string, eventInitDict?: EventInit): Event;
prototype: Event;
readonly NONE: 0;
readonly CAPTURING_PHASE: 1;
readonly AT_TARGET: 2;
readonly BUBBLING_PHASE: 3;
}, "prototype" | "NONE" | "CAPTURING_PHASE" | "AT_TARGET" | "BUBBLING_PHASE"> & Pick<import("typed-event-target").TypedCustomEvent<any, "webrtc-multiplayer-message">, "type">;
/**
* An event that is omitted from {@link WebrtcController} when a WebRTC message is received.
*
* @category Internal
*/
export declare class WebrtcMultiplayerMessageEvent<MessageData extends JsonCompatibleValue> extends WebrtcMultiplayerMessageEvent_base {
readonly sourceClientId: Uuid;
detail: MessageData;
constructor(sourceClientId: Uuid, detail: MessageData);
}
/**
* Type for data in {@link WebrtcMultiplayerConnectionUpdateEvent}.
*
* @category Internal
*/
export type MultiplayerConnectionUpdate = RequireExactlyOne<{
newHost: Uuid;
newMember: Uuid;
lostHost: Uuid;
lostMember: Uuid;
}>;
declare const WebrtcMultiplayerConnectionUpdateEvent_base: (new (eventInitDict: {
bubbles?: boolean;
cancelable?: boolean;
composed?: boolean;
detail: import("type-fest/source/require-exactly-one.js")._RequireExactlyOne<{
newHost: Uuid;
newMember: Uuid;
lostHost: Uuid;
lostMember: Uuid;
}, "newHost" | "newMember" | "lostHost" | "lostMember">;
}) => import("typed-event-target").TypedCustomEvent<import("type-fest/source/require-exactly-one.js")._RequireExactlyOne<{
newHost: Uuid;
newMember: Uuid;
lostHost: Uuid;
lostMember: Uuid;
}, "newHost" | "newMember" | "lostHost" | "lostMember">, "webrtc-multiplayer-connection-update">) & Pick<{
new (type: string, eventInitDict?: EventInit): Event;
prototype: Event;
readonly NONE: 0;
readonly CAPTURING_PHASE: 1;
readonly AT_TARGET: 2;
readonly BUBBLING_PHASE: 3;
}, "prototype" | "NONE" | "CAPTURING_PHASE" | "AT_TARGET" | "BUBBLING_PHASE"> & Pick<import("typed-event-target").TypedCustomEvent<import("type-fest/source/require-exactly-one.js")._RequireExactlyOne<{
newHost: Uuid;
newMember: Uuid;
lostHost: Uuid;
lostMember: Uuid;
}, "newHost" | "newMember" | "lostHost" | "lostMember">, "webrtc-multiplayer-connection-update">, "type">;
/**
* An event that is omitted from {@link WebrtcMultiplayerController} when the multiplayer room host
* is updated.
*
* @category Internal
*/
export declare class WebrtcMultiplayerConnectionUpdateEvent extends WebrtcMultiplayerConnectionUpdateEvent_base {
}
/**
* A helper for creating a new empty room.
*
* @category Internal
*/
export declare function createNewRoom(params?: Readonly<PartialWithUndefined<Omit<RoomInput, 'roomId'>>>): RoomInput;
/**
* Room selection input for {@link WebrtcMultiplayerController}.
*
* @category Internal
*/
export type RoomInput = Pick<Extract<MultiplayerService['webSockets']['/connect']['MessageFromClientType'], {
type: MultiplayerWebSocketMessageType.Offer;
}>, 'roomPassword' | 'roomId' | 'roomName'>;
/**
* This is used to check if a new WebRTC connection should be allowed. This will only be triggered
* on a room host client. Return `true`
*
* @category Internal
*/
export type ShouldAllowConnectionCheck<Controller> = (data: {
connectingClientId: Uuid;
controller: Controller;
}) => MaybePromise<boolean>;
/**
* A controller that connects to the multiplayer api and establishes a WebRTC connection to the
* selected room, or, if the room does not exist yet, creates the room and becomes the host.
*
* Make sure, after constructing this class, to call
* {@link WebrtcMultiplayerController.initConnection} when you're ready to being the connection.
*
* @category Internal
*/
export declare class WebrtcMultiplayerController<MessageData extends JsonCompatibleValue = any> extends ListenTarget<WebrtcMultiplayerMessageEvent<MessageData> | WebrtcMultiplayerConnectionUpdateEvent> {
private readonly gameId;
private readonly multiplayerApi;
/**
* - 'stun.l.google.com:19302'
* - 'stun.stunprotocol.org'
* - 'stun.cloudflare.com:3478'
*/
readonly stunServerUrls: ReadonlyArray<string>;
readonly multiplayerRoom: Readonly<RoomInput>;
/** The randomized client id for this controller and client. */
readonly clientId: Uuid;
/**
* This is fired when a WebRTC peer attempts to connect to the host client (this will only
* be fired if your client is the host). Return `true` to accept the connection. Return
* `false` to reject it.
*
* @default accept all connections
*/
private readonly shouldAllowConnectionCheck;
readonly hostClientId: Uuid | undefined;
/**
* Connections between multiple WebRTC peers.
*
* A connection with the current client's id is the init connection.
*/
private connections;
private webSocket;
private readonly clientSecret;
readonly isDestroyed: boolean;
constructor(gameId: string, multiplayerApi: Readonly<MultiplayerApi>,
/**
* - 'stun.l.google.com:19302'
* - 'stun.stunprotocol.org'
* - 'stun.cloudflare.com:3478'
*/
stunServerUrls: ReadonlyArray<string>, multiplayerRoom: Readonly<RoomInput>,
/** The randomized client id for this controller and client. */
clientId?: Uuid,
/**
* This is fired when a WebRTC peer attempts to connect to the host client (this will only
* be fired if your client is the host). Return `true` to accept the connection. Return
* `false` to reject it.
*
* @default accept all connections
*/
shouldAllowConnectionCheck?: ShouldAllowConnectionCheck<WebrtcMultiplayerController<MessageData>>);
/**
* If this controller is the host, it'll behave differently:
*
* - Hosts hold WebRTC connections to all clients (non-hosts only hold a WebRTC connection to the
* host).
* - Hosts hold a WebSocket connection to the signal server so they can receive more clients at
* any time.
*/
isHost(): boolean;
/**
* Get all connected client ids.
*
* - For host clients, this will indicate how many member clients are connected to the host
* client, _not_ including the host itself.
* - For non-host clients, this will only list the host's client.
*
* For host clients, this does ont include the host client id whereas
* {@link WebrtcMultiplayerController.getAllClientIds} does.
*/
getConnectedClientIds(): Uuid[];
/**
* Get all room client ids.
*
* - For host clients, this will indicate how many clients are connected to the room, including
* the host client itself.
* - For non-host clients, this will only list the host's client.
*
* For host clients, this includes the host client id whereas
* {@link WebrtcMultiplayerController.getConnectedClientIds} does not.
*/
getAllClientIds(): Uuid[];
/** Indicates whether ths client is connected to a multiplayer room. */
isConnected(): boolean;
/** Destroy this controller and clean everything up. */
destroy(): void;
/**
* Send a message to the room participants.
*
* - If the current client is the room host, this message is sent to all other room clients.
* - If the current client is just a room member (not the host), the message is sent to the host.
*/
sendMessage(data: Readonly<MessageData>): void;
/** Send a message to just a single client. This is only allowed on a host client. */
sendToOnlyOneClient(clientId: Uuid, data: Readonly<MessageData>): void;
/**
* Call this to connect to the multiplayer server.
*
* @returns Whether or not the connection was initialized (it won't be initialized, for example,
* if the WebRTC connections already exist).
*/
initConnection(): Promise<boolean>;
private sendHostPing;
private connectionQueue;
private setupWebSocket;
private createNewConnection;
}
export {};