diff options
author | WlodekM <[email protected]> | 2024-11-26 09:51:39 +0200 |
---|---|---|
committer | WlodekM <[email protected]> | 2024-11-26 09:51:39 +0200 |
commit | ae159f6d6cb2d5ab933730a3c07903452df8c1ef (patch) | |
tree | eb289275e861578632003e5b983213aeb320cedb | |
parent | 2fb9a1cae1e2b2dc59f529e46965719367f53964 (diff) |
begin rewrite
-rw-r--r-- | .vscode/settings.json | 3 | ||||
-rw-r--r-- | config.ini | 6 | ||||
-rw-r--r-- | newindex.js | 1 | ||||
-rw-r--r-- | oldindex.js (renamed from index.js) | 0 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | pnpm-lock.yaml | 27 | ||||
-rw-r--r-- | server.ts (renamed from server.js) | 184 | ||||
-rw-r--r-- | user.js | 8 |
8 files changed, 137 insertions, 93 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b943dbc --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "deno.enable": true +} \ No newline at end of file diff --git a/config.ini b/config.ini index ffd91e1..5fc55eb 100644 --- a/config.ini +++ b/config.ini @@ -19,11 +19,11 @@ annonFormat = "Anonymous#[num]" [profanity] filter = true -removeWords = ["butt", "arse", "balls", "dick"] -addWords = ["kys"] +removeWords = butt, arse, balls, dick +addWords = kys [channels] -channels = ["home", "off-topic", "random", "safe"] +channels = home, off-topic, random, safe [channel-home] ; You can set settings like profanity for specific channels diff --git a/newindex.js b/newindex.js index 536264f..a2d2763 100644 --- a/newindex.js +++ b/newindex.js @@ -1,4 +1,5 @@ import Server from './server.js'; import ini from "ini" +import fs from "fs" const server = new Server(ini.parse(String(fs.readFileSync("config.ini")))) diff --git a/index.js b/oldindex.js index 6c17622..6c17622 100644 --- a/index.js +++ b/oldindex.js diff --git a/package.json b/package.json index 06f596a..344cf6b 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ }, "dependencies": { "@2toad/profanity": "^2.2.0", + "@types/node": "^22.10.0", "cuid": "^3.0.0", "ini": "^5.0.0", "ws": "^8.17.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3a57313..be20854 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,12 +11,18 @@ importers: '@2toad/profanity': specifier: ^2.2.0 version: 2.5.0 + '@types/node': + specifier: ^22.10.0 + version: 22.10.0 cuid: specifier: ^3.0.0 version: 3.0.0 ini: specifier: ^5.0.0 version: 5.0.0 + typescript: + specifier: ^5.0.0 + version: 5.6.3 ws: specifier: ^8.17.1 version: 8.18.0 @@ -40,6 +46,9 @@ packages: '@types/[email protected]': resolution: {integrity: sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==} + '@types/[email protected]': + resolution: {integrity: sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==} + '@types/[email protected]': resolution: {integrity: sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==} @@ -59,9 +68,17 @@ packages: engines: {node: '>=14'} hasBin: true + [email protected]: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + engines: {node: '>=14.17'} + hasBin: true + [email protected]: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + [email protected]: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + [email protected]: resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} @@ -86,9 +103,13 @@ snapshots: dependencies: undici-types: 5.26.5 + '@types/[email protected]': + dependencies: + undici-types: 6.20.0 + '@types/[email protected]': dependencies: - '@types/node': 20.12.14 + '@types/node': 22.10.0 [email protected]: dependencies: @@ -101,6 +122,10 @@ snapshots: [email protected]: {} + [email protected]: {} + [email protected]: {} + [email protected]: {} + [email protected]: {} diff --git a/server.js b/server.ts index e5653c8..f47abb2 100644 --- a/server.js +++ b/server.ts @@ -2,107 +2,79 @@ import { WebSocketServer } from "ws"; import { profanity } from "@2toad/profanity"; import { commands } from "./commands.js"; import * as accounts from "./accounts.js"; -import fs from "fs"; +import fs from "node:fs"; import User from "./user.js"; import handleJsonMessage from './jsondata.js' +import { EventEmitter } from "node:events"; -export default class Server { - sendInChannel(msg, channel, server=this) { - // console.log('this is a', this) - for (const userID in server.users) { - const user = server.users[userID]; - if (user.channel == channel) user.socket.send(msg); - } - } +class Events { // JSON events for clients - format(txt) { - txt = String(txt); - txt = txt.replaceAll("$(serverName)$", this.config.name); - txt = txt.replaceAll("$(userCount)$", Object.keys(this.users).length); - for (const configName in this.config) { - if (Object.prototype.hasOwnProperty.call(this.config, configName)) { - const configValue = this.config[configName]; - if(typeof configValue != 'string' && typeof configValue != 'number') continue; - txt = txt.replaceAll(`$(${configName})$`, configValue); - } - } - return txt; - } - - updateUsers() { - Object.keys(this.users).forEach((user) => { - if (user.subscribedToUsers) { - user.socket.send( - `:json.sub<users>:${JSON.stringify( - Object.values(this.users).map((usr) => { - return { - username: usr.username, - nickname: usr.nickname, - t: usr.t, - channel: user.channel, - displayName: user.name(), - }; - }) - )}` - ); - } - }); - } +} - /** - * @typedef ServerConfig - * @property {Number} port - * @property {String} name - * @property {String} motd - * @property {String} fullMessage - * @property {Number} max - * - * @typedef Config - * @property {ServerConfig} server - */ +type ServerConfig = { + port: number + name: string + motd: string + fullMessage: string + max: number +} + +type AccountsConfig = { + owner: string + saveIP: boolean + requireLogin: boolean + annonFormat: boolean +} + +type ProfanityConfig = { + filter: boolean + removeWords: string + addWords: string +} + +type ChannelsConfig = { + channels: string +} +type Config = { + server: ServerConfig + accounts: AccountsConfig + channels: ChannelsConfig + profanity: ProfanityConfig +} + +export default class Server { + config: Config; + channels: string[]; + users: Map<string, User> = new Map(); + accounts = accounts; + ws: WebSocketServer&EventEmitter; /** * A wsChat server - * @param {{ - * name: String, - * motd: String, - * max: Number, - * owner: String, - * saveIP: Boolean, - * requireLogin: Boolean, - * profanity: Boolean, - * profanityRemoveWords: String[], - * profanityAddWords: String[], - * fullMessage: String, - * annonFormat: String, - * port: Number, - * channels: String[], - * annonChannels: String[] - * }} config */ - constructor (config) { + constructor (config: Config) { this.config = config; - this.channels = this.config.channels; - this.annonChannels = this.config.annonChannels; - this.users = [] - this.accounts = accounts; + this.channels = this.config.channels.channels.split(/, */g); + // this.annonChannels = this.config.annonChannels.split(/, */g); this.ws = new WebSocketServer({ - port: this.config.port, + port: this.config.server.port, }); - if (this.config.profanityRemoveWords) profanity.removeWords(this.config.profanityRemoveWords); - if (this.config.profanityAddWords) profanity.addWords(this.config.profanityAddWords); + if (this.config.profanity.removeWords) profanity.removeWords(this.config.profanity.removeWords.split(/, */g)); + if (this.config.profanity.addWords) profanity.addWords(this.config.profanity.addWords.split(/, */g)); + + let server = this; - let server = this + if (!fs.existsSync("db/bannedIps.json")) fs.writeFileSync("db/bannedIps.json", "{}"); - this.ws.on("connection", (socket, request) => { + this.ws.on("connection", (socket: WebSocket, request) => { try { - if (server.config.max && Object.keys(server.users).length >= server.config.max) { - socket.send(server.format(server.config.fullMessage ?? "Sorry, but the server is full right now, come back later")); + if (server.config.server.max && Object.keys(server.users).length >= server.config.server.max) { + socket.send(server.format(server.config.server.fullMessage ?? "Sorry, but the server is full right now, come back later")); socket.close(1001, "Server full"); return; } - const user = new User(request, socket, server) + const user: User = new User(request, socket, server) server.users[user.id] = user let ipBanList = JSON.parse(String(fs.readFileSync("db/bannedIps.json"))); if (ipBanList[user.ip]) { @@ -110,7 +82,7 @@ export default class Server { socket.close(1002, "Banned"); return; } - socket.send(server.format(server.config.motd)); + socket.send(server.format(server.config.server.motd)); console.info(`${user.name()}[${user.id}] joined the server!`); server.sendInChannel(`${user.name()} joined.`, server.users[user.id].channel); server.updateUsers(); @@ -153,9 +125,9 @@ export default class Server { return; } if(handleJsonMessage(server, rawData, user)) return; - if (server.config.requireLogin && user.guest && !server.annonChannels.includes(user.channel)) 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."); + if (server.config.accounts.requireLogin && user.guest && !server.annonChannels.includes(user.channel)) 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 (server.config.profanity.filter) 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!"); server.sendInChannel(`${user.admin ? '[ADMIN] ' : ''}<${user.name()}${user.guest ? " (guest)" : ""}> ${rawData}`, user.channel); @@ -170,4 +142,46 @@ export default class Server { console.info("Server started!"); }); } + + sendInChannel(msg, channel, server=this) { + // console.log('this is a', this) + for (const userID in server.users) { + const user = server.users[userID]; + if (user.channel == channel) user.socket.send(msg); + } + } + + format(txt) { + txt = String(txt); + txt = txt.replaceAll("$(serverName)$", this.config.server.name); + txt = txt.replaceAll("$(userCount)$", Object.keys(this.users).length); + for (const configName in this.config.server) { + if (Object.prototype.hasOwnProperty.call(this.config.server, configName)) { + const configValue = this.config.server[configName]; + if(typeof configValue != 'string' && typeof configValue != 'number') continue; + txt = txt.replaceAll(`$(${configName})$`, configValue); + } + } + return txt; + } + + updateUsers() { + Object.keys(this.users).forEach((user) => { + if (user.subscribedToUsers) { + user.socket.send( + `:json.sub<users>:${JSON.stringify( + Object.values(this.users).map((usr) => { + return { + username: usr.username, + nickname: usr.nickname, + t: usr.t, + channel: user.channel, + displayName: user.name(), + }; + }) + )}` + ); + } + }); + } } \ No newline at end of file diff --git a/user.js b/user.js index d3254f7..c801659 100644 --- a/user.js +++ b/user.js @@ -6,14 +6,14 @@ import cuid from "cuid"; export default class User { /** * the user class - * @param {import("http").IncomingMessage} request request + * @param {import("node:http").IncomingMessage} request request * @param {WebSocket} socket socket - * @param {import("./server.js").Server} server the server + * @param {import("./server.ts").Server} server the server */ constructor (request, socket, server) { this.id = cuid(); - let anonID = getRandomInt(0, 99999); - let annonNum = "0".repeat(5 - anonID.toString().length) + anonID.toString() + const anonID = getRandomInt(0, 99999); + const annonNum = "0".repeat(5 - anonID.toString().length) + anonID.toString() this.username = server.config.annonFormat ? server.config.annonFormat.replace('[num]', annonNum) : 'Anonymous' + annonNum; this.nickname = server.config.annonFormat ? server.config.annonFormat.replace('[num]', annonNum) : 'Anonymous' + annonNum; this.guest = true; |