diff options
Diffstat (limited to 'server.ts')
-rw-r--r-- | server.ts | 143 |
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 |