2021-05-27 15:46:56 -04:00
|
|
|
import * as irc from "./lib/irc.js";
|
2021-03-03 03:58:09 -05:00
|
|
|
import { SERVER_BUFFER, BufferType } from "./state.js";
|
2020-07-13 11:22:24 -04:00
|
|
|
|
2021-01-22 11:36:53 -05:00
|
|
|
function getActiveClient(app) {
|
|
|
|
var buf = app.state.buffers.get(app.state.activeBuffer);
|
|
|
|
if (!buf) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return app.clients.get(buf.network);
|
|
|
|
}
|
|
|
|
|
2021-05-27 16:02:08 -04:00
|
|
|
const ban = {
|
|
|
|
usage: "<nick>",
|
|
|
|
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}`
|
|
|
|
]});
|
|
|
|
});
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2021-05-27 08:13:22 -04:00
|
|
|
const join = {
|
|
|
|
usage: "<name>",
|
|
|
|
description: "Join a channel",
|
|
|
|
execute: (app, args) => {
|
|
|
|
var channel = args[0];
|
|
|
|
if (!channel) {
|
|
|
|
throw new Error("Missing channel name");
|
|
|
|
}
|
2021-05-27 13:10:42 -04:00
|
|
|
app.open(channel);
|
2021-05-27 08:13:22 -04:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2021-05-27 16:02:08 -04:00
|
|
|
const kick = {
|
|
|
|
usage: "<nick>",
|
|
|
|
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 });
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2020-07-13 11:22:24 -04:00
|
|
|
export default {
|
2021-05-27 16:02:08 -04:00
|
|
|
"ban": ban,
|
2021-03-08 11:25:00 -05:00
|
|
|
"buffer": {
|
|
|
|
usage: "<name>",
|
|
|
|
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;
|
|
|
|
}
|
2021-03-07 15:06:26 -05:00
|
|
|
}
|
2021-03-08 11:25:00 -05:00
|
|
|
throw new Error("Unknown buffer");
|
|
|
|
},
|
2020-07-13 11:22:24 -04:00
|
|
|
},
|
2021-03-08 11:25:00 -05:00
|
|
|
"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);
|
|
|
|
},
|
2020-07-13 11:22:24 -04:00
|
|
|
},
|
2021-05-27 13:48:49 -04:00
|
|
|
"deop": {
|
|
|
|
usage: "<nick>",
|
|
|
|
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,
|
|
|
|
]});
|
|
|
|
},
|
|
|
|
},
|
2021-03-08 11:25:00 -05:00
|
|
|
"disconnect": {
|
|
|
|
description: "Disconnect from the server",
|
|
|
|
execute: (app, args) => {
|
|
|
|
app.disconnect();
|
|
|
|
},
|
2021-03-07 15:06:26 -05:00
|
|
|
},
|
2021-03-08 11:25:00 -05:00
|
|
|
"help": {
|
|
|
|
description: "Show help menu",
|
|
|
|
execute: (app, args) => {
|
|
|
|
app.openHelp();
|
|
|
|
},
|
2021-03-08 11:05:48 -05:00
|
|
|
},
|
2021-05-27 08:13:22 -04:00
|
|
|
"j": join,
|
|
|
|
"join": join,
|
2021-05-27 16:02:08 -04:00
|
|
|
"kick": kick,
|
|
|
|
"kickban": {
|
|
|
|
usage: "<target>",
|
|
|
|
description: "Bans a user and removes them from the channel",
|
2021-05-26 19:28:24 -04:00
|
|
|
execute: (app, args) => {
|
2021-05-27 16:02:08 -04:00
|
|
|
kick.execute(app, args);
|
|
|
|
ban.execute(app, args);
|
2021-05-26 19:28:24 -04:00
|
|
|
},
|
|
|
|
},
|
2021-03-08 11:25:00 -05:00
|
|
|
"me": {
|
|
|
|
usage: "<action>",
|
|
|
|
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);
|
|
|
|
},
|
2020-07-13 11:22:24 -04:00
|
|
|
},
|
2021-05-23 05:41:04 -04:00
|
|
|
"mode": {
|
2021-05-28 05:17:37 -04:00
|
|
|
usage: "[target] <modes> [mode args...]",
|
2021-05-23 05:41:04 -04:00
|
|
|
description: "Change channel or user mode",
|
|
|
|
execute: (app, args) => {
|
2021-05-27 09:37:09 -04:00
|
|
|
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];
|
|
|
|
}
|
2021-05-23 05:41:04 -04:00
|
|
|
getActiveClient(app).send({ command: "MODE", params: args });
|
|
|
|
},
|
|
|
|
},
|
2021-05-28 05:17:37 -04:00
|
|
|
"motd": {
|
|
|
|
usage: "[server]",
|
|
|
|
description: "Get the Message Of The Day",
|
|
|
|
execute: (app, args) => {
|
|
|
|
getActiveClient(app).send({ command: "MOTD", params: args });
|
|
|
|
},
|
|
|
|
},
|
2021-03-08 11:25:00 -05:00
|
|
|
"msg": {
|
|
|
|
usage: "<target> <message>",
|
|
|
|
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] });
|
|
|
|
},
|
2021-03-07 15:06:26 -05:00
|
|
|
},
|
2021-03-08 11:25:00 -05:00
|
|
|
"nick": {
|
|
|
|
usage: "<nick>",
|
|
|
|
description: "Change current nickname",
|
|
|
|
execute: (app, args) => {
|
|
|
|
var newNick = args[0];
|
|
|
|
getActiveClient(app).send({ command: "NICK", params: [newNick] });
|
|
|
|
},
|
2020-07-13 11:22:24 -04:00
|
|
|
},
|
2021-03-08 11:25:00 -05:00
|
|
|
"notice": {
|
|
|
|
usage: "<target> <message>",
|
|
|
|
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] });
|
|
|
|
},
|
2020-08-13 05:04:39 -04:00
|
|
|
},
|
2021-05-27 13:48:49 -04:00
|
|
|
"op": {
|
|
|
|
usage: "<nick>",
|
|
|
|
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,
|
|
|
|
]});
|
|
|
|
},
|
|
|
|
},
|
2021-03-08 11:25:00 -05:00
|
|
|
"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 });
|
|
|
|
},
|
2021-03-07 15:06:26 -05:00
|
|
|
},
|
2021-03-08 11:25:00 -05:00
|
|
|
"query": {
|
|
|
|
usage: "<nick>",
|
|
|
|
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);
|
|
|
|
},
|
2021-03-07 15:06:26 -05:00
|
|
|
},
|
2021-03-08 11:25:00 -05:00
|
|
|
"quit": {
|
|
|
|
description: "Quit",
|
|
|
|
execute: (app, args) => {
|
|
|
|
app.close({ name: SERVER_BUFFER });
|
|
|
|
},
|
2021-03-07 15:06:26 -05:00
|
|
|
},
|
2021-05-27 05:22:34 -04:00
|
|
|
"quote": {
|
|
|
|
usage: "<command>",
|
|
|
|
description: "Send a raw IRC command to the server",
|
|
|
|
execute: (app, args) => {
|
|
|
|
var msg;
|
|
|
|
try {
|
|
|
|
msg = irc.parseMessage(args.join(" "));
|
|
|
|
} catch (err) {
|
2021-05-27 05:26:42 -04:00
|
|
|
throw new Error("Failed to parse IRC command: " + err.message);
|
2021-05-27 05:22:34 -04:00
|
|
|
}
|
|
|
|
getActiveClient(app).send(msg);
|
|
|
|
},
|
|
|
|
},
|
2021-03-08 11:25:00 -05:00
|
|
|
"reconnect": {
|
|
|
|
description: "Reconnect to the server",
|
|
|
|
execute: (app, args) => {
|
|
|
|
app.reconnect();
|
|
|
|
},
|
2020-07-13 11:22:24 -04:00
|
|
|
},
|
2021-05-25 14:22:21 -04:00
|
|
|
"setname": {
|
|
|
|
usage: "<realname>",
|
|
|
|
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] });
|
|
|
|
},
|
|
|
|
},
|
2021-05-27 08:36:46 -04:00
|
|
|
"stats": {
|
|
|
|
usage: "<query> [<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 });
|
|
|
|
},
|
|
|
|
},
|
2021-03-08 11:25:00 -05:00
|
|
|
"topic": {
|
|
|
|
usage: "<topic>",
|
|
|
|
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 });
|
|
|
|
},
|
2020-07-13 11:22:24 -04:00
|
|
|
},
|
2021-05-27 16:02:07 -04:00
|
|
|
"whois": {
|
|
|
|
usage: "<nick>",
|
|
|
|
description: "Retrieve information about a user",
|
|
|
|
execute: (app, args) => {
|
|
|
|
var nick = args[0];
|
|
|
|
if (!nick) {
|
|
|
|
throw new Error("Missing nick");
|
|
|
|
}
|
|
|
|
getActiveClient(app).whois(nick);
|
|
|
|
},
|
|
|
|
},
|
2020-07-13 11:22:24 -04:00
|
|
|
};
|