forked from Hri7566/mpp-server-dev2
major update
This commit is contained in:
parent
2887369331
commit
784853a7c7
|
@ -1,3 +1,4 @@
|
||||||
.env
|
.env
|
||||||
node_modules
|
node_modules
|
||||||
ssl/
|
ssl/
|
||||||
|
src/db/users.json
|
||||||
|
|
|
@ -3,10 +3,10 @@ module.exports = Object.seal({
|
||||||
motd: "big th0nk",
|
motd: "big th0nk",
|
||||||
_id_PrivateKey: process.env.SALT,
|
_id_PrivateKey: process.env.SALT,
|
||||||
defaultUsername: "Anonymous",
|
defaultUsername: "Anonymous",
|
||||||
//defaultRoomColor: "#3b5054",
|
// defaultRoomColor: "#3b5054",
|
||||||
defaultRoomColor: "#9900ff",
|
defaultRoomColor: "#000000",
|
||||||
// defaultLobbyColor: "#19b4b9",
|
// defaultLobbyColor: "#19b4b9",
|
||||||
defaultLobbyColor: "#5e32a8",
|
defaultLobbyColor: "#9900ff",
|
||||||
// defaultLobbyColor2: "#801014",
|
// defaultLobbyColor2: "#801014",
|
||||||
defaultLobbyColor2: "#801014",
|
defaultLobbyColor2: "#801014",
|
||||||
adminpass: process.env.ADMINPASS,
|
adminpass: process.env.ADMINPASS,
|
||||||
|
|
20
index.js
20
index.js
|
@ -1,26 +1,31 @@
|
||||||
// dotenv to keep secret variables in (they won't show on github)
|
// dotenv
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
|
|
||||||
//call new Server
|
// call new Server
|
||||||
global.WebSocket = require('ws');
|
global.WebSocket = require('ws');
|
||||||
global.EventEmitter = require('events').EventEmitter;
|
global.EventEmitter = require('events').EventEmitter;
|
||||||
global.fs = require('fs');
|
global.fs = require('fs');
|
||||||
global.createKeccakHash = require('keccak');
|
const AsyncConsole = require('asyncconsole');
|
||||||
const AsyncConsole = require('asyncconsole')
|
|
||||||
|
|
||||||
global.isString = function(a){
|
global.isString = function(a) {
|
||||||
return typeof a === 'string';
|
return typeof a === 'string';
|
||||||
}
|
}
|
||||||
global.isBool = function(a){
|
|
||||||
|
global.isBool = function(a) {
|
||||||
return typeof a === 'boolean';
|
return typeof a === 'boolean';
|
||||||
}
|
}
|
||||||
global.isObj = function(a){
|
|
||||||
|
global.isObj = function(a) {
|
||||||
return typeof a === "object" && !Array.isArray(a) && a !== null;
|
return typeof a === "object" && !Array.isArray(a) && a !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let Server = require("./src/Server.js");
|
let Server = require("./src/Server.js");
|
||||||
let config = require('./config');
|
let config = require('./config');
|
||||||
global.SERVER = new Server(config);
|
global.SERVER = new Server(config);
|
||||||
|
|
||||||
|
// below commented because it doesn't work with pm2
|
||||||
|
|
||||||
|
/*
|
||||||
let console = process.platform == 'win32' ? new AsyncConsole("", input => {
|
let console = process.platform == 'win32' ? new AsyncConsole("", input => {
|
||||||
try {
|
try {
|
||||||
console.log(JSON.stringify(eval(input)));
|
console.log(JSON.stringify(eval(input)));
|
||||||
|
@ -28,3 +33,4 @@ let console = process.platform == 'win32' ? new AsyncConsole("", input => {
|
||||||
console.log(e.toString());
|
console.log(e.toString());
|
||||||
}
|
}
|
||||||
}) : {};
|
}) : {};
|
||||||
|
*/
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"ignore": [
|
||||||
|
"**/*.json"
|
||||||
|
]
|
||||||
|
}
|
|
@ -3,42 +3,55 @@ const Quota = require ("./Quota.js");
|
||||||
const quotas = require('../Quotas');
|
const quotas = require('../Quotas');
|
||||||
const RateLimit = require('./Ratelimit.js').RateLimit;
|
const RateLimit = require('./Ratelimit.js').RateLimit;
|
||||||
const RateLimitChain = require('./Ratelimit.js').RateLimitChain;
|
const RateLimitChain = require('./Ratelimit.js').RateLimitChain;
|
||||||
|
const User = require("./User.js");
|
||||||
|
const Database = require("./Database.js");
|
||||||
require('node-json-color-stringify');
|
require('node-json-color-stringify');
|
||||||
|
|
||||||
class Client extends EventEmitter {
|
class Client extends EventEmitter {
|
||||||
constructor(ws, req, server) {
|
constructor(ws, req, server) {
|
||||||
super();
|
super();
|
||||||
EventEmitter.call(this);
|
EventEmitter.call(this);
|
||||||
this.user;
|
|
||||||
this.connectionid = server.connectionid;
|
this.connectionid = server.connectionid;
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.participantId;
|
this.participantId;
|
||||||
this.channel;
|
this.channel;
|
||||||
|
|
||||||
this.staticQuotas = {
|
this.staticQuotas = {
|
||||||
room: new RateLimit(quotas.room.time)
|
room: new RateLimit(quotas.room.time)
|
||||||
};
|
};
|
||||||
|
|
||||||
this.quotas = {};
|
this.quotas = {};
|
||||||
this.ws = ws;
|
this.ws = ws;
|
||||||
this.req = req;
|
this.req = req;
|
||||||
this.ip = (req.connection.remoteAddress).replace("::ffff:", "");
|
this.ip = (req.connection.remoteAddress).replace("::ffff:", "");
|
||||||
this.destroied = false;
|
|
||||||
this.bindEventListeners();
|
Database.getUserData(this, server).then(data => {
|
||||||
require('./Message.js')(this);
|
this.user = new User(this, data);
|
||||||
|
this.destroied = false;
|
||||||
|
this.bindEventListeners();
|
||||||
|
require('./Message.js')(this);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
isConnected() {
|
isConnected() {
|
||||||
return this.ws && this.ws.readyState === WebSocket.OPEN;
|
return this.ws && this.ws.readyState === WebSocket.OPEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
isConnecting() {
|
isConnecting() {
|
||||||
return this.ws && this.ws.readyState === WebSocket.CONNECTING;
|
return this.ws && this.ws.readyState === WebSocket.CONNECTING;
|
||||||
}
|
}
|
||||||
|
|
||||||
setChannel(_id, settings) {
|
setChannel(_id, settings) {
|
||||||
if (this.channel && this.channel._id == _id) return;
|
if (this.channel && this.channel._id == _id) return;
|
||||||
if (this.server.rooms.get(_id)) {
|
if (this.server.rooms.get(_id)) {
|
||||||
let room = this.server.rooms.get(_id, settings);
|
let room = this.server.rooms.get(_id, settings);
|
||||||
let userbanned = room.bans.get(this.user._id);
|
let userbanned = room.bans.get(this.user._id);
|
||||||
|
|
||||||
if (userbanned && (Date.now() - userbanned.bannedtime >= userbanned.msbanned)) {
|
if (userbanned && (Date.now() - userbanned.bannedtime >= userbanned.msbanned)) {
|
||||||
room.bans.delete(userbanned.user._id);
|
room.bans.delete(userbanned.user._id);
|
||||||
userbanned = undefined;
|
userbanned = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userbanned) {
|
if (userbanned) {
|
||||||
room.Notification(this.user._id,
|
room.Notification(this.user._id,
|
||||||
"Notice",
|
"Notice",
|
||||||
|
@ -51,9 +64,11 @@ class Client extends EventEmitter {
|
||||||
this.setChannel("test/awkward", settings);
|
this.setChannel("test/awkward", settings);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let channel = this.channel;
|
let channel = this.channel;
|
||||||
if (channel) this.channel.emit("bye", this);
|
if (channel) this.channel.emit("bye", this);
|
||||||
if (channel) this.channel.updateCh();
|
if (channel) this.channel.updateCh(this);
|
||||||
|
|
||||||
this.channel = this.server.rooms.get(_id);
|
this.channel = this.server.rooms.get(_id);
|
||||||
this.channel.join(this);
|
this.channel.join(this);
|
||||||
} else {
|
} else {
|
||||||
|
@ -61,7 +76,7 @@ class Client extends EventEmitter {
|
||||||
this.server.rooms.set(_id, room);
|
this.server.rooms.set(_id, room);
|
||||||
if (this.channel) this.channel.emit("bye", this);
|
if (this.channel) this.channel.emit("bye", this);
|
||||||
this.channel = this.server.rooms.get(_id);
|
this.channel = this.server.rooms.get(_id);
|
||||||
this.channel.join(this);
|
this.channel.join(this, settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sendArray(arr) {
|
sendArray(arr) {
|
||||||
|
@ -70,6 +85,7 @@ class Client extends EventEmitter {
|
||||||
this.ws.send(JSON.stringify(arr));
|
this.ws.send(JSON.stringify(arr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initParticipantQuotas() {
|
initParticipantQuotas() {
|
||||||
this.quotas = {
|
this.quotas = {
|
||||||
//"chat": new Quota(Quota.PARAMS_A_NORMAL),
|
//"chat": new Quota(Quota.PARAMS_A_NORMAL),
|
||||||
|
@ -88,6 +104,7 @@ class Client extends EventEmitter {
|
||||||
"-ls": new Quota(Quota.PARAMS_USED_A_LOT)
|
"-ls": new Quota(Quota.PARAMS_USED_A_LOT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
this.ws.close();
|
this.ws.close();
|
||||||
if (this.channel) {
|
if (this.channel) {
|
||||||
|
@ -102,6 +119,7 @@ class Client extends EventEmitter {
|
||||||
this.destroied = true;
|
this.destroied = true;
|
||||||
console.log(`Removed Connection ${this.connectionid}.`);
|
console.log(`Removed Connection ${this.connectionid}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
bindEventListeners() {
|
bindEventListeners() {
|
||||||
this.ws.on("message", (evt, admin) => {
|
this.ws.on("message", (evt, admin) => {
|
||||||
try {
|
try {
|
||||||
|
@ -120,14 +138,17 @@ class Client extends EventEmitter {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.ws.on("close", () => {
|
this.ws.on("close", () => {
|
||||||
if (!this.destroied)
|
if (!this.destroied) {
|
||||||
this.destroy();
|
this.destroy();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.ws.addEventListener("error", (err) => {
|
this.ws.addEventListener("error", (err) => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
if (!this.destroied)
|
if (!this.destroied) {
|
||||||
this.destroy();
|
this.destroy();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Client;
|
module.exports = Client;
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
const fs = require('fs');
|
||||||
|
const { promisify } = require('util');
|
||||||
|
const createKeccakHash = require('keccak');
|
||||||
|
const ColorEncoder = require('./ColorEncoder');
|
||||||
|
|
||||||
|
class Database {
|
||||||
|
static userdb;
|
||||||
|
|
||||||
|
static async load() {
|
||||||
|
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))
|
||||||
|
this.userdb = new Map(Object.entries(require("./db/users.json")));
|
||||||
|
} else {
|
||||||
|
this.userdb = new Map(Object.entries(require("./db/users.json")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getUserData(cl, server) {
|
||||||
|
if (!this.userdb || (this.userdb instanceof Map && [...this.userdb.entries()] == [])) {
|
||||||
|
await this.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
let _id = createKeccakHash('keccak256').update((cl.server._id_Private_Key + cl.ip)).digest('hex').substr(0, 24);
|
||||||
|
let usertofind = this.userdb.get(_id);
|
||||||
|
|
||||||
|
if (!usertofind) {
|
||||||
|
if (typeof usertofind == 'object' && (usertofind.hasOwnProperty('name') && usertofind.name != this.server.defaultUsername)) return;
|
||||||
|
|
||||||
|
this.userdb.set(_id, {
|
||||||
|
"color": `#${ColorEncoder.intToRGB(ColorEncoder.hashCode(_id)).toLowerCase()}`,
|
||||||
|
"name": server.defaultUsername,
|
||||||
|
"_id": _id,
|
||||||
|
"ip": cl.ip
|
||||||
|
});
|
||||||
|
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
let user = this.userdb.get(_id);
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async update() {
|
||||||
|
const writeFile = promisify(fs.writeFile);
|
||||||
|
await writeFile('src/db/users.json', JSON.stringify(this.strMapToObj(this.userdb), null, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
static strMapToObj(strMap) {
|
||||||
|
return [...strMap.entries()].reduce((obj, [key, value]) => (obj[key] = value, obj), {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Database;
|
117
src/Message.js
117
src/Message.js
|
@ -1,20 +1,27 @@
|
||||||
const Quota = require('./Quota');
|
const Quota = require('./Quota');
|
||||||
const User = require("./User.js");
|
const User = require("./User.js");
|
||||||
const Room = require("./Room.js");
|
const Room = require("./Room.js");
|
||||||
|
const RoomSettings = require('./RoomSettings');
|
||||||
|
|
||||||
module.exports = (cl) => {
|
module.exports = (cl) => {
|
||||||
cl.once("hi", () => {
|
cl.once("hi", msg => {
|
||||||
let user = new User(cl);
|
let m = {};
|
||||||
user.getUserData().then((data) => {
|
|
||||||
let msg = {};
|
m.m = "hi";
|
||||||
msg.m = "hi";
|
m.motd = cl.server.welcome_motd;
|
||||||
msg.motd = cl.server.welcome_motd;
|
m.t = Date.now();
|
||||||
msg.t = Date.now();
|
m.u = {
|
||||||
msg.u = data;
|
name: cl.user.name,
|
||||||
msg.v = "Beta";
|
_id: cl.user._id,
|
||||||
cl.sendArray([msg])
|
id: cl.participantId,
|
||||||
cl.user = data;
|
color: cl.user.color
|
||||||
})
|
};
|
||||||
})
|
|
||||||
|
m.v = "https://gitlab.com/hri7566/mpp-server";
|
||||||
|
|
||||||
|
cl.sendArray([m]);
|
||||||
|
});
|
||||||
|
|
||||||
cl.on("t", msg => {
|
cl.on("t", msg => {
|
||||||
if (msg.hasOwnProperty("e") && !isNaN(msg.e))
|
if (msg.hasOwnProperty("e") && !isNaN(msg.e))
|
||||||
cl.sendArray([{
|
cl.sendArray([{
|
||||||
|
@ -22,13 +29,17 @@ module.exports = (cl) => {
|
||||||
t: Date.now(),
|
t: Date.now(),
|
||||||
e: msg.e
|
e: msg.e
|
||||||
}])
|
}])
|
||||||
})
|
});
|
||||||
|
|
||||||
cl.on("ch", msg => {
|
cl.on("ch", msg => {
|
||||||
if (!msg.hasOwnProperty("set") || !msg.set) msg.set = {};
|
if (typeof(msg.set) !== 'object') msg.set = {};
|
||||||
|
|
||||||
if (msg.hasOwnProperty("_id") && typeof msg._id == "string") {
|
if (msg.hasOwnProperty("_id") && typeof msg._id == "string") {
|
||||||
if (msg._id.length > 512) return;
|
if (msg._id.length > 512) return;
|
||||||
if (!cl.staticQuotas.room.attempt()) return;
|
if (!cl.staticQuotas.room.attempt()) return;
|
||||||
|
|
||||||
cl.setChannel(msg._id, msg.set);
|
cl.setChannel(msg._id, msg.set);
|
||||||
|
|
||||||
let param;
|
let param;
|
||||||
if (cl.channel.isLobby(cl.channel._id)) {
|
if (cl.channel.isLobby(cl.channel._id)) {
|
||||||
param = Quota.N_PARAMS_LOBBY;
|
param = Quota.N_PARAMS_LOBBY;
|
||||||
|
@ -39,10 +50,12 @@ module.exports = (cl) => {
|
||||||
param = Quota.N_PARAMS_RIDICULOUS;
|
param = Quota.N_PARAMS_RIDICULOUS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
param.m = "nq";
|
param.m = "nq";
|
||||||
cl.sendArray([param])
|
cl.sendArray([param]);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
cl.on("m", (msg, admin) => {
|
cl.on("m", (msg, admin) => {
|
||||||
// if (!cl.quotas.cursor.attempt() && !admin) return;
|
// if (!cl.quotas.cursor.attempt() && !admin) return;
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
if (!(cl.channel && cl.participantId)) return;
|
||||||
|
@ -50,43 +63,63 @@ module.exports = (cl) => {
|
||||||
if (!msg.hasOwnProperty("y")) msg.y = null;
|
if (!msg.hasOwnProperty("y")) msg.y = null;
|
||||||
if (parseInt(msg.x) == NaN) msg.x = null;
|
if (parseInt(msg.x) == NaN) msg.x = null;
|
||||||
if (parseInt(msg.y) == NaN) msg.y = null;
|
if (parseInt(msg.y) == NaN) msg.y = null;
|
||||||
cl.channel.emit("m", cl, msg.x, msg.y)
|
cl.channel.emit("m", cl, msg.x, msg.y);
|
||||||
|
});
|
||||||
|
|
||||||
})
|
|
||||||
cl.on("chown", (msg, admin) => {
|
cl.on("chown", (msg, admin) => {
|
||||||
if (!cl.quotas.chown.attempt() && !admin) return;
|
if (!cl.quotas.chown.attempt() && !admin) return;
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
if (!(cl.channel && cl.participantId)) return;
|
||||||
|
|
||||||
//console.log((Date.now() - cl.channel.crown.time))
|
//console.log((Date.now() - cl.channel.crown.time))
|
||||||
//console.log(!(cl.channel.crown.userId != cl.user._id), !((Date.now() - cl.channel.crown.time) > 15000));
|
//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 (!(cl.channel.crown.userId == cl.user._id) && !((Date.now() - cl.channel.crown.time) > 15000)) return;
|
||||||
|
|
||||||
if (msg.hasOwnProperty("id")) {
|
if (msg.hasOwnProperty("id")) {
|
||||||
// console.log(cl.channel.crown)
|
// console.log(cl.channel.crown)
|
||||||
if (cl.user._id == cl.channel.crown.userId || cl.channel.crowndropped)
|
if (!admin) {
|
||||||
|
if (cl.user._id == cl.channel.crown.userId || cl.channel.crowndropped) {
|
||||||
|
cl.channel.chown(msg.id);
|
||||||
|
if (msg.id == cl.user.id) {
|
||||||
|
param = Quota.N_PARAMS_RIDICULOUS;
|
||||||
|
param.m = "nq";
|
||||||
|
cl.sendArray([param])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
cl.channel.chown(msg.id);
|
cl.channel.chown(msg.id);
|
||||||
if (msg.id == cl.user.id) {
|
if (msg.id == cl.user.id) {
|
||||||
param = Quota.N_PARAMS_RIDICULOUS;
|
param = Quota.N_PARAMS_RIDICULOUS;
|
||||||
param.m = "nq";
|
param.m = "nq";
|
||||||
cl.sendArray([param])
|
cl.sendArray([param])
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (cl.user._id == cl.channel.crown.userId || cl.channel.crowndropped)
|
if (!admin) {
|
||||||
|
if (cl.user._id == cl.channel.crown.userId || cl.channel.crowndropped) {
|
||||||
|
cl.channel.chown();
|
||||||
|
param = Quota.N_PARAMS_NORMAL;
|
||||||
|
param.m = "nq";
|
||||||
|
cl.sendArray([param])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
cl.channel.chown();
|
cl.channel.chown();
|
||||||
param = Quota.N_PARAMS_NORMAL;
|
param = Quota.N_PARAMS_NORMAL;
|
||||||
param.m = "nq";
|
param.m = "nq";
|
||||||
cl.sendArray([param])
|
cl.sendArray([param]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
cl.on("chset", msg => {
|
cl.on("chset", msg => {
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
if (!(cl.channel && cl.participantId)) return;
|
||||||
|
if (!cl.channel.crown) return;
|
||||||
if (!(cl.user._id == cl.channel.crown.userId)) return;
|
if (!(cl.user._id == cl.channel.crown.userId)) return;
|
||||||
if (!msg.hasOwnProperty("set") || !msg.set) msg.set = cl.channel.verifySet(cl.channel._id,{});
|
if (!msg.hasOwnProperty("set") || !msg.set) msg.set = new RoomSettings(cl.channel.settings, 'user');
|
||||||
Object.keys(cl.channel.settings).forEach(key => {
|
cl.channel.settings.changeSettings(msg.set);
|
||||||
if (cl.channel.settings[key] !== msg.set[key]) {
|
|
||||||
cl.channel.settings[key] = msg.set[key];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
cl.channel.updateCh();
|
cl.channel.updateCh();
|
||||||
})
|
});
|
||||||
|
|
||||||
cl.on("a", (msg, admin) => {
|
cl.on("a", (msg, admin) => {
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
if (!(cl.channel && cl.participantId)) return;
|
||||||
if (!msg.hasOwnProperty('message')) return;
|
if (!msg.hasOwnProperty('message')) return;
|
||||||
|
@ -102,7 +135,8 @@ module.exports = (cl) => {
|
||||||
}
|
}
|
||||||
cl.channel.emit('a', cl, msg);
|
cl.channel.emit('a', cl, msg);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
cl.on('n', msg => {
|
cl.on('n', msg => {
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
if (!(cl.channel && cl.participantId)) return;
|
||||||
if (!msg.hasOwnProperty('t') || !msg.hasOwnProperty('n')) return;
|
if (!msg.hasOwnProperty('t') || !msg.hasOwnProperty('n')) return;
|
||||||
|
@ -114,7 +148,8 @@ module.exports = (cl) => {
|
||||||
} else {
|
} else {
|
||||||
cl.channel.playNote(cl, msg);
|
cl.channel.playNote(cl, msg);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
cl.on('+ls', msg => {
|
cl.on('+ls', msg => {
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
if (!(cl.channel && cl.participantId)) return;
|
||||||
cl.server.roomlisteners.set(cl.connectionid, cl);
|
cl.server.roomlisteners.set(cl.connectionid, cl);
|
||||||
|
@ -131,11 +166,13 @@ module.exports = (cl) => {
|
||||||
"c": true,
|
"c": true,
|
||||||
"u": rooms
|
"u": rooms
|
||||||
}])
|
}])
|
||||||
})
|
});
|
||||||
|
|
||||||
cl.on('-ls', msg => {
|
cl.on('-ls', msg => {
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
if (!(cl.channel && cl.participantId)) return;
|
||||||
cl.server.roomlisteners.delete(cl.connectionid);
|
cl.server.roomlisteners.delete(cl.connectionid);
|
||||||
})
|
});
|
||||||
|
|
||||||
cl.on("userset", msg => {
|
cl.on("userset", msg => {
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
if (!(cl.channel && cl.participantId)) return;
|
||||||
if (!msg.hasOwnProperty("set") || !msg.set) msg.set = {};
|
if (!msg.hasOwnProperty("set") || !msg.set) msg.set = {};
|
||||||
|
@ -157,7 +194,8 @@ module.exports = (cl) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
cl.on('kickban', msg => {
|
cl.on('kickban', msg => {
|
||||||
if (cl.channel.crown == null) return;
|
if (cl.channel.crown == null) return;
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
if (!(cl.channel && cl.participantId)) return;
|
||||||
|
@ -169,17 +207,20 @@ module.exports = (cl) => {
|
||||||
let ms = msg.ms || 3600000;
|
let ms = msg.ms || 3600000;
|
||||||
cl.channel.kickban(_id, ms);
|
cl.channel.kickban(_id, ms);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
cl.on("bye", msg => {
|
cl.on("bye", msg => {
|
||||||
cl.destroy();
|
cl.destroy();
|
||||||
})
|
});
|
||||||
|
|
||||||
cl.on("admin message", msg => {
|
cl.on("admin message", msg => {
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
if (!(cl.channel && cl.participantId)) return;
|
||||||
if (!msg.hasOwnProperty('password') || !msg.hasOwnProperty('msg')) return;
|
if (!msg.hasOwnProperty('password') || !msg.hasOwnProperty('msg')) return;
|
||||||
if (typeof msg.msg != 'object') return;
|
if (typeof msg.msg != 'object') return;
|
||||||
if (msg.password !== cl.server.adminpass) return;
|
if (msg.password !== cl.server.adminpass) return;
|
||||||
cl.ws.emit("message", JSON.stringify([msg.msg]), true);
|
cl.ws.emit("message", JSON.stringify([msg.msg]), true);
|
||||||
})
|
});
|
||||||
|
|
||||||
//admin only stuff
|
//admin only stuff
|
||||||
cl.on('color', (msg, admin) => {
|
cl.on('color', (msg, admin) => {
|
||||||
if (!admin) return;
|
if (!admin) return;
|
||||||
|
|
133
src/Room.js
133
src/Room.js
|
@ -2,7 +2,11 @@
|
||||||
//room class
|
//room class
|
||||||
//room deleter
|
//room deleter
|
||||||
//databases in Map
|
//databases in Map
|
||||||
|
|
||||||
|
const createKeccakHash = require('keccak');
|
||||||
const Quota = require("./Quota.js");
|
const Quota = require("./Quota.js");
|
||||||
|
const RoomSettings = require('./RoomSettings.js');
|
||||||
|
|
||||||
class Room extends EventEmitter {
|
class Room extends EventEmitter {
|
||||||
constructor(server, _id, settings) {
|
constructor(server, _id, settings) {
|
||||||
super();
|
super();
|
||||||
|
@ -11,9 +15,7 @@ class Room extends EventEmitter {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.crown = null;
|
this.crown = null;
|
||||||
this.crowndropped = false;
|
this.crowndropped = false;
|
||||||
this.settings = this.verifySet(this._id, {
|
this.settings = settings;
|
||||||
set: settings
|
|
||||||
});
|
|
||||||
this.chatmsgs = [];
|
this.chatmsgs = [];
|
||||||
this.ppl = new Map();
|
this.ppl = new Map();
|
||||||
this.connections = [];
|
this.connections = [];
|
||||||
|
@ -21,14 +23,15 @@ class Room extends EventEmitter {
|
||||||
this.server.rooms.set(_id, this);
|
this.server.rooms.set(_id, this);
|
||||||
this.bans = new Map();
|
this.bans = new Map();
|
||||||
}
|
}
|
||||||
join(cl) { //this stuff is complicated
|
|
||||||
|
join(cl, set) { //this stuff is complicated
|
||||||
let otheruser = this.connections.find((a) => a.user._id == cl.user._id)
|
let otheruser = this.connections.find((a) => a.user._id == cl.user._id)
|
||||||
if (!otheruser) {
|
if (!otheruser) {
|
||||||
let participantId = createKeccakHash('keccak256').update((Math.random().toString() + cl.ip)).digest('hex').substr(0, 24);
|
let participantId = createKeccakHash('keccak256').update((Math.random().toString() + cl.ip)).digest('hex').substr(0, 24);
|
||||||
cl.user.id = participantId;
|
cl.user.id = participantId;
|
||||||
cl.participantId = participantId;
|
cl.participantId = participantId;
|
||||||
cl.initParticipantQuotas();
|
cl.initParticipantQuotas();
|
||||||
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.
|
if (((this.connections.length == 0 && Array.from(this.ppl.values()).length == 0) && this.isLobby(this._id) == false) || this.crown && (this.crown.userId == cl.user._id)) { //user that created the room, give them the crown.
|
||||||
//cl.quotas.a.setParams(Quota.PARAMS_A_CROWNED);
|
//cl.quotas.a.setParams(Quota.PARAMS_A_CROWNED);
|
||||||
this.crown = {
|
this.crown = {
|
||||||
participantId: cl.participantId,
|
participantId: cl.participantId,
|
||||||
|
@ -43,15 +46,29 @@ class Room extends EventEmitter {
|
||||||
y: this.getCrownY()
|
y: this.getCrownY()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.crowndropped = false;
|
this.crowndropped = false;
|
||||||
this.settings = {visible:true,color:this.server.defaultRoomColor,chat:true,crownsolo:false};
|
this.settings = new RoomSettings(set, 'user');
|
||||||
} else {
|
} else {
|
||||||
//cl.quotas.a.setParams(Quota.PARAMS_A_NORMAL);
|
//cl.quotas.a.setParams(Quota.PARAMS_A_NORMAL);
|
||||||
this.settings = {visible:true,color:this.server.defaultRoomColor,chat:true,crownsolo:false,lobby:true};
|
console.log(this.isLobby(this._id));
|
||||||
|
|
||||||
|
if (this.isLobby(this._id)) {
|
||||||
|
this.settings = new RoomSettings(this.server.lobbySettings, 'user');
|
||||||
|
this.settings.visible = true;
|
||||||
|
this.settings.crownsolo = false;
|
||||||
|
this.settings.color = this.server.lobbySettings.color;
|
||||||
|
this.settings.color2 = this.server.lobbySettings.color2;
|
||||||
|
this.settings.lobby = true;
|
||||||
|
} else {
|
||||||
|
this.settings = new RoomSettings(set, 'user');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ppl.set(participantId, cl);
|
this.ppl.set(participantId, cl);
|
||||||
|
|
||||||
this.connections.push(cl);
|
this.connections.push(cl);
|
||||||
|
|
||||||
this.sendArray([{
|
this.sendArray([{
|
||||||
color: this.ppl.get(cl.participantId).user.color,
|
color: this.ppl.get(cl.participantId).user.color,
|
||||||
id: this.ppl.get(cl.participantId).participantId,
|
id: this.ppl.get(cl.participantId).participantId,
|
||||||
|
@ -79,6 +96,7 @@ class Room extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(p) { //this is complicated too
|
remove(p) { //this is complicated too
|
||||||
let otheruser = this.connections.filter((a) => a.user._id == p.user._id);
|
let otheruser = this.connections.filter((a) => a.user._id == p.user._id);
|
||||||
if (!(otheruser.length > 1)) {
|
if (!(otheruser.length > 1)) {
|
||||||
|
@ -99,31 +117,40 @@ class Room extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCh(cl) { //update channel for all people in channel
|
updateCh(cl) { //update channel for all people in channel
|
||||||
if (Array.from(this.ppl.values()).length <= 0) {
|
if (Array.from(this.ppl.values()).length <= 0) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.destroy();
|
this.destroy();
|
||||||
}, 10000);
|
}, 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.connections.forEach((usr) => {
|
this.connections.forEach((usr) => {
|
||||||
this.server.connections.get(usr.connectionid).sendArray([this.fetchData(usr, cl)])
|
this.server.connections.get(usr.connectionid).sendArray([this.fetchData(usr, cl)])
|
||||||
})
|
});
|
||||||
|
|
||||||
this.server.updateRoom(this.fetchData());
|
this.server.updateRoom(this.fetchData());
|
||||||
}
|
}
|
||||||
|
|
||||||
updateParticipant(pid, options) {
|
updateParticipant(pid, options) {
|
||||||
let p = null;
|
let p;
|
||||||
|
|
||||||
Array.from(this.ppl).map(rpg => {
|
Array.from(this.ppl).map(rpg => {
|
||||||
if(rpg[1].user._id == pid) p = rpg[1];
|
if (rpg[1].user._id == pid) p = rpg[1];
|
||||||
});
|
});
|
||||||
if (p == null) return;
|
|
||||||
|
if (typeof(p) == 'undefined') return;
|
||||||
|
|
||||||
options.name ? p.user.name = options.name : {};
|
options.name ? p.user.name = options.name : {};
|
||||||
options._id ? p.user._id = options._id : {};
|
options._id ? p.user._id = options._id : {};
|
||||||
options.color ? p.user.color = options.color : {};
|
options.color ? p.user.color = options.color : {};
|
||||||
|
|
||||||
this.connections.filter((ofo) => ofo.participantId == p.participantId).forEach((usr) => {
|
this.connections.filter((ofo) => ofo.participantId == p.participantId).forEach((usr) => {
|
||||||
options.name ? usr.user.name = options.name : {};
|
options.name ? usr.user.name = options.name : {};
|
||||||
options._id ? usr.user._id = options._id : {};
|
options._id ? usr.user._id = options._id : {};
|
||||||
options.color ? usr.user.color = options.color : {};
|
options.color ? usr.user.color = options.color : {};
|
||||||
})
|
});
|
||||||
|
|
||||||
this.sendArray([{
|
this.sendArray([{
|
||||||
color: p.user.color,
|
color: p.user.color,
|
||||||
id: p.participantId,
|
id: p.participantId,
|
||||||
|
@ -132,17 +159,20 @@ class Room extends EventEmitter {
|
||||||
x: p.x || 200,
|
x: p.x || 200,
|
||||||
y: p.y || 100,
|
y: p.y || 100,
|
||||||
_id: p.user._id
|
_id: p.user._id
|
||||||
}])
|
}]);
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() { //destroy room
|
destroy() { //destroy room
|
||||||
|
if (this.ppl.size > 0) return;
|
||||||
this._id;
|
this._id;
|
||||||
console.log(`Deleted room ${this._id}`);
|
console.log(`Deleted room ${this._id}`);
|
||||||
this.settings = {};
|
this.settings = undefined;
|
||||||
this.ppl;
|
this.ppl;
|
||||||
this.connnections;
|
this.connnections;
|
||||||
this.chatmsgs;
|
this.chatmsgs;
|
||||||
this.server.rooms.delete(this._id);
|
this.server.rooms.delete(this._id);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendArray(arr, not, onlythisparticipant) {
|
sendArray(arr, not, onlythisparticipant) {
|
||||||
this.connections.forEach((usr) => {
|
this.connections.forEach((usr) => {
|
||||||
if (!not || (usr.participantId != not.participantId && !onlythisparticipant) || (usr.connectionid != not.connectionid && onlythisparticipant)) {
|
if (!not || (usr.participantId != not.participantId && !onlythisparticipant) || (usr.connectionid != not.connectionid && onlythisparticipant)) {
|
||||||
|
@ -152,13 +182,16 @@ class Room extends EventEmitter {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchData(usr, cl) {
|
fetchData(usr, cl) {
|
||||||
let chppl = [];
|
let chppl = [];
|
||||||
|
|
||||||
[...this.ppl.values()].forEach((a) => {
|
[...this.ppl.values()].forEach((a) => {
|
||||||
chppl.push(a.user);
|
chppl.push(a.user);
|
||||||
})
|
});
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
m: "ch",
|
m: "ch",
|
||||||
p: "ofo",
|
p: "ofo",
|
||||||
|
@ -170,6 +203,7 @@ class Room extends EventEmitter {
|
||||||
},
|
},
|
||||||
ppl: chppl
|
ppl: chppl
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cl) {
|
if (cl) {
|
||||||
if (usr.connectionid == cl.connectionid) {
|
if (usr.connectionid == cl.connectionid) {
|
||||||
data.p = cl.participantId;
|
data.p = cl.participantId;
|
||||||
|
@ -179,13 +213,16 @@ class Room extends EventEmitter {
|
||||||
} else {
|
} else {
|
||||||
delete data.p;
|
delete data.p;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.ch.crown == null) {
|
if (data.ch.crown == null) {
|
||||||
delete data.ch.crown;
|
delete data.ch.crown;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
verifyColor(strColor) {
|
verifyColor(strColor) {
|
||||||
var test2 = /^#[0-9A-F]{6}$/i.test(strColor);
|
var test2 = /^#[0-9A-F]{6}$/i.test(strColor);
|
||||||
if (test2 == true) {
|
if (test2 == true) {
|
||||||
|
@ -194,6 +231,7 @@ class Room extends EventEmitter {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isLobby(_id) {
|
isLobby(_id) {
|
||||||
if (_id.startsWith("lobby")) {
|
if (_id.startsWith("lobby")) {
|
||||||
if (_id == "lobby") {
|
if (_id == "lobby") {
|
||||||
|
@ -221,12 +259,15 @@ class Room extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCrownY() {
|
getCrownY() {
|
||||||
return 50 - 30;
|
return Math.floor(Math.random() * 10000) / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCrownX() {
|
getCrownX() {
|
||||||
return 50;
|
return Math.floor(Math.random() * 10000) / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
chown(id) {
|
chown(id) {
|
||||||
let prsn = this.ppl.get(id);
|
let prsn = this.ppl.get(id);
|
||||||
if (prsn) {
|
if (prsn) {
|
||||||
|
@ -259,9 +300,11 @@ class Room extends EventEmitter {
|
||||||
}
|
}
|
||||||
this.crowndropped = true;
|
this.crowndropped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateCh();
|
this.updateCh();
|
||||||
}
|
}
|
||||||
setCords(p, x, y) {
|
|
||||||
|
setCoords(p, x, y) {
|
||||||
if (p.participantId && this.ppl.get(p.participantId)) {
|
if (p.participantId && this.ppl.get(p.participantId)) {
|
||||||
x ? this.ppl.get(p.participantId).x = x : {};
|
x ? this.ppl.get(p.participantId).x = x : {};
|
||||||
y ? this.ppl.get(p.participantId).y = y : {};
|
y ? this.ppl.get(p.participantId).y = y : {};
|
||||||
|
@ -273,6 +316,7 @@ class Room extends EventEmitter {
|
||||||
}], p, false);
|
}], p, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chat(p, msg) {
|
chat(p, msg) {
|
||||||
if (msg.message.length > 512) return;
|
if (msg.message.length > 512) return;
|
||||||
let filter = ["AMIGHTYWIND"];
|
let filter = ["AMIGHTYWIND"];
|
||||||
|
@ -309,6 +353,7 @@ class Room extends EventEmitter {
|
||||||
this.chatmsgs.push(message);
|
this.chatmsgs.push(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
playNote(cl, note) {
|
playNote(cl, note) {
|
||||||
this.sendArray([{
|
this.sendArray([{
|
||||||
m: "n",
|
m: "n",
|
||||||
|
@ -317,6 +362,7 @@ class Room extends EventEmitter {
|
||||||
t: note.t
|
t: note.t
|
||||||
}], cl, true);
|
}], cl, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
kickban(_id, ms) {
|
kickban(_id, ms) {
|
||||||
ms = parseInt(ms);
|
ms = parseInt(ms);
|
||||||
if (ms >= (1000 * 60 * 60)) return;
|
if (ms >= (1000 * 60 * 60)) return;
|
||||||
|
@ -365,6 +411,7 @@ class Room extends EventEmitter {
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
Notification(who, title, text, html, duration, target, klass, id) {
|
Notification(who, title, text, html, duration, target, klass, id) {
|
||||||
let obj = {
|
let obj = {
|
||||||
m: "notification",
|
m: "notification",
|
||||||
|
@ -410,7 +457,7 @@ class Room extends EventEmitter {
|
||||||
})
|
})
|
||||||
|
|
||||||
this.on("m", (participant, x, y) => {
|
this.on("m", (participant, x, y) => {
|
||||||
this.setCords(participant, x, y);
|
this.setCoords(participant, x, y);
|
||||||
})
|
})
|
||||||
|
|
||||||
this.on("a", (participant, msg) => {
|
this.on("a", (participant, msg) => {
|
||||||
|
@ -418,37 +465,27 @@ class Room extends EventEmitter {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
verifySet(_id,msg){
|
verifySet(_id, msg){
|
||||||
if(!isObj(msg.set)) msg.set = {visible:true,color:this.server.defaultRoomColor,chat:true,crownsolo:false};
|
if(typeof(msg.set) !== 'object') {
|
||||||
if(isBool(msg.set.lobby)){
|
msg.set = {
|
||||||
if(!this.isLobby(_id)) delete msg.set.lobby; // keep it nice and clean
|
visible: true,
|
||||||
}else{
|
color: this.server.defaultSettings.color, chat:true,
|
||||||
if(this.isLobby(_id)) msg.set = {visible:true,color:this.server.defaultLobbyColor,color2:this.server.defaultLobbyColor2,chat:true,crownsolo:false,lobby:true};
|
crownsolo:false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(!isBool(msg.set.visible)){
|
|
||||||
if(msg.set.visible == undefined) msg.set.visible = (!isObj(this.settings) ? true : this.settings.visible);
|
msg.set = RoomSettings.changeSettings(msg.set);
|
||||||
else msg.set.visible = true;
|
|
||||||
};
|
if (typeof(msg.set.lobby) !== 'undefined') {
|
||||||
if(!isBool(msg.set.chat)){
|
if (msg.set.lobby == true) {
|
||||||
if(msg.set.chat == undefined) msg.set.chat = (!isObj(this.settings) ? true : this.settings.chat);
|
if (!this.isLobby(_id)) delete msg.set.lobby; // keep it nice and clean
|
||||||
else msg.set.chat = true;
|
} else {
|
||||||
};
|
if (this.isLobby(_id)) {
|
||||||
if(!isBool(msg.set.crownsolo)){
|
msg.set = this.server.lobbySettings;
|
||||||
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
|
|
||||||
} else {
|
|
||||||
delete msg.set.color2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
return msg.set;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Room;
|
module.exports = Room;
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
class RoomSettings {
|
||||||
|
static allowedProperties = {
|
||||||
|
color: {
|
||||||
|
type: 'color',
|
||||||
|
default: "#9900ff",
|
||||||
|
allowedChange: true,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
color2: {
|
||||||
|
type: 'color2',
|
||||||
|
default: "#5900bf",
|
||||||
|
allowedChange: true,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
lobby: {
|
||||||
|
type: 'boolean',
|
||||||
|
allowedChange: false,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
visible: {
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
allowedChange: true,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
chat: {
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
allowedChange: true,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
owner_id: {
|
||||||
|
type: 'string',
|
||||||
|
allowedChange: false,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
crownsolo: {
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
allowedChange: true,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor (set, cont) {
|
||||||
|
Object.keys(RoomSettings.allowedProperties).forEach(key => {
|
||||||
|
if (typeof(RoomSettings.allowedProperties[key].default) !== 'undefined') {
|
||||||
|
if (this[key] !== RoomSettings.allowedProperties[key].default) {
|
||||||
|
this[key] = RoomSettings.allowedProperties[key].default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(RoomSettings.allowedProperties).forEach(key => {
|
||||||
|
if (RoomSettings.allowedProperties[key].required == true) {
|
||||||
|
if (typeof(this[key]) == 'undefined') {
|
||||||
|
this[key] = RoomSettings.allowedProperties[key].default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (typeof(set) !== 'undefined') {
|
||||||
|
Object.keys(set).forEach(key => {
|
||||||
|
if (typeof(set[key]) == 'undefined') return;
|
||||||
|
if (Object.keys(RoomSettings.allowedProperties).indexOf(key) !== -1) {
|
||||||
|
if (typeof(cont) == 'undefined') {
|
||||||
|
this[key] = this.verifyPropertyType(key, set[key], RoomSettings.allowedProperties[key].type);
|
||||||
|
} else {
|
||||||
|
if (cont == 'user') {
|
||||||
|
if (RoomSettings.allowedProperties[key].allowedChange) {
|
||||||
|
this[key] = this.verifyPropertyType(key, set[key], RoomSettings.allowedProperties[key].type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
verifyPropertyType(key, pr, type) {
|
||||||
|
let ret;
|
||||||
|
|
||||||
|
if (typeof(RoomSettings.allowedProperties[key]) !== 'object') return;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'color':
|
||||||
|
if (/^#[0-9a-f]{6}$/i.test(pr)) {
|
||||||
|
ret = pr;
|
||||||
|
} else {
|
||||||
|
ret = RoomSettings.allowedProperties[key].default;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'color2':
|
||||||
|
if (/^#[0-9a-f]{6}$/i.test(pr)) {
|
||||||
|
ret = pr;
|
||||||
|
} else {
|
||||||
|
ret = RoomSettings.allowedProperties[key].default;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (typeof(pr) == type) {
|
||||||
|
ret = pr;
|
||||||
|
} else if (typeof(RoomSettings.allowedProperties[key].default) !== 'undefined') {
|
||||||
|
ret = RoomSettings.allowedProperties[key].default;
|
||||||
|
} else {
|
||||||
|
ret = undefined;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
changeSettings(set) {
|
||||||
|
Object.keys(set).forEach(key => {
|
||||||
|
if (RoomSettings.allowedProperties[key].allowedChange) {
|
||||||
|
this[key] = this.verifyPropertyType(key, set[key], RoomSettings.allowedProperties[key].type);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static changeSettings(set) {
|
||||||
|
Object.keys(set).forEach(key => {
|
||||||
|
if (RoomSettings.allowedProperties[key].allowedChange) {
|
||||||
|
set[key] = RoomSettings.verifyPropertyType(key, set[key], RoomSettings.allowedProperties[key].type);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
static verifyPropertyType(key, pr, type) {
|
||||||
|
let ret;
|
||||||
|
|
||||||
|
if (typeof(RoomSettings.allowedProperties[key]) !== 'object') return;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'color':
|
||||||
|
if (/^#[0-9a-f]{6}$/i.test(pr)) {
|
||||||
|
ret = pr;
|
||||||
|
} else {
|
||||||
|
ret = RoomSettings.allowedProperties[key].default;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'color2':
|
||||||
|
if (/^#[0-9a-f]{6}$/i.test(pr)) {
|
||||||
|
ret = pr;
|
||||||
|
} else {
|
||||||
|
ret = RoomSettings.allowedProperties[key].default;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (typeof(pr) == type) {
|
||||||
|
ret = pr;
|
||||||
|
} else if (typeof(RoomSettings.allowedProperties[key].default) !== 'undefined') {
|
||||||
|
ret = RoomSettings.allowedProperties[key].default;
|
||||||
|
} else {
|
||||||
|
ret = undefined;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = RoomSettings;
|
|
@ -3,11 +3,13 @@ const banned = require('../banned.json');
|
||||||
const https = require("https");
|
const https = require("https");
|
||||||
const http = require("http");
|
const http = require("http");
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const RoomSettings = require('./RoomSettings');
|
||||||
|
|
||||||
class Server extends EventEmitter {
|
class Server extends EventEmitter {
|
||||||
constructor(config) {
|
constructor(config) {
|
||||||
super();
|
super();
|
||||||
EventEmitter.call(this);
|
EventEmitter.call(this);
|
||||||
|
|
||||||
if (config.ssl == true) {
|
if (config.ssl == true) {
|
||||||
this.https_server = https.createServer({
|
this.https_server = https.createServer({
|
||||||
key: fs.readFileSync('ssl/privkey.pem', 'utf8'),
|
key: fs.readFileSync('ssl/privkey.pem', 'utf8'),
|
||||||
|
@ -35,31 +37,42 @@ class Server extends EventEmitter {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.defaultUsername = "Anonymous";
|
||||||
|
this.defaultRoomSettings = new RoomSettings(config.defaultRoomSettings);
|
||||||
|
|
||||||
|
this.lobbySettings = new RoomSettings(config.defaultRoomSettings);
|
||||||
|
this.lobbySettings.lobby = true;
|
||||||
|
this.lobbySettings.color = config.defaultLobbyColor || "#9900ff";
|
||||||
|
this.lobbySettings.color2 = config.defaultLobbyColor2 || "#9900ff";
|
||||||
|
|
||||||
console.log(`Server started on port ${config.port}`);
|
console.log(`Server started on port ${config.port}`);
|
||||||
this.connectionid = 0;
|
this.connectionid = 0;
|
||||||
this.connections = new Map();
|
this.connections = new Map();
|
||||||
this.roomlisteners = new Map();
|
this.roomlisteners = new Map();
|
||||||
this.rooms = new Map();
|
this.rooms = new Map();
|
||||||
|
|
||||||
this.wss.on('connection', (ws, req) => {
|
this.wss.on('connection', (ws, req) => {
|
||||||
this.connections.set(++this.connectionid, new Client(ws, req, this));
|
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", "eval", "notification"]
|
this.legit_m = ["a", "bye", "hi", "ch", "+ls", "-ls", "m", "n", "devices", "t", "chset", "userset", "chown", "kickban", "admin message", "color", "eval", "notification"]
|
||||||
this.welcome_motd = config.motd || "You agree to read this message.";
|
this.welcome_motd = config.motd || "You agree to read this message.";
|
||||||
|
|
||||||
this._id_Private_Key = config._id_PrivateKey || "boppity";
|
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";
|
this.adminpass = config.adminpass || "Bop It";
|
||||||
};
|
}
|
||||||
|
|
||||||
updateRoom(data) {
|
updateRoom(data) {
|
||||||
if (!data.ch.settings.visible) return;
|
if (!data.ch.settings.visible) return;
|
||||||
|
|
||||||
for (let cl of Array.from(this.roomlisteners.values())) {
|
for (let cl of Array.from(this.roomlisteners.values())) {
|
||||||
cl.sendArray([{
|
cl.sendArray([{
|
||||||
"m": "ls",
|
"m": "ls",
|
||||||
"c": false,
|
"c": false,
|
||||||
"u": [data.ch]
|
"u": [data.ch]
|
||||||
}])
|
}]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
65
src/User.js
65
src/User.js
|
@ -1,53 +1,24 @@
|
||||||
const ColorEncoder = require("./ColorEncoder.js");
|
const Database = require("./Database");
|
||||||
const { promisify } = require('util');
|
|
||||||
let userdb;
|
|
||||||
class User {
|
class User {
|
||||||
constructor(cl) {
|
constructor(cl, data) {
|
||||||
this.cl = cl;
|
this.server = cl.server;
|
||||||
this.server = this.cl.server;
|
this.name = data.name;
|
||||||
this.userdb = userdb;
|
this._id = data._id;
|
||||||
this.default_db = {};
|
this.color = data.color;
|
||||||
|
this.ip = data.ip;
|
||||||
}
|
}
|
||||||
async getUserData() {
|
|
||||||
if (!userdb || (userdb instanceof Map && [...userdb.entries()] == [])) {
|
static updateUserModel(cl, user) {
|
||||||
await this.setUpDb();
|
let u2 = new User(cl, user);
|
||||||
|
if (typeof(u2) == 'undefined') return;
|
||||||
|
|
||||||
|
for (let id in Object.keys(u2)) {
|
||||||
|
if (!user.hasOwnProperty(id)) {
|
||||||
|
user[id] = u2[id];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
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;
|
module.exports = User;
|
||||||
|
|
Loading…
Reference in New Issue