diff options
Diffstat (limited to 'src/routers/tmwa/index.js')
-rw-r--r-- | src/routers/tmwa/index.js | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/routers/tmwa/index.js b/src/routers/tmwa/index.js new file mode 100644 index 0000000..52d241f --- /dev/null +++ b/src/routers/tmwa/index.js @@ -0,0 +1,61 @@ +const express = require("express"); // from npm registry +const fs = require("fs"); // built-in +const poll_symbol = Symbol("TMWA.poll"); // private method + +const middlewares = { + account: require("./middlewares/account.js"), + server: require("./middlewares/server.js"), +}; + +module.exports = exports = class TMWA { + constructor(config, api, challenge, rate_limit) { + // XXX: having to pass a reference to `api` is weird, we should instead + // store config in this.config and make the middlewares (somehow) + // access this.config. the problem is that we can't pass arguments + // to middlewares, so we might have to curry them + + this.api = api; + this.api.locals.tmwa = config; + this.api.locals.tmwa.status = "OfflineTemporarily"; // XXX: storing these in the class feels wrong, I don't think it should be exported... maybe we could use some more curry? + this.api.locals.tmwa.num_online = 0; + this.timeout = null; + this.router = express.Router(["caseSensitive", "strict"]); + + this.router.get("/server", middlewares.server); + + this.router.all("/account", rate_limit); // filter out the flood + this.router.all("/account", challenge); // require a captcha + this.router.use("/account", express.json()); // parse the body as json + this.router.post("/account", middlewares.account); + + tmwa_poll(this); // first heartbeat + + console.info("Loaded TMWA router"); + return this.router; + } +}; + +const tmwa_poll = (_this) => { + fs.readFile("./online.txt", "utf8", (err, data) => { + const lines = data.split("\n"); + + if (err || lines.length < 2) { + console.error("encountered an error while retrieving online.txt", err); + _this.timeout = setTimeout(() => tmwa_poll(_this), 30000); // <= it failed, so check again later + return; + } + + const last_online = Date.parse(lines[0].match(/\((.+)\)/)[1] + ` ${_this.api.locals.tmwa.timezone}`); + + if (Date.now() - last_online < 30000) { + const num = lines[lines.length - 2].match(/([0-9]+) users are online./); + _this.api.locals.tmwa.status = "Online"; + _this.api.locals.tmwa.num_online = num ? num[1] : 0; + } else { + _this.api.locals.tmwa.status = "OfflineTemporarily"; + _this.api.locals.tmwa.num_online = 0; + } + + _this.timeout = setTimeout(() => tmwa_poll(_this), 2000); + }); +}; |