forked from Hri7566/mpp-server-dev2
best update ever
This commit is contained in:
parent
35c52b5a12
commit
2f33925be5
|
@ -2,3 +2,4 @@
|
||||||
node_modules
|
node_modules
|
||||||
ssl/
|
ssl/
|
||||||
src/db/users.json
|
src/db/users.json
|
||||||
|
.history
|
||||||
|
|
|
@ -31,4 +31,4 @@ module.exports = Object.seal({
|
||||||
amount: 2,
|
amount: 2,
|
||||||
time: 1000
|
time: 1000
|
||||||
}
|
}
|
||||||
})
|
});
|
10
config.js
10
config.js
|
@ -4,15 +4,15 @@ module.exports = Object.seal({
|
||||||
_id_PrivateKey: process.env.SALT,
|
_id_PrivateKey: process.env.SALT,
|
||||||
defaultUsername: "Anonymous",
|
defaultUsername: "Anonymous",
|
||||||
// defaultRoomColor: "#3b5054",
|
// defaultRoomColor: "#3b5054",
|
||||||
defaultRoomColor: "#000000",
|
|
||||||
// defaultLobbyColor: "#19b4b9",
|
// defaultLobbyColor: "#19b4b9",
|
||||||
defaultLobbyColor: "#9900ff",
|
defaultLobbyColor: "#76b0db",
|
||||||
// defaultLobbyColor2: "#801014",
|
// defaultLobbyColor2: "#801014",
|
||||||
defaultLobbyColor2: "#801014",
|
defaultLobbyColor2: "#276491",
|
||||||
adminpass: process.env.ADMINPASS,
|
adminpass: process.env.ADMINPASS,
|
||||||
ssl: true,
|
ssl: false,
|
||||||
defaultRoomSettings: {
|
defaultRoomSettings: {
|
||||||
color: "#000000",
|
color: "#3b5054",
|
||||||
|
color2: "#001014",
|
||||||
crownsolo: false,
|
crownsolo: false,
|
||||||
visible: true
|
visible: true
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,6 +26,8 @@
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"events": "^3.1.0",
|
"events": "^3.1.0",
|
||||||
"keccak": "^2.1.0",
|
"keccak": "^2.1.0",
|
||||||
|
"level": "^7.0.0",
|
||||||
|
"mongoose": "^5.12.7",
|
||||||
"node-json-color-stringify": "^1.1.0",
|
"node-json-color-stringify": "^1.1.0",
|
||||||
"ws": "^7.2.3"
|
"ws": "^7.2.3"
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,9 @@ class Client extends EventEmitter {
|
||||||
if (channel) this.channel.updateCh(this);
|
if (channel) this.channel.updateCh(this);
|
||||||
|
|
||||||
this.channel = this.server.rooms.get(_id);
|
this.channel = this.server.rooms.get(_id);
|
||||||
this.channel.join(this);
|
if (!this.user.hasFlag("hidden", true)) {
|
||||||
|
this.channel.join(this);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let room = new Room(this.server, _id, settings);
|
let room = new Room(this.server, _id, settings);
|
||||||
this.server.rooms.set(_id, room);
|
this.server.rooms.set(_id, room);
|
||||||
|
@ -109,7 +111,7 @@ class Client extends EventEmitter {
|
||||||
destroy() {
|
destroy() {
|
||||||
this.ws.close();
|
this.ws.close();
|
||||||
if (this.channel) {
|
if (this.channel) {
|
||||||
this.channel.emit("bye", this)
|
this.channel.emit("bye", this);
|
||||||
}
|
}
|
||||||
this.user;
|
this.user;
|
||||||
this.participantId;
|
this.participantId;
|
||||||
|
@ -118,7 +120,7 @@ class Client extends EventEmitter {
|
||||||
this.connectionid;
|
this.connectionid;
|
||||||
this.server.connections.delete(this.connectionid);
|
this.server.connections.delete(this.connectionid);
|
||||||
this.destroied = true;
|
this.destroied = true;
|
||||||
console.log(`Removed Connection ${this.connectionid}.`);
|
console.log(`Removed Connection ${this.connectionid}. user is ${this.user}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
bindEventListeners() {
|
bindEventListeners() {
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
module.exports = class Crown {
|
||||||
|
constructor (id, _id) {
|
||||||
|
this.participantId = id;
|
||||||
|
this.userId = _id;
|
||||||
|
this.time = Date.now();
|
||||||
|
this.startPos = {
|
||||||
|
x: 50,
|
||||||
|
y: 50
|
||||||
|
}
|
||||||
|
this.endPos = {
|
||||||
|
x: Crown.generateRandomPos(),
|
||||||
|
y: Crown.generateRandomPos()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static generateRandomPos() {
|
||||||
|
return Math.floor(Math.random() * 10000) / 100;
|
||||||
|
}
|
||||||
|
}
|
142
src/Database.js
142
src/Database.js
|
@ -2,57 +2,143 @@ const fs = require('fs');
|
||||||
const { promisify } = require('util');
|
const { promisify } = require('util');
|
||||||
const createKeccakHash = require('keccak');
|
const createKeccakHash = require('keccak');
|
||||||
const ColorEncoder = require('./ColorEncoder');
|
const ColorEncoder = require('./ColorEncoder');
|
||||||
|
const UserModel = require('./UserModel');
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
const level = require('level');
|
||||||
|
const { db } = require('./UserModel');
|
||||||
|
|
||||||
|
mongoose.connect(process.env.MONGO_URL, {
|
||||||
|
useNewUrlParser: true,
|
||||||
|
useUnifiedTopology: true
|
||||||
|
}, err => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("Connected to Database");
|
||||||
|
});
|
||||||
|
|
||||||
class Database {
|
class Database {
|
||||||
static userdb;
|
static userdb;
|
||||||
|
static roomdb;
|
||||||
|
|
||||||
static async load() {
|
static async load() {
|
||||||
const writeFile = promisify(fs.writeFile);
|
this.userdb = mongoose.connection;
|
||||||
const readdir = promisify(fs.readdir);
|
this.roomdb = level('src/db/rooms.db');
|
||||||
|
// const writeFile = promisify(fs.writeFile);
|
||||||
|
// const readdir = promisify(fs.readdir);
|
||||||
|
|
||||||
let files = await readdir("src/db/");
|
// let files = await readdir("src/db/");
|
||||||
if (!files.includes("users.json")) {
|
// if (!files.includes("users.json")) {
|
||||||
await writeFile('src/db/users.json', JSON.stringify(this.default_db, null, 2))
|
// await writeFile('src/db/users.json', JSON.stringify(this.default_db, null, 2))
|
||||||
this.userdb = new Map(Object.entries(require("./db/users.json")));
|
// this.userdb = new Map(Object.entries(require("./db/users.json")));
|
||||||
} else {
|
// } else {
|
||||||
this.userdb = new Map(Object.entries(require("./db/users.json")));
|
// this.userdb = new Map(Object.entries(require("./db/users.json")));
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getUserData(cl, server) {
|
static async getUserData(cl, server) {
|
||||||
if (!this.userdb || (this.userdb instanceof Map && [...this.userdb.entries()] == [])) {
|
if (!this.userdb) {
|
||||||
await this.load();
|
await this.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
let _id = createKeccakHash('keccak256').update((cl.server._id_Private_Key + cl.ip)).digest('hex').substr(0, 24);
|
let _id = createKeccakHash('keccak256').update((cl.server._id_Private_Key + cl.ip)).digest('hex').substr(0, 24);
|
||||||
let usertofind = this.userdb.get(_id);
|
let user = await UserModel.findOne({ _id: _id }).exec();
|
||||||
|
|
||||||
if (!usertofind) {
|
if (user == null) {
|
||||||
if (typeof usertofind == 'object' && (usertofind.hasOwnProperty('name') && usertofind.name != this.server.defaultUsername)) return;
|
user = this.createUser(_id);
|
||||||
|
|
||||||
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);
|
console.log('user flags:');
|
||||||
|
console.log(user.flags);
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async update() {
|
static async createUser(_id) {
|
||||||
const writeFile = promisify(fs.writeFile);
|
let user = new UserModel({
|
||||||
await writeFile('src/db/users.json', JSON.stringify(this.strMapToObj(this.userdb), null, 2));
|
name: "Anonymous",
|
||||||
|
_id: _id,
|
||||||
|
color: "#" + ColorEncoder.intToRGB(ColorEncoder.hashCode(_id)),
|
||||||
|
flags: {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
user.save();
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async updateUser(_id, data) {
|
||||||
|
UserModel.findById(_id, (err, doc) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!doc) {
|
||||||
|
return console.warn('Could not find user to save.');
|
||||||
|
}
|
||||||
|
|
||||||
|
doc.set(data);
|
||||||
|
|
||||||
|
doc.save();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async wipe() {
|
||||||
|
await UserModel.find({}, (err, docs) => {
|
||||||
|
docs.forEach(doc => {
|
||||||
|
doc.remove();
|
||||||
|
});
|
||||||
|
}).exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
static strMapToObj(strMap) {
|
static strMapToObj(strMap) {
|
||||||
return [...strMap.entries()].reduce((obj, [key, value]) => (obj[key] = value, obj), {});
|
return [...strMap.entries()].reduce((obj, [key, value]) => (obj[key] = value, obj), {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getRoomSettings(_id, cb) {
|
||||||
|
let key = "room~"+_id;
|
||||||
|
|
||||||
|
roomSettings
|
||||||
|
|
||||||
|
this.roomdb.get(key, (err, value) => {
|
||||||
|
if (err || !value || value == "") {
|
||||||
|
cb(err, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cb(undefined, value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static setRoomSettings(_id, roomSettings, chat) {
|
||||||
|
let roomData = new RoomDataModel(roomSettings, chat);
|
||||||
|
let key = "room~"+_id;
|
||||||
|
this.roomdb.put(key, JSON.stringify(roomData));
|
||||||
|
}
|
||||||
|
|
||||||
|
static getRoomSettings(_id, cb) {
|
||||||
|
let key = "room~"+_id;
|
||||||
|
this.roomdb.get(key, (err, value) => {
|
||||||
|
if (err) {
|
||||||
|
cb(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let settings = JSON.parse(value);
|
||||||
|
cb(err, settings);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static deleteRoomSettings(_id) {
|
||||||
|
this.roomdb.del("room~"+_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RoomDataModel {
|
||||||
|
constructor (settings, chat) {
|
||||||
|
this.settings = settings;
|
||||||
|
this.chat = chat;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Database;
|
module.exports = Database;
|
||||||
|
|
|
@ -6,6 +6,7 @@ const Database = require('./Database');
|
||||||
|
|
||||||
module.exports = (cl) => {
|
module.exports = (cl) => {
|
||||||
cl.once("hi", (msg, admin) => {
|
cl.once("hi", (msg, admin) => {
|
||||||
|
console.log('hi on')
|
||||||
if (msg.hasOwnProperty("password")) {
|
if (msg.hasOwnProperty("password")) {
|
||||||
if (msg.password == "hideme") {
|
if (msg.password == "hideme") {
|
||||||
cl.hidden = true;
|
cl.hidden = true;
|
||||||
|
@ -23,8 +24,7 @@ module.exports = (cl) => {
|
||||||
color: cl.user.color
|
color: cl.user.color
|
||||||
};
|
};
|
||||||
|
|
||||||
m.v = "https://gitlab.com/hri7566/mpp-server";
|
m.v = "2.0";
|
||||||
|
|
||||||
cl.sendArray([m]);
|
cl.sendArray([m]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ module.exports = (cl) => {
|
||||||
cl.on("ch", msg => {
|
cl.on("ch", msg => {
|
||||||
if (typeof(msg.set) !== 'object') msg.set = {};
|
if (typeof(msg.set) !== 'object') msg.set = {};
|
||||||
|
|
||||||
if (msg.hasOwnProperty("_id") && typeof msg._id == "string") {
|
if (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;
|
||||||
|
|
||||||
|
@ -57,8 +57,12 @@ module.exports = (cl) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
param.m = "nq";
|
param.m = "nq";
|
||||||
cl.sendArray([param]);
|
setTimeout(() => {
|
||||||
|
cl.user.checkFlags();
|
||||||
|
cl.sendArray([param]);
|
||||||
|
}, 1000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -164,7 +168,7 @@ module.exports = (cl) => {
|
||||||
cl.server.roomlisteners.set(cl.connectionid, cl);
|
cl.server.roomlisteners.set(cl.connectionid, cl);
|
||||||
let rooms = [];
|
let rooms = [];
|
||||||
for (let room of Array.from(cl.server.rooms.values())) {
|
for (let room of Array.from(cl.server.rooms.values())) {
|
||||||
let data = room.fetchData().ch;
|
let data = room.fetchChannelData().ch;
|
||||||
if (room.bans.get(cl.user._id)) {
|
if (room.bans.get(cl.user._id)) {
|
||||||
data.banned = true;
|
data.banned = true;
|
||||||
}
|
}
|
||||||
|
@ -190,10 +194,11 @@ module.exports = (cl) => {
|
||||||
if(!cl.quotas.userset.attempt()) return;
|
if(!cl.quotas.userset.attempt()) return;
|
||||||
cl.user.name = msg.set.name;
|
cl.user.name = msg.set.name;
|
||||||
Database.getUserData(cl, cl.server).then((usr) => {
|
Database.getUserData(cl, cl.server).then((usr) => {
|
||||||
let dbentry = Database.userdb.get(cl.user._id);
|
// let dbentry = Database.userdb.get(cl.user._id);
|
||||||
if (!dbentry) return;
|
// if (!dbentry) return;
|
||||||
dbentry.name = msg.set.name;
|
// dbentry.name = msg.set.name;
|
||||||
Database.update();
|
// Database.update();
|
||||||
|
Database.updateUser(cl.user._id, cl.user);
|
||||||
cl.server.rooms.forEach((room) => {
|
cl.server.rooms.forEach((room) => {
|
||||||
room.updateParticipant(cl.user._id, {
|
room.updateParticipant(cl.user._id, {
|
||||||
name: msg.set.name
|
name: msg.set.name
|
||||||
|
@ -218,6 +223,7 @@ module.exports = (cl) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
cl.on("bye", msg => {
|
cl.on("bye", msg => {
|
||||||
|
clearInterval(cl.user.rainbow);
|
||||||
cl.destroy();
|
cl.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -264,7 +270,52 @@ module.exports = (cl) => {
|
||||||
|
|
||||||
cl.on('notification', (msg, admin) => {
|
cl.on('notification', (msg, admin) => {
|
||||||
if (!admin) return;
|
if (!admin) return;
|
||||||
if (!msg.hasOwnProperty("id") || (!msg.hasOwnProperty("targetChannel") && !msg.hasOwnProperty("targetUser")) || !msg.hasOwnProperty("target") || !msg.hasOwnProperty("duration") || !msg.hasOwnProperty("class") || !msg.hasOwnProperty("html")) return;
|
if (!msg.hasOwnProperty("id") || (!msg.hasOwnProperty("targetChannel") && !msg.hasOwnProperty("targetUser"))
|
||||||
cl.channel.Notification(msg.targetUser || msg.targetChannel, null, null, msg.html, msg.duration, msg.target, msg.class);
|
|| !msg.hasOwnProperty("target") || !msg.hasOwnProperty("duration")) return;
|
||||||
|
|
||||||
|
let id = msg.id;
|
||||||
|
let targetChannel = msg.targetChannel;
|
||||||
|
let targetUser = msg.targetUser;
|
||||||
|
let target = msg.target;
|
||||||
|
let duration = msg.duration;
|
||||||
|
let klass;
|
||||||
|
let title;
|
||||||
|
let text;
|
||||||
|
let html;
|
||||||
|
|
||||||
|
if (msg.hasOwnProperty("class")) {
|
||||||
|
klass = msg.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!msg.hasOwnProperty("html")) {
|
||||||
|
if (!msg.hasOwnProperty("title") || !msg.hasOwnProperty("text")) return;
|
||||||
|
title = msg.title;
|
||||||
|
text = msg.text;
|
||||||
|
} else {
|
||||||
|
html = msg.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
cl.channel.Notification(targetUser || targetChannel, title, text, html, duration, target, klass, id);
|
||||||
|
});
|
||||||
|
|
||||||
|
cl.on('user_flag', (msg, admin) => {
|
||||||
|
if (!admin) return;
|
||||||
|
if (!msg.hasOwnProperty('_id') || !msg.hasOwnProperty('key') || !msg.hasOwnProperty('value')) return;
|
||||||
|
console.log("stuff");
|
||||||
|
|
||||||
|
cl.server.connections.forEach((usr) => {
|
||||||
|
if ((usr.channel && usr.participantId && usr.user) && (usr.user._id == msg._id || (usr.participantId == msg.id))) {
|
||||||
|
if (!usr.hasOwnProperty('user')) return;
|
||||||
|
usr.user.flags[msg.key] = msg.value;
|
||||||
|
usr.user.checkFlags();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`set user flag: ${msg.key} - ${msg.value}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
cl.on('clear_chat', (msg, admin) => {
|
||||||
|
if (!admin) return;
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
38
src/Quota.js
38
src/Quota.js
|
@ -45,61 +45,72 @@ class Quota {
|
||||||
this.setParams(params);
|
this.setParams(params);
|
||||||
this.resetPoints();
|
this.resetPoints();
|
||||||
this.interval;
|
this.interval;
|
||||||
};
|
}
|
||||||
|
|
||||||
static N_PARAMS_LOBBY = {
|
static N_PARAMS_LOBBY = {
|
||||||
allowance: 200,
|
allowance: 200,
|
||||||
max: 600,
|
max: 600,
|
||||||
interval: 2000
|
interval: 2000
|
||||||
};
|
}
|
||||||
|
|
||||||
static N_PARAMS_NORMAL = {
|
static N_PARAMS_NORMAL = {
|
||||||
allowance: 400,
|
allowance: 400,
|
||||||
max: 1200,
|
max: 1200,
|
||||||
interval: 2000
|
interval: 2000
|
||||||
};
|
}
|
||||||
|
|
||||||
static N_PARAMS_RIDICULOUS = {
|
static N_PARAMS_RIDICULOUS = {
|
||||||
allowance: 600,
|
allowance: 600,
|
||||||
max: 1800,
|
max: 1800,
|
||||||
interval: 2000
|
interval: 2000
|
||||||
};
|
}
|
||||||
|
|
||||||
static PARAMS_OFFLINE = {
|
static PARAMS_OFFLINE = {
|
||||||
allowance: 8000,
|
allowance: 8000,
|
||||||
max: 24000,
|
max: 24000,
|
||||||
maxHistLen: 3,
|
maxHistLen: 3,
|
||||||
interval: 2000
|
interval: 2000
|
||||||
};
|
}
|
||||||
|
|
||||||
static PARAMS_A_NORMAL = {
|
static PARAMS_A_NORMAL = {
|
||||||
allowance: 4,
|
allowance: 4,
|
||||||
max: 4,
|
max: 4,
|
||||||
interval: 6000
|
interval: 6000
|
||||||
};
|
}
|
||||||
|
|
||||||
static PARAMS_A_CROWNED = {
|
static PARAMS_A_CROWNED = {
|
||||||
allowance:10,
|
allowance:10,
|
||||||
max:10,
|
max:10,
|
||||||
interval: 2000
|
interval: 2000
|
||||||
}
|
}
|
||||||
|
|
||||||
static PARAMS_CH = {
|
static PARAMS_CH = {
|
||||||
allowance: 1,
|
allowance: 1,
|
||||||
max: 2,
|
max: 2,
|
||||||
interval: 1000
|
interval: 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
static PARAMS_USED_A_LOT = {
|
static PARAMS_USED_A_LOT = {
|
||||||
allowance:1,
|
allowance:1,
|
||||||
max:1,
|
max:1,
|
||||||
interval: 2000
|
interval: 2000
|
||||||
}
|
}
|
||||||
|
|
||||||
static PARAMS_M = {
|
static PARAMS_M = {
|
||||||
allowance:15000,
|
allowance:15000,
|
||||||
max:500000,
|
max:500000,
|
||||||
interval: 2000
|
interval: 2000
|
||||||
}
|
}
|
||||||
|
|
||||||
getParams() {
|
getParams() {
|
||||||
return {
|
return {
|
||||||
m: "nq",
|
m: "nq",
|
||||||
allowance: this.allowance,
|
allowance: this.allowance,
|
||||||
max: this.max,
|
max: this.max,
|
||||||
maxHistLen: this.maxHistLen
|
maxHistLen: this.maxHistLen
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
setParams(params) {
|
setParams(params) {
|
||||||
params = params || Quota.PARAMS_OFFLINE;
|
params = params || Quota.PARAMS_OFFLINE;
|
||||||
var allowance = params.allowance || this.allowance || Quota.PARAMS_OFFLINE.allowance;
|
var allowance = params.allowance || this.allowance || Quota.PARAMS_OFFLINE.allowance;
|
||||||
|
@ -118,14 +129,16 @@ class Quota {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
}
|
||||||
|
|
||||||
resetPoints() {
|
resetPoints() {
|
||||||
this.points = this.max;
|
this.points = this.max;
|
||||||
this.history = [];
|
this.history = [];
|
||||||
for (var i = 0; i < this.maxHistLen; i++)
|
for (var i = 0; i < this.maxHistLen; i++)
|
||||||
this.history.unshift(this.points);
|
this.history.unshift(this.points);
|
||||||
if (this.cb) this.cb(this.points);
|
if (this.cb) this.cb(this.points);
|
||||||
};
|
}
|
||||||
|
|
||||||
tick() {
|
tick() {
|
||||||
// keep a brief history
|
// keep a brief history
|
||||||
this.history.unshift(this.points);
|
this.history.unshift(this.points);
|
||||||
|
@ -137,7 +150,8 @@ class Quota {
|
||||||
// fire callback
|
// fire callback
|
||||||
if (this.cb) this.cb(this.points);
|
if (this.cb) this.cb(this.points);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
spend(needed) {
|
spend(needed) {
|
||||||
// check whether aggressive limitation is needed
|
// check whether aggressive limitation is needed
|
||||||
var sum = 0;
|
var sum = 0;
|
||||||
|
@ -153,7 +167,7 @@ class Quota {
|
||||||
if (this.cb) this.cb(this.points); // fire callback
|
if (this.cb) this.cb(this.points); // fire callback
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Quota
|
module.exports = Quota
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
module.exports = class Rank {
|
||||||
|
constructor (name, _id) {
|
||||||
|
this.name = name;
|
||||||
|
this._id = _id;
|
||||||
|
}
|
||||||
|
}
|
131
src/Room.js
131
src/Room.js
|
@ -1,14 +1,15 @@
|
||||||
const createKeccakHash = require('keccak');
|
const createKeccakHash = require('keccak');
|
||||||
|
const Crown = require('./Crown.js');
|
||||||
|
const Database = require('./Database.js');
|
||||||
const Quota = require("./Quota.js");
|
const Quota = require("./Quota.js");
|
||||||
const RoomSettings = require('./RoomSettings.js');
|
const RoomSettings = require('./RoomSettings.js');
|
||||||
|
|
||||||
class Room extends EventEmitter {
|
class Room extends EventEmitter {
|
||||||
constructor(server, _id, settings) {
|
constructor(server, _id, settings) {
|
||||||
super();
|
super();
|
||||||
EventEmitter.call(this);
|
|
||||||
this._id = _id;
|
this._id = _id;
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.crown = null;
|
this.crown;
|
||||||
this.crowndropped = false;
|
this.crowndropped = false;
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.chatmsgs = [];
|
this.chatmsgs = [];
|
||||||
|
@ -17,30 +18,31 @@ class Room extends EventEmitter {
|
||||||
this.bindEventListeners();
|
this.bindEventListeners();
|
||||||
this.server.rooms.set(_id, this);
|
this.server.rooms.set(_id, this);
|
||||||
this.bans = new Map();
|
this.bans = new Map();
|
||||||
|
this.flags = {}
|
||||||
|
|
||||||
|
Database.getRoomSettings(this._id, (err, set) => {
|
||||||
|
if (err) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.settings = set.settings;
|
||||||
|
this.chatmsgs = set.chat;
|
||||||
|
this.setData();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
join(cl, set) { //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) == false) || 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 = new Crown(cl.participantId, cl.user._id);
|
||||||
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.crowndropped = false;
|
||||||
this.settings = new RoomSettings(set, 'user');
|
this.settings = new RoomSettings(set, 'user');
|
||||||
|
@ -105,7 +107,6 @@ class Room extends EventEmitter {
|
||||||
if (!(otheruser.length > 1)) {
|
if (!(otheruser.length > 1)) {
|
||||||
this.ppl.delete(p.participantId);
|
this.ppl.delete(p.participantId);
|
||||||
this.connections.splice(this.connections.findIndex((a) => a.connectionid == p.connectionid), 1);
|
this.connections.splice(this.connections.findIndex((a) => a.connectionid == p.connectionid), 1);
|
||||||
console.log(`Deleted client ${p.user.id}`);
|
|
||||||
this.sendArray([{
|
this.sendArray([{
|
||||||
m: "bye",
|
m: "bye",
|
||||||
p: p.participantId
|
p: p.participantId
|
||||||
|
@ -125,19 +126,15 @@ class Room extends EventEmitter {
|
||||||
if (Array.from(this.ppl.values()).length <= 0) {
|
if (Array.from(this.ppl.values()).length <= 0) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.destroy();
|
this.destroy();
|
||||||
}, 10000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.connections.forEach((usr) => {
|
this.connections.forEach((usr) => {
|
||||||
let u = this.fetchData(usr, cl);
|
let u = this.fetchChannelData(usr, cl);
|
||||||
u.ppl.forEach(c => {
|
this.server.connections.get(usr.connectionid).sendArray([u]);
|
||||||
c.ip = undefined;
|
|
||||||
c.server = undefined;
|
|
||||||
});
|
|
||||||
this.server.connections.get(usr.connectionid).sendArray([u])
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.server.updateRoom(this.fetchData());
|
this.server.updateRoom(this.fetchChannelData());
|
||||||
}
|
}
|
||||||
|
|
||||||
updateParticipant(pid, options) {
|
updateParticipant(pid, options) {
|
||||||
|
@ -195,11 +192,17 @@ class Room extends EventEmitter {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchData(usr, cl) {
|
fetchChannelData(usr, cl) {
|
||||||
let chppl = [];
|
let chppl = [];
|
||||||
|
|
||||||
[...this.ppl.values()].forEach((a) => {
|
[...this.ppl.values()].forEach(c => {
|
||||||
chppl.push(a.user);
|
let u = {
|
||||||
|
_id: c.user._id,
|
||||||
|
name: c.user.name,
|
||||||
|
color: c.user.color,
|
||||||
|
id: c.participantId
|
||||||
|
}
|
||||||
|
chppl.push(u);
|
||||||
});
|
});
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
|
@ -270,44 +273,13 @@ class Room extends EventEmitter {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCrownY() {
|
|
||||||
return Math.floor(Math.random() * 10000) / 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
getCrownX() {
|
|
||||||
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) {
|
||||||
this.crown = {
|
this.crown = new Crown(id, prsn.user._id);
|
||||||
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;
|
this.crowndropped = false;
|
||||||
} else {
|
} else {
|
||||||
this.crown = {
|
this.crown = new Crown(id, this.crown.userId);
|
||||||
userId: this.crown.userId,
|
|
||||||
time: Date.now(),
|
|
||||||
startPos: {
|
|
||||||
x: 50,
|
|
||||||
y: 50
|
|
||||||
},
|
|
||||||
endPos: {
|
|
||||||
x: this.getCrownX(),
|
|
||||||
y: this.getCrownY()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.crowndropped = true;
|
this.crowndropped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,7 +301,7 @@ class Room extends EventEmitter {
|
||||||
|
|
||||||
chat(p, msg) {
|
chat(p, msg) {
|
||||||
if (msg.message.length > 512) return;
|
if (msg.message.length > 512) return;
|
||||||
let filter = ["AMIGHTYWIND"];
|
let filter = ["AMIGHTYWIND", "CHECKLYHQ"];
|
||||||
let regexp = new RegExp("\\b(" + filter.join("|") + ")\\b", "i");
|
let regexp = new RegExp("\\b(" + filter.join("|") + ")\\b", "i");
|
||||||
if (regexp.test(msg.message)) return;
|
if (regexp.test(msg.message)) return;
|
||||||
if (p.participantId == 0) {
|
if (p.participantId == 0) {
|
||||||
|
@ -344,7 +316,9 @@ class Room extends EventEmitter {
|
||||||
};
|
};
|
||||||
message.t = Date.now();
|
message.t = Date.now();
|
||||||
this.sendArray([message]);
|
this.sendArray([message]);
|
||||||
|
|
||||||
this.chatmsgs.push(message);
|
this.chatmsgs.push(message);
|
||||||
|
this.setData();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let prsn = this.ppl.get(p.participantId);
|
let prsn = this.ppl.get(p.participantId);
|
||||||
|
@ -352,6 +326,9 @@ class Room extends EventEmitter {
|
||||||
let message = {};
|
let message = {};
|
||||||
message.m = "a";
|
message.m = "a";
|
||||||
message.a = msg.message;
|
message.a = msg.message;
|
||||||
|
if (prsn.user.hasFlag('vowels')) {
|
||||||
|
message.a = message.a.split(/[aeiouAEIOU]/).join(prsn.user.flags["vowels"]);
|
||||||
|
}
|
||||||
message.p = {
|
message.p = {
|
||||||
color: p.user.color,
|
color: p.user.color,
|
||||||
id: p.participantId,
|
id: p.participantId,
|
||||||
|
@ -361,34 +338,46 @@ class Room extends EventEmitter {
|
||||||
message.t = Date.now();
|
message.t = Date.now();
|
||||||
this.sendArray([message]);
|
this.sendArray([message]);
|
||||||
this.chatmsgs.push(message);
|
this.chatmsgs.push(message);
|
||||||
|
this.setData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
playNote(cl, note) {
|
playNote(cl, note) {
|
||||||
|
let vel = Math.round(cl.user.flags["volume"])/100 || undefined;
|
||||||
|
if (vel == 1) vel = undefined;
|
||||||
|
|
||||||
this.sendArray([{
|
this.sendArray([{
|
||||||
m: "n",
|
m: "n",
|
||||||
n: note.n,
|
n: note.n,
|
||||||
p: cl.participantId,
|
p: cl.participantId,
|
||||||
t: note.t
|
t: note.t,
|
||||||
|
v: vel
|
||||||
}], 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;
|
||||||
if (ms < 0) return;
|
if (ms < 0) return;
|
||||||
|
|
||||||
ms = Math.round(ms / 1000) * 1000;
|
ms = Math.round(ms / 1000) * 1000;
|
||||||
|
|
||||||
let user = this.connections.find((usr) => usr.user._id == _id);
|
let user = this.connections.find((usr) => usr.user._id == _id);
|
||||||
if (!user) return;
|
if (!user) return;
|
||||||
let asd = true;
|
let asd = true;
|
||||||
let pthatbanned = this.ppl.get(this.crown.participantId);
|
let pthatbanned = this.ppl.get(this.crown.participantId);
|
||||||
|
|
||||||
this.connections.filter((usr) => usr.participantId == user.participantId).forEach((u) => {
|
this.connections.filter((usr) => usr.participantId == user.participantId).forEach((u) => {
|
||||||
user.bantime = Math.floor(Math.floor(ms / 1000) / 60);
|
user.bantime = Math.floor(Math.floor(ms / 1000) / 60);
|
||||||
user.bannedtime = Date.now();
|
user.bannedtime = Date.now();
|
||||||
user.msbanned = ms;
|
user.msbanned = ms;
|
||||||
|
|
||||||
this.bans.set(user.user._id, user);
|
this.bans.set(user.user._id, user);
|
||||||
if (this.crown && (this.crown.userId)) {
|
|
||||||
|
//if (this.crown && (this.crown.userId)) {
|
||||||
u.setChannel("test/awkward", {});
|
u.setChannel("test/awkward", {});
|
||||||
|
|
||||||
if (asd)
|
if (asd)
|
||||||
this.Notification(user.user._id,
|
this.Notification(user.user._id,
|
||||||
"Notice",
|
"Notice",
|
||||||
|
@ -416,8 +405,7 @@ class Room extends EventEmitter {
|
||||||
"#room"
|
"#room"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
//}
|
||||||
}
|
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -433,6 +421,7 @@ class Room extends EventEmitter {
|
||||||
class: klass,
|
class: klass,
|
||||||
id: id
|
id: id
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!id) delete obj.id;
|
if (!id) delete obj.id;
|
||||||
if (!title) delete obj.title;
|
if (!title) delete obj.title;
|
||||||
if (!text) delete obj.text;
|
if (!text) delete obj.text;
|
||||||
|
@ -440,6 +429,7 @@ class Room extends EventEmitter {
|
||||||
if (!target) delete obj.target;
|
if (!target) delete obj.target;
|
||||||
if (!duration) delete obj.duration;
|
if (!duration) delete obj.duration;
|
||||||
if (!klass) delete obj.class;
|
if (!klass) delete obj.class;
|
||||||
|
|
||||||
switch (who) {
|
switch (who) {
|
||||||
case "all": {
|
case "all": {
|
||||||
for (let con of Array.from(this.server.connections.values())) {
|
for (let con of Array.from(this.server.connections.values())) {
|
||||||
|
@ -475,7 +465,7 @@ class Room extends EventEmitter {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
verifySet(_id, msg){
|
verifySet(_id, msg) {
|
||||||
if(typeof(msg.set) !== 'object') {
|
if(typeof(msg.set) !== 'object') {
|
||||||
msg.set = {
|
msg.set = {
|
||||||
visible: true,
|
visible: true,
|
||||||
|
@ -496,6 +486,15 @@ class Room extends EventEmitter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setData() {
|
||||||
|
Database.setRoomSettings(this._id, this.settings, this.chatmsgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
hasFlag(flag, val) {
|
||||||
|
if (!val) return this.flags.hasOwnProperty(flag);
|
||||||
|
return this.flags.hasOwnProperty(flag) && this.flags[flag] == val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Room;
|
module.exports = Room;
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
|
const config = require ('../config');
|
||||||
|
|
||||||
class RoomSettings {
|
class RoomSettings {
|
||||||
static allowedProperties = {
|
static allowedProperties = {
|
||||||
color: {
|
color: {
|
||||||
type: 'color',
|
type: 'color',
|
||||||
default: "#9900ff",
|
default: config.defaultRoomSettings.color,
|
||||||
allowedChange: true,
|
allowedChange: true,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
color2: {
|
color2: {
|
||||||
type: 'color2',
|
type: 'color2',
|
||||||
default: "#5900bf",
|
default: config.defaultRoomSettings.color2,
|
||||||
allowedChange: true,
|
allowedChange: true,
|
||||||
required: false
|
required: false
|
||||||
},
|
},
|
||||||
|
@ -39,10 +41,15 @@ class RoomSettings {
|
||||||
default: false,
|
default: false,
|
||||||
allowedChange: true,
|
allowedChange: true,
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
"no cussing": {
|
||||||
|
type: 'boolean',
|
||||||
|
allowedChange: true,
|
||||||
|
required: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor (set, cont) {
|
constructor (set, context) {
|
||||||
Object.keys(RoomSettings.allowedProperties).forEach(key => {
|
Object.keys(RoomSettings.allowedProperties).forEach(key => {
|
||||||
if (typeof(RoomSettings.allowedProperties[key].default) !== 'undefined') {
|
if (typeof(RoomSettings.allowedProperties[key].default) !== 'undefined') {
|
||||||
if (this[key] !== RoomSettings.allowedProperties[key].default) {
|
if (this[key] !== RoomSettings.allowedProperties[key].default) {
|
||||||
|
@ -63,10 +70,10 @@ class RoomSettings {
|
||||||
Object.keys(set).forEach(key => {
|
Object.keys(set).forEach(key => {
|
||||||
if (typeof(set[key]) == 'undefined') return;
|
if (typeof(set[key]) == 'undefined') return;
|
||||||
if (Object.keys(RoomSettings.allowedProperties).indexOf(key) !== -1) {
|
if (Object.keys(RoomSettings.allowedProperties).indexOf(key) !== -1) {
|
||||||
if (typeof(cont) == 'undefined') {
|
if (typeof(context) == 'undefined') {
|
||||||
this[key] = this.verifyPropertyType(key, set[key], RoomSettings.allowedProperties[key].type);
|
this[key] = this.verifyPropertyType(key, set[key], RoomSettings.allowedProperties[key].type);
|
||||||
} else {
|
} else {
|
||||||
if (cont == 'user') {
|
if (context == 'user') {
|
||||||
if (RoomSettings.allowedProperties[key].allowedChange) {
|
if (RoomSettings.allowedProperties[key].allowedChange) {
|
||||||
this[key] = this.verifyPropertyType(key, set[key], RoomSettings.allowedProperties[key].type);
|
this[key] = this.verifyPropertyType(key, set[key], RoomSettings.allowedProperties[key].type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,11 +52,13 @@ class Server extends EventEmitter {
|
||||||
this.roomlisteners = new Map();
|
this.roomlisteners = new Map();
|
||||||
this.rooms = new Map();
|
this.rooms = new Map();
|
||||||
|
|
||||||
|
this.specialIntervals = {};
|
||||||
|
|
||||||
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", "user_flag", "room_flag", "clear_chat"]
|
||||||
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";
|
||||||
|
@ -68,6 +70,10 @@ class Server extends EventEmitter {
|
||||||
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())) {
|
||||||
|
if (cl.destroied) {
|
||||||
|
cl = undefined;
|
||||||
|
return;
|
||||||
|
}
|
||||||
cl.sendArray([{
|
cl.sendArray([{
|
||||||
"m": "ls",
|
"m": "ls",
|
||||||
"c": false,
|
"c": false,
|
||||||
|
|
69
src/User.js
69
src/User.js
|
@ -1,12 +1,77 @@
|
||||||
const Database = require("./Database");
|
const Database = require("./Database");
|
||||||
|
|
||||||
|
function hslToHex(h, s, l) {
|
||||||
|
l /= 100;
|
||||||
|
const a = s * Math.min(l, 1 - l) / 100;
|
||||||
|
const f = n => {
|
||||||
|
const k = (n + h / 30) % 12;
|
||||||
|
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
||||||
|
return Math.round(255 * color).toString(16).padStart(2, '0');
|
||||||
|
};
|
||||||
|
return `#${f(0)}${f(8)}${f(4)}`;
|
||||||
|
}
|
||||||
|
|
||||||
class User {
|
class User {
|
||||||
constructor(cl, data) {
|
constructor(cl, data) {
|
||||||
this.server = cl.server;
|
|
||||||
this.name = data.name;
|
this.name = data.name;
|
||||||
|
this.cl = cl;
|
||||||
this._id = data._id;
|
this._id = data._id;
|
||||||
this.color = data.color;
|
this.color = data.color;
|
||||||
this.ip = data.ip;
|
this.flags = typeof data.flags == "object" ? data.flags : {
|
||||||
|
volume: 100,
|
||||||
|
"no chat rate limit": false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getPublicUser() {
|
||||||
|
let t = {};
|
||||||
|
t.name = this.name;
|
||||||
|
t.color = this.color;
|
||||||
|
t._id = this._id;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkFlags() {
|
||||||
|
if (typeof(this.cl.server.specialIntervals[this._id]) == 'undefined') this.cl.server.specialIntervals[this._id] = {};
|
||||||
|
if (this.hasFlag('rainbow', true)) {
|
||||||
|
if (!this.cl.server.specialIntervals[this._id].hasOwnProperty('rainbow')) {
|
||||||
|
let h = Math.floor(Math.random() * 360);
|
||||||
|
let s = 50;
|
||||||
|
let l = 50;
|
||||||
|
|
||||||
|
let hvel = 5;
|
||||||
|
let svel = 1;
|
||||||
|
let lvel = 0.5;
|
||||||
|
|
||||||
|
this.cl.server.specialIntervals[this._id].rainbow = setInterval(() => {
|
||||||
|
hvel = Math.floor(Math.random()*10);
|
||||||
|
h += hvel;
|
||||||
|
if (h > 360) h = 0;
|
||||||
|
|
||||||
|
s += svel;
|
||||||
|
if (s >= 100 || s <= 50) {
|
||||||
|
svel = -svel;
|
||||||
|
}
|
||||||
|
|
||||||
|
l += lvel;
|
||||||
|
if (l >= 75 || l <= 25) {
|
||||||
|
lvel = -lvel;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.color = hslToHex(h, s, l);
|
||||||
|
Database.updateUser(this._id, this);
|
||||||
|
|
||||||
|
this.cl.channel.updateParticipant(this._id, this);
|
||||||
|
}, 1000/15);
|
||||||
|
}
|
||||||
|
} else if (this.hasFlag('rainbow', false)) {
|
||||||
|
clearInterval(this.cl.server.specialIntervals[this._id].rainbow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hasFlag(flag, val) {
|
||||||
|
if (!val) return this.flags.hasOwnProperty(flag);
|
||||||
|
return this.flags.hasOwnProperty(flag) && this.flags[flag] == val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static updateUserModel(cl, user) {
|
static updateUserModel(cl, user) {
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
module.exports = mongoose.model('User', {
|
||||||
|
name: String,
|
||||||
|
_id: String,
|
||||||
|
color: String,
|
||||||
|
flags: Object
|
||||||
|
});
|
1976
src/db/users.json
1976
src/db/users.json
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue