forked from Hri7566/mpp-server-dev2
best update ever
This commit is contained in:
parent
35c52b5a12
commit
2f33925be5
|
@ -2,3 +2,4 @@
|
|||
node_modules
|
||||
ssl/
|
||||
src/db/users.json
|
||||
.history
|
||||
|
|
|
@ -31,4 +31,4 @@ module.exports = Object.seal({
|
|||
amount: 2,
|
||||
time: 1000
|
||||
}
|
||||
})
|
||||
});
|
10
config.js
10
config.js
|
@ -4,15 +4,15 @@ module.exports = Object.seal({
|
|||
_id_PrivateKey: process.env.SALT,
|
||||
defaultUsername: "Anonymous",
|
||||
// defaultRoomColor: "#3b5054",
|
||||
defaultRoomColor: "#000000",
|
||||
// defaultLobbyColor: "#19b4b9",
|
||||
defaultLobbyColor: "#9900ff",
|
||||
defaultLobbyColor: "#76b0db",
|
||||
// defaultLobbyColor2: "#801014",
|
||||
defaultLobbyColor2: "#801014",
|
||||
defaultLobbyColor2: "#276491",
|
||||
adminpass: process.env.ADMINPASS,
|
||||
ssl: true,
|
||||
ssl: false,
|
||||
defaultRoomSettings: {
|
||||
color: "#000000",
|
||||
color: "#3b5054",
|
||||
color2: "#001014",
|
||||
crownsolo: false,
|
||||
visible: true
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,6 +26,8 @@
|
|||
"dotenv": "^8.2.0",
|
||||
"events": "^3.1.0",
|
||||
"keccak": "^2.1.0",
|
||||
"level": "^7.0.0",
|
||||
"mongoose": "^5.12.7",
|
||||
"node-json-color-stringify": "^1.1.0",
|
||||
"ws": "^7.2.3"
|
||||
}
|
||||
|
|
|
@ -71,7 +71,9 @@ class Client extends EventEmitter {
|
|||
if (channel) this.channel.updateCh(this);
|
||||
|
||||
this.channel = this.server.rooms.get(_id);
|
||||
if (!this.user.hasFlag("hidden", true)) {
|
||||
this.channel.join(this);
|
||||
}
|
||||
} else {
|
||||
let room = new Room(this.server, _id, settings);
|
||||
this.server.rooms.set(_id, room);
|
||||
|
@ -109,7 +111,7 @@ class Client extends EventEmitter {
|
|||
destroy() {
|
||||
this.ws.close();
|
||||
if (this.channel) {
|
||||
this.channel.emit("bye", this)
|
||||
this.channel.emit("bye", this);
|
||||
}
|
||||
this.user;
|
||||
this.participantId;
|
||||
|
@ -118,7 +120,7 @@ class Client extends EventEmitter {
|
|||
this.connectionid;
|
||||
this.server.connections.delete(this.connectionid);
|
||||
this.destroied = true;
|
||||
console.log(`Removed Connection ${this.connectionid}.`);
|
||||
console.log(`Removed Connection ${this.connectionid}. user is ${this.user}`);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
138
src/Database.js
138
src/Database.js
|
@ -2,57 +2,143 @@ const fs = require('fs');
|
|||
const { promisify } = require('util');
|
||||
const createKeccakHash = require('keccak');
|
||||
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 {
|
||||
static userdb;
|
||||
static roomdb;
|
||||
|
||||
static async load() {
|
||||
const writeFile = promisify(fs.writeFile);
|
||||
const readdir = promisify(fs.readdir);
|
||||
this.userdb = mongoose.connection;
|
||||
this.roomdb = level('src/db/rooms.db');
|
||||
// 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")));
|
||||
}
|
||||
// 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()] == [])) {
|
||||
if (!this.userdb) {
|
||||
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);
|
||||
let user = await UserModel.findOne({ _id: _id }).exec();
|
||||
|
||||
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();
|
||||
if (user == null) {
|
||||
user = this.createUser(_id);
|
||||
}
|
||||
|
||||
let user = this.userdb.get(_id);
|
||||
console.log('user flags:');
|
||||
console.log(user.flags);
|
||||
|
||||
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 async createUser(_id) {
|
||||
let user = new UserModel({
|
||||
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) {
|
||||
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;
|
||||
|
|
|
@ -6,6 +6,7 @@ const Database = require('./Database');
|
|||
|
||||
module.exports = (cl) => {
|
||||
cl.once("hi", (msg, admin) => {
|
||||
console.log('hi on')
|
||||
if (msg.hasOwnProperty("password")) {
|
||||
if (msg.password == "hideme") {
|
||||
cl.hidden = true;
|
||||
|
@ -23,8 +24,7 @@ module.exports = (cl) => {
|
|||
color: cl.user.color
|
||||
};
|
||||
|
||||
m.v = "https://gitlab.com/hri7566/mpp-server";
|
||||
|
||||
m.v = "2.0";
|
||||
cl.sendArray([m]);
|
||||
});
|
||||
|
||||
|
@ -40,7 +40,7 @@ module.exports = (cl) => {
|
|||
cl.on("ch", msg => {
|
||||
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 (!cl.staticQuotas.room.attempt()) return;
|
||||
|
||||
|
@ -57,8 +57,12 @@ module.exports = (cl) => {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
param.m = "nq";
|
||||
setTimeout(() => {
|
||||
cl.user.checkFlags();
|
||||
cl.sendArray([param]);
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -164,7 +168,7 @@ module.exports = (cl) => {
|
|||
cl.server.roomlisteners.set(cl.connectionid, cl);
|
||||
let rooms = [];
|
||||
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)) {
|
||||
data.banned = true;
|
||||
}
|
||||
|
@ -190,10 +194,11 @@ module.exports = (cl) => {
|
|||
if(!cl.quotas.userset.attempt()) return;
|
||||
cl.user.name = msg.set.name;
|
||||
Database.getUserData(cl, cl.server).then((usr) => {
|
||||
let dbentry = Database.userdb.get(cl.user._id);
|
||||
if (!dbentry) return;
|
||||
dbentry.name = msg.set.name;
|
||||
Database.update();
|
||||
// let dbentry = Database.userdb.get(cl.user._id);
|
||||
// if (!dbentry) return;
|
||||
// dbentry.name = msg.set.name;
|
||||
// Database.update();
|
||||
Database.updateUser(cl.user._id, cl.user);
|
||||
cl.server.rooms.forEach((room) => {
|
||||
room.updateParticipant(cl.user._id, {
|
||||
name: msg.set.name
|
||||
|
@ -218,6 +223,7 @@ module.exports = (cl) => {
|
|||
});
|
||||
|
||||
cl.on("bye", msg => {
|
||||
clearInterval(cl.user.rainbow);
|
||||
cl.destroy();
|
||||
});
|
||||
|
||||
|
@ -264,7 +270,52 @@ module.exports = (cl) => {
|
|||
|
||||
cl.on('notification', (msg, admin) => {
|
||||
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;
|
||||
cl.channel.Notification(msg.targetUser || msg.targetChannel, null, null, msg.html, msg.duration, msg.target, msg.class);
|
||||
if (!msg.hasOwnProperty("id") || (!msg.hasOwnProperty("targetChannel") && !msg.hasOwnProperty("targetUser"))
|
||||
|| !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.resetPoints();
|
||||
this.interval;
|
||||
};
|
||||
}
|
||||
|
||||
static N_PARAMS_LOBBY = {
|
||||
allowance: 200,
|
||||
max: 600,
|
||||
interval: 2000
|
||||
};
|
||||
}
|
||||
|
||||
static N_PARAMS_NORMAL = {
|
||||
allowance: 400,
|
||||
max: 1200,
|
||||
interval: 2000
|
||||
};
|
||||
}
|
||||
|
||||
static N_PARAMS_RIDICULOUS = {
|
||||
allowance: 600,
|
||||
max: 1800,
|
||||
interval: 2000
|
||||
};
|
||||
}
|
||||
|
||||
static PARAMS_OFFLINE = {
|
||||
allowance: 8000,
|
||||
max: 24000,
|
||||
maxHistLen: 3,
|
||||
interval: 2000
|
||||
};
|
||||
}
|
||||
|
||||
static PARAMS_A_NORMAL = {
|
||||
allowance: 4,
|
||||
max: 4,
|
||||
interval: 6000
|
||||
};
|
||||
}
|
||||
|
||||
static PARAMS_A_CROWNED = {
|
||||
allowance:10,
|
||||
max:10,
|
||||
interval: 2000
|
||||
}
|
||||
|
||||
static PARAMS_CH = {
|
||||
allowance: 1,
|
||||
max: 2,
|
||||
interval: 1000
|
||||
}
|
||||
|
||||
static PARAMS_USED_A_LOT = {
|
||||
allowance:1,
|
||||
max:1,
|
||||
interval: 2000
|
||||
}
|
||||
|
||||
static PARAMS_M = {
|
||||
allowance:15000,
|
||||
max:500000,
|
||||
interval: 2000
|
||||
}
|
||||
|
||||
getParams() {
|
||||
return {
|
||||
m: "nq",
|
||||
allowance: this.allowance,
|
||||
max: this.max,
|
||||
maxHistLen: this.maxHistLen
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
setParams(params) {
|
||||
params = params || Quota.PARAMS_OFFLINE;
|
||||
var allowance = params.allowance || this.allowance || Quota.PARAMS_OFFLINE.allowance;
|
||||
|
@ -118,14 +129,16 @@ class Quota {
|
|||
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);
|
||||
|
@ -137,7 +150,8 @@ class Quota {
|
|||
// fire callback
|
||||
if (this.cb) this.cb(this.points);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
spend(needed) {
|
||||
// check whether aggressive limitation is needed
|
||||
var sum = 0;
|
||||
|
@ -153,7 +167,7 @@ class Quota {
|
|||
if (this.cb) this.cb(this.points); // fire callback
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Quota
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
module.exports = class Rank {
|
||||
constructor (name, _id) {
|
||||
this.name = name;
|
||||
this._id = _id;
|
||||
}
|
||||
}
|
129
src/Room.js
129
src/Room.js
|
@ -1,14 +1,15 @@
|
|||
const createKeccakHash = require('keccak');
|
||||
const Crown = require('./Crown.js');
|
||||
const Database = require('./Database.js');
|
||||
const Quota = require("./Quota.js");
|
||||
const RoomSettings = require('./RoomSettings.js');
|
||||
|
||||
class Room extends EventEmitter {
|
||||
constructor(server, _id, settings) {
|
||||
super();
|
||||
EventEmitter.call(this);
|
||||
this._id = _id;
|
||||
this.server = server;
|
||||
this.crown = null;
|
||||
this.crown;
|
||||
this.crowndropped = false;
|
||||
this.settings = settings;
|
||||
this.chatmsgs = [];
|
||||
|
@ -17,30 +18,31 @@ class Room extends EventEmitter {
|
|||
this.bindEventListeners();
|
||||
this.server.rooms.set(_id, this);
|
||||
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
|
||||
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;
|
||||
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.
|
||||
//cl.quotas.a.setParams(Quota.PARAMS_A_CROWNED);
|
||||
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.crown = new Crown(cl.participantId, cl.user._id);
|
||||
|
||||
this.crowndropped = false;
|
||||
this.settings = new RoomSettings(set, 'user');
|
||||
|
@ -105,7 +107,6 @@ class Room extends EventEmitter {
|
|||
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
|
||||
|
@ -125,19 +126,15 @@ class Room extends EventEmitter {
|
|||
if (Array.from(this.ppl.values()).length <= 0) {
|
||||
setTimeout(() => {
|
||||
this.destroy();
|
||||
}, 10000);
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
this.connections.forEach((usr) => {
|
||||
let u = this.fetchData(usr, cl);
|
||||
u.ppl.forEach(c => {
|
||||
c.ip = undefined;
|
||||
c.server = undefined;
|
||||
});
|
||||
this.server.connections.get(usr.connectionid).sendArray([u])
|
||||
let u = this.fetchChannelData(usr, cl);
|
||||
this.server.connections.get(usr.connectionid).sendArray([u]);
|
||||
});
|
||||
|
||||
this.server.updateRoom(this.fetchData());
|
||||
this.server.updateRoom(this.fetchChannelData());
|
||||
}
|
||||
|
||||
updateParticipant(pid, options) {
|
||||
|
@ -195,11 +192,17 @@ class Room extends EventEmitter {
|
|||
});
|
||||
}
|
||||
|
||||
fetchData(usr, cl) {
|
||||
fetchChannelData(usr, cl) {
|
||||
let chppl = [];
|
||||
|
||||
[...this.ppl.values()].forEach((a) => {
|
||||
chppl.push(a.user);
|
||||
[...this.ppl.values()].forEach(c => {
|
||||
let u = {
|
||||
_id: c.user._id,
|
||||
name: c.user.name,
|
||||
color: c.user.color,
|
||||
id: c.participantId
|
||||
}
|
||||
chppl.push(u);
|
||||
});
|
||||
|
||||
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) {
|
||||
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.crown = new Crown(id, prsn.user._id);
|
||||
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.crown = new Crown(id, this.crown.userId);
|
||||
this.crowndropped = true;
|
||||
}
|
||||
|
||||
|
@ -329,7 +301,7 @@ class Room extends EventEmitter {
|
|||
|
||||
chat(p, msg) {
|
||||
if (msg.message.length > 512) return;
|
||||
let filter = ["AMIGHTYWIND"];
|
||||
let filter = ["AMIGHTYWIND", "CHECKLYHQ"];
|
||||
let regexp = new RegExp("\\b(" + filter.join("|") + ")\\b", "i");
|
||||
if (regexp.test(msg.message)) return;
|
||||
if (p.participantId == 0) {
|
||||
|
@ -344,7 +316,9 @@ class Room extends EventEmitter {
|
|||
};
|
||||
message.t = Date.now();
|
||||
this.sendArray([message]);
|
||||
|
||||
this.chatmsgs.push(message);
|
||||
this.setData();
|
||||
return;
|
||||
}
|
||||
let prsn = this.ppl.get(p.participantId);
|
||||
|
@ -352,6 +326,9 @@ class Room extends EventEmitter {
|
|||
let message = {};
|
||||
message.m = "a";
|
||||
message.a = msg.message;
|
||||
if (prsn.user.hasFlag('vowels')) {
|
||||
message.a = message.a.split(/[aeiouAEIOU]/).join(prsn.user.flags["vowels"]);
|
||||
}
|
||||
message.p = {
|
||||
color: p.user.color,
|
||||
id: p.participantId,
|
||||
|
@ -361,34 +338,46 @@ class Room extends EventEmitter {
|
|||
message.t = Date.now();
|
||||
this.sendArray([message]);
|
||||
this.chatmsgs.push(message);
|
||||
this.setData();
|
||||
}
|
||||
}
|
||||
|
||||
playNote(cl, note) {
|
||||
let vel = Math.round(cl.user.flags["volume"])/100 || undefined;
|
||||
if (vel == 1) vel = undefined;
|
||||
|
||||
this.sendArray([{
|
||||
m: "n",
|
||||
n: note.n,
|
||||
p: cl.participantId,
|
||||
t: note.t
|
||||
t: note.t,
|
||||
v: vel
|
||||
}], cl, true);
|
||||
}
|
||||
|
||||
kickban(_id, ms) {
|
||||
ms = parseInt(ms);
|
||||
|
||||
if (ms >= (1000 * 60 * 60)) 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 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)) {
|
||||
|
||||
//if (this.crown && (this.crown.userId)) {
|
||||
u.setChannel("test/awkward", {});
|
||||
|
||||
if (asd)
|
||||
this.Notification(user.user._id,
|
||||
"Notice",
|
||||
|
@ -416,8 +405,7 @@ class Room extends EventEmitter {
|
|||
"#room"
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
//}
|
||||
|
||||
})
|
||||
}
|
||||
|
@ -433,6 +421,7 @@ class Room extends EventEmitter {
|
|||
class: klass,
|
||||
id: id
|
||||
};
|
||||
|
||||
if (!id) delete obj.id;
|
||||
if (!title) delete obj.title;
|
||||
if (!text) delete obj.text;
|
||||
|
@ -440,6 +429,7 @@ class Room extends EventEmitter {
|
|||
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())) {
|
||||
|
@ -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;
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
const config = require ('../config');
|
||||
|
||||
class RoomSettings {
|
||||
static allowedProperties = {
|
||||
color: {
|
||||
type: 'color',
|
||||
default: "#9900ff",
|
||||
default: config.defaultRoomSettings.color,
|
||||
allowedChange: true,
|
||||
required: true
|
||||
},
|
||||
color2: {
|
||||
type: 'color2',
|
||||
default: "#5900bf",
|
||||
default: config.defaultRoomSettings.color2,
|
||||
allowedChange: true,
|
||||
required: false
|
||||
},
|
||||
|
@ -39,10 +41,15 @@ class RoomSettings {
|
|||
default: false,
|
||||
allowedChange: true,
|
||||
required: true
|
||||
},
|
||||
"no cussing": {
|
||||
type: 'boolean',
|
||||
allowedChange: true,
|
||||
required: false
|
||||
}
|
||||
}
|
||||
|
||||
constructor (set, cont) {
|
||||
constructor (set, context) {
|
||||
Object.keys(RoomSettings.allowedProperties).forEach(key => {
|
||||
if (typeof(RoomSettings.allowedProperties[key].default) !== 'undefined') {
|
||||
if (this[key] !== RoomSettings.allowedProperties[key].default) {
|
||||
|
@ -63,10 +70,10 @@ class RoomSettings {
|
|||
Object.keys(set).forEach(key => {
|
||||
if (typeof(set[key]) == 'undefined') return;
|
||||
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);
|
||||
} else {
|
||||
if (cont == 'user') {
|
||||
if (context == 'user') {
|
||||
if (RoomSettings.allowedProperties[key].allowedChange) {
|
||||
this[key] = this.verifyPropertyType(key, set[key], RoomSettings.allowedProperties[key].type);
|
||||
}
|
||||
|
|
|
@ -52,11 +52,13 @@ class Server extends EventEmitter {
|
|||
this.roomlisteners = new Map();
|
||||
this.rooms = new Map();
|
||||
|
||||
this.specialIntervals = {};
|
||||
|
||||
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", "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._id_Private_Key = config._id_PrivateKey || "boppity";
|
||||
|
@ -68,6 +70,10 @@ class Server extends EventEmitter {
|
|||
if (!data.ch.settings.visible) return;
|
||||
|
||||
for (let cl of Array.from(this.roomlisteners.values())) {
|
||||
if (cl.destroied) {
|
||||
cl = undefined;
|
||||
return;
|
||||
}
|
||||
cl.sendArray([{
|
||||
"m": "ls",
|
||||
"c": false,
|
||||
|
|
69
src/User.js
69
src/User.js
|
@ -1,12 +1,77 @@
|
|||
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 {
|
||||
constructor(cl, data) {
|
||||
this.server = cl.server;
|
||||
this.name = data.name;
|
||||
this.cl = cl;
|
||||
this._id = data._id;
|
||||
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) {
|
||||
|
|
|
@ -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