summary refs log tree commit diff
path: root/server.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server.ts')
-rw-r--r--server.ts143
1 files changed, 82 insertions, 61 deletions
diff --git a/server.ts b/server.ts
index f47abb2..f3bc077 100644
--- a/server.ts
+++ b/server.ts
@@ -1,13 +1,14 @@
-import { WebSocketServer } from "ws";
+import { WebSocketServer, WebSocket } from "ws";
 import { profanity } from "@2toad/profanity";
-import { commands } from "./commands.js";
-import * as accounts from "./accounts.js";
+import { commands, type Command } from "./commands.ts";
+import * as accounts from "./accounts.ts";
 import fs from "node:fs";
-import User from "./user.js";
+import User from "./user.ts";
 import handleJsonMessage from './jsondata.js'
 import { EventEmitter } from "node:events";
 
-class Events { // JSON events for clients
+// TODO - actually make this
+class _Events { // JSON events for clients
     
 }
 
@@ -23,7 +24,7 @@ type AccountsConfig = {
     owner: string
     saveIP: boolean
     requireLogin: boolean
-    annonFormat: boolean
+    annonFormat: string
 }
 
 type ProfanityConfig = {
@@ -36,11 +37,22 @@ type ChannelsConfig = {
     channels: string
 }
 
+type ChannelConfig = {
+    slowmode?: number
+    requireLogin?: boolean
+    profanity?: boolean
+}
+
+type addPrefixToObject<T, P extends string> = {
+    [K in keyof T as K extends string ? `${P}${K}` : never]: T[K]
+}
+
 type Config = {
     server: ServerConfig
     accounts: AccountsConfig
     channels: ChannelsConfig
     profanity: ProfanityConfig
+    [key: string]: ServerConfig | AccountsConfig | ChannelsConfig | ProfanityConfig | ChannelConfig;
 }
 
 export default class Server {
@@ -63,7 +75,8 @@ export default class Server {
         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;
+        // deno-lint-ignore no-this-alias
+        const server = this;
 
         if (!fs.existsSync("db/bannedIps.json")) fs.writeFileSync("db/bannedIps.json", "{}");
 
@@ -75,27 +88,32 @@ export default class Server {
                     return;
                 }
                 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]) {
-                    socket.send("Your IP is banned for " + ipBanList[user.ip]);
+                server.users.set(user.id, user);
+                type IPbanList = {
+                    [key: string]: string
+                }
+                const ipBanList: IPbanList = JSON.parse(String(fs.readFileSync("db/bannedIps.json")));
+                if (user.ip && ipBanList[user.ip[0]]) {
+                    socket.send("Your IP is banned for " + ipBanList[user.ip[0]]);
                     socket.close(1002, "Banned");
                     return;
                 }
                 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.sendInChannel(`${user.name()} joined.`, user.channel);
                 server.updateUsers();
-                socket.on("close", function (code, reason) {
-                    server.sendInChannel(`${user.name()} left.`, server.users[user.id].channel);
+                socket.on("close", function () {
+                    server.sendInChannel(`${user.name()} left.`, user.channel);
                     server.updateUsers();
-                    delete server.users[user.id];
+                    server.users.delete(user.id);
                 });
                 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));
+                    let data: string = rawData.toString()
+                    if (data.toString().startsWith("/")) {
+                        const args: string[] = String(data).replace("/", "").split(" ");
+                        const command: string = args.shift() as string;
+                        // TODO: make command class
+                        const commandObj: Command = Object.values(commands).find((cmd) => cmd.name == command || cmd.aliases.includes(command)) as Command;
                         console.log(`${user.name()} used /${command}`);
                         if (!commandObj) return socket.send(`Error: Command "${command}" not found!`);
                         try {
@@ -103,7 +121,7 @@ export default class Server {
                                 user,
                                 command,
                                 args,
-                                sendInChannel: function (msg, channel) {
+                                sendInChannel: function (msg: string, channel: string) {
                                     console.log(msg, channel)
                                     server.sendInChannel(msg, channel, server);
                                 },
@@ -116,22 +134,24 @@ export default class Server {
                         }
                         return;
                     }
-                    if (rawData.toString().startsWith(":client")) {
-                        let client = String(rawData).replace(":client", "");
+                    if (data.toString().startsWith(":client")) {
+                        const client = String(data).replace(":client", "");
                         if (!client) return socket.send("Error: client info missing!");
                         if (client.length < 2) return socket.send("Error: client info too short!");
                         if (client.length >= 100) return socket.send("Error: client info too long!");
                         user.client = client;
                         return;
                     }
-                    if(handleJsonMessage(server, rawData, user)) return;
-                    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.");
+                    if(handleJsonMessage(server, data, user)) return;
+                    const thisChannelConfig: ChannelConfig | undefined = server.config['channel-'+user.channel] as ChannelConfig;
+                    if (server.config.accounts.requireLogin && user.guest && thisChannelConfig?.requireLogin != undefined && !thisChannelConfig.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.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);
-                    console.log(`(#${user.channel}) <${user.name()}> ${rawData}`);
+                    if (server.config.profanity.filter) data = profanity.censor(String(data));
+                    if (data.length < 1) return socket.send("Error: message too short!");
+                    if (data.length >= 2000) return socket.send("Error: message too long!");
+                    server.sendInChannel(`${user.admin ? '[ADMIN] ' : ''}<${user.name()}${user.guest ? " (guest)" : ""}> ${data}`, user.channel);
+                    console.log(`(#${user.channel}) <${user.name()}> ${data}`);
                 });
             } catch (error) {
                 socket.send(`ERROR ${error}`);
@@ -143,45 +163,46 @@ export default class Server {
         });
     }
 
-    sendInChannel(msg, channel, server=this) {
+    sendInChannel(msg: string, channel: string, server=this) {
         // console.log('this is a', this)
-        for (const userID in server.users) {
-            const user = server.users[userID];
+        for (const [userID] of server.users.entries()) {
+            const user = server.users.get(userID) as User;
             if (user.channel == channel) user.socket.send(msg);
         }
     }
     
-    format(txt) {
-        txt = String(txt);
+    format(txt: string) {
         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);
-            }
-        }
+        txt = txt.replaceAll("$(userCount)$", [...this.users.entries()].length.toString());
+        // 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(),
-                            };
-                        })
-                    )}`
-                );
-            }
-        });
-    }
+    //TODO - finish event system, rewrite this
+    // 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(),
+    //                         };
+    //                     })
+    //                 )}`
+    //             );
+    //         }
+    //     });
+    // }
+    updateUsers() {}
 }
\ No newline at end of file