many new things

This commit is contained in:
Hri7566 2022-07-09 05:06:51 -04:00
parent e19e209d67
commit 008092ac86
6 changed files with 198 additions and 31 deletions

View File

@ -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) {
@ -42,7 +43,7 @@ class Channel extends EventEmitter {
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 (vel) { 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 (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", () => {

View File

@ -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;

View File

@ -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
} }

View File

@ -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);
});
} }

View File

@ -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]);
} }

View File

@ -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;