diff options
author | WlodekM <[email protected]> | 2024-07-02 15:59:55 +0300 |
---|---|---|
committer | WlodekM <[email protected]> | 2024-07-02 15:59:55 +0300 |
commit | 299eaa17fa5c390df1f8e525a66279fad45748d3 (patch) | |
tree | 73005a2e152fd8338bbd0c68dca05b88c0f8d196 | |
parent | bac2526c99506ecc9a2e04905e3d0307233e47f2 (diff) |
v1.1
-rw-r--r-- | commands.js | 51 | ||||
-rw-r--r-- | config.json | 6 | ||||
-rw-r--r-- | index.js | 65 | ||||
-rw-r--r-- | package.json | 1 |
4 files changed, 87 insertions, 36 deletions
diff --git a/commands.js b/commands.js new file mode 100644 index 0000000..9a34409 --- /dev/null +++ b/commands.js @@ -0,0 +1,51 @@ +export const commands = { + 'join': { + name: 'join', + aliases: [], + command: function({user, channels, args, sendInChannel}) { + if(args.length < 1) return user.socket.send("Error: You need to specify a channel (example: /join #home)."); + if(!args[0].startsWith("#")) return user.socket.send("Error: Channel not found, run /channels to see a list of channels."); + if(!channels.includes(args[0].replace("#", ""))) return user.socket.send("Error: Channel not found, run /channels to see a list of channels."); + sendInChannel(`${user.username} left #${user.channel}.`, user.channel) + user.channel = args[0].replace("#", ""); + sendInChannel(`${user.username} joined #${user.channel}!`, user.channel) + } + }, + 'channels': { + name: 'channels', + aliases: [], + command: function({user, channels}) { + user.socket.send(`Channels:\n${channels.map(ch => ` * #${ch}`).join("\n")}`) + } + }, + 'nick': { + name: 'nick', + aliases: ['nickname', 'name'], + command: function({user, users, args, sendInChannel}) { + if(args.length < 1) return user.socket.send("Error: You need to specify a nick (example: /nick WlodekM)."); + if(args[0].length < 3 ) return user.socket.send("Error: Nick too long."); + if(args[0].length > 20) return user.socket.send("Error: Nick too short."); + if(Object.values(users).find(usr => usr.username == args[0])) return user.socket.send("Error: Nick already used."); + sendInChannel(`${user.username} changed their nick to ${args[0]}!`, user.channel) + user.username = args[0]; + } + }, + 'users': { + name: 'users', + aliases: [], + command: function({user, users, args}) { + user.socket.send(`Users${args[0] != "global" ? ` in ${user.channel}` : ""}:\n${Object.values(users).filter(usr => (usr.channel == user.channel) || args[0] == "global").map(usr => ` * ${usr.username}`).join("\n")}`) + } + }, + 'help': { + name: 'help', + aliases: ['?'], + command: function({user, users, args, commands}) { + user.socket.send(`Commands available:\n${Object.values(commands).map(cmd => `* /${cmd.name} (Aliases: ${(cmd.aliases.join(", ")) || "<None>"})`).join("\n")}`) + } + }, +} + +export function register(cmd, data) { + commands[cmd] = data +} \ No newline at end of file diff --git a/config.json b/config.json new file mode 100644 index 0000000..9524704 --- /dev/null +++ b/config.json @@ -0,0 +1,6 @@ +{ + "name": "wsChat server", + "motd": "Welcome to $(serverName)$", + "max": 20, + "fullMessage": "Sorry, but the server is full right now, come back later" +} \ No newline at end of file diff --git a/index.js b/index.js index 2043219..ea5ac55 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,10 @@ import { WebSocketServer } from "ws"; import cuid from 'cuid'; import { getRandomInt } from "./lib.js" +import { commands } from "./commands.js"; +import fs from 'fs'; + +const config = JSON.parse(String(fs.readFileSync("config.json"))) const channels = ["home", "off-topic"] @@ -13,14 +17,25 @@ const users = {} function sendInChannel(msg, channel) { for (const userID in users) { const user = 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)$", config.name) + txt = txt.replaceAll("$(userCount)$", Object.keys(users).length) + txt = txt.replaceAll("$(max)$", config.max) + return txt +} + ws.on('connection', (socket, request) => { - // console.log(request, socket); + if (config.max && Object.keys(users).length >= config.max) { + socket.send(format(config.fullMessage ?? "Sorry, but the server is full right now, come back later")) + socket.close(1001, "Server full") + } let userID = cuid() - socket.send("Welcome to WlodekM's wsChat server!") + socket.send(format(config.motd)) let anonID = getRandomInt(0, 99999) users[userID] = { username: `Anonymous${"0".repeat(5 - anonID.length) + anonID.toString()}`, @@ -34,49 +49,27 @@ ws.on('connection', (socket, request) => { channel: 'home' } sendInChannel(`${users[userID].username} joined #${users[userID].channel}!`, users[userID].channel) - socket.on('close', function(code, reason) { + socket.on('close', function (code, reason) { sendInChannel(`${users[userID].username} left.`, users[userID].channel) delete users[userID] }) socket.on('message', function (rawData) { - if(rawData.toString().startsWith("/")) { + 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(`${users[userID].username} used /${command}`) - switch (command) { - case 'join': - if(args.length < 1) return socket.send("Error: You need to specify a channel (example: /join #home)."); - if(!args[0].startsWith("#")) return socket.send("Error: Channel not found, run /channels to see a list of channels."); - if(!channels.includes(args[0].replace("#", ""))) return socket.send("Error: Channel not found, run /channels to see a list of channels."); - sendInChannel(`${users[userID].username} left #${users[userID].channel}.`, users[userID].channel) - users[userID].channel = args[0].replace("#", ""); - sendInChannel(`${users[userID].username} joined #${users[userID].channel}!`, users[userID].channel) - break; - case 'channels': - socket.send(`Channels:\n${channels.map(ch => ` * #${ch}`).join("\n")}`) - break; - case 'name': - case 'nickname': - case 'nick': - if(args.length < 1) return socket.send("Error: You need to specify a nick (example: /nick WlodekM)."); - if(args[0].length < 3 ) return socket.send("Error: Nick too long."); - if(args[0].length > 20) return socket.send("Error: Nick too short."); - if(Object.values(users).find(usr => usr.username == args[0])) return socket.send("Error: Nick already used."); - sendInChannel(`${users[userID].username} changed their nick to ${args[0]}!`, users[userID].channel) - users[userID].username = args[0] - break; - case 'users': - socket.send(`Users${args[0] != "global" ? ` in ${users[userID].channel}` : ""}:\n${Object.values(users).filter(usr => (usr.channel == users[userID].channel) || args[0] == "global").map(ch => ` * ${ch}`).join("\n")}`) - break; - - default: - socket.send(`Error: Command "${command}" not found!`); - break; + if (!commandObj) return socket.send(`Error: Command "${command}" not found!`); + let user = users[userID] + try { + commandObj.command({ user, command, args, sendInChannel, channels, users, commands }) + } catch (error) { + user.socket.send(`Unexpected error ocurred while running the command`) } return } - if(rawData.length < 1) return socket.send("Error: message too short!") - if(rawData.length >= 2000) return socket.send("Error: message too long!") + if (rawData.length < 1) return socket.send("Error: message too short!") + if (rawData.length >= 2000) return socket.send("Error: message too long!") sendInChannel(`<${users[userID].username}> ${rawData}`, users[userID].channel) console.log(`(#${users[userID].channel}) <${users[userID].username}> ${rawData}`) }) diff --git a/package.json b/package.json index 28078ba..1c6f0b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "wschat", "description": "A simple IRC-like chat made using nodejs and webSockets", + "version": "1.1.0", "author": { "name": "WlodekM", "email": "[email protected]", |