Remove
This commit is contained in:
parent
cb75504365
commit
4d876c6160
27
index.js
27
index.js
|
@ -1,27 +0,0 @@
|
||||||
//call new Server
|
|
||||||
global.WebSocket = require('ws');
|
|
||||||
global.EventEmitter = require('events').EventEmitter;
|
|
||||||
global.fs = require('fs');
|
|
||||||
global.createKeccakHash = require('keccak');
|
|
||||||
const AsyncConsole = require('asyncconsole')
|
|
||||||
|
|
||||||
global.isString = function(a){
|
|
||||||
return typeof a === 'string';
|
|
||||||
}
|
|
||||||
global.isBool = function(a){
|
|
||||||
return typeof a === 'boolean';
|
|
||||||
}
|
|
||||||
global.isObj = function(a){
|
|
||||||
return typeof a === "object" && !Array.isArray(a) && a !== null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let Server = require("./src/Server");
|
|
||||||
let config = require('./src/db/config');
|
|
||||||
global.SERVER = new Server(config);
|
|
||||||
let console = process.platform == 'win32' ? new AsyncConsole("", input => {
|
|
||||||
try {
|
|
||||||
console.log(JSON.stringify(eval(input)));
|
|
||||||
} catch(e) {
|
|
||||||
console.log(e.toString());
|
|
||||||
}
|
|
||||||
}) : {};
|
|
32
package.json
32
package.json
|
@ -1,32 +0,0 @@
|
||||||
{
|
|
||||||
"name": "mpp-server-master",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "Attempt at making a MPP Server.",
|
|
||||||
"main": "index.js",
|
|
||||||
"scripts": {
|
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/BopItFreak/mpp-server.git"
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"mpp",
|
|
||||||
"server",
|
|
||||||
"multiplayerpiano"
|
|
||||||
],
|
|
||||||
"author": "BopItFreak",
|
|
||||||
"license": "ISC",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/BopItFreak/mpp-server/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://github.com/BopItFreak/mpp-server#readme",
|
|
||||||
"dependencies": {
|
|
||||||
"asyncconsole": "^1.3.9",
|
|
||||||
"events": "^3.0.0",
|
|
||||||
"keccak": "^2.0.0",
|
|
||||||
"node-json-color-stringify": "^1.1.0",
|
|
||||||
"ws": "^7.1.2"
|
|
||||||
},
|
|
||||||
"devDependencies": {}
|
|
||||||
}
|
|
117
src/Client.js
117
src/Client.js
|
@ -1,117 +0,0 @@
|
||||||
const config = require('./db/config');
|
|
||||||
const quotas = config.quotas;
|
|
||||||
const RateLimit = require('./RateLimit.js').RateLimit;
|
|
||||||
const RateLimitChain = require('./RateLimit.js').RateLimitChain;
|
|
||||||
const Room = require("./Room.js");
|
|
||||||
require('node-json-color-stringify');
|
|
||||||
class Client extends EventEmitter {
|
|
||||||
constructor(ws, req, server) {
|
|
||||||
super();
|
|
||||||
EventEmitter.call(this);
|
|
||||||
this.user;
|
|
||||||
this.connectionid = server.connectionid;
|
|
||||||
this.server = server;
|
|
||||||
this.participantId;
|
|
||||||
this.channel;
|
|
||||||
this.ws = ws;
|
|
||||||
this.req = req;
|
|
||||||
this.ip = (req.connection.remoteAddress).replace("::ffff:", "");
|
|
||||||
this.destroied = false;
|
|
||||||
this.bindEventListeners();
|
|
||||||
this.quotas = {
|
|
||||||
chat: new RateLimitChain(quotas.chat.amount, quotas.chat.time),
|
|
||||||
name: new RateLimitChain(quotas.name.amount, quotas.name.time),
|
|
||||||
room: new RateLimit(quotas.room.time),
|
|
||||||
cursor: new RateLimit(quotas.cursor.time),
|
|
||||||
kickban: new RateLimitChain(quotas.kickban.amount, quotas.kickban.time),
|
|
||||||
crowned_chat: new RateLimitChain(quotas.crowned_chat.amount, quotas.crowned_chat.time)
|
|
||||||
}
|
|
||||||
require('./Message.js')(this);
|
|
||||||
}
|
|
||||||
isConnected() {
|
|
||||||
return this.ws && this.ws.readyState === WebSocket.OPEN;
|
|
||||||
}
|
|
||||||
isConnecting() {
|
|
||||||
return this.ws && this.ws.readyState === WebSocket.CONNECTING;
|
|
||||||
}
|
|
||||||
setChannel(_id, settings) {
|
|
||||||
if (this.channel && this.channel._id == _id) return;
|
|
||||||
if (this.server.rooms.get(_id)) {
|
|
||||||
let room = this.server.rooms.get(_id);
|
|
||||||
let userbanned = room.bans.get(this.user._id);
|
|
||||||
if (userbanned && (Date.now() - userbanned.bannedtime >= userbanned.msbanned)) {
|
|
||||||
room.bans.delete(userbanned.user._id);
|
|
||||||
userbanned = undefined;
|
|
||||||
}
|
|
||||||
if (userbanned) {
|
|
||||||
console.log(Date.now() - userbanned.bannedtime)
|
|
||||||
room.Notification(this.user._id,
|
|
||||||
"Notice",
|
|
||||||
`Currently banned from \"${_id}\" for ${Math.ceil(Math.floor((userbanned.msbanned - (Date.now() - userbanned.bannedtime)) / 1000) / 60)} minutes.`,
|
|
||||||
7000,
|
|
||||||
"",
|
|
||||||
"#room",
|
|
||||||
"short"
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let channel = this.channel;
|
|
||||||
if (channel) this.channel.emit("bye", this);
|
|
||||||
if (channel) this.channel.updateCh();
|
|
||||||
this.channel = this.server.rooms.get(_id);
|
|
||||||
this.channel.join(this);
|
|
||||||
} else {
|
|
||||||
let room = new Room(this.server, _id, settings);
|
|
||||||
this.server.rooms.set(_id, room);
|
|
||||||
if (this.channel) this.channel.emit("bye", this);
|
|
||||||
this.channel = this.server.rooms.get(_id);
|
|
||||||
this.channel.join(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sendArray(arr) {
|
|
||||||
if (this.isConnected()) {
|
|
||||||
//console.log(`SEND: `, JSON.colorStringify(arr));
|
|
||||||
this.ws.send(JSON.stringify(arr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
destroy() {
|
|
||||||
this.ws.close();
|
|
||||||
if (this.channel) {
|
|
||||||
this.channel.emit("bye", this)
|
|
||||||
}
|
|
||||||
this.user;
|
|
||||||
this.participantId;
|
|
||||||
this.channel;
|
|
||||||
this.server.roomlisteners.delete(this.connectionid);
|
|
||||||
this.connectionid;
|
|
||||||
this.server.connections.delete(this.connectionid);
|
|
||||||
this.destroied = true;
|
|
||||||
console.log(`Removed Connection ${this.connectionid}.`);
|
|
||||||
}
|
|
||||||
bindEventListeners() {
|
|
||||||
this.ws.on("message", (evt, admin) => {
|
|
||||||
try {
|
|
||||||
let transmission = JSON.parse(evt);
|
|
||||||
for (let msg of transmission) {
|
|
||||||
if (!msg.hasOwnProperty("m")) return;
|
|
||||||
if (!this.server.legit_m.includes(msg.m)) return;
|
|
||||||
this.emit(msg.m, msg, !!admin);
|
|
||||||
//console.log(`RECIEVE: `, JSON.colorStringify(msg));
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
this.destroy();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.ws.on("close", () => {
|
|
||||||
if (!this.destroied)
|
|
||||||
this.destroy();
|
|
||||||
});
|
|
||||||
this.ws.addEventListener("error", (err) => {
|
|
||||||
console.error(err);
|
|
||||||
if (!this.destroied)
|
|
||||||
this.destroy();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
module.exports = Client;
|
|
|
@ -1,16 +0,0 @@
|
||||||
function hashCode(str) { // java String#hashCode
|
|
||||||
var hash = 0;
|
|
||||||
for (var i = 0; i < str.length; i++) {
|
|
||||||
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
|
||||||
}
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
function intToRGB(i){
|
|
||||||
var c = (i & 0x00FFFFFF)
|
|
||||||
.toString(16)
|
|
||||||
.toUpperCase();
|
|
||||||
|
|
||||||
return "00000".substring(0, 6 - c.length) + c;
|
|
||||||
}
|
|
||||||
module.exports = {hashCode, intToRGB};
|
|
181
src/Message.js
181
src/Message.js
|
@ -1,181 +0,0 @@
|
||||||
const User = require("./User.js");
|
|
||||||
const Room = require("./Room.js");
|
|
||||||
module.exports = (cl) => {
|
|
||||||
cl.once("hi", () => {
|
|
||||||
let user = new User(cl);
|
|
||||||
user.getUserData().then((data) => {
|
|
||||||
let msg = {};
|
|
||||||
msg.m = "hi";
|
|
||||||
msg.motd = cl.server.welcome_motd;
|
|
||||||
msg.t = Date.now();
|
|
||||||
msg.u = data;
|
|
||||||
msg.v = "Beta";
|
|
||||||
cl.sendArray([msg])
|
|
||||||
cl.user = data;
|
|
||||||
})
|
|
||||||
})
|
|
||||||
cl.on("t", msg => {
|
|
||||||
if (msg.hasOwnProperty("e") && !isNaN(msg.e))
|
|
||||||
cl.sendArray([{
|
|
||||||
m: "t",
|
|
||||||
t: Date.now(),
|
|
||||||
e: msg.e
|
|
||||||
}])
|
|
||||||
})
|
|
||||||
cl.on("ch", msg => {
|
|
||||||
if (!cl.quotas.room.attempt()) return;
|
|
||||||
if (!msg.hasOwnProperty("set") || !msg.set) msg.set = {};
|
|
||||||
if (msg.hasOwnProperty("_id") && typeof msg._id == "string") {
|
|
||||||
if (msg._id.length > 512) return;
|
|
||||||
cl.setChannel(msg._id, msg.set);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
cl.on("m", msg => {
|
|
||||||
if (!cl.quotas.cursor.attempt()) return;
|
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
|
||||||
if (!msg.hasOwnProperty("x")) msg.x = null;
|
|
||||||
if (!msg.hasOwnProperty("y")) msg.y = null;
|
|
||||||
if (parseInt(msg.x) == NaN) msg.x = null;
|
|
||||||
if (parseInt(msg.y) == NaN) msg.y = null;
|
|
||||||
cl.channel.emit("m", cl, msg.x, msg.y)
|
|
||||||
|
|
||||||
})
|
|
||||||
cl.on("chown", msg => {
|
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
|
||||||
//console.log((Date.now() - cl.channel.crown.time))
|
|
||||||
//console.log(!(cl.channel.crown.userId != cl.user._id), !((Date.now() - cl.channel.crown.time) > 15000));
|
|
||||||
if (!(cl.channel.crown.userId == cl.user._id) && !((Date.now() - cl.channel.crown.time) > 15000)) return;
|
|
||||||
if (msg.hasOwnProperty("id")) {
|
|
||||||
// console.log(cl.channel.crown)
|
|
||||||
if (cl.user._id == cl.channel.crown.userId || cl.channel.crowndropped)
|
|
||||||
cl.channel.chown(msg.id);
|
|
||||||
} else {
|
|
||||||
if (cl.user._id == cl.channel.crown.userId || cl.channel.crowndropped)
|
|
||||||
cl.channel.chown();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
cl.on("chset", msg => {
|
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
|
||||||
if (!(cl.user._id == cl.channel.crown.userId)) return;
|
|
||||||
if (!msg.hasOwnProperty("set") || !msg.set) msg.set = cl.channel.verifySet(cl.channel._id,{});
|
|
||||||
cl.channel.settings = msg.set;
|
|
||||||
cl.channel.updateCh();
|
|
||||||
})
|
|
||||||
cl.on("a", msg => {
|
|
||||||
if (cl.channel.isLobby(cl.channel._id)) {
|
|
||||||
if (!cl.quotas.chat.attempt()) return;
|
|
||||||
} else {
|
|
||||||
if (!(cl.user._id == cl.channel.crown.userId)) {
|
|
||||||
if (!cl.quotas.chat.attempt()) return;
|
|
||||||
} else {
|
|
||||||
if (!cl.quotas.crowned_chat.attempt()) return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
|
||||||
if (!msg.hasOwnProperty('message')) return;
|
|
||||||
if (cl.channel.settings.chat) {
|
|
||||||
cl.channel.emit('a', cl, msg);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
cl.on('n', msg => {
|
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
|
||||||
if (!msg.hasOwnProperty('t') || !msg.hasOwnProperty('n')) return;
|
|
||||||
if (typeof msg.t != 'number' || typeof msg.n != 'object') return;
|
|
||||||
if (cl.channel.settings.crownsolo) {
|
|
||||||
if ((cl.channel.crown.userId == cl.user._id) && !cl.channel.crowndropped) {
|
|
||||||
cl.channel.playNote(cl, msg);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cl.channel.playNote(cl, msg);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
cl.on('+ls', msg => {
|
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
|
||||||
cl.server.roomlisteners.set(cl.connectionid, cl);
|
|
||||||
let rooms = [];
|
|
||||||
for (let room of Array.from(cl.server.rooms.values())) {
|
|
||||||
let data = room.fetchData().ch;
|
|
||||||
if (room.bans.get(cl.user._id)) {
|
|
||||||
data.banned = true;
|
|
||||||
}
|
|
||||||
if (room.settings.visible) rooms.push(data);
|
|
||||||
}
|
|
||||||
cl.sendArray([{
|
|
||||||
"m": "ls",
|
|
||||||
"c": true,
|
|
||||||
"u": rooms
|
|
||||||
}])
|
|
||||||
})
|
|
||||||
cl.on('-ls', msg => {
|
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
|
||||||
cl.server.roomlisteners.delete(cl.connectionid);
|
|
||||||
})
|
|
||||||
cl.on("userset", msg => {
|
|
||||||
if (!cl.quotas.name.attempt()) return;
|
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
|
||||||
if (!msg.hasOwnProperty("set") || !msg.set) msg.set = {};
|
|
||||||
if (msg.set.hasOwnProperty('name') && typeof msg.set.name == "string") {
|
|
||||||
if (msg.set.name.length > 40) return;
|
|
||||||
cl.user.name = msg.set.name;
|
|
||||||
let user = new User(cl);
|
|
||||||
user.getUserData().then((usr) => {
|
|
||||||
let dbentry = user.userdb.get(cl.user._id);
|
|
||||||
if (!dbentry) return;
|
|
||||||
dbentry.name = msg.set.name;
|
|
||||||
user.updatedb();
|
|
||||||
cl.server.rooms.forEach((room) => {
|
|
||||||
room.updateParticipant(cl.participantId, {
|
|
||||||
name: msg.set.name
|
|
||||||
});
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
||||||
cl.on('kickban', msg => {
|
|
||||||
if (!cl.quotas.kickban.attempt()) return;
|
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
|
||||||
if (!(cl.user._id == cl.channel.crown.userId)) return;
|
|
||||||
if (msg.hasOwnProperty('_id') && typeof msg._id == "string") {
|
|
||||||
let _id = msg._id;
|
|
||||||
let ms = msg.ms || 0;
|
|
||||||
cl.channel.kickban(_id, ms);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
cl.on("bye", msg => {
|
|
||||||
cl.destroy();
|
|
||||||
})
|
|
||||||
cl.on("admin message", msg => {
|
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
|
||||||
if (!msg.hasOwnProperty('password') || !msg.hasOwnProperty('msg')) return;
|
|
||||||
if (typeof msg.msg != 'object') return;
|
|
||||||
if (msg.password !== cl.server.adminpass) return;
|
|
||||||
cl.ws.emit("message", JSON.stringify([msg.msg]), true);
|
|
||||||
})
|
|
||||||
//admin only stuff
|
|
||||||
cl.on('color', (msg, admin) => {
|
|
||||||
if (!admin) return;
|
|
||||||
if (typeof cl.channel.verifyColor(msg.color) != 'string') return;
|
|
||||||
if (!msg.hasOwnProperty('id') && !msg.hasOwnProperty('_id')) return;
|
|
||||||
cl.server.connections.forEach((usr) => {
|
|
||||||
if ((usr.channel && usr.participantId && usr.user) && (usr.user._id == msg._id || (usr.participantId == msg.id))) {
|
|
||||||
let user = new User(usr);
|
|
||||||
user.cl.user.color = msg.color;
|
|
||||||
user.getUserData().then((uSr) => {
|
|
||||||
if (!uSr._id) return;
|
|
||||||
let dbentry = user.userdb.get(uSr._id);
|
|
||||||
if (!dbentry) return;
|
|
||||||
dbentry.color = msg.color;
|
|
||||||
//user.updatedb();
|
|
||||||
cl.server.rooms.forEach((room) => {
|
|
||||||
room.updateParticipant(usr.participantId, {
|
|
||||||
color: msg.color
|
|
||||||
});
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
87
src/Quota.js
87
src/Quota.js
|
@ -1,87 +0,0 @@
|
||||||
class Quota {
|
|
||||||
constructor(cb) {
|
|
||||||
this.cb = cb;
|
|
||||||
this.setParams();
|
|
||||||
this.resetPoints();
|
|
||||||
};
|
|
||||||
static NQ_PARAMS_LOBBY = {
|
|
||||||
allowance: 200,
|
|
||||||
max: 600
|
|
||||||
};
|
|
||||||
static NQ_PARAMS_NORMAL = {
|
|
||||||
allowance: 400,
|
|
||||||
max: 1200
|
|
||||||
};
|
|
||||||
static NQ_PARAMS_RIDICULOUS = {
|
|
||||||
allowance: 600,
|
|
||||||
max: 1800
|
|
||||||
};
|
|
||||||
static NQ_PARAMS_OFFLINE = {
|
|
||||||
allowance: 8000,
|
|
||||||
max: 24000,
|
|
||||||
maxHistLen: 3
|
|
||||||
};
|
|
||||||
static CH_PARAMS = {
|
|
||||||
allowance: 8000,
|
|
||||||
max: 24000,
|
|
||||||
maxHistLen: 3
|
|
||||||
}
|
|
||||||
getParams() {
|
|
||||||
return {
|
|
||||||
m: "nq",
|
|
||||||
allowance: this.allowance,
|
|
||||||
max: this.max,
|
|
||||||
maxHistLen: this.maxHistLen
|
|
||||||
};
|
|
||||||
};
|
|
||||||
setParams(params) {
|
|
||||||
params = params || NoteQuota.PARAMS_OFFLINE;
|
|
||||||
var allowance = params.allowance || this.allowance || NoteQuota.PARAMS_OFFLINE.allowance;
|
|
||||||
var max = params.max || this.max || NoteQuota.PARAMS_OFFLINE.max;
|
|
||||||
var maxHistLen = params.maxHistLen || this.maxHistLen || NoteQuota.PARAMS_OFFLINE.maxHistLen;
|
|
||||||
if (allowance !== this.allowance || max !== this.max || maxHistLen !== this.maxHistLen) {
|
|
||||||
this.allowance = allowance;
|
|
||||||
this.max = max;
|
|
||||||
this.maxHistLen = maxHistLen;
|
|
||||||
this.resetPoints();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
resetPoints() {
|
|
||||||
this.points = this.max;
|
|
||||||
this.history = [];
|
|
||||||
for (var i = 0; i < this.maxHistLen; i++)
|
|
||||||
this.history.unshift(this.points);
|
|
||||||
if (this.cb) this.cb(this.points);
|
|
||||||
};
|
|
||||||
tick() {
|
|
||||||
// keep a brief history
|
|
||||||
this.history.unshift(this.points);
|
|
||||||
this.history.length = this.maxHistLen;
|
|
||||||
// hook a brother up with some more quota
|
|
||||||
if (this.points < this.max) {
|
|
||||||
this.points += this.allowance;
|
|
||||||
if (this.points > this.max) this.points = this.max;
|
|
||||||
// fire callback
|
|
||||||
if (this.cb) this.cb(this.points);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
spend(needed) {
|
|
||||||
// check whether aggressive limitation is needed
|
|
||||||
var sum = 0;
|
|
||||||
for (var i in this.history) {
|
|
||||||
sum += this.history[i];
|
|
||||||
}
|
|
||||||
if (sum <= 0) needed *= this.allowance;
|
|
||||||
// can they afford it? spend
|
|
||||||
if (this.points < needed) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
this.points -= needed;
|
|
||||||
if (this.cb) this.cb(this.points); // fire callback
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
module.exports = Quota;
|
|
|
@ -1,40 +0,0 @@
|
||||||
|
|
||||||
var RateLimit = function(interval_ms) {
|
|
||||||
this._interval_ms = interval_ms || 0; // (0 means no limit)
|
|
||||||
this._after = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
RateLimit.prototype.attempt = function(time) {
|
|
||||||
var time = time || Date.now();
|
|
||||||
if(time < this._after) return false;
|
|
||||||
this._after = time + this._interval_ms;
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
RateLimit.prototype.setInterval = function(interval_ms) {
|
|
||||||
this._after += interval_ms - this._interval_ms;
|
|
||||||
this._interval_ms = interval_ms;
|
|
||||||
};
|
|
||||||
|
|
||||||
var RateLimitChain = function(num, interval_ms) {
|
|
||||||
this.setNumAndInterval(num, interval_ms);
|
|
||||||
};
|
|
||||||
|
|
||||||
RateLimitChain.prototype.attempt = function(time) {
|
|
||||||
var time = time || Date.now();
|
|
||||||
for(var i = 0; i < this._chain.length; i++) {
|
|
||||||
if(this._chain[i].attempt(time)) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
RateLimitChain.prototype.setNumAndInterval = function(num, interval_ms) {
|
|
||||||
this._chain = [];
|
|
||||||
for(var i = 0; i < num; i++) {
|
|
||||||
this._chain.push(new RateLimit(interval_ms));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var exports = typeof module !== "undefined" ? module.exports : this;
|
|
||||||
exports.RateLimit = RateLimit;
|
|
||||||
exports.RateLimitChain = RateLimitChain;
|
|
420
src/Room.js
420
src/Room.js
|
@ -1,420 +0,0 @@
|
||||||
//array of rooms
|
|
||||||
//room class
|
|
||||||
//room deleter
|
|
||||||
//databases in Map
|
|
||||||
|
|
||||||
class Room extends EventEmitter {
|
|
||||||
constructor(server, _id, settings) {
|
|
||||||
super();
|
|
||||||
EventEmitter.call(this);
|
|
||||||
this._id = _id;
|
|
||||||
this.server = server;
|
|
||||||
this.crown = null;
|
|
||||||
this.crowndropped = false;
|
|
||||||
this.settings = this.verifySet(this._id,{set:settings});
|
|
||||||
this.chatmsgs = [];
|
|
||||||
this.ppl = new Map();
|
|
||||||
this.connections = [];
|
|
||||||
this.bindEventListeners();
|
|
||||||
this.server.rooms.set(_id, this);
|
|
||||||
this.bans = new Map();
|
|
||||||
}
|
|
||||||
join(cl) { //this stuff is complicated
|
|
||||||
let otheruser = this.connections.find((a) => a.user._id == cl.user._id)
|
|
||||||
if (!otheruser) {
|
|
||||||
let participantId = createKeccakHash('keccak256').update((Math.random().toString() + cl.ip)).digest('hex').substr(0, 24);
|
|
||||||
cl.user.id = participantId;
|
|
||||||
cl.participantId = participantId;
|
|
||||||
if (((this.connections.length == 0 && Array.from(this.ppl.values()).length == 0) && !this.isLobby(this._id)) || this.crown && (this.crown.userId == cl.user._id)) { //user that created the room, give them the crown.
|
|
||||||
this.crown = {
|
|
||||||
participantId: cl.participantId,
|
|
||||||
userId: cl.user._id,
|
|
||||||
time: Date.now(),
|
|
||||||
startPos: {
|
|
||||||
x: 50,
|
|
||||||
y: 50
|
|
||||||
},
|
|
||||||
endPos: {
|
|
||||||
x: this.getCrownX(),
|
|
||||||
y: this.getCrownY()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.crowndropped = false;
|
|
||||||
}
|
|
||||||
this.ppl.set(participantId, cl);
|
|
||||||
this.connections.push(cl);
|
|
||||||
this.sendArray([{
|
|
||||||
color: this.ppl.get(cl.participantId).user.color,
|
|
||||||
id: this.ppl.get(cl.participantId).participantId,
|
|
||||||
m: "p",
|
|
||||||
name: this.ppl.get(cl.participantId).user.name,
|
|
||||||
x: this.ppl.get(cl.participantId).x || 200,
|
|
||||||
y: this.ppl.get(cl.participantId).y || 100,
|
|
||||||
_id: cl.user._id
|
|
||||||
}], cl, false)
|
|
||||||
cl.sendArray([{
|
|
||||||
m: "c",
|
|
||||||
c: this.chatmsgs.slice(-1 * 32)
|
|
||||||
}])
|
|
||||||
this.updateCh(cl);
|
|
||||||
} else {
|
|
||||||
cl.user.id = otheruser.participantId;
|
|
||||||
cl.participantId = otheruser.participantId;
|
|
||||||
this.connections.push(cl);
|
|
||||||
cl.sendArray([{
|
|
||||||
m: "c",
|
|
||||||
c: this.chatmsgs.slice(-1 * 32)
|
|
||||||
}])
|
|
||||||
this.updateCh(cl);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
remove(p) { //this is complicated too
|
|
||||||
let otheruser = this.connections.filter((a) => a.user._id == p.user._id);
|
|
||||||
if (!(otheruser.length > 1)) {
|
|
||||||
this.ppl.delete(p.participantId);
|
|
||||||
this.connections.splice(this.connections.findIndex((a) => a.connectionid == p.connectionid), 1);
|
|
||||||
console.log(`Deleted client ${p.user.id}`);
|
|
||||||
this.sendArray([{
|
|
||||||
m: "bye",
|
|
||||||
p: p.participantId
|
|
||||||
}], p, false);
|
|
||||||
if (this.crown)
|
|
||||||
if (this.crown.userId == p.user._id && !this.crowndropped) {
|
|
||||||
this.chown();
|
|
||||||
}
|
|
||||||
this.updateCh();
|
|
||||||
} else {
|
|
||||||
this.connections.splice(this.connections.findIndex((a) => a.connectionid == p.connectionid), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
updateCh(cl) { //update channel for all people in channel
|
|
||||||
if (Array.from(this.ppl.values()).length <= 0) this.destroy();
|
|
||||||
this.connections.forEach((usr) => {
|
|
||||||
this.server.connections.get(usr.connectionid).sendArray([this.fetchData(usr, cl)])
|
|
||||||
})
|
|
||||||
this.server.updateRoom(this.fetchData());
|
|
||||||
}
|
|
||||||
updateParticipant(pid, options) {
|
|
||||||
let p = this.ppl.get(pid);
|
|
||||||
if (!p) return;
|
|
||||||
options.name ? this.ppl.get(pid).user.name = options.name : {};
|
|
||||||
options._id ? this.ppl.get(pid).user._id = options._id : {};
|
|
||||||
options.color ? this.ppl.get(pid).user.color = options.color : {};
|
|
||||||
this.connections.filter((ofo) => ofo.participantId == p.participantId).forEach((usr) => {
|
|
||||||
options.name ? usr.user.name = options.name : {};
|
|
||||||
options._id ? usr.user._id = options._id : {};
|
|
||||||
options.color ? usr.user.color = options.color : {};
|
|
||||||
})
|
|
||||||
this.sendArray([{
|
|
||||||
color: p.user.color,
|
|
||||||
id: p.participantId,
|
|
||||||
m: "p",
|
|
||||||
name: p.user.name,
|
|
||||||
x: p.x || 200,
|
|
||||||
y: p.y || 100,
|
|
||||||
_id: p.user._id
|
|
||||||
}])
|
|
||||||
}
|
|
||||||
destroy() { //destroy room
|
|
||||||
this._id;
|
|
||||||
console.log(`Deleted room ${this._id}`);
|
|
||||||
this.settings = {};
|
|
||||||
this.ppl;
|
|
||||||
this.connnections;
|
|
||||||
this.chatmsgs;
|
|
||||||
this.server.rooms.delete(this._id);
|
|
||||||
}
|
|
||||||
sendArray(arr, not, onlythisparticipant) {
|
|
||||||
this.connections.forEach((usr) => {
|
|
||||||
if (!not || (usr.participantId != not.participantId && !onlythisparticipant) || (usr.connectionid != not.connectionid && onlythisparticipant)) {
|
|
||||||
try {
|
|
||||||
this.server.connections.get(usr.connectionid).sendArray(arr)
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
fetchData(usr, cl) {
|
|
||||||
let chppl = [];
|
|
||||||
[...this.ppl.values()].forEach((a) => {
|
|
||||||
chppl.push(a.user);
|
|
||||||
})
|
|
||||||
let data = {
|
|
||||||
m: "ch",
|
|
||||||
p: "ofo",
|
|
||||||
ch: {
|
|
||||||
count: chppl.length,
|
|
||||||
crown: this.crown,
|
|
||||||
settings: this.settings,
|
|
||||||
_id: this._id
|
|
||||||
},
|
|
||||||
ppl: chppl
|
|
||||||
}
|
|
||||||
if (cl) {
|
|
||||||
if (usr.connectionid == cl.connectionid) {
|
|
||||||
data.p = cl.participantId;
|
|
||||||
} else {
|
|
||||||
delete data.p;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
delete data.p;
|
|
||||||
}
|
|
||||||
if (data.ch.crown == null) {
|
|
||||||
delete data.ch.crown;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
verifyColor(strColor){
|
|
||||||
var test2 = /^#[0-9A-F]{6}$/i.test(strColor);
|
|
||||||
if(test2 == true){
|
|
||||||
return strColor;
|
|
||||||
} else{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
isLobby(_id) {
|
|
||||||
if (_id.startsWith("lobby")) {
|
|
||||||
let lobbynum = _id.split("lobby")[1];
|
|
||||||
if (_id == "lobby") {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!(parseInt(lobbynum).toString() == lobbynum)) return false;
|
|
||||||
for (let i in lobbynum) {
|
|
||||||
if (parseInt(lobbynum[i]) >= 0) {
|
|
||||||
if (parseInt(i) + 1 == lobbynum.length) return true;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (_id.startsWith("test/")) {
|
|
||||||
if (_id == "test/") {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
getCrownY() {
|
|
||||||
return 50 - 30;
|
|
||||||
}
|
|
||||||
getCrownX() {
|
|
||||||
return 50;
|
|
||||||
}
|
|
||||||
chown(id) {
|
|
||||||
let prsn = this.ppl.get(id);
|
|
||||||
if (prsn) {
|
|
||||||
this.crown = {
|
|
||||||
participantId: prsn.participantId,
|
|
||||||
userId: prsn.user._id,
|
|
||||||
time: Date.now(),
|
|
||||||
startPos: {
|
|
||||||
x: 50,
|
|
||||||
y: 50
|
|
||||||
},
|
|
||||||
endPos: {
|
|
||||||
x: this.getCrownX(),
|
|
||||||
y: this.getCrownY()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
this.crowndropped = false;
|
|
||||||
} else {
|
|
||||||
this.crown = {
|
|
||||||
userId: this.crown.userId,
|
|
||||||
time: Date.now(),
|
|
||||||
startPos: {
|
|
||||||
x: 50,
|
|
||||||
y: 50
|
|
||||||
},
|
|
||||||
endPos: {
|
|
||||||
x: this.getCrownX(),
|
|
||||||
y: this.getCrownY()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.crowndropped = true;
|
|
||||||
}
|
|
||||||
this.updateCh();
|
|
||||||
}
|
|
||||||
setCords(p, x, y) {
|
|
||||||
if (p.participantId && this.ppl.get(p.participantId)) {
|
|
||||||
x ? this.ppl.get(p.participantId).x = x : {};
|
|
||||||
y ? this.ppl.get(p.participantId).y = y : {};
|
|
||||||
this.sendArray([{
|
|
||||||
m: "m",
|
|
||||||
id: p.participantId,
|
|
||||||
x: this.ppl.get(p.participantId).x,
|
|
||||||
y: this.ppl.get(p.participantId).y
|
|
||||||
}], p, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
chat(p, msg) {
|
|
||||||
if (msg.message.length > 512) return;
|
|
||||||
let filter = ["AMIGHTYWIND"];
|
|
||||||
let regexp = new RegExp("\\b(" + filter.join("|") + ")\\b", "i");
|
|
||||||
if (regexp.test(msg.message)) return;
|
|
||||||
let prsn = this.ppl.get(p.participantId);
|
|
||||||
if (prsn) {
|
|
||||||
let message = {};
|
|
||||||
message.m = "a";
|
|
||||||
message.a = msg.message;
|
|
||||||
message.p = {
|
|
||||||
color: p.user.color,
|
|
||||||
id: p.participantId,
|
|
||||||
name: p.user.name,
|
|
||||||
_id: p.user._id
|
|
||||||
};
|
|
||||||
message.t = Date.now();
|
|
||||||
this.sendArray([message]);
|
|
||||||
this.chatmsgs.push(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
playNote(cl, note) {
|
|
||||||
this.sendArray([{
|
|
||||||
m: "n",
|
|
||||||
n: note.n,
|
|
||||||
p: cl.participantId,
|
|
||||||
t: note.t
|
|
||||||
}], cl, true);
|
|
||||||
}
|
|
||||||
kickban(_id, ms) {
|
|
||||||
ms = parseInt(ms);
|
|
||||||
if (ms >= (1000 * 60 * 60 - 500)) return;
|
|
||||||
if (ms < 0) return;
|
|
||||||
ms = Math.round(ms / 1000) * 1000;
|
|
||||||
let user = this.connections.find((usr) => usr.user._id == _id);
|
|
||||||
if (!user) return;
|
|
||||||
let asd = true;
|
|
||||||
let tonc = true;
|
|
||||||
let pthatbanned = this.ppl.get(this.crown.participantId);
|
|
||||||
this.connections.filter((usr) => usr.participantId == user.participantId).forEach((u) => {
|
|
||||||
user.bantime = Math.floor(Math.floor(ms / 1000) / 60);
|
|
||||||
user.bannedtime = Date.now();
|
|
||||||
user.msbanned = ms;
|
|
||||||
this.bans.set(user.user._id, user);
|
|
||||||
if (this.crown && (this.crown.userId)) {
|
|
||||||
u.setChannel("test/awkward", {});
|
|
||||||
if (asd)
|
|
||||||
this.Notification(user.user._id,
|
|
||||||
"Notice",
|
|
||||||
`Banned from \"${this._id}\" for ${Math.floor(Math.floor(ms / 1000) / 60)} minutes.`,
|
|
||||||
"",
|
|
||||||
7000,
|
|
||||||
"#room",
|
|
||||||
"short"
|
|
||||||
)
|
|
||||||
if (asd)
|
|
||||||
this.Notification("room",
|
|
||||||
"Notice",
|
|
||||||
`${pthatbanned.user.name} banned ${user.user.name} from the channel for ${Math.floor(Math.floor(ms / 1000) / 60)} minutes.`,
|
|
||||||
"",
|
|
||||||
7000,
|
|
||||||
"#room",
|
|
||||||
"short"
|
|
||||||
)
|
|
||||||
if (this.crown && (this.crown.userId == _id) && tonc) {
|
|
||||||
this.Notification("room",
|
|
||||||
"Certificate of Award",
|
|
||||||
`Let it be known that ${user.user.name} kickbanned him/her self.`,
|
|
||||||
"",
|
|
||||||
7000,
|
|
||||||
"#room"
|
|
||||||
);
|
|
||||||
tonc = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Notification(who, title, text, html, duration, target, klass, id) {
|
|
||||||
let obj = {
|
|
||||||
m: "notification",
|
|
||||||
title: title,
|
|
||||||
text: text,
|
|
||||||
html: html,
|
|
||||||
target: target,
|
|
||||||
duration: duration,
|
|
||||||
class: klass,
|
|
||||||
id: id
|
|
||||||
};
|
|
||||||
if (!id) delete obj.id;
|
|
||||||
if (!title) delete obj.title;
|
|
||||||
if (!text) delete obj.text;
|
|
||||||
if (!html) delete obj.html;
|
|
||||||
if (!target) delete obj.target;
|
|
||||||
if (!duration) delete obj.duration;
|
|
||||||
if (!klass) delete obj.class;
|
|
||||||
switch (who) {
|
|
||||||
case "all": {
|
|
||||||
for (let con of Array.from(this.server.connections.values())) {
|
|
||||||
con.sendArray([obj]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "room": {
|
|
||||||
for (let con of this.connections) {
|
|
||||||
con.sendArray([obj]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
Array.from(this.server.connections.values()).filter((usr) => usr.user._id == who).forEach((p) => {
|
|
||||||
p.sendArray([obj]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bindEventListeners() {
|
|
||||||
this.on("bye", participant => {
|
|
||||||
this.remove(participant);
|
|
||||||
})
|
|
||||||
|
|
||||||
this.on("m", (participant, x, y) => {
|
|
||||||
this.setCords(participant, x, y);
|
|
||||||
})
|
|
||||||
|
|
||||||
this.on("a", (participant, msg) => {
|
|
||||||
this.chat(participant, msg);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
verifySet(_id,msg){
|
|
||||||
if(!isObj(msg.set)) msg.set = {visible:true,color:this.server.defaultRoomColor,chat:true,crownsolo:false};
|
|
||||||
if(isBool(msg.set.lobby)){
|
|
||||||
if(!this.isLobby(_id)) delete msg.set.lobby; // keep it nice and clean
|
|
||||||
}else{
|
|
||||||
if(this.isLobby(_id)) msg.set = {visible:true,color:this.server.defaultLobbyColor,color2:this.server.defaultLobbyColor2,chat:true,crownsolo:false,lobby:true};
|
|
||||||
}
|
|
||||||
if(!isBool(msg.set.visible)){
|
|
||||||
if(msg.set.visible == undefined) msg.set.visible = (!isObj(this.settings) ? true : this.settings.visible);
|
|
||||||
else msg.set.visible = true;
|
|
||||||
};
|
|
||||||
if(!isBool(msg.set.chat)){
|
|
||||||
if(msg.set.chat == undefined) msg.set.chat = (!isObj(this.settings) ? true : this.settings.chat);
|
|
||||||
else msg.set.chat = true;
|
|
||||||
};
|
|
||||||
if(!isBool(msg.set.crownsolo)){
|
|
||||||
if(msg.set.crownsolo == undefined) msg.set.crownsolo = (!isObj(this.settings) ? false : this.settings.crownsolo);
|
|
||||||
else msg.set.crownsolo = false;
|
|
||||||
};
|
|
||||||
if(!isString(msg.set.color) || !/^#[0-9a-f]{6}$/i.test(msg.set.color)) msg.set.color = (!isObj(this.settings) ? this.server.defaultRoomColor : this.settings.color);
|
|
||||||
if(isString(msg.set.color2)){
|
|
||||||
if(!/^#[0-9a-f]{6}$/i.test(msg.set.color2)){
|
|
||||||
if(this.settings){
|
|
||||||
if(this.settings.color2) msg.set.color2 = this.settings.color2;
|
|
||||||
else delete msg.set.color2; // keep it nice and clean
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return msg.set;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
module.exports = Room;
|
|
|
@ -1,41 +0,0 @@
|
||||||
const Client = require("./Client.js")
|
|
||||||
class Server extends EventEmitter {
|
|
||||||
constructor(config) {
|
|
||||||
super();
|
|
||||||
EventEmitter.call(this);
|
|
||||||
this.wss = new WebSocket.Server({
|
|
||||||
port: config.port,
|
|
||||||
backlog: 100,
|
|
||||||
verifyClient: function (info, done) {
|
|
||||||
done(true)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.connectionid = 0;
|
|
||||||
this.connections = new Map();
|
|
||||||
this.roomlisteners = new Map();
|
|
||||||
this.rooms = new Map();
|
|
||||||
this.wss.on('connection', (ws, req) => {
|
|
||||||
this.connections.set(++this.connectionid, new Client(ws, req, this));
|
|
||||||
});
|
|
||||||
this.legit_m = ["a", "bye", "hi", "ch", "+ls", "-ls", "m", "n", "devices", "t", "chset", "userset", "chown", "kickban", "admin message", "color"]
|
|
||||||
this.welcome_motd = config.motd || "You agree to read this message.";
|
|
||||||
this._id_Private_Key = config._id_PrivateKey || "boppity";
|
|
||||||
this.defaultUsername = config.defaultUsername || "Anonymous";
|
|
||||||
this.defaultRoomColor = config.defaultRoomColor || "#3b5054";
|
|
||||||
this.defaultLobbyColor = config.defaultLobbyColor || "#19b4b9";
|
|
||||||
this.defaultLobbyColor2 = config.defaultLobbyColor2 || "#801014";
|
|
||||||
this.adminpass = config.adminpass || "Bop It";
|
|
||||||
};
|
|
||||||
updateRoom(data) {
|
|
||||||
if (!data.ch.settings.visible) return;
|
|
||||||
for (let cl of Array.from(this.roomlisteners.values())) {
|
|
||||||
cl.sendArray([{
|
|
||||||
"m": "ls",
|
|
||||||
"c": false,
|
|
||||||
"u": [data.ch]
|
|
||||||
}])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Server;
|
|
|
@ -1,2 +0,0 @@
|
||||||
|
|
||||||
Room.js make color verifier
|
|
53
src/User.js
53
src/User.js
|
@ -1,53 +0,0 @@
|
||||||
const ColorEncoder = require("./ColorEncoder.js");
|
|
||||||
const { promisify } = require('util');
|
|
||||||
let userdb;
|
|
||||||
class User {
|
|
||||||
constructor(cl) {
|
|
||||||
this.cl = cl;
|
|
||||||
this.server = this.cl.server;
|
|
||||||
this.userdb = userdb;
|
|
||||||
this.default_db = {};
|
|
||||||
}
|
|
||||||
async getUserData() {
|
|
||||||
if (!userdb || (userdb instanceof Map && [...userdb.entries()] == [])) {
|
|
||||||
await this.setUpDb();
|
|
||||||
}
|
|
||||||
let _id = createKeccakHash('keccak256').update((this.cl.server._id_Private_Key + this.cl.ip)).digest('hex').substr(0, 24);
|
|
||||||
let usertofind = userdb.get(_id);
|
|
||||||
if (!usertofind) {
|
|
||||||
if (typeof usertofind == 'object' && (usertofind.hasOwnProperty('name') && usertofind.name != this.server.defaultUsername)) return;
|
|
||||||
userdb.set(_id, {
|
|
||||||
"color": `#${ColorEncoder.intToRGB(ColorEncoder.hashCode(_id)).toLowerCase()}`,
|
|
||||||
"name": this.server.defaultUsername,
|
|
||||||
"_id": _id,
|
|
||||||
"ip": this.cl.ip
|
|
||||||
});
|
|
||||||
this.updatedb();
|
|
||||||
}
|
|
||||||
let user = userdb.get(_id);
|
|
||||||
return {
|
|
||||||
"color": user.color,
|
|
||||||
"name": user.name,
|
|
||||||
"_id": user._id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async updatedb() {
|
|
||||||
const writeFile = promisify(fs.writeFile);
|
|
||||||
await writeFile('src/db/users.json', JSON.stringify(User.strMapToObj(userdb), null, 2));
|
|
||||||
}
|
|
||||||
async setUpDb() {
|
|
||||||
const writeFile = promisify(fs.writeFile);
|
|
||||||
const readdir = promisify(fs.readdir);
|
|
||||||
let files = await readdir("src/db/");
|
|
||||||
if (!files.includes("users.json")) {
|
|
||||||
await writeFile('src/db/users.json', JSON.stringify(this.default_db, null, 2))
|
|
||||||
userdb = new Map(Object.entries(require("./db/users.json")));
|
|
||||||
} else {
|
|
||||||
userdb = new Map(Object.entries(require("./db/users.json")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static strMapToObj(strMap) {
|
|
||||||
return [...strMap.entries()].reduce((obj, [key, value]) => (obj[key] = value, obj), {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
module.exports = User;
|
|
|
@ -1,34 +0,0 @@
|
||||||
module.exports = Object.seal({
|
|
||||||
"port": "3000",
|
|
||||||
"motd": "You agree to read this message.",
|
|
||||||
"_id_PrivateKey": "boppity",
|
|
||||||
"defaultUsername": "Anonymous",
|
|
||||||
"defaultRoomColor": "#3b5054",
|
|
||||||
"defaultLobbyColor": "#19b4b9",
|
|
||||||
"defaultLobbyColor2": "#801014",
|
|
||||||
"adminpass": "adminpass",
|
|
||||||
"quotas":{
|
|
||||||
"chat":{
|
|
||||||
"amount": 4,
|
|
||||||
"time": 4000
|
|
||||||
},
|
|
||||||
"name":{
|
|
||||||
"amount": 30,
|
|
||||||
"time": 30 * 60000
|
|
||||||
},
|
|
||||||
"room":{
|
|
||||||
"time": 500
|
|
||||||
},
|
|
||||||
"cursor":{
|
|
||||||
"time": 16
|
|
||||||
},
|
|
||||||
"kickban":{
|
|
||||||
"amount": 2,
|
|
||||||
"time": 1000
|
|
||||||
},
|
|
||||||
"crowned_chat":{
|
|
||||||
"amount": 10,
|
|
||||||
"time": 4000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
|
@ -1 +0,0 @@
|
||||||
{}
|
|
Loading…
Reference in New Issue