commit 4f1e787613031b0e82e1cd5e389bc77fe2efe1b9 Author: root Date: Tue Sep 12 20:38:54 2023 -0500 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8755c0f --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.env +node_modules +db diff --git a/ch.js b/ch.js new file mode 100644 index 0000000..ace5da4 --- /dev/null +++ b/ch.js @@ -0,0 +1,32 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected || user.channel === msg._id) return; +var part = users[user._id].p +part.m = "p" + +if (!channels[msg._id]) {channels[msg._id] = {m: "ch",ppl: [users[user._id].p], ch: {id: msg._id, _id: msg._id, settings: {color: "#000000", color2: "#000000", chat: true, visible: true, limit: 100} }, p: user._id} +if (!chat[msg._id])chat[msg._id] = [] + //if (user.channel) { +//var list = [] +//channels[user.channel].ppl.forEach(a => {list.push(a); list.at(-1).m = "p"}) +//ws.send(JSON.stringify(list)) + +//} + ws.sendData(channels[msg._id]) +} else { +if (!channels[msg._id].ppl.find(a => a._id === user._id))channels[msg._id].ppl.push(users[user._id].p) +var channel = channels[msg._id] +channel.p = user._id +ws.sendData(channel) +connections.filter(a => a.user.channel === msg._id).forEach(a => {var channel = channels[msg._id]; channel.p = a.user._id; a.sendData(channel)}) +//connections.filter(a => a.user.channel === msg._id && a !== ws).forEach(a => a.send(JSON.stringify([users[user._id].p]))) + //if (channels[user.channel].ppl.length == 0) delete channels[user.channel + //] +//if (user.channel) channels[user.channel].ppl.splice(channels[user.channel].indexOf(users[user._id].p),1) +} +connections.filter(founduser => founduser.user.channel === user.channel && founduser.user._id !== user._id).forEach(founduser => founduser.sendData(part.p)) + +if (user.channel) {if (connections.filter(a => a.user._id === user._id && a.user.channel === user.channel).length ==1) {channels[user.channel].ppl.splice(channels[user.channel].ppl.indexOf(channels[user.channel].ppl.find(a => a._id === user._id)),1); connections.filter(a => a.user.channel === user.channel && a.user._id !== user._id).forEach(a => {var channel = channels[user.channel];channel.p = a.user._id; a.sendData(channel)}) }} +ws.sendData({m: "c", c: chat[msg._id].filter(a => a.m === "a" || (a.m === "dm" && (a.sender._id === user._id || a.recipient._id === user._id)))}) +user.channel = msg._id +} +module.exports.name = "ch" diff --git a/index.js b/index.js new file mode 100644 index 0000000..3f95f11 --- /dev/null +++ b/index.js @@ -0,0 +1,117 @@ +setTimeout(() => { +/* +for (var b = 0; b < connections.length; b++) { +if (connections[b].msgs.length != 0) { +connections[b].send(JSON.stringify(connections[b].msgs)) +connections[b].msgs = [] +} +} +*/ +//Object.values(connections).forEach(b => {if (b.msgs.length != 0) {b.send(JSON.stringify(b.msgs)); b.msgs = []}}) +},50) + +fs = require('fs') +var db = new (require('level')).Level('db'); +var dbs = {ips: db.sublevel('ips'), users: db.sublevel('users'), tokens: db.sublevel('tokens')} +const WebSocket = require('ws') +//var protocol = new Map() +protocol = {} +var protocolfiles = fs.readdirSync('protocol').filter(file => file.endsWith('.js')) +protocolfiles.forEach(file => { +var protofile = require(`./protocol/${file}`) +//protocol.set(protofile.name, protofile) +protocol[protofile.name] = protofile +}) +var connections = [] +channels = {} +chat = {} +kickbans = {} +var users = {} +var httpServer = require('https').createServer({key: fs.readFileSync("ssl/privkey.pem").toString(), cert: fs.readFileSync("ssl/fullchain.pem").toString()}); + +const wss = new WebSocket.Server({ server: httpServer }); +//const wss = new WebSocket.Server({ port: 8448, key: fs.readFileSync('mppserver/ssl/privkey.pem'),cert: fs.readFileSync('mppserver/ssl/cert.pem') }) +wss.on('connection', function connection(ws, request) { +ws.on('error', () => {}) + // Handle new client connection +// ws.ip = request.socket.remoteAddress +ws.ip = (request.socket.remoteAddress == "127.0.0.1" && request.headers["x-forwarded-for"]) ? request.headers["x-forwarded-for"] : request.socket.remoteAddress; + ws.msgs = [] + ws.last = Date.now() +//setTimeout(() => {if (Date.now() - ws.last >= 30000) ws.close()},30000) +ws.user = {connected: false, msgs: fun.quota(500,10000)} +// ws.sendData = (data) => {ws.msgs.push(data)} +//ws.isSending = false +ws.sendData = (data) => {if (!data)return;ws.send(JSON.stringify([data]))} + // ws.sendData = (data) => {ws.msgs.push(data);if (ws.isSending) return; ws.isSending = true; setTimeout(() => {ws.send(JSON.stringify(ws.msgs)); ws.msgs = []; ws.isSending = false;},50)} +console.log('A client connected.'); + connections.push(ws) + ws.send(JSON.stringify([{m:"b", code: "code"}])) + // Handle messages received from the client + ws.on('message', async function (message) { + try { + var rec = JSON.parse(Buffer.from(message).toString()) + +var msgs = JSON.parse(JSON.stringify(rec)) +if (JSON.stringify(rec).startsWith('{'))var msgs = [ rec ] +if (!ws.user.msgs.try(msgs.length > 0 ? msgs.length : 1)) {ws.close()} +//console.log('got ' + JSON.stringify(msgs)) + for (var msgpart = 0; msgpart < msgs.length; msgpart++) { + var msg = msgs[msgpart] +// console.log('Received message:', msg); +try { + //var found = protocol.get(msg.m) + var found = protocol[msg.m] + if (found) var protocode = await found.run(ws,ws.user,dbs,msg,fun,users,connections) + if (protocode === "user sitebanned") break; +} catch (error) { +console.log(error) +} +} +ws.user.msgs.spend(msgs.length > 0 ? msgs.length : 1) +} catch (error) { +//console.log(error) +} + }); +ws.on('close',() => {connections.splice(connections.indexOf(ws),1); console.log('Client disconnected.'); if (ws.user.channel && connections.filter(a => a.user.channel === ws.user.channel && a.user._id === ws.user._id).length == 0) {channels[ws.user.channel].ppl.splice(channels[ws.user.channel].ppl.indexOf(channels[ws.user.channel].ppl.find(a => a._id === ws.user._id)),1); if (channels[ws.user.channel].ch.crown && channels[ws.user.channel].ch.crown.userId === ws.user._id) channels[ws.user.channel].ch.crown.t = Date.now(); connections.filter(a => a.user.channel === ws.user.channel).forEach(a => {var channel = channels[ws.user.channel]; channel.p = a.user._id; a.sendData(fun.vanish(channel, users[a.user._id].rank))})} }) +}); +var fun = { + quota: function ( count, interval ) { + var newQuota = {points: count, interval: interval, max: count, time: 0} + newQuota.try = function (num) { + if (Date.now() >= newQuota.time) {newQuota.time = Date.now() + newQuota.interval; newQuota.points = newQuota.max} + if (newQuota.points > 0 + (!isNaN(num) ? (num - 1) : 0)) return true; + return false; + } + + newQuota.spend = function (num) { + if (Date.now() >= newQuota.time) {newQuota.time = Date.now() + newQuota.interval; newQuota.points = newQuota.max} + if (typeof num !== "number") return; + newQuota.points -= Math.floor(num) + if (newQuota.points < 0) newQuota.points = 0 + } + return newQuota +}, +vanish: (ch,rank) => { +if (rank >= 1) return ch +var thech = JSON.parse(JSON.stringify(ch)) +thech.ppl = ch.ppl.filter(p => !users[p._id].p.vanished) + +return thech +} + +} +oldchannels = {} +setInterval(() => { +//Object.values(channels).filter(a => a.ppl.length == 0).forEach(a => delete channels[a.ch._id]) +var newchannels = Object.values(channels).filter(a => !oldchannels[a.ch._id] || fun.vanish(oldchannels[a.ch._id]).ppl.length != fun.vanish(a).ppl.length) +var roomlist = [] +newchannels.forEach(a => {roomlist.push(a.ch); roomlist.at(-1).count = fun.vanish(a,0).ppl.length;}) + +if (roomlist.length != 0)connections.filter(a => a.user.connected && a.user.sub.ls).forEach(a => a.sendData({m: "ls",c: false, u: (users[a.user._id].rank >= 2 ? roomlist : roomlist.filter(a => a.settings.visible)) .map(b => {var c = b; c.banned = (kickbans[b._id][a.user._id] && kickbans[b._id][a.user._id] > Date.now()); return c;}) })) +oldchannels = JSON.parse(JSON.stringify(channels)) +Object.values(channels).filter(a => a.ppl.length == 0).forEach(a => {delete oldchannels[a.ch._id]; delete channels[a.ch._id];}) +connections.forEach(a => {if (Date.now() - a.last >= 40000) a.close()}) +},5000) +//eval(fs.readFileSync('site/index.js')) +httpServer.listen(8448, '0.0.0.0', () => console.log('Server online')) diff --git a/protocol/+custom.js b/protocol/+custom.js new file mode 100644 index 0000000..9f00b09 --- /dev/null +++ b/protocol/+custom.js @@ -0,0 +1,7 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected) return; +user.sub.custom = true + + +} +module.exports.name = "+custom" diff --git a/protocol/+ls.js b/protocol/+ls.js new file mode 100644 index 0000000..17ccc69 --- /dev/null +++ b/protocol/+ls.js @@ -0,0 +1,10 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected || user.sub.ls) return; +user.sub.ls = true +var roomlist = [] + +Object.values(channels).forEach(a => {roomlist.push(a.ch); roomlist.at(-1).count = fun.vanish(a,0).ppl.length}) +ws.sendData({m: "ls", c: true, u: (users[user._id].rank >= 2 ? roomlist : roomlist.filter(a => a.settings.visible).map(a => {var b = a; b.banned = (kickbans[a._id][user._id] && kickbans[a._id][user._id] > Date.now()); return b}))}) + +} +module.exports.name = "+ls" diff --git a/protocol/-custom.js b/protocol/-custom.js new file mode 100644 index 0000000..e784cde --- /dev/null +++ b/protocol/-custom.js @@ -0,0 +1,7 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected) return; +user.sub.custom = false + + +} +module.exports.name = "-custom" diff --git a/protocol/-ls.js b/protocol/-ls.js new file mode 100644 index 0000000..93f48ef --- /dev/null +++ b/protocol/-ls.js @@ -0,0 +1,7 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected) return; +user.sub.ls = false + + +} +module.exports.name = "-ls" diff --git a/protocol/a.js b/protocol/a.js new file mode 100644 index 0000000..5e66b5d --- /dev/null +++ b/protocol/a.js @@ -0,0 +1,285 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (typeof msg.message !== "string") return; +if (!user.channel) return; +if (!user.connected) return +if (!users[user._id].chatbypass && !user.quotas.chat.try()) return; + + +Object.values(connections).filter(f => f.user.channel === user.channel).forEach(f => f.sendData({m: "a", a: msg.message.substr(0,1023), p: users[user._id].p, t: Date.now()})) +chat[user.channel].push({m: "a", a: msg.message.substr(0,1023), p: users[user._id].p, t: Date.now()}) +if (chat[user.channel].length > 32) chat[user.channel].splice(0,1) +user.quotas.chat.spend(1) +var cmd = msg.message.trim().split(' ')[0] +var args = msg.message.trim().substr(cmd.length).trim() +var rank = users[user._id].rank +var say = (message) => ws.sendData({m: "a", p: {name: "Server", _id: "server", id: "server", color: "#5555ff"}, a: message, t: Date.now()}) +if (cmd === "~help") { +var cmds = {"~help":0, "~gentoken": 2, "~setrank": 2, "~clearchat":1, "~settag": 1, "~removetag":1, "~endprocess": 2, "~notebypass":2, "~custombypass": 2, "~chatbypass": 2, "~info": 1, "~js": 3, "~unban": 2, "~token": 3, "~baninfo": 2, "~usersetothers": 3} +var availablecmds = Object.keys(cmds).filter(a => cmds[a] <= users[user._id].rank) +return say(`Commands: ${availablecmds.join(', ')}`) +} + + +if (cmd === "~gentoken" && rank >= 2) { + var token = "" +for (var i = 0; i < 48; i++) token+= ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"][Math.floor(Math.random() * 16)] + var _id = "" + for (var i = 0; i < 24; i++) _id+= ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"][Math.floor(Math.random() * 16)] + var color = "#" + for (var i = 0; i < 6; i++) color+= ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"][Math.floor(Math.random() * 16)] + var part = {rank: 0,p: {m:"p",name: "Anonymous", _id: _id, id: _id, color: color}} + db.tokens.put(token, _id) + db.users.put(_id, JSON.stringify(part)) + say(`Token successfully generated! \`${token} , ${_id}\``) +} + +if (cmd === "~settag" && rank >= 1) { +if (args.length == 0) return say('Usage: ~settag (_id) (Hex Color) (Tag)') +var argsplit = args.split(' ') +try { +var user = await db.users.get(argsplit[0]) +user = JSON.parse(user) +} catch (error) { +return say(`There was an error getting info about \`${argsplit[0]}\`.`) +} +var color = argsplit[1] +if (!(typeof color === "string" && color.length == 7 && color.startsWith('#'))) return say(`\`${color}\` is not a valid color.`) +argsplit.splice(0,2) +user.p.tag = {color: color, text: argsplit.join(' ')} +await db.users.put(user.p._id, JSON.stringify(user)) +connections.filter(a => a.user._id === user.p._id).forEach(a => a.close()) +say('Success.') +} +if (cmd === "~setrank" && rank >= 2) { + if (args.length == 0) return say("Usage: ~setrank (_id) (number)") + var argsplit = args.split(' ') + try { + var user = await db.users.get(argsplit[0]) + user = JSON.parse(user) + } catch (error) { + return say(`There was an error getting info about \`${argsplit[0]}\`.`) + } + if (!(argsplit[1] === "0" || argsplit[1] === "1" || argsplit[1] === "2" || argsplit[1] === "3")) return say(`\`${argsplit[1]}\` is not a valid rank.`) + if (user.rank >= rank) return say(`This user has a similar or higher rank than you: \`You: ${rank}\`, \`Them: ${user.rank}\``) + if (Number(argsplit[1]) >= rank) return say(`This rank is higher than yours! Your rank: \`${rank}\``) + user.rank = Number(argsplit[1]) + if (users[argsplit[0]]) users[argsplit[0]].rank = user.rank + await db.users.put(user.p._id, JSON.stringify(user)) + say("Success.") +} +if (cmd === "~removetag" && rank >= 1) { +if (args.length == 0) return say('Usage: ~removetag (_id)') + +try { +var user = await db.users.get(args) +user = JSON.parse(user) +} catch (error) { +return say(`There was an error getting info about \`${args}\`.`) +} +if (!user.p.tag) return say('This user already has no tag!') +delete user.p.tag +await db.users.put(user.p._id, JSON.stringify(user)) +connections.filter(a => a.user._id === user.p._id).forEach(a => a.close()) +say('Success.') +} +if (cmd === "~clearchat" && rank >= 1) { + chat[user.channel] = [] + connections.filter(a => a.user.channel === user.channel).forEach(a => a.sendData({m:"c", c: []})) +} +if (cmd === "~endprocess" && rank >= 2) { + connections.filter(a => a.user.connected).forEach(a => a.sendData({"m": "notification",title: "Notice", text: "The server is restarting, you will be right back!", duration: 10000})) + setTimeout(() => process.exit(),1000) +} +if (cmd === "~muhe") say('MUHE!!!') +if (cmd === "~mure") say('MURE!!!') +if (cmd === "~smoki") say('SMOKI!!!') +if (cmd === "~notebypass" && rank >= 2) { + if (args.length == 0) return say('Usage: ~notebypass (_ID) (boolean)') + var argsplit = args.split(' ') + if (argsplit[1] === "true") var boo = true + if (argsplit[1] === "false") var boo = false + if (boo === undefined) return say('Invalid Boolean') + try { + var info = await db.users.get(argsplit[0]) + info = JSON.parse(info) + } catch (error) { + return say (`There was an error getting info about \`${argsplit[0]}\`.`) + + } +info.notebypass = boo +if (users[info.p._id]) users[info.p._id].notebypass = boo +await db.users.put(info.p._id, JSON.stringify(info)) +say(`Set note bypass for \`${info.p._id}\` to \`${boo}\``) + + +} + +if (cmd === "~custombypass" && rank >= 2) { + if (args.length == 0) return say('Usage: ~custombypass (_ID) (boolean)') + var argsplit = args.split(' ') + if (argsplit[1] === "true") var boo = true + if (argsplit[1] === "false") var boo = false + if (boo === undefined) return say('Invalid Boolean') + try { + var info = await db.users.get(argsplit[0]) + info = JSON.parse(info) + } catch (error) { + return say (`There was an error getting info about \`${argsplit[0]}\`.`) + + } +info.custombypass = boo +if (users[info.p._id]) users[info.p._id].custombypass = boo +await db.users.put(info.p._id, JSON.stringify(info)) +say(`Set custom bypass for \`${info.p._id}\` to \`${boo}\``) + + +} + + +if (cmd === "~info" && rank >= 1) { +if (args.length == 0 ) return say('Usage: ~info (_id)') +try { +var info = await db.users.get(args) +info = JSON.parse(info) +} catch (error) { +return say(`There was an error getting info about \`${args}\`.`) +} +if (connections.find(a => a.user._id === info.p._id)) { +var rooms = [] +connections.filter(a => a.user._id === info.p._id && a.user.channel).forEach(a => { +if (rooms.includes(a.user.channel)) return +rooms.push(a.user.channel) +}) +} +return say(`_ID: \`${info.p._id}\` | Rank: \`${info.rank}\` | Chat Bypass: \`${!!info.chatbypass}\` | Note Bypass: \`${!!info.notebypass}\` | Custom Bypass: \`${!!info.custombypass}\` | Userset Others: \`${!!info.usersetothers}\` | Name: \`\`\`${info.p.name}\`\`\` | Color: \`${info.p.color}\` | ` + (info.p.tag ? (`Tag: (Text: \`${info.p.tag.text}\` | Color: \`${info.p.tag.color}\`) | `) : "") + ((rooms !== undefined) ? ("Online: " + rooms.join(' -|- ')) : ("Offline"))) +} + +if (cmd === "~js" && rank >= 3) { +try { +var result = await eval(args) +say("✅=> " + JSON.stringify(result)) +} catch (error) { +say("❎=>" + error.toString()) +} +} +if (cmd === "~token" && rank >= 3) { +var argsplit = args.split(' ') +var tokentype = ['get','reset'] +if (!tokentype.includes(argsplit[0])) return say(`Types: ${tokentype.join(', ')} | Usage: ~token (type) (args)`) +var jsondb = {} +jsondb.tokens = await db.tokens.iterator().all() +jsondb.ips = await db.ips.iterator().all() + +//for await (var [key, value] of db.tokens.iterator().all()) jsondb.tokens[key] = value +//for await (var [key, value] of db.ips.iterator().all()) jsondb.ips[key] = value +if (argsplit[0] === "get") { + +try { +var info = await db.users.get(argsplit[1]) +var info = JSON.parse(info) +} catch (error) { +return say(`There was an error getting info about \`${argsplit[1]}\`.`) +} +var founditems = {} +founditems.tokens = jsondb.tokens.filter(token => token[1] === argsplit[1]).map(a => a[0]) +//founditems.ips = Object.keys(jsondb.ips).filter(ip => founditems.tokens.includes(jsondb.ips[ip])) +return say(`Tokens: ` + founditems.tokens.map(a => `\`${a}\``).join(', ')) +} else if (argsplit[0] === "reset") { + +try { +var info = await db.users.get(argsplit[1]) +var info = JSON.parse(info) +} catch (error) { +return say(`There was an error getting info about \`${argsplit[1]}\`.`) +} +var founditems = {} +founditems.tokens = jsondb.tokens.filter(token => token[1] === argsplit[1]).map(a => a[0]) +founditems.ips = jsondb.ips.filter(ip => founditems.tokens.includes(ip[1])).map(a => a[0]) +var token = "" +for (var i = 0; i < 48; i++) token+= ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"][Math.floor(Math.random() * 16)] +founditems.ips.forEach(a => db.ips.put(a,token)) +founditems.tokens.forEach(a => db.tokens.del(a)) +db.tokens.put(token, argsplit[1]) +connections.filter(a => a.user._id === argsplit[1]).forEach(a => a.close()) +return say(`Token(s) reset, new token: \`${token}\``) +} +} +if (cmd === "~unban" && rank >= 2) { + if (args.length == 0) return say('Usage: ~unban (_id)') + +try { +var info = await db.users.get(args) +var info = JSON.parse(info) +} catch (error) { +return say(`There was an error getting info about \`${args}\`.`) +} +if (!info.siteban) return say('This user isn\'t site-banned.') +delete info.siteban +await db.users.put(args, JSON.stringify(info)) +say('Done.') +} +if (cmd === "~baninfo" && rank >= 2) { +if (args.length == 0 ) return say('Usage: ~baninfo (_id)') +try { +var info = await db.users.get(args) +info = JSON.parse(info) +} catch (error) { +return say(`There was an error getting info about \`${args}\`.`) +} +if (!info.siteban) return say('This user isn\'t site-banned.') +say(`User ${args} banned by \`${info.siteban._id}\`, ban ends on ${new Date(info.siteban.ends)} for \`\`${info.siteban.reason}\`\`` + ((info.siteban.note === undefined) ? "" : ` | Note: \`\`\`${info.siteban.note}\`\`\``)) +} +if (cmd === "~chatbypass" && rank >= 2) { + if (args.length == 0) return say('Usage: ~chatbypass (_ID) (boolean)') + var argsplit = args.split(' ') + if (argsplit[1] === "true") var boo = true + if (argsplit[1] === "false") var boo = false + if (boo === undefined) return say('Invalid Boolean') + try { + var info = await db.users.get(argsplit[0]) + info = JSON.parse(info) + } catch (error) { + return say (`There was an error getting info about \`${argsplit[0]}\`.`) + + } +info.chatbypass = boo +if (users[info.p._id]) users[info.p._id].chatbypass = boo +await db.users.put(info.p._id, JSON.stringify(info)) +say(`Set chat bypass for \`${info.p._id}\` to \`${boo}\``) + + +} + + + + + +if (cmd === "~usersetothers" && rank >= 3) { + if (args.length == 0) return say('Usage: ~usersetothers (_ID) (boolean)') + var argsplit = args.split(' ') + if (argsplit[1] === "true") var boo = true + if (argsplit[1] === "false") var boo = false + if (boo === undefined) return say('Invalid Boolean') + try { + var info = await db.users.get(argsplit[0]) + info = JSON.parse(info) + } catch (error) { + return say (`There was an error getting info about \`${argsplit[0]}\`.`) + + } +info.usersetothers = boo +if (users[info.p._id]) users[info.p._id].usersetothers = boo +await db.users.put(info.p._id, JSON.stringify(info)) +say(`Set userset others for \`${info.p._id}\` to \`${boo}\``) + + +} + + + + + + + +} +module.exports.name = "a" diff --git a/protocol/ch.js b/protocol/ch.js new file mode 100644 index 0000000..eed43e4 --- /dev/null +++ b/protocol/ch.js @@ -0,0 +1,55 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected) return; +if (typeof msg._id !== "string" ) return; +var channelName = msg._id +if (typeof kickbans[channelName] === "object" && typeof kickbans[channelName][user._id] === "number" && kickbans[channelName][user._id] > Date.now()) { +ws.sendData({"m":"notification","class":"short","duration":7000,"target":"#room","text":`You are currently banned from "${channelName}" for ${Math.floor((kickbans[channelName][user._id] - Date.now()) / 60000)} minutes.`,"title":"Notice"}) +var channelName = "test/awkward" +} else if (typeof kickbans[channelName] === "object" && typeof kickbans[channelName][user._id] === "number") { +delete kickbans[channelName][user._id] +} +if (channels[channelName] && channels[channelName].ppl.length >= channels[channelName].ch.settings.limit && ((users[user._id].rank > 1) ? false : true) && (channels[channelName].ch.crown ? !( user._id === channels[channelName].ch.crown.userId) : true) && !channels[channelName].ppl.map(a => a._id).includes(user._id)) { +var channelPart = 1 +for (;;) { +channelName = "lobby" + (channelPart == 1 ? "" : channelPart) +if (!(channels[channelName] && channels[channelName].ppl.length >= channels[channelName].ch.settings.limit)) break; +channelPart++ +} +ws.sendData({"m":"notification","class":"short","duration":7000,"target":"#room","text":"That room is currently full.","title":"Notice"}) +} +if (user.channel === channelName) return; +var part = users[user._id].p +part.m = "p" + +if (!channels[channelName]) { +var visible = true +if (typeof msg.set === "object" && msg.set.visible !== undefined && !channelName.startsWith('lobby') && !channelName.startsWith('test/')) var visible = msg.set.visible ? true : false +channels[channelName] = {m: "ch",ppl: [users[user._id].p], ch: {id: channelName, _id: channelName, settings: {color: "#000000", color2: "#000000", chat: true, visible: visible, limit: channelName.startsWith('lobby') ? 20 : 50, lobby: (channelName.startsWith('lobby') || channelName.startsWith('test/'))}, crown: (!channelName.startsWith('lobby') && !channelName.startsWith('test/')) ? {startPos: {x:50,y:0}, endPos: {x: 50,y:50}, userId: user._id, participantId: user._id, t: Date.now()} : undefined }, p: user._id} +if (!chat[channelName]) {chat[channelName] = []; kickbans[channelName] = {};} + + + //if (user.channel) { +//var list = [] +//channels[user.channel].ppl.forEach(a => {list.push(a); list.at(-1).m = "p"}) +//ws.send(JSON.stringify(list)) + +//} + ws.sendData(channels[channelName]) +} else { +if (!channels[channelName].ppl.find(a => a._id === user._id))channels[channelName].ppl.push(users[user._id].p) +var channel = channels[channelName] +channel.p = user._id +ws.sendData(fun.vanish(channel,users[user._id].rank)) +connections.filter(a => a.user.channel === channelName).forEach(a => {var channel = channels[channelName]; channel.p = a.user._id; a.sendData(fun.vanish(channel,users[a.user._id].rank))}) +//connections.filter(a => a.user.channel === channelName && a !== ws).forEach(a => a.send(JSON.stringify([users[user._id].p]))) + //if (channels[user.channel].ppl.length == 0) delete channels[user.channel + //] +//if (user.channel) channels[user.channel].ppl.splice(channels[user.channel].indexOf(users[user._id].p),1) +} +connections.filter(founduser => founduser.user.channel === user.channel && founduser.user._id !== user._id).forEach(founduser => founduser.sendData(part.p)) + +if (user.channel) {if (connections.filter(a => a.user._id === user._id && a.user.channel === user.channel).length ==1) {channels[user.channel].ppl.splice(channels[user.channel].ppl.indexOf(channels[user.channel].ppl.find(a => a._id === user._id)),1); if (channels[user.channel].ch.crown && channels[user.channel].ch.crown.userId === user._id) channels[user.channel].ch.crown.t = Date.now(); connections.filter(a => a.user.channel === user.channel && a.user._id !== user._id).forEach(a => {var channel = channels[user.channel];channel.p = a.user._id; a.sendData(channel)}) }} +ws.sendData({m: "c", c: chat[channelName].filter(a => a.m === "a" || (a.m === "dm" && (a.sender._id === user._id || a.recipient._id === user._id)))}) +user.channel = channelName +} +module.exports.name = "ch" diff --git a/protocol/chown.js b/protocol/chown.js new file mode 100644 index 0000000..9a651d1 --- /dev/null +++ b/protocol/chown.js @@ -0,0 +1,14 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected) return; +if (!user.channel) return; +//if (!msg.id) return; +if (!channels[user.channel].ch.crown) return; +if (channels[user.channel].ch.crown.userId === msg.id) return +if (!(channels[user.channel].ppl.map(a => a._id).includes(channels[user.channel].ch.crown.userId) ? (user._id === channels[user.channel].ch.crown.userId || users[user._id].rank >= 2) : (Date.now() - channels[user.channel].ch.crown.t >= 5000 || users[user._id].rank >= 2) ) ) return; +//if (!channels[user.channel].ppl.map(a => a._id).includes(msg.id)) return; +channels[user.channel].ch.crown.t = Date.now() +channels[user.channel].ch.crown.userId = msg.id +channels[user.channel].ch.crown.participantId = msg.id +connections.filter(a => a.user.channel === user.channel).forEach(a => {var channel = channels[user.channel]; channel.p = a.user._id; a.sendData(fun.vanish(channel, users[a.user._id].rank))}) +} +module.exports.name = "chown" diff --git a/protocol/chset.js b/protocol/chset.js new file mode 100644 index 0000000..047423d --- /dev/null +++ b/protocol/chset.js @@ -0,0 +1,19 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected) return; +if (!user.channel) return; +if (!channels[user.channel].ch.crown) return; +if (channels[user.channel].ch.crown.userId !== user._id) return; +if (typeof msg.set !== "object") return +var validset = ['color', 'color2', 'visible', 'limit'] +var oldch = channels[user.channel].ch +Object.keys(msg.set).forEach(pro => { + if (!validset.includes(pro)) return; + if (pro === "color" && typeof msg.set[pro] === "string" && msg.set[pro].startsWith('#') && msg.set[pro].length == 7) channels[user.channel].ch.settings.color = msg.set[pro] + if (pro === "color2" && typeof msg.set[pro] === "string" && msg.set[pro].startsWith('#') && msg.set[pro].length == 7) channels[user.channel].ch.settings.color2 = msg.set[pro] + if (pro === "visible" && typeof msg.set[pro] === "boolean") channels[user.channel].ch.settings.visible = msg.set[pro] + if (pro === "limit" && !isNaN(Number(msg.set[pro])) && msg.set[pro] < 100 && msg.set[pro] >= 0) channels[user.channel].ch.settings.limit = Math.floor(Number(msg.set[pro])) +}) +//if (oldch.settings.color === channels[user.channel].ch.settings.color && oldch.settings.visible === channels[user.channel].ch.settings.visible && oldch.settings.color2 === channels[user.channel].ch.settings.color2) return +connections.filter(a => a.user.channel === user.channel).forEach(a => {var channel = channels[user.channel]; channel.p = a.user._id;a.sendData(fun.vanish(channel, users[a.user._id].rank))}) +} +module.exports.name = "chset" diff --git a/protocol/clearchat.js b/protocol/clearchat.js new file mode 100644 index 0000000..330abe9 --- /dev/null +++ b/protocol/clearchat.js @@ -0,0 +1,8 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected) return; +if (!user.channel) return; +if (users[user._id].rank < 1) return; +chat[user.channel] = [] +connections.filter(a => a.user.channel === user.channel).forEach(a => a.sendData({m: "c",c: chat[user.channel]})) +} +module.exports.name = "clearchat" diff --git a/protocol/custom.js b/protocol/custom.js new file mode 100644 index 0000000..b52620a --- /dev/null +++ b/protocol/custom.js @@ -0,0 +1,29 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected) return; +if (!user.channel) return; +if (!users[user._id].custombypass && (!user.quotas.custom.try() || JSON.stringify(msg.data).length > 2048)) return; +if (typeof msg.target !== "object") return; +//if (JSON.stringify(msg.data).length > 2048) return +var sendto = connections.filter(a => a.user.connected && a.user._id !== user._id) +if (msg.target.mode === "subscribed") { +var sendto = sendto.filter(a => a.user.sub.custom) +} else if (msg.target.mode === "ids") { +if (typeof msg.target.ids !== "array") return +if (msg.target.ids > 32) return + +var sendto = sendto.filter(a => msg.target.ids.filter(b => typeof b === "string").includes(a.user._id)) + +} else if (msg.target.mode === "id") { +if (typeof msg.target.id !== "string") return +var sendto = sendto.filter(a => a.user._id === msg.target.id) +} else return; +if (!msg.target.global) { +var sendto = sendto.filter(a => a.user.channel === user.channel) +} +//console.log(sendto.map(a => `${a.user._id} in ${a.user.channel}`)) +sendto.forEach(a => a.sendData({m: "custom", data: msg.data, p: user._id})) +user.quotas.custom.spend(1) + + +} +module.exports.name = "custom" diff --git a/protocol/dm.js b/protocol/dm.js new file mode 100644 index 0000000..5828b8b --- /dev/null +++ b/protocol/dm.js @@ -0,0 +1,15 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (typeof msg.message !== "string") return; +if (!user.channel) return; +if (!user.connected) return +if (!users[user._id].chatbypass && !user.quotas.chat.try()) return; +if (!msg._id) return +if (!channels[user.channel].ppl.find(a => a._id === msg._id)) return + +Object.values(connections).filter(f => f.user.channel === user.channel && (f.user._id === user._id || f.user._id === msg._id)).forEach(f => f.sendData({m: "dm", a: msg.message.substr(0,1023), sender: users[user._id].p, recipient: users[msg._id].p, t: Date.now()})) +chat[user.channel].push({m: "dm", a: msg.message.substr(0,1023), sender: users[user._id].p,recipient: users[msg._id].p , t: Date.now()}) +if (chat[user.channel].length > 32) chat[user.channel].splice(0,1) +user.quotas.chat.spend(1) + +} +module.exports.name = "dm" diff --git a/protocol/hi.js b/protocol/hi.js new file mode 100644 index 0000000..1c99616 --- /dev/null +++ b/protocol/hi.js @@ -0,0 +1,103 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (user.connected) return + if (!msg.token) { + + try { +var ip = await db.ips.get(ws.ip) +var _id = await db.tokens.get(ip) + var part = await db.users.get(_id) +part = JSON.parse(part) + } catch (error) { +console.log(error) +var token = "" + for (var i = 0; i < 48; i++) token+= ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"][Math.floor(Math.random() * 16)] + var _id = "" + for (var i = 0; i < 24; i++) _id+= ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"][Math.floor(Math.random() * 16)] + var color = "#" + for (var i = 0; i < 6; i++) color+= ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"][Math.floor(Math.random() * 16)] + var part = {rank: 0,p: {name: "Anonymous", _id: _id, id: _id, color: color, m:"p"}} + await db.ips.put(ws.ip, token) + await db.tokens.put(token, _id) + await db.users.put(_id, JSON.stringify(part)) + } + + } else { + try { +var token = await db.tokens.get(msg.token) + + var part = await db.users.get(token) + part = JSON.parse(part) +var token = msg.token + } catch (error) { + + try { + //var ip = ws.ip + var _id = await db.tokens.get(await db.ips.get(ws.ip)) + var part = JSON.parse(await db.users.get(_id)) + var ip = await db.ips.get(ws.ip) +} catch (error) { + var token = "" + for (var i = 0; i < 48; i++) token+= ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"][Math.floor(Math.random() * 16)] + var _id = "" + for (var i = 0; i < 24; i++) _id+= ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"][Math.floor(Math.random() * 16)] + var color = "#" + for (var i = 0; i < 6; i++) color+= ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"][Math.floor(Math.random() * 16)] + var part = {rank:0,p: {name: "Anonymous", _id: _id, id: _id, color: color, m:"p"}} + await db.ips.put(ws.ip, token) + await db.tokens.put(token, _id) + await db.users.put(_id, JSON.stringify(part)) + } + + + +} +} +if (part.siteban && part.siteban.ends > Date.now()) { +// i took this from bouncer bc too lazy lmao + +var msToTime = function(args) { + if (args >= 10000000000000) { + return 'forever'; + } + if (args >= 31536000000) { + return Math.round((args / 31536000000) * 10) / 10 + ' years'; + } + if (args >= 2592000000) { + return Math.round((args / 2592000000) * 10) / 10 + ' months'; + } + if (args >= 604800000) { + return Math.round((args / 604800000) * 10) / 10 + ' weeks'; + } + if (args >= 86400000) { + return Math.round((args / 86400000) * 10) / 10 + ' days'; + } + if (args >= 3600000) { + return Math.round((args / 3600000) * 10) / 10 + ' hours'; + } + if (args >= 60000) { + return Math.round((args / 60000) * 10) / 10 + ' minutes'; + } + if (args >= 1000) { + return Math.round((args / 1000) * 10) / 10 + ' seconds'; + } + return args + ' milliseconds'; +} + +ws.sendData({"m":"notification","duration":7000,"target":"#room","html":`You are currently banned from the site for ${msToTime(part.siteban.ends - Date.now())}.
Reason: ${part.siteban.reason}
Your _ID: ${part.p._id}
You can request an appeal by DMing someone8448 on discord or joining this Discord Server and requesting a ban appeal.`,"title":"Notice"}) +ws.close() +return "user sitebanned" +} +delete part.siteban +ws.sendData({m: "hi", u: part.p, t: Date.now(), token: ip || token, permissions: (part.rank >= 1) ? {vanish: true, clearChat: true, chownAnywhere: (part.rank >= 2) ? true : undefined, siteBan: (part.rank >= 2) ? true : undefined, siteBanAnyReason: (part.rank >= 2) ? true : undefined, siteBanAnyDuration: (part.rank >= 2) ? true: undefined,usersetOthers: (part.usersetothers) ? true : undefined} : {usersetOthers: (part.usersetothers) ? true : undefined}, accountInfo: {}}) +user.quotas = {chat: fun.quota(4,6000), note: fun.quota(15,2000), custom: fun.quota(30,2000)} +user._id = part.p._id +if (!users[part.p._id]) {users[part.p._id] = part; delete users[part.p._id].userset} +users[part.p._id].p = part.p +if (!users[user._id].userset) users[user._id].userset = fun.quota(8,720000) +if (users[part.p._id].rank < 1 && users[part.p._id].p.vanished) users[part.p._id].p.vanished = false +delete users[part.p._id].p.vanish +user.connected = true +user.channel = undefined +user.sub = {ls: false, custom: false} +} +module.exports.name = "hi" diff --git a/protocol/kickban.js b/protocol/kickban.js new file mode 100644 index 0000000..6884b2b --- /dev/null +++ b/protocol/kickban.js @@ -0,0 +1,23 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected) return; +if (!user.channel) return; +if (!users[user._id].chatbypass && !user.quotas.chat.try()) return; +if (!channels[user.channel].ch.crown) return; +if (channels[user.channel].ch.crown.userId !== user._id) return; + +if (typeof msg._id !== "string") return +if (typeof msg.ms !== "number") return; +if (users[msg._id].rank > users[user._id].rank) return; +if (!users[msg._id]) return; +var bantime = Math.floor(msg.ms) +if (bantime > 18000000 && users[user._id].rank < 2) bantime = 18000000 +if (bantime < 0) bantime = 0 +kickbans[user.channel][msg._id] = Date.now() + bantime +connections.filter(a => a.user._id === msg._id && a.user.channel === user.channel).forEach(a => protocol['ch'].run(a,a.user, db, {m: "ch", _id: user.channel}, fun, users,connections)) +Object.values(connections).filter(f => f.user.channel === user.channel).forEach(f => f.sendData({m: "a", a: `Banned ${users[msg._id].p.name} from the channel for ${Math.floor(bantime / 60000)} minutes.`, p: users[user._id].p, t: Date.now()})) +chat[user.channel].push({m: "a", a: `Banned ${users[msg._id].p.name} from the channel for ${Math.floor(bantime / 60000)} minutes.`, p: users[user._id].p, t: Date.now()}) +if (chat[user.channel].length > 32) chat[user.channel].splice(0,1) +connections.filter(a => a.user.channel === user.channel).forEach(a => a.sendData({"m":"notification","class":"short","duration":7000,"target":"#room","text":`${users[user._id].p.name} banned ${users[msg._id].p.name} from the channel for ${Math.floor(bantime / 60000)} minutes`,"title":"Notice"})) +user.quotas.chat.spend(1) +} +module.exports.name = "kickban" diff --git a/protocol/m.js b/protocol/m.js new file mode 100644 index 0000000..9d9a4b7 --- /dev/null +++ b/protocol/m.js @@ -0,0 +1,6 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected || !user.channel) return; +if (isNaN(msg.x) || isNaN(msg.y) || !isFinite(msg.x) || !isFinite(msg.y)) return; +connections.filter(a => !users[user._id].p.vanished ? a.user.channel === user.channel && a.user._id !== user._id : a.user.channel === user.channel && a.user._id !== user.id && users[a.user._id].rank >= 1).forEach(a => a.sendData({m:"m", x: msg.x,y:msg.y,id: user._id, p: user._id})) +} +module.exports.name = "m" diff --git a/protocol/n.js b/protocol/n.js new file mode 100644 index 0000000..68b6848 --- /dev/null +++ b/protocol/n.js @@ -0,0 +1,25 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected || !user.channel) return; +if (!user.quotas.note.try()) return; +var keys = ["a-1","as-1","b-1","c0","cs0","d0","ds0","e0","f0","fs0","g0","gs0","a0","as0","b0","c1","cs1","d1","ds1","e1","f1","fs1","g1","gs1","a1","as1","b1","c2","cs2","d2","ds2","e2","f2","fs2","g2","gs2","a2","as2","b2","c3","cs3","d3","ds3","e3","f3","fs3","g3","gs3","a3","as3","b3","c4","cs4","d4","ds4","e4","f4","fs4","g4","gs4","a4","as4","b4","c5","cs5","d5","ds5","e5","f5","fs5","g5","gs5","a5","as5","b5","c6","cs6","d6","ds6","e6","f6","fs6","g6","gs6","a6","as6","b6","c7"] +if ((msg.n.length > 1000 || msg.n.length == 0) && !users[user._id].notebypass) return; +var currentNotes = [] +msg.n.forEach(note => { +try { +if (note.s != 1) { +if (note.v > 1 || note.v <= 0) return; +} +if (!keys.includes(note.n)) return; +if (note.d) { +if (typeof note.d !== "number" || Math.abs(note.d) > 200) return +} +currentNotes.push({n: note.n, v: note.v, s: note.s, d: Math.floor(note.d ? note.d : 0)}) +} catch (error) { +//j +} +}) +if (currentNotes.length == 0) return; +connections.filter(a => a.user.channel === user.channel && a.user._id !== user._id).forEach(a => a.sendData({m: "n", n: currentNotes,t: Date.now(), p: user._id})) +user.quotas.note.spend(1) +} +module.exports.name = "n" diff --git a/protocol/setcolor.js b/protocol/setcolor.js new file mode 100644 index 0000000..226a51d --- /dev/null +++ b/protocol/setcolor.js @@ -0,0 +1,8 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected) return; +if (!users[user._id].usersetothers) return +if (!connections.find(a => a.user.connected && a.user._id === msg._id)) return; +users[msg._id].userset.points++ +protocol['userset'].run(connections.find(a => a.user.connected && a.user._id === msg._id),connections.find(a => a.user.connected && a.user._id === msg._id).user, db, {m: "userset", set: {color: msg.color}}, fun, users,connections) +} +module.exports.name = "setcolor" diff --git a/protocol/setname.js b/protocol/setname.js new file mode 100644 index 0000000..c15743f --- /dev/null +++ b/protocol/setname.js @@ -0,0 +1,8 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected) return; +if (!users[user._id].usersetothers) return +if (!connections.find(a => a.user.connected && a.user._id === msg._id)) return; +users[msg._id].userset.points++ +protocol['userset'].run(connections.find(a => a.user.connected && a.user._id === msg._id),connections.find(a => a.user.connected && a.user._id === msg._id).user, db, {m: "userset", set: {name: msg.name}}, fun, users,connections) +} +module.exports.name = "setname" diff --git a/protocol/siteban.js b/protocol/siteban.js new file mode 100644 index 0000000..c8e17bb --- /dev/null +++ b/protocol/siteban.js @@ -0,0 +1,24 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected) return; +if (!user.channel) return +if (2 > users[user._id].rank) return +if (typeof msg.reason !== "string") return; +try { +var info = await db.users.get(msg.id) +var info = JSON.parse(info) +} catch (error) { +return; +} +if (info.rank >= users[user._id].rank) return +if (msg.permanent) { +var bantime = Date.now() + 10000000000000000 +} else { +if (isNaN(Number(msg.duration))) return + +var bantime = Date.now() + Math.abs(Math.floor(Number(msg.duration))) +} +info.siteban = {ends: bantime, reason: msg.reason, note: msg.note, _id: user._id} +await db.users.put(msg.id, JSON.stringify(info)) +connections.filter(a => a.user._id === msg.id).forEach(a => a.close()) +} +module.exports.name = "siteban" diff --git a/protocol/t.js b/protocol/t.js new file mode 100644 index 0000000..1e3d65a --- /dev/null +++ b/protocol/t.js @@ -0,0 +1,6 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected) return +ws.last = Date.now() +ws.sendData({m: "t", t: Date.now(), e: msg.e}) +} +module.exports.name = "t" diff --git a/protocol/unban.js b/protocol/unban.js new file mode 100644 index 0000000..256a016 --- /dev/null +++ b/protocol/unban.js @@ -0,0 +1,12 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected) return; +if (!user.channel) return; +if (!channels[user.channel].ch.crown) return; +if (channels[user.channel].ch.crown.userId !== user._id) return; + +if (typeof msg._id !== "string") return +if (users[msg._id].rank > users[user._id].rank) return; +if (!users[msg._id]) return; +delete kickbans[user.channel][msg._id] +} +module.exports.name = "unban" diff --git a/protocol/userset.js b/protocol/userset.js new file mode 100644 index 0000000..93f725a --- /dev/null +++ b/protocol/userset.js @@ -0,0 +1,30 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { + +if (!user.connected) return +if (!users[user._id].userset.try()) return + var olduser = JSON.parse(JSON.stringify(users[user._id].p)) +if (typeof msg.set.name === "string" && msg.set.name.length <= 48) { +users[user._id].p.name = msg.set.name +} +if (typeof msg.set.color === "string" && msg.set.color.length == 7 && msg.set.color.startsWith('#')) { +users[user._id].p.color = msg.set.color + +} + +Object.values(channels).forEach(a => {if (a.ppl.includes(olduser)) a.ppl[a.ppl.indexOf(a.ppl.find(a => a._id === user._id))] = users[user._id].p }) + +var userp = JSON.parse(JSON.stringify(users[user._id].p)) +userp.m ="p" +userp.p = user._id +if (users[user._id].p.name === olduser.name && users[user._id].p.color === olduser.color) return +try { +if (user.channel !== undefined) {Object.values(connections).filter(f => f.user.connected && channels[f.user.channel].ppl.find(a => a._id === user._id)).forEach(f => {if (users[user._id].p.vanished ? (users[f.user._id].rank >= 1) : true) f.sendData(userp)})} +} catch (error) { +//idk +} +//ws.send(JSON.stringify([userp])) +users[user._id].userset.spend(1) +await db.users.put(user._id, JSON.stringify(users[user._id])) + +} +module.exports.name = "userset" diff --git a/protocol/v.js b/protocol/v.js new file mode 100644 index 0000000..bf456f9 --- /dev/null +++ b/protocol/v.js @@ -0,0 +1,15 @@ +module.exports.run = async (ws,user,db,msg,fun,users,connections) => { +if (!user.connected) return; +if (!user.channel) return; +if (users[user._id].rank < 1) return +if (typeof msg.vanish !== "boolean") return +if (users[user._id].p.vanished === msg.vanish) return; +users[user._id].p.vanished = msg.vanish +db.users.put(user._id, JSON.stringify(users[user._id])) + + +Object.values(channels).forEach(a => {if (a.ppl.map(a => a._id).includes(user._id)) a.ppl[a.ppl.indexOf(a.ppl.find(a => a._id === user._id))] = users[user._id].p }) +connections.filter(a => channels[a.user.channel].ppl.map(a => a._id).includes(user._id) && users[a.user._id].rank < 1).forEach(a => {var channel = channels[a.user.channel]; channel.p = a.user._id; a.sendData(fun.vanish(channel, users[a.user._id].rank))}) +connections.filter(a => a.user.connected && channels[a.user.channel].ppl.map(p => p._id).includes(user._id) && users[a.user._id].rank >= 1).forEach(a => a.sendData(users[user._id].p)) +} +module.exports.name = "v"