#!/usr/bin/env node const net = require("net"); const util = require("util"); if (process.argv.length != 4) { console.log("Usage: ./main.js "); console.log("Pass address of doomrooms server as arguments."); process.exit(1); } const GAME_ID = "tictactoe-tom"; const GAME_NAME = "Tic Tac Toe"; { let id = 0; function uniqid() { return id++; } } function lineReader(conn, lineCb) { let buffer = ""; conn.on("data", (data) => { buffer += data.toString(); let idx = buffer.indexOf("\n"); while (idx != -1) { lineCb(buffer.slice(0, idx)); buffer = buffer.slice(idx + 1); idx = buffer.indexOf("\n"); } }); } class Message { constructor(/*...*/) { if (typeof arguments[0] == "number") this.makeReply(...arguments); else this.makeCommand(...arguments); } makeCommand(method, ...args) { this.isCommand = true; this.method = method; this.args = args; this.id = uniqid(); } makeReply(id, res, err) { this.isCommand = false; this.id = id; this.res = res; this.err = err; } toJSON() { if (this.isCommand) { return JSON.stringify({ method: this.method, args: this.args, id: this.id, }); } else { return JSON.stringify({ res: this.res, err: this.err, id: this.id, }); } } } class Connection { constructor(conn, msgCb) { this.conn = conn; lineReader(conn, (line) => { let obj; try { obj = JSON.parse(line); } catch (e) { console.log("Invalid JSON received: " + line); return; } if (obj.res || obj.err) { const msg = new Message(obj.id, obj.res, obj.err); if (this.replyHandlers[msg.id]) { this.replyHandlers[msg.id](msg); this.replyHandlers[msg.id] = null; } else { console.log("Reply for unexpected message id " + msg.id); } } else { msgCb(new Message(obj.method, ...obj.args)); } }); this.replyHandlers = {}; } send(msg, replyCb) { const data = msg.toJSON(); console.log("Writing to conn: " + data); this.conn.write(data + "\n"); if (replyCb && msg.isCommand) { this.replyHandlers[msg.id] = replyCb; } } } function messageHandler(msg) { console.log("Message: " + util.inspect(msg)); } const conn = new Connection(net.createConnection(+process.argv[3], process.argv[2]), messageHandler); conn.conn.on("connect", () => { console.log("Connected to roomserver"); conn.conn.on("end", () => { console.log("Connection with roomserver unexpectedly closed!"); }); setInterval(() => { conn.send(new Message("ping"), (msg) => console.log("Ping reply: " + util.inspect(msg))); }, 30000); conn.send(new Message("make-game", GAME_ID, GAME_NAME), (msg) => console.log(msg)); });