refactor everything out of one file, add channel rememberance
This commit is contained in:
parent
e8860722f0
commit
adf3e5fe4d
17 changed files with 661 additions and 686 deletions
|
@ -26,5 +26,6 @@ module.exports = {
|
||||||
"require-atomic-updates": OFF,
|
"require-atomic-updates": OFF,
|
||||||
},
|
},
|
||||||
globals: {
|
globals: {
|
||||||
|
comcord: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -56,4 +56,4 @@ You **MUST** grant your bot all Privileged Gateway Intents.
|
||||||
- [ ] Default guild/channel
|
- [ ] Default guild/channel
|
||||||
- [ ] Threads
|
- [ ] Threads
|
||||||
- [ ] Not have the token just be in argv
|
- [ ] Not have the token just be in argv
|
||||||
- [ ] Not have everything in one file
|
- [x] Not have everything in one file
|
||||||
|
|
5
src/commands/clear.js
Normal file
5
src/commands/clear.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
const {addCommand} = require("../lib/command");
|
||||||
|
|
||||||
|
addCommand("c", "clear", function () {
|
||||||
|
console.clear();
|
||||||
|
});
|
26
src/commands/emote.js
Normal file
26
src/commands/emote.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
const {addCommand} = require("../lib/command");
|
||||||
|
const {startPrompt} = require("../lib/prompt");
|
||||||
|
|
||||||
|
addCommand("e", "emote", function () {
|
||||||
|
if (!comcord.state.currentChannel) {
|
||||||
|
console.log("<not in a channel>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
startPrompt(":emote> ", async function (input) {
|
||||||
|
if (input == "") {
|
||||||
|
console.log("<no message sent>");
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
process.stdout.write("\n");
|
||||||
|
await comcord.client.createMessage(
|
||||||
|
comcord.state.currentChannel,
|
||||||
|
`*${input}*`
|
||||||
|
);
|
||||||
|
console.log(`<${comcord.client.user.username} ${input}>`);
|
||||||
|
} catch (err) {
|
||||||
|
console.log("<failed to send message: " + err.message + ">");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
29
src/commands/help.js
Normal file
29
src/commands/help.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
const chalk = require("chalk");
|
||||||
|
|
||||||
|
const {addCommand} = require("../lib/command");
|
||||||
|
|
||||||
|
addCommand("h", "command help", function () {
|
||||||
|
console.log("\nCOMcord (c)left 2022\n");
|
||||||
|
|
||||||
|
const keys = Object.keys(comcord.commands);
|
||||||
|
keys.sort((a, b) => a.localeCompare(b));
|
||||||
|
|
||||||
|
let index = 0;
|
||||||
|
for (const key of keys) {
|
||||||
|
const desc = comcord.commands[key].name;
|
||||||
|
const length = ` ${key} - ${desc}`.length;
|
||||||
|
|
||||||
|
process.stdout.write(
|
||||||
|
" " +
|
||||||
|
chalk.bold.yellow(key) +
|
||||||
|
chalk.reset(" - " + desc) +
|
||||||
|
" ".repeat(Math.abs(25 - length))
|
||||||
|
);
|
||||||
|
|
||||||
|
index++;
|
||||||
|
if (index % 3 == 0) process.stdout.write("\n");
|
||||||
|
}
|
||||||
|
if (index % 3 != 0) process.stdout.write("\n");
|
||||||
|
|
||||||
|
console.log("\nTo begin TALK MODE, press [SPACE]\n");
|
||||||
|
});
|
72
src/commands/history.js
Normal file
72
src/commands/history.js
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
const {addCommand} = require("../lib/command");
|
||||||
|
const {startPrompt} = require("../lib/prompt");
|
||||||
|
const {processMessage} = require("../lib/messages");
|
||||||
|
|
||||||
|
async function getHistory(limit = 20) {
|
||||||
|
if (!comcord.state.currentChannel) {
|
||||||
|
console.log("<not in a channel>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const messages = await comcord.client.getMessages(
|
||||||
|
comcord.state.currentChannel,
|
||||||
|
{limit}
|
||||||
|
);
|
||||||
|
messages.reverse();
|
||||||
|
|
||||||
|
console.log("--Beginning-Review".padEnd(72, "-"));
|
||||||
|
|
||||||
|
for (const msg of messages) {
|
||||||
|
if (msg.content.indexOf("\n") > -1) {
|
||||||
|
const lines = msg.content.split("\n");
|
||||||
|
for (const index in lines) {
|
||||||
|
const line = lines[index];
|
||||||
|
processMessage({
|
||||||
|
name: msg.author.username,
|
||||||
|
bot: msg.author.bot,
|
||||||
|
content:
|
||||||
|
line +
|
||||||
|
(msg.editedTimestamp != null && index == lines.length - 1
|
||||||
|
? " (edited)"
|
||||||
|
: ""),
|
||||||
|
attachments: index == lines.length - 1 ? msg.attachments : null,
|
||||||
|
reply: index == 0 ? msg.referencedMessage : null,
|
||||||
|
noColor: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
processMessage({
|
||||||
|
name: msg.author.username,
|
||||||
|
bot: msg.author.bot,
|
||||||
|
content: msg.content + (msg.editedTimestamp != null ? " (edited)" : ""),
|
||||||
|
attachments: msg.attachments,
|
||||||
|
reply: msg.referencedMessage,
|
||||||
|
noColor: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("--Review-Complete".padEnd(73, "-"));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getExtendedHistory(input) {
|
||||||
|
input = parseInt(input);
|
||||||
|
if (isNaN(input)) {
|
||||||
|
console.log("<not a number>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await getHistory(input);
|
||||||
|
} catch (err) {
|
||||||
|
console.log("<failed to get history: " + err.message + ">");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addCommand("r", "channel history", getHistory);
|
||||||
|
addCommand("R", "extended history", function () {
|
||||||
|
startPrompt(":lines> ", async function (input) {
|
||||||
|
process.stdout.write("\n");
|
||||||
|
await getExtendedHistory(input);
|
||||||
|
});
|
||||||
|
});
|
62
src/commands/listChannels.js
Normal file
62
src/commands/listChannels.js
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
const Eris = require("eris");
|
||||||
|
|
||||||
|
const {addCommand} = require("../lib/command");
|
||||||
|
|
||||||
|
function listChannels() {
|
||||||
|
if (!comcord.state.currentGuild) {
|
||||||
|
console.log("<not in a guild>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let longest = 0;
|
||||||
|
let longestTopic = 0;
|
||||||
|
const guild = comcord.client.guilds.get(comcord.state.currentGuild);
|
||||||
|
const channels = [...guild.channels.values()].filter((c) => c.type == 0);
|
||||||
|
channels.sort((a, b) => a.position - b.position);
|
||||||
|
|
||||||
|
for (const channel of channels) {
|
||||||
|
const perms = channel.permissionsOf(comcord.client.user.id);
|
||||||
|
const private = !perms.has(Eris.Constants.Permissions.readMessages);
|
||||||
|
|
||||||
|
if (channel.name.length + (private ? 1 : 0) > longest)
|
||||||
|
longest = Math.min(25, channel.name.length + (private ? 1 : 0));
|
||||||
|
if (channel.topic != null && channel.topic.length > longestTopic)
|
||||||
|
longestTopic = channel.topic.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("");
|
||||||
|
console.log(
|
||||||
|
" " +
|
||||||
|
"channel-name".padStart(longest, " ") +
|
||||||
|
" " +
|
||||||
|
"topic".padStart(Math.min(80 - (longest + 5), longestTopic), " ")
|
||||||
|
);
|
||||||
|
console.log("-".repeat(80));
|
||||||
|
for (const channel of channels) {
|
||||||
|
const topic =
|
||||||
|
channel.topic != null ? channel.topic.replace(/\n/g, " ") : "";
|
||||||
|
const perms = channel.permissionsOf(comcord.client.user.id);
|
||||||
|
const private = !perms.has(Eris.Constants.Permissions.readMessages);
|
||||||
|
|
||||||
|
const name = (private ? "*" : "") + channel.name;
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
" " +
|
||||||
|
(name.length > 24 ? name.substring(0, 24) + "\u2026" : name).padStart(
|
||||||
|
longest,
|
||||||
|
" "
|
||||||
|
) +
|
||||||
|
" " +
|
||||||
|
(topic.length > 80 - longest + 9
|
||||||
|
? topic.substring(0, 79 - (longest + 5)) + "\u2026"
|
||||||
|
: topic.padStart(Math.min(80 - (longest + 5), longestTopic), " "))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
console.log("");
|
||||||
|
}
|
||||||
|
|
||||||
|
addCommand("l", "list channels", listChannels);
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
listChannels,
|
||||||
|
};
|
34
src/commands/listGuilds.js
Normal file
34
src/commands/listGuilds.js
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
const {addCommand} = require("../lib/command");
|
||||||
|
|
||||||
|
function listGuilds() {
|
||||||
|
let longest = 0;
|
||||||
|
const guilds = [];
|
||||||
|
|
||||||
|
for (const guild of comcord.client.guilds.values()) {
|
||||||
|
if (guild.name.length > longest) longest = guild.name.length;
|
||||||
|
|
||||||
|
const online = [...guild.members.values()].filter((m) => m.status).length;
|
||||||
|
guilds.push({name: guild.name, members: guild.memberCount, online});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("");
|
||||||
|
console.log(" " + "guild-name".padStart(longest, " ") + " online total");
|
||||||
|
console.log("-".repeat(80));
|
||||||
|
for (const guild of guilds) {
|
||||||
|
console.log(
|
||||||
|
" " +
|
||||||
|
guild.name.padStart(longest, " ") +
|
||||||
|
" " +
|
||||||
|
guild.online.toString().padStart(6, " ") +
|
||||||
|
" " +
|
||||||
|
guild.members.toString().padStart(5, " ")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
console.log("");
|
||||||
|
}
|
||||||
|
|
||||||
|
addCommand("L", "list guilds", listGuilds);
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
listGuilds,
|
||||||
|
};
|
86
src/commands/listUsers.js
Normal file
86
src/commands/listUsers.js
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
const chalk = require("chalk");
|
||||||
|
|
||||||
|
const {addCommand} = require("../lib/command");
|
||||||
|
|
||||||
|
function getStatus(status) {
|
||||||
|
let color;
|
||||||
|
switch (status) {
|
||||||
|
case "online":
|
||||||
|
color = chalk.bold.green;
|
||||||
|
break;
|
||||||
|
case "idle":
|
||||||
|
color = chalk.bold.yellow;
|
||||||
|
break;
|
||||||
|
case "dnd":
|
||||||
|
color = chalk.bold.red;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
color = chalk.bold;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return color(" \u2022 ");
|
||||||
|
}
|
||||||
|
|
||||||
|
function listUsers() {
|
||||||
|
if (!comcord.state.currentGuild) {
|
||||||
|
console.log("<not in a guild>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!comcord.state.currentChannel) {
|
||||||
|
console.log("<not in a channel>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const guild = comcord.client.guilds.get(comcord.state.currentGuild);
|
||||||
|
const channel = guild.channels.get(comcord.state.currentChannel);
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`\n[you are in '${guild.name}' in '${channel.name}' among ${guild.memberCount}]\n`
|
||||||
|
);
|
||||||
|
|
||||||
|
const online = [...guild.members.values()].filter((m) => m.status);
|
||||||
|
online.sort((a, b) => a.name - b.name);
|
||||||
|
|
||||||
|
let longest = 0;
|
||||||
|
for (const member of online) {
|
||||||
|
const name = member.user.username + "#" + member.user.discriminator;
|
||||||
|
if (name.length + 3 > longest) longest = name.length + 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
const columns = Math.ceil(process.stdout.columns / longest);
|
||||||
|
|
||||||
|
let index = 0;
|
||||||
|
for (const member of online) {
|
||||||
|
const name = member.user.username + "#" + member.user.discriminator;
|
||||||
|
const status = getStatus(member.status);
|
||||||
|
const nameAndStatus = chalk.reset(name) + status;
|
||||||
|
|
||||||
|
index++;
|
||||||
|
process.stdout.write(
|
||||||
|
nameAndStatus +
|
||||||
|
" ".repeat(
|
||||||
|
index % columns == 0 ? 0 : Math.abs(longest - (name.length + 3))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (index % columns == 0) process.stdout.write("\n");
|
||||||
|
}
|
||||||
|
if (index % columns != 0) process.stdout.write("\n");
|
||||||
|
console.log("");
|
||||||
|
|
||||||
|
if (channel.topic != null) {
|
||||||
|
console.log("--Topic".padEnd(80, "-"));
|
||||||
|
console.log(channel.topic);
|
||||||
|
console.log("-".repeat(80));
|
||||||
|
console.log("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!comcord.commands.w) {
|
||||||
|
addCommand("w", "who is in guild", listUsers);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
listUsers,
|
||||||
|
};
|
6
src/commands/quit.js
Normal file
6
src/commands/quit.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
const {addCommand} = require("../lib/command");
|
||||||
|
|
||||||
|
addCommand("q", "quit comcord", function () {
|
||||||
|
comcord.client.disconnect(false);
|
||||||
|
process.exit(0);
|
||||||
|
});
|
35
src/commands/send.js
Normal file
35
src/commands/send.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
const chalk = require("chalk");
|
||||||
|
|
||||||
|
const {startPrompt} = require("../lib/prompt");
|
||||||
|
|
||||||
|
function sendMode() {
|
||||||
|
if (!comcord.state.currentChannel) {
|
||||||
|
console.log("<not in a channel>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
startPrompt(
|
||||||
|
chalk.bold.cyan(`[${comcord.client.user.username}]`) +
|
||||||
|
" ".repeat(
|
||||||
|
comcord.state.nameLength - (comcord.client.user.username.length + 2)
|
||||||
|
) +
|
||||||
|
chalk.reset(" "),
|
||||||
|
async function (input) {
|
||||||
|
if (input == "") {
|
||||||
|
console.log("<no message sent>");
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
process.stdout.write("\n");
|
||||||
|
await comcord.client.createMessage(
|
||||||
|
comcord.state.currentChannel,
|
||||||
|
input
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
console.log("<failed to send message: " + err.message + ">");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {sendMode};
|
41
src/commands/switchChannel.js
Normal file
41
src/commands/switchChannel.js
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
const {addCommand} = require("../lib/command");
|
||||||
|
const {startPrompt} = require("../lib/prompt");
|
||||||
|
|
||||||
|
const {listUsers} = require("./listUsers");
|
||||||
|
|
||||||
|
function switchChannel(input) {
|
||||||
|
if (input == "") {
|
||||||
|
listUsers();
|
||||||
|
comcord.state.channelSwitch = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let target;
|
||||||
|
|
||||||
|
const guild = comcord.client.guilds.get(comcord.state.currentGuild);
|
||||||
|
const channels = [...guild.channels.values()].filter((c) => c.type == 0);
|
||||||
|
channels.sort((a, b) => a.position - b.position);
|
||||||
|
|
||||||
|
for (const channel of channels) {
|
||||||
|
if (channel.name.toLowerCase().indexOf(input.toLowerCase()) > -1) {
|
||||||
|
target = channel.id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == null) {
|
||||||
|
console.log("<channel not found>");
|
||||||
|
} else {
|
||||||
|
comcord.state.currentChannel = target;
|
||||||
|
comcord.state.lastChannel.set(comcord.state.currentGuild, target);
|
||||||
|
|
||||||
|
listUsers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addCommand("g", "goto channel", function () {
|
||||||
|
if (!comcord.state.currentGuild) {
|
||||||
|
console.log("<not in a guild>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
startPrompt(":channel> ", switchChannel);
|
||||||
|
});
|
51
src/commands/switchGuild.js
Normal file
51
src/commands/switchGuild.js
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
const {addCommand} = require("../lib/command");
|
||||||
|
const {startPrompt} = require("../lib/prompt");
|
||||||
|
|
||||||
|
const {listChannels} = require("./listChannels");
|
||||||
|
const {listUsers} = require("./listUsers");
|
||||||
|
|
||||||
|
function findTopChannel(guildId) {
|
||||||
|
const guild = comcord.client.guilds.get(guildId);
|
||||||
|
const channels = [...guild.channels.values()].filter((c) => c.type == 0);
|
||||||
|
channels.sort((a, b) => a.position - b.position);
|
||||||
|
|
||||||
|
return channels[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchGuild(input) {
|
||||||
|
if (input == "") {
|
||||||
|
listChannels();
|
||||||
|
listUsers();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let target;
|
||||||
|
|
||||||
|
for (const guild of comcord.client.guilds.values()) {
|
||||||
|
if (guild.name.toLowerCase().indexOf(input.toLowerCase()) > -1) {
|
||||||
|
target = guild.id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == null) {
|
||||||
|
console.log("<guild not found>");
|
||||||
|
} else {
|
||||||
|
comcord.state.currentGuild = target;
|
||||||
|
// TODO: store last visited channel and switch to it if we've been to this guild before
|
||||||
|
if (!comcord.state.lastChannel.has(target)) {
|
||||||
|
const topChannel = findTopChannel(target);
|
||||||
|
comcord.state.currentChannel = topChannel.id;
|
||||||
|
comcord.state.lastChannel.set(target, topChannel.id);
|
||||||
|
} else {
|
||||||
|
comcord.state.currentChannel = comcord.state.lastChannel.get(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
listChannels();
|
||||||
|
listUsers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addCommand("G", "goto guild", function () {
|
||||||
|
startPrompt(":guild> ", switchGuild);
|
||||||
|
});
|
738
src/index.js
738
src/index.js
|
@ -2,46 +2,41 @@ const Eris = require("eris");
|
||||||
const chalk = require("chalk");
|
const chalk = require("chalk");
|
||||||
|
|
||||||
const token = process.argv[2];
|
const token = process.argv[2];
|
||||||
const stdin = process.stdin;
|
|
||||||
const stdout = process.stdout;
|
|
||||||
|
|
||||||
stdin.setRawMode(true);
|
global.comcord = {
|
||||||
stdin.resume();
|
state: {
|
||||||
stdin.setEncoding("utf8");
|
currentGuild: null,
|
||||||
|
currentChannel: null,
|
||||||
let currentGuild,
|
nameLength: 2,
|
||||||
currentChannel,
|
inPrompt: false,
|
||||||
inSendMode = false,
|
messageQueue: [],
|
||||||
inEmoteMode = false,
|
lastChannel: new Map(),
|
||||||
guildSwitch = false,
|
},
|
||||||
channelSwitch = false,
|
commands: {},
|
||||||
extendedHistory = false,
|
|
||||||
nameLength = 2;
|
|
||||||
|
|
||||||
const messageQueue = [];
|
|
||||||
|
|
||||||
const commands = {
|
|
||||||
q: "quit comcord",
|
|
||||||
e: "emote",
|
|
||||||
g: "goto a channel",
|
|
||||||
G: "goto a guild",
|
|
||||||
l: "list channels",
|
|
||||||
L: "list guilds",
|
|
||||||
w: "who is in guild",
|
|
||||||
f: "finger",
|
|
||||||
r: "channel history",
|
|
||||||
R: "extended history",
|
|
||||||
h: "command help",
|
|
||||||
c: "clear",
|
|
||||||
"<": "surf backwards",
|
|
||||||
">": "surf forwards",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const client = new Eris("Bot " + token, {
|
const client = new Eris("Bot " + token, {
|
||||||
defaultImageFormat: "png",
|
defaultImageFormat: "png",
|
||||||
defaultImageSize: 1024,
|
defaultImageSize: 1024,
|
||||||
intents: Eris.Constants.Intents.all,
|
intents: Eris.Constants.Intents.all,
|
||||||
});
|
});
|
||||||
|
comcord.client = client;
|
||||||
|
|
||||||
|
const {finalizePrompt} = require("./lib/prompt");
|
||||||
|
const {processMessage, processQueue} = require("./lib/messages");
|
||||||
|
|
||||||
|
require("./commands/quit");
|
||||||
|
require("./commands/clear");
|
||||||
|
require("./commands/help");
|
||||||
|
const {sendMode} = require("./commands/send");
|
||||||
|
require("./commands/emote");
|
||||||
|
const {listGuilds} = require("./commands/listGuilds");
|
||||||
|
require("./commands/switchGuild"); // loads listChannels and listUsers
|
||||||
|
require("./commands/switchChannel"); //loads listUsers
|
||||||
|
require("./commands/history"); // includes extended history
|
||||||
|
|
||||||
|
process.stdin.setRawMode(true);
|
||||||
|
process.stdin.resume();
|
||||||
|
process.stdin.setEncoding("utf8");
|
||||||
|
|
||||||
client.once("ready", function () {
|
client.once("ready", function () {
|
||||||
console.log(
|
console.log(
|
||||||
|
@ -50,125 +45,17 @@ client.once("ready", function () {
|
||||||
`${client.user.username}#${client.user.discriminator} (${client.user.id})`
|
`${client.user.username}#${client.user.discriminator} (${client.user.id})`
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
nameLength = client.user.username.length + 2;
|
comcord.state.nameLength = client.user.username.length + 2;
|
||||||
|
|
||||||
listGuilds();
|
listGuilds();
|
||||||
});
|
});
|
||||||
|
|
||||||
function processMessage({
|
|
||||||
name,
|
|
||||||
content,
|
|
||||||
bot,
|
|
||||||
attachments,
|
|
||||||
reply,
|
|
||||||
isHistory = false,
|
|
||||||
}) {
|
|
||||||
if (name.length + 2 > nameLength) nameLength = name.length + 2;
|
|
||||||
|
|
||||||
if (reply) {
|
|
||||||
const nameColor = reply.author.bot ? chalk.bold.yellow : chalk.bold.cyan;
|
|
||||||
|
|
||||||
const headerLength = 5 + reply.author.username.length;
|
|
||||||
const length = headerLength + reply.content.length;
|
|
||||||
|
|
||||||
if (isHistory) {
|
|
||||||
console.log(
|
|
||||||
` \u250d [${reply.author.username}] ${
|
|
||||||
length > 79
|
|
||||||
? reply.content.substring(0, length - headerLength) + "\u2026"
|
|
||||||
: reply.content
|
|
||||||
}`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
console.log(
|
|
||||||
chalk.bold.white(" \u250d ") +
|
|
||||||
nameColor(`[${reply.author.username}] `) +
|
|
||||||
chalk.reset(
|
|
||||||
`${
|
|
||||||
length > 79
|
|
||||||
? reply.content.substring(0, length - headerLength) + "\u2026"
|
|
||||||
: reply.content
|
|
||||||
}`
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
(content.startsWith("*") && content.endsWith("*")) ||
|
|
||||||
(content.startsWith("_") && content.endsWith("_"))
|
|
||||||
) {
|
|
||||||
if (isHistory) {
|
|
||||||
console.log(`<${name} ${content.substring(1, content.length - 1)}>`);
|
|
||||||
} else {
|
|
||||||
console.log(
|
|
||||||
chalk.bold.green(
|
|
||||||
`<${name} ${content.substring(1, content.length - 1)}>`
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (isHistory) {
|
|
||||||
console.log(
|
|
||||||
`[${name}]${" ".repeat(nameLength - (name.length + 2))} ${content}`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
const nameColor = bot ? chalk.bold.yellow : chalk.bold.cyan;
|
|
||||||
|
|
||||||
// TODO: markdown
|
|
||||||
console.log(
|
|
||||||
nameColor(`[${name}]`) +
|
|
||||||
" ".repeat(nameLength - (name.length + 2)) +
|
|
||||||
chalk.reset(" " + content)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attachments) {
|
|
||||||
for (const attachment of attachments) {
|
|
||||||
if (isHistory) {
|
|
||||||
console.log(`<attachment: ${attachment.url} >`);
|
|
||||||
} else {
|
|
||||||
console.log(chalk.bold.yellow(`<attachment: ${attachment.url} >`));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function processQueue() {
|
|
||||||
for (const msg of messageQueue) {
|
|
||||||
if (msg.content.indexOf("\n") > -1) {
|
|
||||||
const lines = msg.content.split("\n");
|
|
||||||
for (const index in lines) {
|
|
||||||
const line = lines[index];
|
|
||||||
processMessage({
|
|
||||||
name: msg.author.username,
|
|
||||||
bot: msg.author.bot,
|
|
||||||
content: line,
|
|
||||||
attachments: index == lines.length - 1 ? msg.attachments : [],
|
|
||||||
reply: index == 0 ? msg.referencedMessage : null,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
processMessage({
|
|
||||||
name: msg.author.username,
|
|
||||||
bot: msg.author.bot,
|
|
||||||
content: msg.content,
|
|
||||||
attachments: msg.attachments,
|
|
||||||
reply: msg.referencedMessage,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
messageQueue.splice(0, messageQueue.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
client.on("messageCreate", function (msg) {
|
client.on("messageCreate", function (msg) {
|
||||||
if (msg.author.id === client.user.id) return;
|
if (msg.author.id === client.user.id) return;
|
||||||
|
|
||||||
if (msg.channel.id == currentChannel) {
|
if (msg.channel.id == comcord.state.currentChannel) {
|
||||||
if (inSendMode || inEmoteMode) {
|
if (comcord.state.inPrompt) {
|
||||||
messageQueue.push(msg);
|
comcord.state.messageQueue.push(msg);
|
||||||
} else {
|
} else {
|
||||||
if (msg.content.indexOf("\n") > -1) {
|
if (msg.content.indexOf("\n") > -1) {
|
||||||
const lines = msg.content.split("\n");
|
const lines = msg.content.split("\n");
|
||||||
|
@ -197,11 +84,11 @@ client.on("messageCreate", function (msg) {
|
||||||
client.on("messageUpdate", function (msg, old) {
|
client.on("messageUpdate", function (msg, old) {
|
||||||
if (msg.author.id === client.user.id) return;
|
if (msg.author.id === client.user.id) return;
|
||||||
|
|
||||||
if (msg.channel.id == currentChannel) {
|
if (msg.channel.id == comcord.state.currentChannel) {
|
||||||
if (msg.content == old.content) return;
|
if (msg.content == old.content) return;
|
||||||
|
|
||||||
if (inSendMode || inEmoteMode) {
|
if (comcord.state.inPrompt) {
|
||||||
messageQueue.push(msg);
|
comcord.state.messageQueue.push(msg);
|
||||||
} else {
|
} else {
|
||||||
if (msg.content.indexOf("\n") > -1) {
|
if (msg.content.indexOf("\n") > -1) {
|
||||||
const lines = msg.content.split("\n");
|
const lines = msg.content.split("\n");
|
||||||
|
@ -228,551 +115,32 @@ client.on("messageUpdate", function (msg, old) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let toSend = "";
|
process.stdin.on("data", async function (key) {
|
||||||
async function setupSendMode() {
|
if (comcord.state.inPrompt) {
|
||||||
inSendMode = true;
|
|
||||||
toSend = "";
|
|
||||||
stdout.write(
|
|
||||||
chalk.bold.cyan(`[${client.user.username}]`) +
|
|
||||||
" ".repeat(nameLength - (client.user.username.length + 2)) +
|
|
||||||
chalk.reset(" ")
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
await client.guilds
|
|
||||||
.get(currentGuild)
|
|
||||||
.channels.get(currentChannel)
|
|
||||||
.sendTyping();
|
|
||||||
} catch (err) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async function sendMessage() {
|
|
||||||
toSend = toSend.trim();
|
|
||||||
if (toSend === "") {
|
|
||||||
stdout.write("<no message sent>\n");
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
stdout.write("\n");
|
|
||||||
await client.createMessage(currentChannel, toSend);
|
|
||||||
} catch (err) {
|
|
||||||
console.log("<failed to send message: " + err.message + ">");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inSendMode = false;
|
|
||||||
processQueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
function showHelp() {
|
|
||||||
console.log("\nCOMcord (c)left 2022\n");
|
|
||||||
|
|
||||||
const keys = Object.keys(commands);
|
|
||||||
keys.sort((a, b) => a.localeCompare(b));
|
|
||||||
|
|
||||||
let index = 0;
|
|
||||||
for (const key of keys) {
|
|
||||||
const desc = commands[key];
|
|
||||||
const length = ` ${key} - ${desc}`.length;
|
|
||||||
|
|
||||||
stdout.write(
|
|
||||||
" " +
|
|
||||||
chalk.bold.yellow(key) +
|
|
||||||
chalk.reset(" - " + desc) +
|
|
||||||
" ".repeat(Math.abs(25 - length))
|
|
||||||
);
|
|
||||||
|
|
||||||
index++;
|
|
||||||
if (index % 3 == 0) stdout.write("\n");
|
|
||||||
}
|
|
||||||
if (index % 3 != 0) stdout.write("\n");
|
|
||||||
|
|
||||||
console.log("\nTo begin TALK MODE, press [SPACE]\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
function listGuilds() {
|
|
||||||
let longest = 0;
|
|
||||||
const guilds = [];
|
|
||||||
|
|
||||||
for (const guild of client.guilds.values()) {
|
|
||||||
if (guild.name.length > longest) longest = guild.name.length;
|
|
||||||
|
|
||||||
const online = [...guild.members.values()].filter((m) => m.status).length;
|
|
||||||
guilds.push({name: guild.name, members: guild.memberCount, online});
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("");
|
|
||||||
console.log(" " + "guild-name".padStart(longest, " ") + " online total");
|
|
||||||
console.log("-".repeat(80));
|
|
||||||
for (const guild of guilds) {
|
|
||||||
console.log(
|
|
||||||
" " +
|
|
||||||
guild.name.padStart(longest, " ") +
|
|
||||||
" " +
|
|
||||||
guild.online.toString().padStart(6, " ") +
|
|
||||||
" " +
|
|
||||||
guild.members.toString().padStart(5, " ")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
console.log("");
|
|
||||||
}
|
|
||||||
|
|
||||||
function listChannels() {
|
|
||||||
let longest = 0;
|
|
||||||
let longestTopic = 0;
|
|
||||||
const guild = client.guilds.get(currentGuild);
|
|
||||||
const channels = [...guild.channels.values()].filter((c) => c.type == 0);
|
|
||||||
channels.sort((a, b) => a.position - b.position);
|
|
||||||
|
|
||||||
for (const channel of channels) {
|
|
||||||
const perms = channel.permissionsOf(client.user.id);
|
|
||||||
const private = !perms.has(Eris.Constants.Permissions.readMessages);
|
|
||||||
|
|
||||||
if (channel.name.length + (private ? 1 : 0) > longest)
|
|
||||||
longest = channel.name.length + (private ? 1 : 0);
|
|
||||||
if (channel.topic != null && channel.topic.length > longestTopic)
|
|
||||||
longestTopic = channel.topic.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("");
|
|
||||||
console.log(
|
|
||||||
" " +
|
|
||||||
"channel-name".padStart(longest, " ") +
|
|
||||||
" " +
|
|
||||||
"topic".padStart(Math.min(80 - (longest + 5), longestTopic), " ")
|
|
||||||
);
|
|
||||||
console.log("-".repeat(80));
|
|
||||||
for (const channel of channels) {
|
|
||||||
const topic =
|
|
||||||
channel.topic != null ? channel.topic.replace(/\n/g, " ") : "";
|
|
||||||
const perms = channel.permissionsOf(client.user.id);
|
|
||||||
const private = !perms.has(Eris.Constants.Permissions.readMessages);
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
" " +
|
|
||||||
((private ? "*" : "") + channel.name).padStart(longest, " ") +
|
|
||||||
" " +
|
|
||||||
(topic.length > 80 - longest + 9
|
|
||||||
? topic.substring(0, 79 - (longest + 5)) + "\u2026"
|
|
||||||
: topic.padStart(Math.min(80 - (longest + 5), longestTopic), " "))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
console.log("");
|
|
||||||
}
|
|
||||||
|
|
||||||
let targetGuild = "";
|
|
||||||
function gotoGuild() {
|
|
||||||
targetGuild = "";
|
|
||||||
guildSwitch = true;
|
|
||||||
|
|
||||||
stdout.write(":guild> ");
|
|
||||||
}
|
|
||||||
|
|
||||||
function findTopChannel(guildId) {
|
|
||||||
const guild = client.guilds.get(guildId);
|
|
||||||
const channels = [...guild.channels.values()].filter((c) => c.type == 0);
|
|
||||||
channels.sort((a, b) => a.position - b.position);
|
|
||||||
|
|
||||||
return channels[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
function getStatus(status) {
|
|
||||||
let color;
|
|
||||||
switch (status) {
|
|
||||||
case "online":
|
|
||||||
color = chalk.bold.green;
|
|
||||||
break;
|
|
||||||
case "idle":
|
|
||||||
color = chalk.bold.yellow;
|
|
||||||
break;
|
|
||||||
case "dnd":
|
|
||||||
color = chalk.bold.red;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
color = chalk.bold;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return color(" \u2022 ");
|
|
||||||
}
|
|
||||||
|
|
||||||
function listUsers() {
|
|
||||||
const guild = client.guilds.get(currentGuild);
|
|
||||||
const channel = guild.channels.get(currentChannel);
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
`\n[you are in '${guild.name}' in '${channel.name}' among ${guild.memberCount}]\n`
|
|
||||||
);
|
|
||||||
|
|
||||||
const online = [...guild.members.values()].filter((m) => m.status);
|
|
||||||
online.sort((a, b) => a.name - b.name);
|
|
||||||
|
|
||||||
let longest = 0;
|
|
||||||
for (const member of online) {
|
|
||||||
const name = member.user.username + "#" + member.user.discriminator;
|
|
||||||
if (name.length + 3 > longest) longest = name.length + 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
const columns = Math.ceil(stdout.columns / longest);
|
|
||||||
|
|
||||||
let index = 0;
|
|
||||||
for (const member of online) {
|
|
||||||
const name = member.user.username + "#" + member.user.discriminator;
|
|
||||||
const status = getStatus(member.status);
|
|
||||||
const nameAndStatus = chalk.reset(name) + status;
|
|
||||||
|
|
||||||
index++;
|
|
||||||
stdout.write(
|
|
||||||
nameAndStatus +
|
|
||||||
" ".repeat(
|
|
||||||
index % columns == 0 ? 0 : Math.abs(longest - (name.length + 3))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (index % columns == 0) stdout.write("\n");
|
|
||||||
}
|
|
||||||
if (index % columns != 0) stdout.write("\n");
|
|
||||||
console.log("");
|
|
||||||
|
|
||||||
if (channel.topic != null) {
|
|
||||||
console.log("--Topic".padEnd(80, "-"));
|
|
||||||
console.log(channel.topic);
|
|
||||||
console.log("-".repeat(80));
|
|
||||||
console.log("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function switchGuild() {
|
|
||||||
targetGuild = targetGuild.trim();
|
|
||||||
if (targetGuild == "") {
|
|
||||||
listChannels();
|
|
||||||
listUsers();
|
|
||||||
guildSwitch = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let target;
|
|
||||||
|
|
||||||
for (const guild of client.guilds.values()) {
|
|
||||||
if (guild.name.toLowerCase().indexOf(targetGuild.toLowerCase()) > -1) {
|
|
||||||
target = guild.id;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target == null) {
|
|
||||||
console.log("<guild not found>");
|
|
||||||
} else {
|
|
||||||
currentGuild = target;
|
|
||||||
// TODO: store last visited channel and switch to it if we've been to this guild before
|
|
||||||
const topChannel = findTopChannel(target);
|
|
||||||
currentChannel = topChannel.id;
|
|
||||||
|
|
||||||
listChannels();
|
|
||||||
listUsers();
|
|
||||||
}
|
|
||||||
|
|
||||||
guildSwitch = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let targetChannel = "";
|
|
||||||
function gotoChannel() {
|
|
||||||
targetChannel = "";
|
|
||||||
channelSwitch = true;
|
|
||||||
|
|
||||||
stdout.write(":channel> ");
|
|
||||||
}
|
|
||||||
|
|
||||||
function switchChannel() {
|
|
||||||
targetChannel = targetChannel.trim();
|
|
||||||
if (targetChannel == "") {
|
|
||||||
listUsers();
|
|
||||||
channelSwitch = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let target;
|
|
||||||
|
|
||||||
const guild = client.guilds.get(currentGuild);
|
|
||||||
const channels = [...guild.channels.values()].filter((c) => c.type == 0);
|
|
||||||
channels.sort((a, b) => a.position - b.position);
|
|
||||||
|
|
||||||
for (const channel of channels) {
|
|
||||||
if (channel.name.toLowerCase().indexOf(targetChannel.toLowerCase()) > -1) {
|
|
||||||
target = channel.id;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target == null) {
|
|
||||||
console.log("<channel not found>");
|
|
||||||
} else {
|
|
||||||
currentChannel = target;
|
|
||||||
|
|
||||||
listUsers();
|
|
||||||
}
|
|
||||||
|
|
||||||
channelSwitch = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function startEmote() {
|
|
||||||
toSend = "";
|
|
||||||
inEmoteMode = true;
|
|
||||||
|
|
||||||
stdout.write(":emote> ");
|
|
||||||
}
|
|
||||||
|
|
||||||
async function sendEmote() {
|
|
||||||
toSend = toSend.trim();
|
|
||||||
if (toSend === "") {
|
|
||||||
console.log("<no message sent>");
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
await client.createMessage(currentChannel, "*" + toSend + "*");
|
|
||||||
console.log(`<${client.user.username} ${toSend}>`);
|
|
||||||
} catch (err) {
|
|
||||||
console.log("<failed to send message: " + err.message + ">");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inEmoteMode = false;
|
|
||||||
processQueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getHistory(limit = 20) {
|
|
||||||
const messages = await client.getMessages(currentChannel, {limit});
|
|
||||||
messages.reverse();
|
|
||||||
|
|
||||||
console.log("--Beginning-Review".padEnd(72, "-"));
|
|
||||||
|
|
||||||
for (const msg of messages) {
|
|
||||||
if (msg.content.indexOf("\n") > -1) {
|
|
||||||
const lines = msg.content.split("\n");
|
|
||||||
for (const index in lines) {
|
|
||||||
const line = lines[index];
|
|
||||||
processMessage({
|
|
||||||
name: msg.author.username,
|
|
||||||
bot: msg.author.bot,
|
|
||||||
content:
|
|
||||||
line +
|
|
||||||
(msg.editedTimestamp != null && index == lines.length - 1
|
|
||||||
? " (edited)"
|
|
||||||
: ""),
|
|
||||||
attachments: index == lines.length - 1 ? msg.attachments : null,
|
|
||||||
reply: index == 0 ? msg.referencedMessage : null,
|
|
||||||
isHistory: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
processMessage({
|
|
||||||
name: msg.author.username,
|
|
||||||
bot: msg.author.bot,
|
|
||||||
content: msg.content + (msg.editedTimestamp != null ? " (edited)" : ""),
|
|
||||||
attachments: msg.attachments,
|
|
||||||
reply: msg.referencedMessage,
|
|
||||||
isHistory: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("--Review-Complete".padEnd(73, "-"));
|
|
||||||
}
|
|
||||||
|
|
||||||
let numLines = "";
|
|
||||||
function startExtendedHistory() {
|
|
||||||
numLines = "";
|
|
||||||
extendedHistory = true;
|
|
||||||
|
|
||||||
stdout.write(":lines> ");
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getExtendedHistory() {
|
|
||||||
numLines = numLines.trim();
|
|
||||||
numLines = parseInt(numLines);
|
|
||||||
if (isNaN(numLines)) {
|
|
||||||
console.log("<not a number>");
|
|
||||||
extendedHistory = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await getHistory(numLines);
|
|
||||||
} catch (err) {
|
|
||||||
console.log("<failed to get history: " + err.message + ">");
|
|
||||||
}
|
|
||||||
|
|
||||||
extendedHistory = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
stdin.on("data", function (key) {
|
|
||||||
if (guildSwitch) {
|
|
||||||
if (key === "\r") {
|
if (key === "\r") {
|
||||||
console.log("");
|
await finalizePrompt();
|
||||||
switchGuild();
|
processQueue();
|
||||||
} else {
|
} else {
|
||||||
if (key === "\b") {
|
if (key === "\b") {
|
||||||
if (targetGuild.length > 0) {
|
if (comcord.state.promptInput.length > 0) {
|
||||||
stdout.moveCursor(-1);
|
process.stdout.moveCursor(-1);
|
||||||
stdout.write(" ");
|
process.stdout.write(" ");
|
||||||
stdout.moveCursor(-1);
|
process.stdout.moveCursor(-1);
|
||||||
targetGuild = targetGuild.substring(0, targetGuild.length - 1);
|
comcord.state.promptInput = comcord.state.promptInput.substring(
|
||||||
|
0,
|
||||||
|
comcord.state.promptInput.length - 1
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
stdout.write(key);
|
process.stdout.write(key);
|
||||||
targetGuild += key;
|
comcord.state.promptInput += key;
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (channelSwitch) {
|
|
||||||
if (key === "\r") {
|
|
||||||
console.log("");
|
|
||||||
switchChannel();
|
|
||||||
} else {
|
|
||||||
if (key === "\b") {
|
|
||||||
if (targetChannel.length > 0) {
|
|
||||||
stdout.moveCursor(-1);
|
|
||||||
stdout.write(" ");
|
|
||||||
stdout.moveCursor(-1);
|
|
||||||
targetChannel = targetChannel.substring(0, targetChannel.length - 1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
stdout.write(key);
|
|
||||||
targetChannel += key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (inSendMode) {
|
|
||||||
if (key === "\r") {
|
|
||||||
sendMessage();
|
|
||||||
} else {
|
|
||||||
if (key === "\b") {
|
|
||||||
if (toSend.length > 0) {
|
|
||||||
stdout.moveCursor(-1);
|
|
||||||
stdout.write(" ");
|
|
||||||
stdout.moveCursor(-1);
|
|
||||||
toSend = toSend.substring(0, toSend.length - 1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
stdout.write(key);
|
|
||||||
toSend += key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (inEmoteMode) {
|
|
||||||
if (key === "\r") {
|
|
||||||
console.log("");
|
|
||||||
sendEmote();
|
|
||||||
} else {
|
|
||||||
if (key === "\b") {
|
|
||||||
if (toSend.length > 0) {
|
|
||||||
stdout.moveCursor(-1);
|
|
||||||
stdout.write(" ");
|
|
||||||
stdout.moveCursor(-1);
|
|
||||||
toSend = toSend.substring(0, toSend.length - 1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
stdout.write(key);
|
|
||||||
toSend += key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (extendedHistory) {
|
|
||||||
if (key === "\r") {
|
|
||||||
console.log("");
|
|
||||||
getExtendedHistory();
|
|
||||||
} else {
|
|
||||||
if (key === "\b") {
|
|
||||||
if (numLines.length > 0) {
|
|
||||||
stdout.moveCursor(-1);
|
|
||||||
stdout.write(" ");
|
|
||||||
stdout.moveCursor(-1);
|
|
||||||
numLines = numLines.substring(0, numLines.length - 1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
stdout.write(key);
|
|
||||||
numLines += key;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (key) {
|
if (comcord.commands[key]) {
|
||||||
case "\u0003":
|
comcord.commands[key].callback();
|
||||||
case "q": {
|
} else {
|
||||||
client.disconnect(false);
|
sendMode();
|
||||||
process.exit(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "h": {
|
|
||||||
showHelp();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "g": {
|
|
||||||
if (currentGuild == null) {
|
|
||||||
console.log("<not in a guild>");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
gotoChannel();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "G": {
|
|
||||||
gotoGuild();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "l": {
|
|
||||||
if (currentGuild == null) {
|
|
||||||
console.log("<not in a guild>");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
listChannels();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "L": {
|
|
||||||
listGuilds();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "w": {
|
|
||||||
if (currentGuild == null) {
|
|
||||||
console.log("<not in a guild>");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
listUsers();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "e": {
|
|
||||||
if (currentChannel == null) {
|
|
||||||
console.log("<not in a channel>");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
startEmote();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "r": {
|
|
||||||
if (currentChannel == null) {
|
|
||||||
console.log("<not in a channel>");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
getHistory();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "R": {
|
|
||||||
if (currentChannel == null) {
|
|
||||||
console.log("<not in a channel>");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
startExtendedHistory();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "c": {
|
|
||||||
console.clear();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "<": {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ">": {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case " ":
|
|
||||||
case "\r":
|
|
||||||
default: {
|
|
||||||
if (currentChannel == null) {
|
|
||||||
console.log("<not in a channel>");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
setupSendMode();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
17
src/lib/command.js
Normal file
17
src/lib/command.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
function addCommand(key, name, callback) {
|
||||||
|
if (comcord.commands[key]) {
|
||||||
|
console.error(
|
||||||
|
`Registering duplicate key for "${key}": "${name}" wants to overwrite "${comcord.commands[key].name}"!`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
comcord.commands[key] = {
|
||||||
|
name,
|
||||||
|
callback,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
addCommand,
|
||||||
|
};
|
117
src/lib/messages.js
Normal file
117
src/lib/messages.js
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
const chalk = require("chalk");
|
||||||
|
|
||||||
|
function processMessage({
|
||||||
|
name,
|
||||||
|
content,
|
||||||
|
bot,
|
||||||
|
attachments,
|
||||||
|
reply,
|
||||||
|
noColor = false,
|
||||||
|
}) {
|
||||||
|
if (name.length + 2 > comcord.state.nameLength)
|
||||||
|
comcord.statenameLength = name.length + 2;
|
||||||
|
|
||||||
|
if (reply) {
|
||||||
|
const nameColor = reply.author.bot ? chalk.bold.yellow : chalk.bold.cyan;
|
||||||
|
|
||||||
|
const headerLength = 5 + reply.author.username.length;
|
||||||
|
const length = headerLength + reply.content.length;
|
||||||
|
|
||||||
|
if (noColor) {
|
||||||
|
console.log(
|
||||||
|
` \u250d [${reply.author.username}] ${
|
||||||
|
length > 79
|
||||||
|
? reply.content.substring(0, length - headerLength) + "\u2026"
|
||||||
|
: reply.content
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.log(
|
||||||
|
chalk.bold.white(" \u250d ") +
|
||||||
|
nameColor(`[${reply.author.username}] `) +
|
||||||
|
chalk.reset(
|
||||||
|
`${
|
||||||
|
length > 79
|
||||||
|
? reply.content.substring(0, length - headerLength) + "\u2026"
|
||||||
|
: reply.content
|
||||||
|
}`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
(content.startsWith("*") && content.endsWith("*")) ||
|
||||||
|
(content.startsWith("_") && content.endsWith("_"))
|
||||||
|
) {
|
||||||
|
if (noColor) {
|
||||||
|
console.log(`<${name} ${content.substring(1, content.length - 1)}>`);
|
||||||
|
} else {
|
||||||
|
console.log(
|
||||||
|
chalk.bold.green(
|
||||||
|
`<${name} ${content.substring(1, content.length - 1)}>`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (noColor) {
|
||||||
|
console.log(
|
||||||
|
`[${name}]${" ".repeat(
|
||||||
|
Math.abs(comcord.state.nameLength - (name.length + 2))
|
||||||
|
)} ${content}`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const nameColor = bot ? chalk.bold.yellow : chalk.bold.cyan;
|
||||||
|
|
||||||
|
// TODO: markdown
|
||||||
|
console.log(
|
||||||
|
nameColor(`[${name}]`) +
|
||||||
|
" ".repeat(Math.abs(comcord.state.nameLength - (name.length + 2))) +
|
||||||
|
chalk.reset(" " + content)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attachments) {
|
||||||
|
for (const attachment of attachments) {
|
||||||
|
if (noColor) {
|
||||||
|
console.log(`<attachment: ${attachment.url} >`);
|
||||||
|
} else {
|
||||||
|
console.log(chalk.bold.yellow(`<attachment: ${attachment.url} >`));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function processQueue() {
|
||||||
|
for (const msg of comcord.state.messageQueue) {
|
||||||
|
if (msg.content.indexOf("\n") > -1) {
|
||||||
|
const lines = msg.content.split("\n");
|
||||||
|
for (const index in lines) {
|
||||||
|
const line = lines[index];
|
||||||
|
processMessage({
|
||||||
|
name: msg.author.username,
|
||||||
|
bot: msg.author.bot,
|
||||||
|
content: line,
|
||||||
|
attachments: index == lines.length - 1 ? msg.attachments : [],
|
||||||
|
reply: index == 0 ? msg.referencedMessage : null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
processMessage({
|
||||||
|
name: msg.author.username,
|
||||||
|
bot: msg.author.bot,
|
||||||
|
content: msg.content,
|
||||||
|
attachments: msg.attachments,
|
||||||
|
reply: msg.referencedMessage,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
comcord.state.messageQueue.splice(0, comcord.state.messageQueue.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
processMessage,
|
||||||
|
processQueue,
|
||||||
|
};
|
25
src/lib/prompt.js
Normal file
25
src/lib/prompt.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
function startPrompt(display, callback) {
|
||||||
|
comcord.state.inPrompt = true;
|
||||||
|
comcord.state.promptText = display;
|
||||||
|
comcord.state.promptInput = "";
|
||||||
|
|
||||||
|
comcord.state.promptCallback = callback;
|
||||||
|
|
||||||
|
process.stdout.write(display);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function finalizePrompt() {
|
||||||
|
comcord.state.inPrompt = false;
|
||||||
|
comcord.state.promptText = null;
|
||||||
|
|
||||||
|
const input = comcord.state.promptInput.trim();
|
||||||
|
await comcord.state.promptCallback(input);
|
||||||
|
|
||||||
|
comcord.state.promptInput = null;
|
||||||
|
comcord.state.promptCallback = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
startPrompt,
|
||||||
|
finalizePrompt,
|
||||||
|
};
|
Loading…
Reference in a new issue