Newer
Older
import DataChannel from "./networking/DataChannel.js";
import Signaler from "./networking/Signaler.js";

Ben Eltschig
committed
/**
* Client/endpoint that manages a connection to a SkribblServer
*/
export default class SkribblClient {
/**
* Constructs a new client for a given game ID or DataChannel.
* @param {string|DataChannel} idOrDataChannel
*/
constructor(idOrDataChannel){

Ben Eltschig
committed
/** @type {string[]} */
this._players = [];
/** @type {((players:string[])=>void)[]} */
this._onPlayersListChangeCallbacks = [];
this._readyPromise = (async()=>{
this._dataChannel = idOrDataChannel instanceof DataChannel?idOrDataChannel:await Signaler.join(idOrDataChannel);
await this._dataChannel.waitUntilReady();
this._dataChannel.onMessage(message=>{
console.log(`message from server: "${message}"`);

Ben Eltschig
committed
if (message.startsWith("players add ")){
let name = message.split(" ").slice(2).join(" ");
this._players.push(name);
this._onPlayersListChangeCallbacks.forEach(callback=>callback(this._players));
}else if(message.startsWith("players list ")){
let json = message.split(" ").slice(2).join(" ");
this._players = JSON.parse(json);
this._onPlayersListChangeCallbacks.forEach(callback=>callback(this._players));
}
});
})();
}
/**
* Waits until the connection to the server is ready.
*/
async waitUntilReady(){
return this._readyPromise;
}

Ben Eltschig
committed
/**
* Joins the game with the given name.
* @param {string} name
*/
async join(name){
this._dataChannel.send(`join ${name}`);
let message = await this._dataChannel.next();
if (message!=="yup"){
throw new Error(`Failed to join! Server response: "${message}"`);
}
}
/**
* Registers a callback whenever the list of players in the game changes, and once when it is registered.
* @param {(players:string[])=>void} callback
*/
onPlayersListChange(callback){
this._onPlayersListChangeCallbacks.push(callback);
callback(this._players);
}