diff options
Diffstat (limited to 'index.js')
-rw-r--r-- | index.js | 210 |
1 files changed, 140 insertions, 70 deletions
diff --git a/index.js b/index.js index ed778b0..10c7a88 100644 --- a/index.js +++ b/index.js @@ -1,18 +1,20 @@ import { WebSocketServer } from "ws"; -import { getRandomInt } from "./lib.js" -import { profanity } from '@2toad/profanity'; +import { getRandomInt } from "./lib.js"; +import { profanity } from "@2toad/profanity"; import { commands } from "./commands.js"; -import * as accounts from "./accounts.js" -import cuid from 'cuid'; -import fs from 'fs'; -profanity.options.grawlixChar = "*" +import * as accounts from "./accounts.js"; +import cuid from "cuid"; +import fs from "fs"; const server = { config: JSON.parse(String(fs.readFileSync("config.json"))), channels: ["home", "off-topic"], users: {}, accounts: accounts, -} +}; + +if (server.config.profanityRemoveWords) profanity.removeWords(server.config.profanityRemoveWords); +if (server.config.profanityAddWords) profanity.addWords(server.config.profanityAddWords); const ws = new WebSocketServer({ port: 9933, @@ -21,64 +23,106 @@ const ws = new WebSocketServer({ function sendInChannel(msg, channel) { for (const userID in server.users) { const user = server.users[userID]; - if (user.channel == channel) user.socket.send(msg) + if (user.channel == channel) user.socket.send(msg); } } function format(txt) { - txt = String(txt) - txt = txt.replaceAll("$(serverName)$", server.config.name) - txt = txt.replaceAll("$(userCount)$", Object.keys(server.users).length) - txt = txt.replaceAll("$(max)$", server.config.max) - return txt + txt = String(txt); + txt = txt.replaceAll("$(serverName)$", server.config.name); + txt = txt.replaceAll("$(userCount)$", Object.keys(server.users).length); + txt = txt.replaceAll("$(max)$", server.config.max); + return txt; +} + +function updateUsers() { + Object.keys(server.users).forEach((user) => { + if (user.subscribedToUsers) { + user.socket.send( + `:json.sub<users>:${JSON.stringify( + Object.values(server.users).map((usr) => { + return { + username: usr.username, + nickname: usr.nickname, + t: usr.t, + channel: user.channel, + displayName: user.name(), + }; + }) + )}` + ); + } + }); } -server.format = format +server.updateUsers = updateUsers; +server.format = format; -ws.on('connection', (socket, request) => { +ws.on("connection", (socket, request) => { if (server.config.max && Object.keys(server.users).length >= server.config.max) { - socket.send(format(server.config.fullMessage ?? "Sorry, but the server is full right now, come back later")) - socket.close(1001, "Server full") + socket.send(format(server.config.fullMessage ?? "Sorry, but the server is full right now, come back later")); + socket.close(1001, "Server full"); + return; } - let userID = cuid() - console.info(`${userID} joined the server.`) - socket.send(format(server.config.motd)) - let anonID = getRandomInt(0, 99999) + let userID = cuid(); + console.info(`${userID} joined the server.`); + socket.send(format(server.config.motd)); + let ip = request.headers["x-forwarded-for"] || request.socket.remoteAddress; + console.log(request.headers["x-forwarded-for"], request.socket.remoteAddress); + let anonID = getRandomInt(0, 99999); server.users[userID] = { username: `Anonymous${"0".repeat(5 - anonID.toString().length) + anonID.toString()}`, nickname: `Anonymous${"0".repeat(5 - anonID.toString().length) + anonID.toString()}`, guest: true, socket: socket, joinReq: request, + ip: ip, t: { js: Number(new Date()), unix: Math.floor(new Date().getTime() / 1000), - str: String(new Date()) + str: String(new Date()), }, - channel: 'home', - name: function(){return this.nickname != "" ? this.nickname : this.username} + channel: "home", + name: function () { + return this.nickname != "" ? this.nickname : this.username; + }, + }; + const user = server.users[userID]; + let ipBanList = JSON.parse(String(fs.readFileSync("db/bannedIps.json"))); + if (ipBanList[user.ip]) { + socket.send("Your IP is banned for " + ipBanList[user.ip]); + socket.close(1002, "Banned"); + return; } - const user = server.users[userID] - console.info(`${user.name()} joined the server!`) - sendInChannel(`${user.name()} joined #${server.users[userID].channel}!`, server.users[userID].channel) - socket.on('close', function (code, reason) { - sendInChannel(`${user.name()} left.`, server.users[userID].channel) - delete server.users[userID] - }) - socket.on('message', function (rawData) { + console.info(`${user.name()} joined the server!`); + sendInChannel(`${user.name()} joined.`, server.users[userID].channel); + server.updateUsers(); + socket.on("close", function (code, reason) { + sendInChannel(`${user.name()} left.`, server.users[userID].channel); + server.updateUsers(); + delete server.users[userID]; + }); + socket.on("message", function (rawData) { if (rawData.toString().startsWith("/")) { let args = String(rawData).replace("/", "").split(" "); let command = args.shift(); - let commandObj = Object.values(commands).find(cmd => cmd.name == command || cmd.aliases.includes(command)) - console.log(`${user.name()} used /${command}`) + let commandObj = Object.values(commands).find((cmd) => cmd.name == command || cmd.aliases.includes(command)); + console.log(`${user.name()} used /${command}`); if (!commandObj) return socket.send(`Error: Command "${command}" not found!`); try { - commandObj.command({ user, command, args, sendInChannel, server, commands }) + commandObj.command({ + user, + command, + args, + sendInChannel, + server, + commands, + }); } catch (error) { - console.error(error) - user.socket.send(`Unexpected error ocurred while running the command`) + console.error(error); + user.socket.send(`Unexpected error ocurred while running the command`); } - return + return; } if (rawData.toString().startsWith(":client")) { let client = String(rawData).replace(":client", ""); @@ -86,53 +130,79 @@ ws.on('connection', (socket, request) => { if (client.length < 2) return socket.send("Error: client info too short!"); if (client.length >= 100) return socket.send("Error: client info too long!"); server.users[userID].client = client; - return + return; } if (rawData.toString().startsWith(":jsonGet")) { let params = String(rawData).split(" "); - params.shift() + params.shift(); switch (params[0]) { - case 'channels': - socket.send(JSON.stringify(server.channels)); + case "channels": + socket.send(":json.channels>" + JSON.stringify(server.channels)); break; - case 'users': - socket.send(JSON.stringify(Object.values(server.users).map(usr => {return { - username: usr.username, - nickname: usr.nickname, - t: usr.t, - channel: user.channel, - displayName: user.name() - }}))); + case "users": + socket.send( + ":json.users>" + + JSON.stringify( + Object.values(server.users).map((usr) => { + return { + username: usr.username, + nickname: usr.nickname, + t: usr.t, + channel: user.channel, + displayName: user.name(), + }; + }) + ) + ); break; - case 'usersLocal': + case "usersLocal": socket.send( JSON.stringify( Object.values(server.users) - .filter(usr => (usr.channel == user.channel)) - .map(usr => {return { - username: usr.username, - nickname: usr.nickname, - t: usr.t, - channel: user.channel, - displayName: user.name() - }}) - )); + .filter((usr) => usr.channel == user.channel) + .map((usr) => { + return { + username: usr.username, + nickname: usr.nickname, + t: usr.t, + channel: user.channel, + displayName: user.name(), + }; + }) + ) + ); break; - + default: socket.send(`unknown "${params[0]}"`); break; } - return + return; } + if (rawData.toString().startsWith(":jsonSubscribe")) { + let params = String(rawData).split(" "); + params.shift(); + switch (params[0]) { + case "users": + user.subscribedToUsers = true; + break; + + default: + socket.send(`unknown "${params[0]}"`); + break; + } + return; + } + if (server.config.requireLogin) return socket.send("This server requires you to log in, use /login <username> <password> to log in or /register <username> <password> to make an account."); + profanity.options.grawlixChar = "*"; + if (!server.config.profanity) rawData = profanity.censor(String(rawData)); if (rawData.length < 1) return socket.send("Error: message too short!"); if (rawData.length >= 2000) return socket.send("Error: message too long!"); - if (!server.profanity) rawData = profanity.censor(String(rawData)); - sendInChannel(`<${user.name()}${user.guest ? " (guest)" : ""}> ${rawData}`, server.users[userID].channel) - console.log(`(#${server.users[userID].channel}) <${user.name()}> ${rawData}`) - }) -}) + sendInChannel(`${user.admin ? '[ADMIN] ' : ''}<${user.name()}${user.guest ? " (guest)" : ""}> ${rawData}`, server.users[userID].channel); + console.log(`(#${server.users[userID].channel}) <${user.name()}> ${rawData}`); + }); +}); -ws.on('listening', () => { - console.info("[INFO] Server started") -}) +ws.on("listening", () => { + console.info("[INFO] Server started"); +}); |