smnmpp-server/index.js

118 lines
5.6 KiB
JavaScript

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'))