forked from Hri7566/mpp-server-dev2
Merge branch 'master' of gitlab.com:Hri7566/mpp-server
This commit is contained in:
commit
32c6b0ffa8
25
config.js
25
config.js
|
@ -2,22 +2,27 @@ module.exports = Object.seal({
|
|||
port: 8443,
|
||||
motd: "big th0nk",
|
||||
_id_PrivateKey: process.env.SALT,
|
||||
defaultUsername: "Anonymous",
|
||||
// defaultRoomColor: "#3b5054",
|
||||
defaultRoomColor: "#480505",
|
||||
|
||||
// defaultLobbyColor: "#19b4b9",
|
||||
// defaultLobbyColor: "#76b0db",
|
||||
// defaultLobbyColor2: "#801014",
|
||||
// defaultLobbyColor2: "#276491",
|
||||
defaultLobbyColor: "#9900ff",
|
||||
defaultLobbyColor2: "#5900af",
|
||||
defaultLobbyColor: "#76b0db",
|
||||
defaultLobbyColor2: "#276491",
|
||||
// defaultLobbyColor: "#9900ff",
|
||||
// defaultLobbyColor2: "#5900af",
|
||||
|
||||
defaultUsername: "Anonymous",
|
||||
adminpass: process.env.ADMINPASS,
|
||||
ssl: process.env.SSL,
|
||||
serveFiles: true,
|
||||
defaultRoomSettings: {
|
||||
color: "#3b5054",
|
||||
color2: "#001014",
|
||||
// color: "#3b5054",
|
||||
// color2: "#001014",
|
||||
|
||||
color: "#480505",
|
||||
crownsolo: false,
|
||||
visible: true
|
||||
}
|
||||
},
|
||||
|
||||
hostDevFiles: false,
|
||||
enableMPPCloneBot: true
|
||||
});
|
||||
|
|
35
index.js
35
index.js
|
@ -34,3 +34,38 @@ let console = process.platform == 'win32' ? new AsyncConsole("", input => {
|
|||
}
|
||||
}) : {};
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// dev environment
|
||||
|
||||
if (config.hostDevFiles) {
|
||||
let express_logger = new (require("./src/Logger"))("Express Server");
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
const path = require('path');
|
||||
var http = require('http');
|
||||
|
||||
let dir = path.join(__dirname, 'mpp.hri7566.info');
|
||||
app.use(express.static(path.join(__dirname, dir)));
|
||||
|
||||
app.get('*', (req, res, next) => {
|
||||
let file = path.join(dir, req.path);
|
||||
if (fs.existsSync(file)) {
|
||||
res.sendFile(file);
|
||||
} else {
|
||||
res.sendFile(path.join(dir, 'index.html'));
|
||||
}
|
||||
});
|
||||
|
||||
const express_port = 8075;
|
||||
|
||||
http.createServer(app).listen(express_port);
|
||||
}
|
||||
|
||||
if (config.enableMPPCloneBot) {
|
||||
require('./mppclonebot');
|
||||
}
|
||||
|
|
|
@ -0,0 +1,231 @@
|
|||
const Client = require('mppclone-client');
|
||||
const Logger = require('./src/Logger');
|
||||
const { EventEmitter } = require('events');
|
||||
|
||||
const token = process.env.MPPCLONE_TOKEN;
|
||||
|
||||
class Command {
|
||||
static commands = {};
|
||||
|
||||
static getUsage(us, prefix) {
|
||||
return us.split('%PREFIX%').join(prefix);
|
||||
}
|
||||
|
||||
constructor(cmd, desc, usage, minargs, func, minrank, hidden) {
|
||||
this.cmd = typeof cmd == 'object' ? cmd : [cmd];
|
||||
this.desc = desc || "No description";
|
||||
this.usage = usage || "No usage";
|
||||
this.minargs = minargs || 0;
|
||||
this.func = func;
|
||||
this.minrank = minrank || 0;
|
||||
this.hidden = hidden || false;
|
||||
|
||||
Command.commands[this.cmd[0]] = this;
|
||||
}
|
||||
}
|
||||
|
||||
class Rank {
|
||||
static ranks = {};
|
||||
|
||||
static user_ranks = {};
|
||||
|
||||
static setRank(_id, rank) {
|
||||
Rank.user_ranks[_id] = rank;
|
||||
}
|
||||
|
||||
static getRank(_id) {
|
||||
return Rank.user_ranks[_id];
|
||||
}
|
||||
|
||||
constructor(name, desc, minrank) {
|
||||
this.name = name;
|
||||
this.desc = desc;
|
||||
this.minrank = minrank;
|
||||
|
||||
Rank.ranks[name] = this;
|
||||
}
|
||||
}
|
||||
|
||||
new Rank("User", "Default rank", 0);
|
||||
new Rank("Mod", "Moderator rank", 1);
|
||||
new Rank("Admin", "Administrator rank", 2);
|
||||
new Rank("Owner", "Owner rank", 3);
|
||||
|
||||
class Prefix {
|
||||
static prefixes = {};
|
||||
|
||||
static hasAnyPrefix(str) {
|
||||
for (let i in Prefix.prefixes) {
|
||||
if (str.startsWith(Prefix.prefixes[i].prefix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static getPrefixFromString(str) {
|
||||
for (let i in Prefix.prefixes) {
|
||||
if (str.startsWith(Prefix.prefixes[i].prefix)) {
|
||||
return Prefix.prefixes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constructor(id, prefix) {
|
||||
this.id = id;
|
||||
this.prefix = prefix;
|
||||
|
||||
Prefix.prefixes[id] = this;
|
||||
}
|
||||
}
|
||||
|
||||
class Bot extends EventEmitter {
|
||||
constructor(cl) {
|
||||
super();
|
||||
|
||||
this.logger = new Logger('MPPClone Bot');
|
||||
|
||||
this.client = cl;
|
||||
this.bindEventListeners();
|
||||
|
||||
this.userset = {
|
||||
name: 'mpp.hri7566.info [indev]', // TODO change this name
|
||||
color: '#76b0db'
|
||||
};
|
||||
|
||||
this.chatBuffer = [];
|
||||
this.chatBufferCycleCounter = 0;
|
||||
|
||||
this.chatBufferCycle();
|
||||
|
||||
this.client.start();
|
||||
this.client.setChannel('✧𝓓𝓔𝓥 𝓡𝓸𝓸𝓶✧');
|
||||
}
|
||||
|
||||
bindEventListeners() {
|
||||
this.client.on('a', msg => {
|
||||
this.emit('receiveChat', msg);
|
||||
});
|
||||
|
||||
this.client.on('ch', msg => {
|
||||
this.emit('resetName', msg);
|
||||
})
|
||||
|
||||
this.client.on('hi', msg => {
|
||||
this.emit('online', msg);
|
||||
});
|
||||
|
||||
this.client.on('t', msg => {
|
||||
this.emit('resetName', msg);
|
||||
});
|
||||
|
||||
this.on('resetName', () => {
|
||||
if (this.client.getOwnParticipant().name !== this.userset.name || this.client.getOwnParticipant().color !== this.userset.color) {
|
||||
this.client.sendArray([{
|
||||
m: 'userset',
|
||||
set: this.userset
|
||||
}]);
|
||||
}
|
||||
});
|
||||
|
||||
this.on('receiveChat', msg => {
|
||||
if (Prefix.hasAnyPrefix(msg.a)) {
|
||||
msg.prefix = Prefix.getPrefixFromString(msg.a);
|
||||
this.emit('runCommand', msg);
|
||||
}
|
||||
});
|
||||
|
||||
this.on('addToChatBuffer', msg => {
|
||||
this.chatBuffer.push(msg);
|
||||
});
|
||||
|
||||
this.on('runCommand', msg => {
|
||||
if (!msg.prefix) return;
|
||||
|
||||
msg.args = msg.a.split(' ');
|
||||
msg.cmd = msg.args[0].substring(msg.prefix.prefix.length).trim();
|
||||
msg.argcat = msg.a.substring(msg.args[0].length).trim();
|
||||
|
||||
let rank = Rank.getRank(msg.p._id);
|
||||
if (!rank) {
|
||||
rank = Rank.ranks['User'];
|
||||
Rank.setRank(msg.p._id, rank);
|
||||
}
|
||||
|
||||
msg.rank = rank;
|
||||
|
||||
for (let cmd of Object.values(Command.commands)) {
|
||||
if (!cmd.cmd.includes(msg.cmd)) continue;
|
||||
console.log(msg.cmd, cmd.cmd);
|
||||
if (msg.args.length < cmd.minargs) return;
|
||||
if (msg.rank.id < cmd.minrank) return;
|
||||
|
||||
try {
|
||||
let out = cmd.func(msg);
|
||||
if (!out) return;
|
||||
|
||||
out = out.split('\n').join(' ').split('\t').join(' ').split('\r').join(' ');
|
||||
|
||||
if (out !== '') {
|
||||
this.emit('addToChatBuffer', {
|
||||
m: 'a',
|
||||
message: out,
|
||||
p: msg.p._id
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
this.emit('addToChatBuffer', {
|
||||
m: 'a',
|
||||
message: 'An error has occurred.',
|
||||
p: msg.p._id
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.on('online', () => {
|
||||
this.logger.log('Connected');
|
||||
});
|
||||
}
|
||||
|
||||
async chatBufferCycle() {
|
||||
if (this.chatBuffer.length <= 0) {
|
||||
setTimeout(() => {
|
||||
this.chatBufferCycle();
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.chatBufferCycleCounter++;
|
||||
let time = 0;
|
||||
if (this.chatBufferCycleCounter > 4) {
|
||||
time += 1000;
|
||||
}
|
||||
setTimeout(() => {
|
||||
let nextMessage = this.chatBuffer.shift();
|
||||
this.client.sendArray([nextMessage]);
|
||||
this.chatBufferCycle();
|
||||
this.chatBufferCycleCounter--;
|
||||
}, time);
|
||||
}
|
||||
}
|
||||
|
||||
new Prefix('hmpp!', 'hmpp!');
|
||||
new Prefix('h!', 'h!');
|
||||
|
||||
new Command(['help', 'cmds', 'h'], 'List all commands', '%PREFIX%help', 0, (msg) => {
|
||||
let cmds = 'Commands: ';
|
||||
for (let cmd of Object.values(Command.commands)) {
|
||||
if (cmd.hidden) continue;
|
||||
cmds += `${cmd.cmd[0]}, `;
|
||||
}
|
||||
cmds = cmds.substring(0, cmds.length - 2).trim();
|
||||
return cmds;
|
||||
}, 0, false);
|
||||
|
||||
new Command(['users'], 'See how many users are online', `%PREFIX%users`, 0, (msg) => {
|
||||
console.log(SERVER.connections.size);
|
||||
return `There are ${SERVER.connections.size} users on HMPP.`;
|
||||
}, 0, false);
|
||||
|
||||
let cl = new Client("wss://mppclone.com:8443", token);
|
||||
|
||||
let bot = new Bot(cl);
|
File diff suppressed because it is too large
Load Diff
|
@ -31,7 +31,7 @@
|
|||
"keccak": "^2.1.0",
|
||||
"level": "^7.0.0",
|
||||
"mongoose": "^5.12.7",
|
||||
"node-json-color-stringify": "^1.1.0",
|
||||
"mppclone-client": "^1.0.0",
|
||||
"nodemon": "^2.0.15",
|
||||
"ws": "^7.2.3"
|
||||
}
|
||||
|
|
282
src/Channel.js
282
src/Channel.js
|
@ -7,6 +7,7 @@ const RoomSettings = require('./RoomSettings.js');
|
|||
const ftc = require('fancy-text-converter');
|
||||
const Notification = require('./Notification');
|
||||
const Color = require('./Color');
|
||||
const { getTimeColor } = require('./ColorEncoder.js');
|
||||
|
||||
class Channel extends EventEmitter {
|
||||
constructor(server, _id, settings) {
|
||||
|
@ -16,7 +17,16 @@ class Channel extends EventEmitter {
|
|||
this.server = server;
|
||||
this.crown;
|
||||
this.crowndropped = false;
|
||||
this.settings = settings;
|
||||
|
||||
if (this.isLobby(this._id)) {
|
||||
this.settings = new RoomSettings(this.server.lobbySettings);
|
||||
// this.settings.lobby = true;
|
||||
// this.settings.color = this.server.lobbySettings.color;
|
||||
// this.settings.color2 = this.server.lobbySettings.color2;
|
||||
} else {
|
||||
this.settings = new RoomSettings(settings, 'user');
|
||||
}
|
||||
|
||||
this.chatmsgs = [];
|
||||
this.ppl = new Map();
|
||||
this.connections = [];
|
||||
|
@ -32,8 +42,8 @@ class Channel extends EventEmitter {
|
|||
if (err) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.settings = set.settings;
|
||||
|
||||
this.settings = RoomSettings.changeSettings(this.settings, true);
|
||||
this.chatmsgs = set.chat;
|
||||
this.connections.forEach(cl => {
|
||||
cl.sendArray([{
|
||||
|
@ -43,6 +53,13 @@ class Channel extends EventEmitter {
|
|||
});
|
||||
this.setData();
|
||||
});
|
||||
|
||||
if (this.isLobby(this._id)) {
|
||||
this.colorInterval = setInterval(() => {
|
||||
this.setDefaultLobbyColorBasedOnDate();
|
||||
}, 1000 * 60 * 5);
|
||||
this.setDefaultLobbyColorBasedOnDate();
|
||||
}
|
||||
}
|
||||
|
||||
setChatArray(arr) {
|
||||
|
@ -54,40 +71,67 @@ class Channel extends EventEmitter {
|
|||
this.setData();
|
||||
}
|
||||
|
||||
setDefaultLobbyColorBasedOnDate() {
|
||||
let col = getTimeColor();
|
||||
let col2 = new Color(col.r - 0x40, col.g - 0x40, col.b - 0x40);
|
||||
|
||||
this.settings.changeSettings({
|
||||
color: col.toHexa(),
|
||||
color2: col2.toHexa()
|
||||
});
|
||||
|
||||
for (let key in this.settings) {
|
||||
this.server.lobbySettings[key] = this.settings[key];
|
||||
}
|
||||
|
||||
this.emit('update');
|
||||
}
|
||||
|
||||
join(cl, set) { //this stuff is complicated
|
||||
let otheruser = this.connections.find((a) => a.user._id == cl.user._id)
|
||||
if (!otheruser) {
|
||||
// we don't exist yet
|
||||
// create id hash
|
||||
let participantId = createKeccakHash('keccak256').update((Math.random().toString() + cl.ip)).digest('hex').substr(0, 24);
|
||||
|
||||
// set id
|
||||
cl.user.id = participantId;
|
||||
cl.participantId = participantId;
|
||||
|
||||
// init quotas (TODO pass type of room in?)
|
||||
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.
|
||||
|
||||
// no users / already had crown? give 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 owns the room
|
||||
// we need to switch the crown to them
|
||||
//cl.quotas.a.setParams(Quota.PARAMS_A_CROWNED);
|
||||
this.crown = new Crown(cl.participantId, cl.user._id);
|
||||
|
||||
this.crowndropped = false;
|
||||
this.settings = new RoomSettings(set, 'user');
|
||||
// this.settings = new RoomSettings(set, 'user');
|
||||
} else {
|
||||
//cl.quotas.a.setParams(Quota.PARAMS_A_NORMAL);
|
||||
|
||||
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;
|
||||
if (this.isLobby(this._id) && this.settings.lobby !== true) {
|
||||
// fix lobby setting
|
||||
this.settings.changeSettings({lobby: true});
|
||||
// this.settings.visible = true;
|
||||
// this.settings.crownsolo = false;
|
||||
// this.settings.lobby = true;
|
||||
// this.settings.color = this.server.lobbySettings.color;
|
||||
// this.settings.color2 = this.server.lobbySettings.color2;
|
||||
} else {
|
||||
if (typeof(set) == 'undefined') {
|
||||
if (typeof(this.settings) == 'undefined') {
|
||||
this.settings = new RoomSettings(this.server.defaultRoomSettings, 'user');
|
||||
if (!this.isLobby) {
|
||||
if (typeof(set) == 'undefined') {
|
||||
if (typeof(this.settings) == 'undefined') {
|
||||
this.settings = new RoomSettings(this.server.defaultRoomSettings, 'user');
|
||||
} else {
|
||||
this.settings = new RoomSettings(cl.channel.settings, 'user');
|
||||
}
|
||||
} else {
|
||||
this.settings = new RoomSettings(cl.channel.settings, 'user');
|
||||
this.settings = new RoomSettings(set, 'user');
|
||||
}
|
||||
} else {
|
||||
this.settings = new RoomSettings(set, 'user');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,21 +140,25 @@ class Channel extends EventEmitter {
|
|||
|
||||
this.connections.push(cl);
|
||||
|
||||
if (!cl.hidden) {
|
||||
cl.sendArray([{
|
||||
m: "c",
|
||||
c: this.chatmsgs.slice(-1 * 32)
|
||||
}]);
|
||||
|
||||
// this.updateCh(cl, this.settings);
|
||||
|
||||
if (!cl.user.hasFlag("hidden", true)) {
|
||||
this.sendArray([{
|
||||
color: this.ppl.get(cl.participantId).user.color,
|
||||
id: this.ppl.get(cl.participantId).participantId,
|
||||
m: "p",
|
||||
name: this.ppl.get(cl.participantId).user.name,
|
||||
m: 'p',
|
||||
_id: cl.user._id,
|
||||
name: cl.user.name,
|
||||
color: cl.user.color,
|
||||
id: cl.participantId,
|
||||
x: this.ppl.get(cl.participantId).x || 200,
|
||||
y: this.ppl.get(cl.participantId).y || 100,
|
||||
_id: cl.user._id
|
||||
}], cl, false)
|
||||
cl.sendArray([{
|
||||
m: "c",
|
||||
c: this.chatmsgs.slice(-1 * 32)
|
||||
}]);
|
||||
y: this.ppl.get(cl.participantId).y || 100
|
||||
}], cl, false);
|
||||
}
|
||||
|
||||
this.updateCh(cl, this.settings);
|
||||
} else {
|
||||
cl.user.id = otheruser.participantId;
|
||||
|
@ -123,9 +171,40 @@ class Channel extends EventEmitter {
|
|||
}])
|
||||
this.updateCh(cl, this.settings);
|
||||
}
|
||||
|
||||
if (this.flags.spin == true) {
|
||||
this.spin(cl);
|
||||
}
|
||||
}
|
||||
|
||||
remove(p) { //this is complicated too
|
||||
spin(cl) { // speeeeeeen
|
||||
let id = cl.user._id;
|
||||
if (!id) id = "room";
|
||||
this.Notification(id,
|
||||
"",
|
||||
``,
|
||||
`<script>$("#piano").addClass("spin")</script>`,
|
||||
1,
|
||||
"#names",
|
||||
"short"
|
||||
);
|
||||
}
|
||||
|
||||
stopSpin(cl) {
|
||||
let id = cl.user._id;
|
||||
if (!id) id = "room";
|
||||
this.Notification(id,
|
||||
"",
|
||||
``,
|
||||
`<script>$("#piano").removeClass("spin")</script>`,
|
||||
1,
|
||||
"#names",
|
||||
"short"
|
||||
);
|
||||
}
|
||||
|
||||
remove(p) { // remove user
|
||||
if (!p) return;
|
||||
let otheruser = this.connections.filter((a) => a.user._id == p.user._id);
|
||||
if (!(otheruser.length > 1)) {
|
||||
this.ppl.delete(p.participantId);
|
||||
|
@ -145,11 +224,11 @@ class Channel extends EventEmitter {
|
|||
|
||||
}
|
||||
|
||||
updateCh(cl) { //update channel for all people in channel
|
||||
updateCh(cl, set) { //update channel for all people in channel
|
||||
if (Array.from(this.ppl.values()).length <= 0) {
|
||||
setTimeout(() => {
|
||||
this.destroy();
|
||||
}, 5000);
|
||||
}, 13000);
|
||||
}
|
||||
|
||||
this.connections.forEach((usr) => {
|
||||
|
@ -195,6 +274,7 @@ class Channel extends EventEmitter {
|
|||
destroy() { //destroy room
|
||||
if (this.destroyed) return;
|
||||
if (this.ppl.size > 0) return;
|
||||
if (this._id == "lobby") return;
|
||||
this.destroyed = true;
|
||||
this._id;
|
||||
console.log(`Deleted room ${this._id}`);
|
||||
|
@ -209,6 +289,8 @@ class Channel extends EventEmitter {
|
|||
this.connections.forEach((usr) => {
|
||||
if (!not || (usr.participantId != not.participantId && !onlythisparticipant) || (usr.connectionid != not.connectionid && onlythisparticipant)) {
|
||||
try {
|
||||
let cl = this.server.connections.get(usr.connectionid);
|
||||
if (!cl) return;
|
||||
this.server.connections.get(usr.connectionid).sendArray(arr)
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
@ -221,6 +303,20 @@ class Channel extends EventEmitter {
|
|||
let chppl = [];
|
||||
|
||||
[...this.ppl.values()].forEach(c => {
|
||||
if (cl) {
|
||||
if (c.hidden == true && c.user._id !== cl.user._id) {
|
||||
// client is hidden and we are that client
|
||||
return;
|
||||
} else if (c.user._id == cl.user._id) {
|
||||
// let u = {
|
||||
// _id: c.user._id,
|
||||
// name: c.user.name + ' [HIDDEN]',
|
||||
// color: c.user.color,
|
||||
// id: c.participantId
|
||||
// }
|
||||
// chppl.push(u);
|
||||
}
|
||||
}
|
||||
let u = {
|
||||
_id: c.user._id,
|
||||
name: c.user.name,
|
||||
|
@ -304,8 +400,10 @@ class Channel extends EventEmitter {
|
|||
this.crown = new Crown(id, prsn.user._id);
|
||||
this.crowndropped = false;
|
||||
} else {
|
||||
this.crown = new Crown(id, this.crown.userId);
|
||||
this.crowndropped = true;
|
||||
if (this.crown) {
|
||||
this.crown = new Crown(id, this.crown.userId);
|
||||
this.crowndropped = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.updateCh();
|
||||
|
@ -326,26 +424,33 @@ class Channel extends EventEmitter {
|
|||
|
||||
chat(p, msg) {
|
||||
if (msg.message.length > 512) return;
|
||||
|
||||
let filter = ["AMIGHTYWIND", "CHECKLYHQ"];
|
||||
let regexp = new RegExp("\\b(" + filter.join("|") + ")\\b", "i");
|
||||
if (regexp.test(msg.message.split(' ').join(''))) return;
|
||||
|
||||
if (p.participantId == 0) {
|
||||
let message = {};
|
||||
|
||||
message.m = "a";
|
||||
message.t = Date.now();
|
||||
message.a = msg.message;
|
||||
|
||||
message.p = {
|
||||
color: "#ffffff",
|
||||
id: "0",
|
||||
name: "mpp",
|
||||
_id: "0"
|
||||
};
|
||||
message.t = Date.now();
|
||||
|
||||
|
||||
this.sendArray([message]);
|
||||
|
||||
this.chatmsgs.push(message);
|
||||
this.setData();
|
||||
return;
|
||||
}
|
||||
|
||||
let prsn = this.ppl.get(p.participantId);
|
||||
if (!prsn) return;
|
||||
let message = {};
|
||||
|
@ -382,6 +487,7 @@ class Channel extends EventEmitter {
|
|||
this.adminChat("pong");
|
||||
break;
|
||||
case "!setcolor":
|
||||
case "!color":
|
||||
if (!isAdmin) {
|
||||
this.adminChat("You do not have permission to use this command.");
|
||||
return;
|
||||
|
@ -394,7 +500,7 @@ class Channel extends EventEmitter {
|
|||
color: c.toHexa(),
|
||||
_id: p.user._id
|
||||
}, true);
|
||||
this.adminChat(`Your color is now: ${c.getName()} [${c.toHexa()}]`);
|
||||
this.adminChat(`Your color is now ${c.getName().replace('A', 'a')} [${c.toHexa()}]`);
|
||||
} else {
|
||||
let winner = this.server.getAllClientsByUserID(args[2])[0];
|
||||
if (winner) {
|
||||
|
@ -412,6 +518,27 @@ class Channel extends EventEmitter {
|
|||
}
|
||||
this.updateCh();
|
||||
break;
|
||||
case "!users":
|
||||
this.adminChat(`There are ${this.server.connections.size} users online.`);
|
||||
break;
|
||||
case "!chown":
|
||||
if (!isAdmin) return;
|
||||
let id = p.participantId;
|
||||
if (args[1]) {
|
||||
id = args[1];
|
||||
}
|
||||
if (this.hasUser(id)) {
|
||||
this.chown(id);
|
||||
}
|
||||
break;
|
||||
case "!chlist":
|
||||
case "!channellist":
|
||||
if (!isAdmin) return;
|
||||
this.adminChat("Channels:");
|
||||
for (let [_id] of this.server.rooms) {
|
||||
this.adminChat(`- ${_id}`);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -423,12 +550,37 @@ class Channel extends EventEmitter {
|
|||
});
|
||||
}
|
||||
|
||||
hasUser(id) {
|
||||
return this.ppl.has(id);
|
||||
}
|
||||
|
||||
playNote(cl, note) {
|
||||
let vel = Math.round(cl.user.flags["volume"])/100 || undefined;
|
||||
if (cl.user.hasFlag('mute', true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cl.user.hasFlag('mute')) {
|
||||
if (Array.isArray(cl.user.flags['mute'])) {
|
||||
if (cl.user.flags['mute'].includes(this._id)) return;
|
||||
}
|
||||
}
|
||||
|
||||
let vol;
|
||||
|
||||
if (cl.user.hasFlag('volume')) {
|
||||
vol = Math.round(cl.user.flags["volume"]) / 100;
|
||||
}
|
||||
|
||||
|
||||
if (vel) {
|
||||
if (typeof vol == 'number') {
|
||||
for (let no of note.n) {
|
||||
no.v /= vel;
|
||||
if (no.v) {
|
||||
if (vol == 0) {
|
||||
no.v = vol;
|
||||
} else {
|
||||
no.v *= vol;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -495,6 +647,20 @@ class Channel extends EventEmitter {
|
|||
})
|
||||
}
|
||||
|
||||
unban(_id) {
|
||||
this.connections.filter((usr) => usr.participantId == user.participantId).forEach(u => {
|
||||
if (user.bantime) {
|
||||
delete user.bantime;
|
||||
}
|
||||
|
||||
if (user.bannedtime) {
|
||||
delete user.bannedtime;
|
||||
}
|
||||
|
||||
this.bans.delete(user.user._id);
|
||||
});
|
||||
}
|
||||
|
||||
Notification(who, title, text, html, duration, target, klass, id) {
|
||||
new Notification({
|
||||
id: id,
|
||||
|
@ -512,15 +678,39 @@ class Channel extends EventEmitter {
|
|||
bindEventListeners() {
|
||||
this.on("bye", participant => {
|
||||
this.remove(participant);
|
||||
})
|
||||
});
|
||||
|
||||
this.on("m", (participant, x, y) => {
|
||||
this.setCoords(participant, x, y);
|
||||
})
|
||||
this.on("m", msg => {
|
||||
let p = this.ppl.get(msg.p);
|
||||
if (!p) return;
|
||||
this.setCoords(p, msg.x, msg.y);
|
||||
});
|
||||
|
||||
this.on("a", (participant, msg) => {
|
||||
this.chat(participant, msg);
|
||||
})
|
||||
});
|
||||
|
||||
this.on("update", (cl, set) => {
|
||||
this.updateCh(cl, set);
|
||||
});
|
||||
|
||||
this.on("remove crown", () => {
|
||||
this.crown = undefined;
|
||||
delete this.crown;
|
||||
this.emit('update');
|
||||
});
|
||||
|
||||
this.on("flag spin", spin => {
|
||||
if (spin) {
|
||||
for (let cl of this.connections) {
|
||||
this.spin(cl);
|
||||
}
|
||||
} else {
|
||||
for (let cl of this.connections) {
|
||||
this.stopSpin(cl);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
verifySet(_id, msg) {
|
||||
|
|
|
@ -5,7 +5,7 @@ const RateLimit = require('./Ratelimit.js').RateLimit;
|
|||
const RateLimitChain = require('./Ratelimit.js').RateLimitChain;
|
||||
const User = require("./User.js");
|
||||
const Database = require("./Database.js");
|
||||
require('node-json-color-stringify');
|
||||
const { EventEmitter } = require('events');
|
||||
|
||||
class Client extends EventEmitter {
|
||||
constructor(ws, req, server) {
|
||||
|
@ -73,9 +73,7 @@ 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);
|
||||
}
|
||||
this.channel.join(this);
|
||||
} else {
|
||||
let room = new Channel(this.server, _id, settings);
|
||||
this.server.rooms.set(_id, room);
|
||||
|
@ -92,6 +90,23 @@ class Client extends EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
userset(name, admin) {
|
||||
if (name.length > 40 && !admin) return;
|
||||
if (!this.quotas.userset.attempt()) return;
|
||||
this.user.name = name;
|
||||
Database.getUserData(this, this.server).then((usr) => {
|
||||
if (!this.user.hasFlag('freeze_name', true)) {
|
||||
Database.updateUser(this.user._id, this.user);
|
||||
}
|
||||
|
||||
this.server.rooms.forEach((room) => {
|
||||
room.updateParticipant(this.user._id, {
|
||||
name: name
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
initParticipantQuotas() {
|
||||
this.quotas = {
|
||||
//"chat": new Quota(Quota.PARAMS_A_NORMAL),
|
||||
|
@ -112,6 +127,7 @@ class Client extends EventEmitter {
|
|||
}
|
||||
|
||||
destroy() {
|
||||
this.user.stopFlagEvents();
|
||||
this.ws.close();
|
||||
if (this.channel) {
|
||||
this.channel.emit("bye", this);
|
||||
|
@ -170,6 +186,16 @@ class Client extends EventEmitter {
|
|||
|
||||
this.sendArray([data]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Channel} ch
|
||||
* @param {Client} cl If this is present, only this client's user data will be sent(?)
|
||||
*/
|
||||
sendChannelUpdate(ch, cl) {
|
||||
let msg = ch.fetchChannelData(this, cl);
|
||||
this.sendArray([msg]);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Client;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
const Color = require("./Color");
|
||||
|
||||
function hashCode(str) { // java String#hashCode
|
||||
var hash = 0;
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
|
@ -13,4 +15,73 @@ function intToRGB(i){
|
|||
|
||||
return "00000".substring(0, 6 - c.length) + c;
|
||||
}
|
||||
module.exports = {hashCode, intToRGB};
|
||||
|
||||
/**
|
||||
* Converts an HSL color value to RGB. Conversion formula
|
||||
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
|
||||
* Assumes h, s, and l are contained in the set [0, 1] and
|
||||
* returns r, g, and b in the set [0, 255].
|
||||
*
|
||||
* @param {number} h The hue
|
||||
* @param {number} s The saturation
|
||||
* @param {number} l The lightness
|
||||
* @return {Array} The RGB representation
|
||||
*/
|
||||
function hslToRgb(h, s, l){
|
||||
var r, g, b;
|
||||
|
||||
if(s == 0){
|
||||
r = g = b = l; // achromatic
|
||||
}else{
|
||||
var hue2rgb = function hue2rgb(p, q, t){
|
||||
if(t < 0) t += 1;
|
||||
if(t > 1) t -= 1;
|
||||
if(t < 1/6) return p + (q - p) * 6 * t;
|
||||
if(t < 1/2) return q;
|
||||
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
}
|
||||
|
||||
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
var p = 2 * l - q;
|
||||
r = hue2rgb(p, q, h + 1/3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1/3);
|
||||
}
|
||||
|
||||
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
|
||||
}
|
||||
|
||||
function getTimeColor(currentDate = new Date()) {
|
||||
// get day of year as a number from 1-365
|
||||
let newYearsDay = new Date(currentDate.getFullYear());
|
||||
let differenceInTime = (currentDate - newYearsDay) + ((newYearsDay.getTimezoneOffset() - currentDate.getTimezoneOffset()) * 60 * 1000);
|
||||
let oneDayInMS = 1000 * 60 * 60 * 24;
|
||||
let dayOfYear = Math.ceil(differenceInTime / oneDayInMS);
|
||||
|
||||
// get hour
|
||||
let hours = currentDate.getHours();
|
||||
let seconds = currentDate.getSeconds();
|
||||
|
||||
// get a hue based on time of day and day of year
|
||||
let h = Math.floor((dayOfYear / 365) * 100) / 10000;
|
||||
let s = (hours + 1) / (24 / 3);
|
||||
// let s = 1;
|
||||
let l = 0.25 + Math.floor(((hours / 60)) * 1000) / 1000;
|
||||
|
||||
if (l > 0.5) l = 0.5;
|
||||
if (s > 1) s = 1;
|
||||
|
||||
// convert to rgb
|
||||
let [r, g, b] = hslToRgb(h, s, l);
|
||||
|
||||
let col = new Color(r, g, b);
|
||||
return col;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
hashCode,
|
||||
intToRGB,
|
||||
getTimeColor,
|
||||
hslToRgb
|
||||
}
|
||||
|
|
|
@ -6,20 +6,20 @@ class Logger {
|
|||
}
|
||||
|
||||
log(args) {
|
||||
console.log(chalk.blue(`[INFO] [${this.context}]`), args);
|
||||
console.log(chalk.green(`[`) + chalk.green(`${this.context}`) + chalk.green(`]`), args);
|
||||
}
|
||||
|
||||
warn(args) {
|
||||
console.warn(chalk.yellow(`[WARNING] [${this.context}]`), args);
|
||||
console.warn(chalk.yellow(`[WARN] [`) + chalk.yellow(`${this.context}`) + chalk.yellow(`]`), args);
|
||||
}
|
||||
|
||||
error(args) {
|
||||
console.error(chalk.red(`[ERROR] [${this.context}]`), args);
|
||||
console.error(chalk.red(`[ERR] [`) + chalk.red(`${this.context}`) + chalk.red(`]`), args);
|
||||
}
|
||||
|
||||
debug(args) {
|
||||
if (process.env.DEBUG_ENABLED) {
|
||||
console.log(chalk.green(`[DEBUG] [${this.context}]`), args);
|
||||
console.log(chalk.blue(`[DEBUG] [`) + chalk.blue(`${this.context}`) + chalk.blue(`]`), args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
117
src/Message.js
117
src/Message.js
|
@ -66,14 +66,28 @@ module.exports = (cl) => {
|
|||
});
|
||||
|
||||
cl.on("m", (msg, admin) => {
|
||||
if (!cl.hasOwnProperty('channel')) return;
|
||||
// nobody will see our cursor if we're not somewhere
|
||||
if (!('channel' in cl)) return;
|
||||
|
||||
// check against cursor rate limit
|
||||
if (!cl.quotas.cursor.attempt() && !admin) return;
|
||||
if (!(cl.channel && cl.participantId)) return;
|
||||
|
||||
// if we are nobody, we don't have a cursor
|
||||
if (!cl.participantId) return;
|
||||
|
||||
// no values? null, not undefined
|
||||
if (!msg.hasOwnProperty("x")) msg.x = null;
|
||||
if (!msg.hasOwnProperty("y")) msg.y = null;
|
||||
if (isNaN(parseFloat(msg.x))) msg.x = null;
|
||||
if (isNaN(parseFloat(msg.y))) msg.y = null;
|
||||
cl.channel.emit("m", cl, msg.x, msg.y);
|
||||
|
||||
let m = {
|
||||
p: cl.participantId,
|
||||
x: msg.x,
|
||||
y: msg.y
|
||||
}
|
||||
|
||||
cl.channel.emit("m", m);
|
||||
});
|
||||
|
||||
cl.on("chown", (msg, admin) => {
|
||||
|
@ -83,7 +97,9 @@ module.exports = (cl) => {
|
|||
//console.log((Date.now() - cl.channel.crown.time))
|
||||
//console.log(!(cl.channel.crown.userId != cl.user._id), !((Date.now() - cl.channel.crown.time) > 15000));
|
||||
|
||||
if (!(cl.channel.crown.userId == cl.user._id) && !((Date.now() - cl.channel.crown.time) > 15000)) return;
|
||||
if (!cl.channel.crown && !admin) {
|
||||
if (!(cl.channel.crown.userId == cl.user._id) && !((Date.now() - cl.channel.crown.time) > 15000)) return;
|
||||
}
|
||||
|
||||
if (msg.hasOwnProperty("id")) {
|
||||
// console.log(cl.channel.crown)
|
||||
|
@ -128,11 +144,12 @@ module.exports = (cl) => {
|
|||
if (!(cl.user._id == cl.channel.crown.userId)) return;
|
||||
}
|
||||
if (!msg.hasOwnProperty("set") || !msg.set) msg.set = new RoomSettings(cl.channel.settings, 'user');
|
||||
cl.channel.settings.changeSettings(msg.set);
|
||||
cl.channel.updateCh();
|
||||
cl.channel.settings.changeSettings(msg.set, admin);
|
||||
// cl.channel.updateCh();
|
||||
cl.channel.emit('update');
|
||||
});
|
||||
|
||||
cl.on("a", (msg, admin) => {
|
||||
cl.on('a', (msg, admin) => {
|
||||
if (!(cl.channel && cl.participantId)) return;
|
||||
if (!msg.hasOwnProperty('message')) return;
|
||||
if (typeof(msg.message) !== 'string') return;
|
||||
|
@ -186,34 +203,21 @@ module.exports = (cl) => {
|
|||
cl.server.roomlisteners.delete(cl.connectionid);
|
||||
});
|
||||
|
||||
cl.on("userset", msg => {
|
||||
cl.on("userset", (msg, admin) => {
|
||||
if (!(cl.channel && cl.participantId)) return;
|
||||
if (!msg.hasOwnProperty("set") || !msg.set) msg.set = {};
|
||||
if (msg.set.hasOwnProperty('name') && typeof msg.set.name == "string") {
|
||||
if (msg.set.name.length > 40) return;
|
||||
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();
|
||||
Database.updateUser(cl.user._id, cl.user);
|
||||
cl.server.rooms.forEach((room) => {
|
||||
room.updateParticipant(cl.user._id, {
|
||||
name: msg.set.name
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
cl.userset(msg.set.name, admin);
|
||||
}
|
||||
});
|
||||
|
||||
cl.on('kickban', msg => {
|
||||
if (cl.channel.crown == null) return;
|
||||
if (!(cl.channel && cl.participantId)) return;
|
||||
if (!cl.channel.crown.userId) return;
|
||||
if (!(cl.user._id == cl.channel.crown.userId)) return;
|
||||
if (!admin) {
|
||||
if (cl.channel.crown == null) return;
|
||||
if (!(cl.channel && cl.participantId)) return;
|
||||
if (!cl.channel.crown.userId) return;
|
||||
if (!(cl.user._id == cl.channel.crown.userId)) return;
|
||||
}
|
||||
if (msg.hasOwnProperty('_id') && typeof msg._id == "string") {
|
||||
if (!cl.quotas.kickban.attempt() && !admin) return;
|
||||
let _id = msg._id;
|
||||
|
@ -222,6 +226,20 @@ module.exports = (cl) => {
|
|||
}
|
||||
});
|
||||
|
||||
cl.on('unban', (msg, admin) => {
|
||||
if (!admin) {
|
||||
if (cl.channel.crown == null) return;
|
||||
if (!(cl.channel && cl.participantId)) return;
|
||||
if (!cl.channel.crown.userId) return;
|
||||
if (!(cl.user._id == cl.channel.crown.userId)) return;
|
||||
}
|
||||
if (msg.hasOwnProperty('_id') && typeof msg._id == "string") {
|
||||
if (!cl.quotas.kickban.attempt() && !admin) return;
|
||||
let _id = msg._id;
|
||||
cl.channel.unban(_id);
|
||||
}
|
||||
});
|
||||
|
||||
cl.on("bye", msg => {
|
||||
cl.user.stopFlagEvents();
|
||||
cl.destroy();
|
||||
|
@ -305,18 +323,24 @@ module.exports = (cl) => {
|
|||
});
|
||||
});
|
||||
|
||||
cl.on('room_flag', (msg, admin) => {
|
||||
cl.on('channel_flag', (msg, admin) => {
|
||||
if (!admin) return;
|
||||
if (!msg.hasOwnProperty('_id') || !msg.hasOwnProperty('key') || !msg.hasOwnProperty('value')) return;
|
||||
|
||||
try {
|
||||
let ch = cl.server.rooms.get(msg._id);
|
||||
ch.flags[msg.key] = msg.value;
|
||||
ch.emit('flag ' + msg.key, msg.value);
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
}
|
||||
});
|
||||
|
||||
cl.on('room_flag', (msg, admin) => {
|
||||
if (!admin) return;
|
||||
cl.emit('channel_flag', msg, admin);
|
||||
})
|
||||
|
||||
cl.on('clear_chat', (msg, admin) => {
|
||||
if (!admin) return;
|
||||
cl.channel.setChatArray([]);
|
||||
|
@ -358,4 +382,39 @@ module.exports = (cl) => {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
cl.on('channel message', (msg, admin) => {
|
||||
if (!admin) return;
|
||||
|
||||
if (!msg.hasOwnProperty('msg')) return;
|
||||
if (typeof msg.msg != 'object') return;
|
||||
if (typeof msg.msg.m != 'string') return;
|
||||
|
||||
if (!cl.channel) return;
|
||||
if (!msg.hasOwnProperty('_id')) msg._id = cl.channel._id;
|
||||
|
||||
let ch = cl.server.rooms.get(msg._id);
|
||||
if (!ch) return;
|
||||
ch.emit(msg.msg.m, msg.msg);
|
||||
});
|
||||
|
||||
cl.on('name', (msg, admin) => {
|
||||
if (!admin) return;
|
||||
|
||||
if (!msg.hasOwnProperty('_id')) return;
|
||||
if (!msg.hasOwnProperty('name')) return;
|
||||
|
||||
for (const [mapID, conn] of cl.server.connections) {
|
||||
if (!conn.user) return;
|
||||
if (conn.user._id == msg._id) {
|
||||
let c = conn;
|
||||
c.userset(msg.name, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
cl.on('restart', (msg, admin) => {
|
||||
if (!admin) return;
|
||||
cl.server.restart(msg.notification);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -13,28 +13,27 @@ module.exports = class Notification {
|
|||
}
|
||||
|
||||
send(_id, room) {
|
||||
let obj = {};
|
||||
Object.assign(obj, this);
|
||||
obj.m = "notification";
|
||||
let msg = {};
|
||||
Object.assign(msg, this);
|
||||
msg.m = "notification";
|
||||
|
||||
switch (_id) {
|
||||
case "all": {
|
||||
case "all":
|
||||
for (let con of Array.from(room.server.connections.values())) {
|
||||
con.sendArray([obj]);
|
||||
con.sendArray([msg]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "room": {
|
||||
case "room":
|
||||
case "channel":
|
||||
for (let con of room.connections) {
|
||||
con.sendArray([obj]);
|
||||
con.sendArray([msg]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
default:
|
||||
Array.from(room.server.connections.values()).filter((usr) => typeof(usr.user) !== 'undefined' ? usr.user._id == _id : null).forEach((p) => {
|
||||
p.sendArray([obj]);
|
||||
p.sendArray([msg]);
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,9 +126,9 @@ class RoomSettings {
|
|||
});
|
||||
}
|
||||
|
||||
static changeSettings(set) {
|
||||
static changeSettings(set, admin) {
|
||||
Object.keys(set).forEach(key => {
|
||||
if (RoomSettings.allowedProperties[key].allowedChange) {
|
||||
if (RoomSettings.allowedProperties[key].allowedChange || admin == true) {
|
||||
set[key] = RoomSettings.verifyPropertyType(key, set[key], RoomSettings.allowedProperties[key].type);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@ const http = require("http");
|
|||
const fs = require('fs');
|
||||
const RoomSettings = require('./RoomSettings');
|
||||
const Logger = require("./Logger.js");
|
||||
const express = require('express');
|
||||
const Notification = require('./Notification');
|
||||
|
||||
class Server extends EventEmitter {
|
||||
constructor(config) {
|
||||
|
@ -89,7 +89,11 @@ class Server extends EventEmitter {
|
|||
"sudo",
|
||||
"subscribe to admin stream",
|
||||
"unsubscribe from admin stream",
|
||||
"data"
|
||||
"data",
|
||||
"channel message",
|
||||
"channel_flag",
|
||||
"name",
|
||||
"restart"
|
||||
];
|
||||
|
||||
this.welcome_motd = config.motd || "You agree to read this message.";
|
||||
|
@ -129,6 +133,13 @@ class Server extends EventEmitter {
|
|||
return this.connections.get(id);
|
||||
}
|
||||
|
||||
getClientByParticipantID(id) {
|
||||
for (let cl of Array.from(this.connections.values())) {
|
||||
if (cl.participantID == id) return cl;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
getAllClientsByUserID(_id) {
|
||||
let out = [];
|
||||
for (let cl of Array.from(this.connections.values())) {
|
||||
|
@ -136,6 +147,23 @@ class Server extends EventEmitter {
|
|||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
restart(notif = {
|
||||
m: "notification",
|
||||
id: "server-restart",
|
||||
title: "Notice",
|
||||
text: "The server will restart in a few moments.",
|
||||
target: "#piano",
|
||||
duration: 20000,
|
||||
class: "classic",
|
||||
}) {
|
||||
let n = new Notification(notif);
|
||||
n.send("all", this.rooms.get('lobby'));
|
||||
|
||||
setTimeout(() => {
|
||||
process.exit();
|
||||
}, n.duration || 20000);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Server;
|
||||
|
|
22
src/User.js
22
src/User.js
|
@ -36,7 +36,6 @@ class User {
|
|||
this.cl.server.specialIntervals[this._id] = {};
|
||||
}
|
||||
if (this.hasFlag('rainbow', true)) {
|
||||
console.log('rainbow on for ' + this._id);
|
||||
if (!this.cl.server.specialIntervals[this._id].hasOwnProperty('rainbow')) {
|
||||
let h = Math.floor(Math.random() * 360);
|
||||
let s = 50;
|
||||
|
@ -65,16 +64,23 @@ class User {
|
|||
Database.updateUser(this._id, this);
|
||||
|
||||
this.cl.channel.updateParticipant(this._id, this);
|
||||
}, 1000/15);
|
||||
}, 1000 / 15);
|
||||
}
|
||||
} else if (this.hasFlag('rainbow', false)) {
|
||||
console.log('rainbow off for ' + this._id);
|
||||
clearInterval(this.cl.server.specialIntervals[this._id].rainbow);
|
||||
this.stopFlagEvents();
|
||||
}
|
||||
}
|
||||
|
||||
stopFlagEvents() {
|
||||
clearInterval(this.cl.server.specialIntervals[this._id].rainbow);
|
||||
let ints = this.cl.server.specialIntervals[this._id];
|
||||
if (!ints) {
|
||||
this.cl.server.specialIntervals[this._id] = {};
|
||||
ints = this.cl.server.specialIntervals[this._id];
|
||||
}
|
||||
if ('rainbow' in ints) {
|
||||
clearInterval(this.cl.server.specialIntervals[this._id].rainbow);
|
||||
delete this.cl.server.specialIntervals[this._id].rainbow;
|
||||
}
|
||||
}
|
||||
|
||||
hasFlag(flag, val) {
|
||||
|
@ -82,6 +88,12 @@ class User {
|
|||
return this.flags.hasOwnProperty(flag) && this.flags[flag] == val;
|
||||
}
|
||||
|
||||
setFlag(flag, val) {
|
||||
if (typeof(this.flags[flag]) == 'undefined') {
|
||||
this.flags[flag] = val;
|
||||
}
|
||||
}
|
||||
|
||||
static updateUserModel(cl, user) {
|
||||
let u2 = new User(cl, user);
|
||||
if (typeof(u2) == 'undefined') return;
|
||||
|
|
94
yarn.lock
94
yarn.lock
|
@ -37,9 +37,9 @@
|
|||
"@types/node" "*"
|
||||
|
||||
"@types/node@*":
|
||||
version "17.0.36"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.36.tgz#c0d5f2fe76b47b63e0e0efc3d2049a9970d68794"
|
||||
integrity sha512-V3orv+ggDsWVHP99K3JlwtH20R7J4IhI1Kksgc+64q5VxgfRkQG8Ws3MFm/FZOKDYGy9feGFlZ70/HpCNe9QaA==
|
||||
version "17.0.42"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.42.tgz#d7e8f22700efc94d125103075c074396b5f41f9b"
|
||||
integrity sha512-Q5BPGyGKcvQgAMbsr7qEGN/kIPN6zZecYYABeTDBizOsau+2NMdSVTar9UQw21A2+JyA2KRNDYaYrPB0Rpk2oQ==
|
||||
|
||||
abbrev@1:
|
||||
version "1.1.1"
|
||||
|
@ -301,11 +301,6 @@ color-name@~1.1.4:
|
|||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
colors@^1.1.2:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
|
||||
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
|
@ -573,13 +568,13 @@ function-bind@^1.1.1:
|
|||
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
||||
|
||||
get-intrinsic@^1.0.2:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6"
|
||||
integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598"
|
||||
integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
has "^1.0.3"
|
||||
has-symbols "^1.0.1"
|
||||
has-symbols "^1.0.3"
|
||||
|
||||
get-stream@^4.1.0:
|
||||
version "4.1.0"
|
||||
|
@ -634,14 +629,14 @@ graceful-fs@^4.1.2:
|
|||
has-flag@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
|
||||
integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
|
||||
|
||||
has-flag@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
|
||||
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
|
||||
|
||||
has-symbols@^1.0.1:
|
||||
has-symbols@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
|
||||
integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
|
||||
|
@ -689,17 +684,17 @@ ieee754@^1.1.13, ieee754@^1.2.1:
|
|||
ignore-by-default@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09"
|
||||
integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk=
|
||||
integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==
|
||||
|
||||
import-lazy@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43"
|
||||
integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=
|
||||
integrity sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==
|
||||
|
||||
imurmurhash@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
|
||||
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
|
||||
integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
|
||||
|
||||
inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3:
|
||||
version "2.0.4"
|
||||
|
@ -743,7 +738,7 @@ is-ci@^2.0.0:
|
|||
is-extglob@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
|
||||
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
|
||||
|
||||
is-fullwidth-code-point@^3.0.0:
|
||||
version "3.0.0"
|
||||
|
@ -788,7 +783,7 @@ is-path-inside@^3.0.2:
|
|||
is-typedarray@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
|
||||
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
|
||||
integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==
|
||||
|
||||
is-yarn-global@^0.3.0:
|
||||
version "0.3.0"
|
||||
|
@ -798,12 +793,12 @@ is-yarn-global@^0.3.0:
|
|||
isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
|
||||
integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
|
||||
|
||||
json-buffer@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
|
||||
integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
|
||||
integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==
|
||||
|
||||
kareem@2.3.2:
|
||||
version "2.3.2"
|
||||
|
@ -935,7 +930,7 @@ lru-cache@^6.0.0:
|
|||
ltgt@^2.1.2:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ltgt/-/ltgt-2.2.1.tgz#f35ca91c493f7b73da0e07495304f17b31f87ee5"
|
||||
integrity sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=
|
||||
integrity sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==
|
||||
|
||||
make-dir@^3.0.0:
|
||||
version "3.1.0"
|
||||
|
@ -947,7 +942,7 @@ make-dir@^3.0.0:
|
|||
media-typer@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
|
||||
integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
|
||||
|
||||
memory-pager@^1.0.2:
|
||||
version "1.5.0"
|
||||
|
@ -957,12 +952,12 @@ memory-pager@^1.0.2:
|
|||
merge-descriptors@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
|
||||
integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
|
||||
integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==
|
||||
|
||||
methods@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
|
||||
integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
|
||||
integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
|
||||
|
||||
mime-db@1.52.0:
|
||||
version "1.52.0"
|
||||
|
@ -1041,6 +1036,13 @@ mpath@0.8.4:
|
|||
resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.8.4.tgz#6b566d9581621d9e931dd3b142ed3618e7599313"
|
||||
integrity sha512-DTxNZomBcTWlrMW76jy1wvV37X/cNNxPW1y2Jzd4DZkAaC5ZGsm8bfGfNOthcDuRJujXLqiuS6o3Tpy0JEoh7g==
|
||||
|
||||
mppclone-client@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/mppclone-client/-/mppclone-client-1.0.0.tgz#7765e4a355b0608ea3d0c02d0056d71255ea17bf"
|
||||
integrity sha512-yZUr4POT8MqlhqwvsYCnwVxnCXSlLGLcSUeLtiiJtE3BsDZOpM4VZ27k32ATC2mZs8M0tNLE7KkDd1j+sTvGSw==
|
||||
dependencies:
|
||||
ws "^8.5.0"
|
||||
|
||||
mquery@3.2.5:
|
||||
version "3.2.5"
|
||||
resolved "https://registry.yarnpkg.com/mquery/-/mquery-3.2.5.tgz#8f2305632e4bb197f68f60c0cffa21aaf4060c51"
|
||||
|
@ -1055,7 +1057,7 @@ mquery@3.2.5:
|
|||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
||||
integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
|
||||
|
||||
ms@2.1.2:
|
||||
version "2.1.2"
|
||||
|
@ -1087,13 +1089,6 @@ node-gyp-build@^4.3.0:
|
|||
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.4.0.tgz#42e99687ce87ddeaf3a10b99dc06abc11021f3f4"
|
||||
integrity sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==
|
||||
|
||||
node-json-color-stringify@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/node-json-color-stringify/-/node-json-color-stringify-1.1.0.tgz#8bb124f913859591058026513121d6609d6ef5b7"
|
||||
integrity sha1-i7Ek+ROFlZEFgCZRMSHWYJ1u9bc=
|
||||
dependencies:
|
||||
colors "^1.1.2"
|
||||
|
||||
nodemon@^2.0.15:
|
||||
version "2.0.16"
|
||||
resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.16.tgz#d71b31bfdb226c25de34afea53486c8ef225fdef"
|
||||
|
@ -1113,7 +1108,7 @@ nodemon@^2.0.15:
|
|||
nopt@~1.0.10:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee"
|
||||
integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=
|
||||
integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==
|
||||
dependencies:
|
||||
abbrev "1"
|
||||
|
||||
|
@ -1142,7 +1137,7 @@ on-finished@2.4.1:
|
|||
once@^1.3.1, once@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
|
||||
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
|
@ -1181,7 +1176,7 @@ parseurl@~1.3.3:
|
|||
path-to-regexp@0.1.7:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
|
||||
integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
|
||||
integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
|
||||
|
||||
picomatch@^2.0.4, picomatch@^2.2.1:
|
||||
version "2.3.1"
|
||||
|
@ -1191,7 +1186,7 @@ picomatch@^2.0.4, picomatch@^2.2.1:
|
|||
prepend-http@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
|
||||
integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
|
||||
integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==
|
||||
|
||||
process-nextick-args@~2.0.0:
|
||||
version "2.0.1"
|
||||
|
@ -1319,7 +1314,7 @@ require-at@^1.0.6:
|
|||
responselike@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
|
||||
integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=
|
||||
integrity sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==
|
||||
dependencies:
|
||||
lowercase-keys "^1.0.0"
|
||||
|
||||
|
@ -1432,12 +1427,12 @@ signal-exit@^3.0.2:
|
|||
sliced@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/sliced/-/sliced-1.0.1.tgz#0b3a662b5d04c3177b1926bea82b03f837a2ef41"
|
||||
integrity sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=
|
||||
integrity sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==
|
||||
|
||||
sparse-bitfield@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11"
|
||||
integrity sha1-/0rm5oZWBWuks+eSqzM004JzyhE=
|
||||
integrity sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==
|
||||
dependencies:
|
||||
memory-pager "^1.0.2"
|
||||
|
||||
|
@ -1479,7 +1474,7 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
|||
strip-json-comments@~2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
||||
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
|
||||
integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==
|
||||
|
||||
supports-color@^5.5.0:
|
||||
version "5.5.0"
|
||||
|
@ -1554,7 +1549,7 @@ unique-string@^2.0.0:
|
|||
unpipe@1.0.0, unpipe@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
||||
integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
|
||||
integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
|
||||
|
||||
update-notifier@^5.1.0:
|
||||
version "5.1.0"
|
||||
|
@ -1579,24 +1574,24 @@ update-notifier@^5.1.0:
|
|||
url-parse-lax@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c"
|
||||
integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=
|
||||
integrity sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==
|
||||
dependencies:
|
||||
prepend-http "^2.0.0"
|
||||
|
||||
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
||||
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
|
||||
|
||||
utils-merge@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
|
||||
integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
|
||||
integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
|
||||
|
||||
vary@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
||||
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
|
||||
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
|
||||
|
||||
widest-line@^3.1.0:
|
||||
version "3.1.0"
|
||||
|
@ -1617,7 +1612,7 @@ wrap-ansi@^7.0.0:
|
|||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
|
||||
|
||||
write-file-atomic@^3.0.0:
|
||||
version "3.0.3"
|
||||
|
@ -1634,6 +1629,11 @@ ws@^7.2.3:
|
|||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.8.tgz#ac2729881ab9e7cbaf8787fe3469a48c5c7f636a"
|
||||
integrity sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==
|
||||
|
||||
ws@^8.5.0:
|
||||
version "8.8.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.0.tgz#8e71c75e2f6348dbf8d78005107297056cb77769"
|
||||
integrity sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==
|
||||
|
||||
xdg-basedir@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
|
||||
|
|
Loading…
Reference in New Issue