@hp4k1h5/terminordle
Version:
> multiplayer [wordle](https://www.powerlanguage.co.uk/wordle/) clone in your terminal
129 lines (128 loc) • 3.94 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.userId = exports.createWSS = void 0;
const fs = require("fs");
const path = require("path");
const https_1 = require("https");
const dotenv = require("dotenv");
const p = path.resolve(__dirname, '../../../../.env');
dotenv.config({ path: p });
const ws_1 = require("ws");
const structs_1 = require("../../lib/structs");
const msg_1 = require("./msg");
const session_1 = require("./session");
const util_1 = require("../../util");
const server = process.env.NODE_ENV === 'production'
? (0, https_1.createServer)({
key: fs.readFileSync('' + process.env.SSL_KEY_PATH),
cert: fs.readFileSync('' + process.env.SSL_FULLCHAIN_PATH),
})
: null;
const msgTypeToFn = {
create: session_1.createSession,
join: session_1.join,
guess: session_1.guess,
again: session_1.again,
};
const MAX_CNX = 1000;
function createWSS(port = 8080, host = 'localhost', log) {
const opts = {
host,
backlog: 100,
maxPayload: 256,
clientTracking: true,
...(server ? { server } : { port }),
};
const wss = new ws_1.WebSocketServer(opts);
wss.on('error', function (e) {
log && log.log({ err: e.toString() });
});
// heartbeat
const cycle = setInterval(function () {
wss.clients.forEach((client) => {
if (client.is_alive === false) {
(0, session_1.remove)(client);
return;
}
// reset
client.is_alive = false;
client.ping();
});
}, 30000);
wss.on('close', function close() {
clearInterval(cycle);
});
wss.on('connection', function (cnx) {
if (wss.clients.size >= MAX_CNX) {
(0, msg_1.err)(cnx, `overload : ${cnx}`, log);
cnx.close();
return;
}
cnx.on('error', e => {
log && log.log({ err: e.toString(), user_id: cnx.user_id });
});
cnx.on('close', function () {
(0, session_1.remove)(cnx, log);
});
cnx.on('pong', heartbeat);
cnx.on('message', function (data) {
let message;
try {
message = (0, msg_1.validateMsg)(cnx, data);
}
catch (e) {
(0, msg_1.msg)(cnx, { type: structs_1.ClientMsgType.error, content: 'bad message' });
(0, msg_1.err)(cnx, e, log);
return;
}
let response;
try {
response = msgTypeToFn[message.type](cnx, message, log);
}
catch (e) {
(0, msg_1.err)(cnx, e, log);
return;
}
response && (0, msg_1.msg)(cnx, response);
});
try {
cnx.user_id = userId();
}
catch (e) {
(0, msg_1.err)(cnx, e, log);
(0, session_1.remove)(cnx);
return;
}
log && log.log({ connection: 'established', with: cnx.user_id });
// send user id back
(0, msg_1.msg)(cnx, {
type: structs_1.ClientMsgType.user_id,
content: cnx.user_id,
user_id: cnx.user_id,
});
});
// ssl support
server && server.listen(port);
return wss;
}
exports.createWSS = createWSS;
function heartbeat() {
this.is_alive = true;
return heartbeat;
}
const nameList = Object.keys(util_1.names);
function userId() {
let attempts = 0;
const MAX_ATTEMPTS = 10;
const _nameList = nameList.filter(name => util_1.names[name] === false);
let name;
while (!name && attempts++ < MAX_ATTEMPTS) {
name = (0, util_1.getRand)(_nameList);
// double check names
if (util_1.names[name] === false) {
util_1.names[name] = true;
return name;
}
}
}
exports.userId = userId;