forked from Hri7566/mpp-server-dev2
many new things
This commit is contained in:
parent
6e3d96111f
commit
2d0fd503b4
119
src/Channel.js
119
src/Channel.js
|
@ -7,6 +7,7 @@ const RoomSettings = require('./RoomSettings.js');
|
||||||
const ftc = require('fancy-text-converter');
|
const ftc = require('fancy-text-converter');
|
||||||
const Notification = require('./Notification');
|
const Notification = require('./Notification');
|
||||||
const Color = require('./Color');
|
const Color = require('./Color');
|
||||||
|
const { getTimeColor } = require('./ColorEncoder.js');
|
||||||
|
|
||||||
class Channel extends EventEmitter {
|
class Channel extends EventEmitter {
|
||||||
constructor(server, _id, settings) {
|
constructor(server, _id, settings) {
|
||||||
|
@ -41,8 +42,8 @@ class Channel extends EventEmitter {
|
||||||
if (err) {
|
if (err) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.settings = set.settings;
|
this.settings = RoomSettings.changeSettings(this.settings, true);
|
||||||
this.chatmsgs = set.chat;
|
this.chatmsgs = set.chat;
|
||||||
this.connections.forEach(cl => {
|
this.connections.forEach(cl => {
|
||||||
cl.sendArray([{
|
cl.sendArray([{
|
||||||
|
@ -52,6 +53,13 @@ class Channel extends EventEmitter {
|
||||||
});
|
});
|
||||||
this.setData();
|
this.setData();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (this.isLobby(this._id)) {
|
||||||
|
this.colorInterval = setInterval(() => {
|
||||||
|
this.setDefaultLobbyColorBasedOnDate();
|
||||||
|
}, 1000 * 60 * 5);
|
||||||
|
this.setDefaultLobbyColorBasedOnDate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setChatArray(arr) {
|
setChatArray(arr) {
|
||||||
|
@ -63,16 +71,37 @@ class Channel extends EventEmitter {
|
||||||
this.setData();
|
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
|
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) {
|
||||||
|
// we don't exist yet
|
||||||
|
// create id hash
|
||||||
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);
|
||||||
|
|
||||||
|
// set id
|
||||||
cl.user.id = participantId;
|
cl.user.id = participantId;
|
||||||
cl.participantId = participantId;
|
cl.participantId = participantId;
|
||||||
|
|
||||||
|
// init quotas (TODO pass type of room in?)
|
||||||
cl.initParticipantQuotas();
|
cl.initParticipantQuotas();
|
||||||
|
|
||||||
// if there are no users or the user with the crown entered the room, crown the user
|
// 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)) {
|
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
|
// user owns the room
|
||||||
// we need to switch the crown to them
|
// we need to switch the crown to them
|
||||||
|
@ -85,7 +114,8 @@ class Channel extends EventEmitter {
|
||||||
//cl.quotas.a.setParams(Quota.PARAMS_A_NORMAL);
|
//cl.quotas.a.setParams(Quota.PARAMS_A_NORMAL);
|
||||||
|
|
||||||
if (this.isLobby(this._id) && this.settings.lobby !== true) {
|
if (this.isLobby(this._id) && this.settings.lobby !== true) {
|
||||||
this.settings.changeSettings(this.server.lobbySettings, 'user');
|
// fix lobby setting
|
||||||
|
this.settings.changeSettings({lobby: true});
|
||||||
// this.settings.visible = true;
|
// this.settings.visible = true;
|
||||||
// this.settings.crownsolo = false;
|
// this.settings.crownsolo = false;
|
||||||
// this.settings.lobby = true;
|
// this.settings.lobby = true;
|
||||||
|
@ -110,21 +140,25 @@ class Channel extends EventEmitter {
|
||||||
|
|
||||||
this.connections.push(cl);
|
this.connections.push(cl);
|
||||||
|
|
||||||
if (cl.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,
|
|
||||||
x: this.ppl.get(cl.participantId).x || 200,
|
|
||||||
y: this.ppl.get(cl.participantId).y || 100,
|
|
||||||
_id: cl.user._id
|
|
||||||
}], cl, false)
|
|
||||||
}
|
|
||||||
cl.sendArray([{
|
cl.sendArray([{
|
||||||
m: "c",
|
m: "c",
|
||||||
c: this.chatmsgs.slice(-1 * 32)
|
c: this.chatmsgs.slice(-1 * 32)
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
|
// this.updateCh(cl, this.settings);
|
||||||
|
|
||||||
|
if (!cl.user.hasFlag("hidden", true)) {
|
||||||
|
this.sendArray([{
|
||||||
|
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
|
||||||
|
}], cl, false);
|
||||||
|
}
|
||||||
|
|
||||||
this.updateCh(cl, this.settings);
|
this.updateCh(cl, this.settings);
|
||||||
} else {
|
} else {
|
||||||
cl.user.id = otheruser.participantId;
|
cl.user.id = otheruser.participantId;
|
||||||
|
@ -190,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) {
|
if (Array.from(this.ppl.values()).length <= 0) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.destroy();
|
this.destroy();
|
||||||
}, 1000);
|
}, 13000);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.connections.forEach((usr) => {
|
this.connections.forEach((usr) => {
|
||||||
|
@ -240,6 +274,7 @@ class Channel extends EventEmitter {
|
||||||
destroy() { //destroy room
|
destroy() { //destroy room
|
||||||
if (this.destroyed) return;
|
if (this.destroyed) return;
|
||||||
if (this.ppl.size > 0) return;
|
if (this.ppl.size > 0) return;
|
||||||
|
if (this._id == "lobby") return;
|
||||||
this.destroyed = true;
|
this.destroyed = true;
|
||||||
this._id;
|
this._id;
|
||||||
console.log(`Deleted room ${this._id}`);
|
console.log(`Deleted room ${this._id}`);
|
||||||
|
@ -270,6 +305,7 @@ class Channel extends EventEmitter {
|
||||||
[...this.ppl.values()].forEach(c => {
|
[...this.ppl.values()].forEach(c => {
|
||||||
if (cl) {
|
if (cl) {
|
||||||
if (c.hidden == true && c.user._id !== cl.user._id) {
|
if (c.hidden == true && c.user._id !== cl.user._id) {
|
||||||
|
// client is hidden and we are that client
|
||||||
return;
|
return;
|
||||||
} else if (c.user._id == cl.user._id) {
|
} else if (c.user._id == cl.user._id) {
|
||||||
// let u = {
|
// let u = {
|
||||||
|
@ -519,11 +555,32 @@ class Channel extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
playNote(cl, note) {
|
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) {
|
for (let no of note.n) {
|
||||||
no.v /= vel;
|
if (no.v) {
|
||||||
|
if (vol == 0) {
|
||||||
|
no.v = vol;
|
||||||
|
} else {
|
||||||
|
no.v *= vol;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -607,20 +664,28 @@ class Channel extends EventEmitter {
|
||||||
bindEventListeners() {
|
bindEventListeners() {
|
||||||
this.on("bye", participant => {
|
this.on("bye", participant => {
|
||||||
this.remove(participant);
|
this.remove(participant);
|
||||||
})
|
});
|
||||||
|
|
||||||
this.on("m", msg => {
|
this.on("m", msg => {
|
||||||
let p = this.ppl.get(msg.p);
|
let p = this.ppl.get(msg.p);
|
||||||
if (!p) return;
|
if (!p) return;
|
||||||
this.setCoords(p, msg.x, msg.y);
|
this.setCoords(p, msg.x, msg.y);
|
||||||
})
|
});
|
||||||
|
|
||||||
this.on("a", (participant, msg) => {
|
this.on("a", (msg) => {
|
||||||
this.chat(participant, msg);
|
if (!msg.msg) return;
|
||||||
})
|
if (!msg.participant) return;
|
||||||
|
if (typeof msg.msg !== 'object') return;
|
||||||
|
if (typeof msg.participant !== 'object') return;
|
||||||
|
if (!msg.msg.m) return;
|
||||||
|
if (msg.msg.m !== 'a') return;
|
||||||
|
if (!msg.participant.name) return;
|
||||||
|
if (!msg.participant._id) return;
|
||||||
|
this.chat(msg.participant, msg.msg);
|
||||||
|
});
|
||||||
|
|
||||||
this.on("update", (cl) => {
|
this.on("update", (cl, set) => {
|
||||||
this.updateCh(cl);
|
this.updateCh(cl, set);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on("remove crown", () => {
|
this.on("remove crown", () => {
|
||||||
|
|
|
@ -186,6 +186,16 @@ class Client extends EventEmitter {
|
||||||
|
|
||||||
this.sendArray([data]);
|
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;
|
module.exports = Client;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
const Color = require("./Color");
|
||||||
|
|
||||||
function hashCode(str) { // java String#hashCode
|
function hashCode(str) { // java String#hashCode
|
||||||
var hash = 0;
|
var hash = 0;
|
||||||
for (var i = 0; i < str.length; i++) {
|
for (var i = 0; i < str.length; i++) {
|
||||||
|
@ -14,7 +16,71 @@ function intToRGB(i){
|
||||||
return "00000".substring(0, 6 - c.length) + c;
|
return "00000".substring(0, 6 - c.length) + c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.1 + Math.floor(((hours / 60)) * 1000) / 1000;
|
||||||
|
if (l > 1) l = 1;
|
||||||
|
// let l = 0.5;
|
||||||
|
l = l / 2;
|
||||||
|
|
||||||
|
// convert to rgb
|
||||||
|
let [r, g, b] = hslToRgb(h, s, l);
|
||||||
|
|
||||||
|
let col = new Color(r, g, b);
|
||||||
|
return col;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
hashCode,
|
hashCode,
|
||||||
intToRGB
|
intToRGB,
|
||||||
|
getTimeColor
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,10 +145,11 @@ module.exports = (cl) => {
|
||||||
}
|
}
|
||||||
if (!msg.hasOwnProperty("set") || !msg.set) msg.set = new RoomSettings(cl.channel.settings, 'user');
|
if (!msg.hasOwnProperty("set") || !msg.set) msg.set = new RoomSettings(cl.channel.settings, 'user');
|
||||||
cl.channel.settings.changeSettings(msg.set, admin);
|
cl.channel.settings.changeSettings(msg.set, admin);
|
||||||
cl.channel.updateCh();
|
// cl.channel.updateCh();
|
||||||
|
cl.channel.emit('update');
|
||||||
});
|
});
|
||||||
|
|
||||||
cl.on("a", (msg, admin) => {
|
cl.on('a', (msg, admin) => {
|
||||||
if (!(cl.channel && cl.participantId)) return;
|
if (!(cl.channel && cl.participantId)) return;
|
||||||
if (!msg.hasOwnProperty('message')) return;
|
if (!msg.hasOwnProperty('message')) return;
|
||||||
if (typeof(msg.message) !== 'string') return;
|
if (typeof(msg.message) !== 'string') return;
|
||||||
|
@ -395,4 +396,9 @@ module.exports = (cl) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cl.on('restart', (msg, admin) => {
|
||||||
|
if (!admin) return;
|
||||||
|
cl.server.restart(msg.notification);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ module.exports = class Notification {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "room":
|
case "room":
|
||||||
|
case "channel":
|
||||||
for (let con of room.connections) {
|
for (let con of room.connections) {
|
||||||
con.sendArray([msg]);
|
con.sendArray([msg]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ const http = require("http");
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const RoomSettings = require('./RoomSettings');
|
const RoomSettings = require('./RoomSettings');
|
||||||
const Logger = require("./Logger.js");
|
const Logger = require("./Logger.js");
|
||||||
|
const Notification = require('./Notification');
|
||||||
|
|
||||||
class Server extends EventEmitter {
|
class Server extends EventEmitter {
|
||||||
constructor(config) {
|
constructor(config) {
|
||||||
|
@ -89,7 +90,8 @@ class Server extends EventEmitter {
|
||||||
"data",
|
"data",
|
||||||
"channel message",
|
"channel message",
|
||||||
"channel_flag",
|
"channel_flag",
|
||||||
"name"
|
"name",
|
||||||
|
"restart"
|
||||||
];
|
];
|
||||||
|
|
||||||
this.welcome_motd = config.motd || "You agree to read this message.";
|
this.welcome_motd = config.motd || "You agree to read this message.";
|
||||||
|
@ -143,6 +145,23 @@ class Server extends EventEmitter {
|
||||||
}
|
}
|
||||||
return out;
|
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;
|
module.exports = Server;
|
||||||
|
|
Loading…
Reference in New Issue