tiny-matchmaking
Version:
Tiny matchmaking server.
168 lines (167 loc) • 7.64 kB
JavaScript
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MatchMakingServer = void 0;
var ws_1 = require("ws");
var MatchMakingServer = /** @class */ (function () {
function MatchMakingServer(_port, _is_match, _results_func, _options) {
var _this = this;
this.pool = new Map();
this.port = _port;
this.allowed_clients = (_options === null || _options === void 0 ? void 0 : _options.allowed_clients) ? _options.allowed_clients : null;
this.disallowed_clients = (_options === null || _options === void 0 ? void 0 : _options.disallowed_clients) ? _options.disallowed_clients : null;
this.queue_time = (_options === null || _options === void 0 ? void 0 : _options.queue_time) ? _options.queue_time : 20000;
this.poll_interval = (_options === null || _options === void 0 ? void 0 : _options.poll_interval) ? _options.poll_interval : 1000;
this.wss = new ws_1.Server(!(_options === null || _options === void 0 ? void 0 : _options.https_server)
? { port: _port }
: { server: _options.https_server, port: _port });
this.is_match = _is_match;
this.results_func = _results_func ? _results_func : null;
this.start();
setInterval(function () { return _this.match_make(); }, this.poll_interval);
}
MatchMakingServer.prototype.start = function () {
var _this = this;
this.wss.on('connection', function (ws, req) {
var _a, _b;
var ip = req.socket.remoteAddress ? req.socket.remoteAddress.slice(7) : '';
console.log('received connection from: ' + ip);
if (!ip || (_this.allowed_clients && !((_a = _this.allowed_clients) === null || _a === void 0 ? void 0 : _a.includes(ip)))) {
console.log("unauthorised IP: " + (ip ? ip : '(no ip)'));
ws.close();
return;
}
if (_this.disallowed_clients && ((_b = _this.disallowed_clients) === null || _b === void 0 ? void 0 : _b.includes(ip))) {
console.log("unauthorised IP: " + ip);
ws.close();
return;
}
//receive player info
ws.on('message', function (message) {
var new_item = __assign({ socket: ws, time_joined: Date.now() }, JSON.parse(message.toString()));
// add player to pool if they are not already in pool
if (!_this.pool.has(new_item.id)) {
_this.pool.set(new_item.id, new_item);
}
else {
ws.close();
}
});
});
console.log("MatchMaking Server running on port " + this.port);
};
MatchMakingServer.prototype.match_make = function () {
var e_1, _a, e_2, _b;
if (this.pool.size < 1) {
return;
}
try {
for (var _c = __values(this.pool), _d = _c.next(); !_d.done; _d = _c.next()) {
var _e = __read(_d.value, 2), A = _e[0], p1 = _e[1];
try {
for (var _f = (e_2 = void 0, __values(this.pool)), _g = _f.next(); !_g.done; _g = _f.next()) {
var _h = __read(_g.value, 2), B = _h[0], p2 = _h[1];
if (p1.id !== p2.id && this.is_match(p1, p2)) {
var a = this.pool.get(A);
var b = this.pool.get(B);
if (a && b) {
console.log("MATCH FOUND: " + a.id + " vs " + b.id);
if (!this.results_func) {
var a_res = remove_socket(a);
var b_res = remove_socket(b);
a.socket.send(JSON.stringify({ client: __assign({}, a_res), opponent: __assign({}, b_res) }));
b.socket.send(JSON.stringify({ client: __assign({}, b_res), opponent: __assign({}, a_res) }));
}
else {
var res = this.results_func(a, b);
a.socket.send(JSON.stringify(res));
b.socket.send(JSON.stringify(res));
}
a.socket.close();
b.socket.close();
this.pool.delete(A);
this.pool.delete(B);
}
}
else {
var b = this.pool.get(B);
if (b && Date.now() - b.time_joined > this.queue_time) {
console.log(b.id + " timed out of queue.");
b.socket.close();
this.pool.delete(B);
}
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
}
finally { if (e_2) throw e_2.error; }
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
}
finally { if (e_1) throw e_1.error; }
}
};
return MatchMakingServer;
}());
exports.MatchMakingServer = MatchMakingServer;
var remove_socket = function (x) {
var socket = x.socket, a = __rest(x, ["socket"]);
return a;
};