diff options
-rwxr-xr-x | main.js | 126 | ||||
-rw-r--r-- | package.json | 11 |
2 files changed, 137 insertions, 0 deletions
@@ -0,0 +1,126 @@ +#!/usr/bin/env node + +const net = require("net"); +const util = require("util"); + +if (process.argv.length != 4) { + console.log("Usage: ./main.js <hostname> <port>"); + 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)); +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000..c13ac27 --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "name": "doomrooms-ttt", + "version": "0.1.0", + "description": "", + "main": "main.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "MIT" +} |