Skip to content
Snippets Groups Projects
SkribblServer.js 1.9 KiB
Newer Older
import DataChannel from "./networking/DataChannel.js";
import Signaler from "./networking/Signaler.js";

/**
 * A local server. Handles all the important game logic, and communicates with clients via DataChannels.
 */
export default class SkribblServer {
	/**
	 * Starts a new SkribblServer.
	 */
	constructor(){
		this._readyPromise = (async()=>{
			/** @type {{name:string,dataChannel:DataChannel}[]} */
			this._clients = [];
			this._id = await Signaler.host(dataChannel=>{
				this.connect(dataChannel);
			});
			let [endpointA,endpointB] = DataChannel.createPair();
			this._dataChannel = endpointA;
			this.connect(endpointB);
		})();
	}

	/**
	 * Waits until the server is ready.
	 */
	async waitUntilReady(){
		return this._readyPromise;
	}

	/**
	 * A dataChannel talking to this server like any other client.
	 * @readonly
	 */
	get dataChannel(){
		return this._dataChannel;
	}

	/**
	 * The ID others can use to connect to this server.
	 * @readonly
	 */
	get id(){
		return this._id;
	}

	/**
	 * Returns the full url others can use to connect to this server.
	 * @readonly
	 */
	get url(){
		return document.location.host+document.location.pathname+"#"+this._id;
	}

	/**
	 * Adds an incoming connection as a client.
	 * @param {DataChannel} dataChannel
	 */
	connect(dataChannel){
		(async()=>{
			let message = await dataChannel.next();
			console.log("message: ",message);
			if (message.startsWith("join ")){
				let name = message.split(" ").slice(1).join(" ");
				if (name.length<30&&name.length>=1){
					dataChannel.send("yup");
					this._clients.forEach(({dataChannel})=>{
						dataChannel.send("players add "+name);
					});
					this._clients.push({name,dataChannel});
					dataChannel.send("players list "+JSON.stringify(this._clients.map(({name})=>name)))
				}else{
					dataChannel.send("nope");
					dataChannel.close();
				}
			}else{
				dataChannel.send("nope");
				dataChannel.close();
			}
		})();