import * as irc from "./lib/irc.js"; import { SERVER_BUFFER, BufferType } from "./state.js"; function getActiveClient(app) { var buf = app.state.buffers.get(app.state.activeBuffer); if (!buf) { return null; } return app.clients.get(buf.network); } const ban = { usage: "", description: "Bans a user from the channel", execute: (app, args) => { var nick = args[0]; if (!nick) { throw new Error("Missing nick"); } var activeBuffer = app.state.buffers.get(app.state.activeBuffer); if (!activeBuffer || !app.isChannel(activeBuffer.name)) { throw new Error("Not in a channel"); } var params = [activeBuffer.name, nick]; if (args.length > 1) { params.push(args.slice(1).join(" ")); } const client = getActiveClient(app); client.whois(nick).then((whois) => { if (whois === null) { throw new Error("No such nick"); }; const info = whois[irc.RPL_WHOISUSER].params; const user = info[2]; const host = info[3]; client.send({ command: "MODE", params: [ activeBuffer.name, "+b", `*!${user}@${host}` ]}); }); }, }; const join = { usage: "", description: "Join a channel", execute: (app, args) => { var channel = args[0]; if (!channel) { throw new Error("Missing channel name"); } app.open(channel); }, }; const kick = { usage: "", description: "Remove a user from the channel", execute: (app, args) => { var nick = args[0]; var activeBuffer = app.state.buffers.get(app.state.activeBuffer); if (!activeBuffer || !app.isChannel(activeBuffer.name)) { throw new Error("Not in a channel"); } var params = [activeBuffer.name, nick]; if (args.length > 1) { params.push(args.slice(1).join(" ")); } getActiveClient(app).send({ command: "KICK", params }); }, }; export default { "ban": ban, "buffer": { usage: "", description: "Switch to a buffer", execute: (app, args) => { var name = args[0]; for (var buf of app.state.buffers.values()) { if (buf.name === name) { app.switchBuffer(buf); return; } } throw new Error("Unknown buffer"); }, }, "close": { description: "Close the current buffer", execute: (app, args) => { var activeBuffer = app.state.buffers.get(app.state.activeBuffer); if (!activeBuffer || activeBuffer.type == BufferType.SERVER) { throw new Error("Not in a user or channel buffer"); } app.close(activeBuffer.id); }, }, "deop": { usage: "", description: "Removes operator status for a user on this channel", execute: (app, args) => { var nick = args[0]; if (!nick) { throw new Error("Missing nick"); } var activeBuffer = app.state.buffers.get(app.state.activeBuffer); if (!activeBuffer || !app.isChannel(activeBuffer.name)) { throw new Error("Not in a channel"); } getActiveClient(app).send({ command: "MODE", params: [ activeBuffer.name, "-o", user, ]}); }, }, "disconnect": { description: "Disconnect from the server", execute: (app, args) => { app.disconnect(); }, }, "help": { description: "Show help menu", execute: (app, args) => { app.openHelp(); }, }, "j": join, "join": join, "kick": kick, "kickban": { usage: "", description: "Bans a user and removes them from the channel", execute: (app, args) => { kick.execute(app, args); ban.execute(app, args); }, }, "me": { usage: "", description: "Send an action message to the current buffer", execute: (app, args) => { var action = args.join(" "); var activeBuffer = app.state.buffers.get(app.state.activeBuffer); if (!activeBuffer) { throw new Error("Not in a buffer"); } var text = `\x01ACTION ${action}\x01`; app.privmsg(activeBuffer.name, text); }, }, "mode": { usage: "[target] [mode args...]", description: "Change channel or user mode", execute: (app, args) => { var target = args[0]; if (target.startsWith("+") || target.startsWith("-")) { var activeBuffer = app.state.buffers.get(app.state.activeBuffer); if (!activeBuffer || !app.isChannel(activeBuffer.name)) { throw new Error("Not in a channel"); } args = [activeBuffer.name, ...args]; } getActiveClient(app).send({ command: "MODE", params: args }); }, }, "motd": { usage: "[server]", description: "Get the Message Of The Day", execute: (app, args) => { getActiveClient(app).send({ command: "MOTD", params: args }); }, }, "msg": { usage: " ", description: "Send a message to a nickname or a channel", execute: (app, args) => { var target = args[0]; var text = args.slice(1).join(" "); getActiveClient(app).send({ command: "PRIVMSG", params: [target, text] }); }, }, "nick": { usage: "", description: "Change current nickname", execute: (app, args) => { var newNick = args[0]; getActiveClient(app).send({ command: "NICK", params: [newNick] }); }, }, "notice": { usage: " ", description: "Send a notice to a nickname or a channel", execute: (app, args) => { var target = args[0]; var text = args.slice(1).join(" "); getActiveClient(app).send({ command: "NOTICE", params: [target, text] }); }, }, "op": { usage: "", description: "Gives a user operator status on this channel", execute: (app, args) => { var nick = args[0]; if (!nick) { throw new Error("Missing nick"); } var activeBuffer = app.state.buffers.get(app.state.activeBuffer); if (!activeBuffer || !app.isChannel(activeBuffer.name)) { throw new Error("Not in a channel"); } getActiveClient(app).send({ command: "MODE", params: [ activeBuffer.name, "+o", nick, ]}); }, }, "part": { usage: "[reason]", description: "Leave a channel", execute: (app, args) => { var reason = args.join(" "); var activeBuffer = app.state.buffers.get(app.state.activeBuffer); if (!activeBuffer || !app.isChannel(activeBuffer.name)) { throw new Error("Not in a channel"); } var params = [activeBuffer.name]; if (reason) { params.push(reason); } getActiveClient(app).send({ command: "PART", params }); }, }, "query": { usage: "", description: "Open a buffer to send messages to a nickname", execute: (app, args) => { var nick = args[0]; if (!nick) { throw new Error("Missing nickname"); } app.open(nick); }, }, "quit": { description: "Quit", execute: (app, args) => { app.close({ name: SERVER_BUFFER }); }, }, "quote": { usage: "", description: "Send a raw IRC command to the server", execute: (app, args) => { var msg; try { msg = irc.parseMessage(args.join(" ")); } catch (err) { throw new Error("Failed to parse IRC command: " + err.message); } getActiveClient(app).send(msg); }, }, "reconnect": { description: "Reconnect to the server", execute: (app, args) => { app.reconnect(); }, }, "setname": { usage: "", description: "Change current realname", execute: (app, args) => { var newRealname = args.join(" "); var client = getActiveClient(app); if (!client.enabledCaps["setname"]) { throw new Error("Server doesn't support changing the realname"); } client.send({ command: "SETNAME", params: [newRealname] }); }, }, "stats": { usage: " [server]", description: "Requests server statistics", execute: (app, args) => { var query = args[0]; if (!query) { throw new Error("Missing query"); } var params = [query]; if (args.length > 1) { params.push(args.slice(1).join(" ")); } getActiveClient(app).send({ command: "STATS", params }); }, }, "topic": { usage: "", description: "Change the topic of the current channel", execute: (app, args) => { var activeBuffer = app.state.buffers.get(app.state.activeBuffer); if (!activeBuffer || !app.isChannel(activeBuffer.name)) { throw new Error("Not in a channel"); } var params = [activeBuffer.name]; if (args.length > 0) { params.push(args.join(" ")); } getActiveClient(app).send({ command: "TOPIC", params }); }, }, "whois": { usage: "", description: "Retrieve information about a user", execute: (app, args) => { var nick = args[0]; if (!nick) { throw new Error("Missing nick"); } getActiveClient(app).whois(nick); }, }, };