From 7a27a7f1b9bdaaa9fca4228e1efeaba891143c13 Mon Sep 17 00:00:00 2001 From: Cynthia Foxwell Date: Sun, 9 Oct 2022 14:39:15 -0600 Subject: [PATCH] move from eris to oceanic --- README.md | 12 ++-- package.json | 2 +- pnpm-lock.yaml | 120 +++++++++++++++++++++++++++-------- src/commands/afk.js | 5 +- src/commands/emote.js | 8 +-- src/commands/history.js | 8 +-- src/commands/listChannels.js | 21 ++---- src/commands/listGuilds.js | 3 +- src/commands/listUsers.js | 8 +-- src/commands/send.js | 8 +-- src/index.js | 34 +++++----- src/lib/messages.js | 4 +- 12 files changed, 148 insertions(+), 85 deletions(-) diff --git a/README.md b/README.md index aaaf716..8330e0d 100644 --- a/README.md +++ b/README.md @@ -10,14 +10,15 @@ A CLI-based client for Discord inspired by [SDF](https://sdf.org)'s [commode](ht 2. `node src/index.js ` Currently only bot accounts are supported, and that is unlikely to change anytime soon. -Eris has a lot of user-only endpoints implemented, but it would require hacking apart Eris to do the things nessicary to spoof being the actual client. +~~Eris has a lot of user-only endpoints implemented, but it would require hacking apart Eris to do the things nessicary to spoof being the actual client.~~ +(I have no idea currently what the state of user support in Oceanic is) I also don't want to give skids an easy point of reference of how to spoof the client. :^) You **MUST** grant your bot all Privileged Gateway Intents. ## Design Decisions * Node.js was chosen currently due to familiarity. -* Eris was chosen due to familiarity and the nature of everything not being abstracted out to 200 different classes unlike discord.js. +* ~~Eris~~ Oceanic was chosen due to familiarity and the nature of everything not being abstracted out to 200 different classes unlike discord.js. * "Jank" by design. While I don't expect anyone to actually use comcord on serial terminals or teletypes other than for meme factor, the option is still there. ## TODO @@ -39,11 +40,12 @@ You **MUST** grant your bot all Privileged Gateway Intents. - [ ] Surf channels forwards (>) - [ ] Surf channels backwards (<) - [x] Message Receiving - - [ ] Markdown styling + - [x] Markdown styling - [ ] Common markdown (bold, italic, etc) - [ ] Figure out how spoilers would work - - [ ] Emotes????? - - [ ] Timestamp parsing + - [x] Emotes????? + - [x] Timestamp parsing + - [x] Mentions parsing - [ ] Embeds in the style of commode's posted links - [x] Messages wrapped in `*`'s or `_`'s parsed as emotes - [ ] Inline DMs to replicate commode's private messages diff --git a/package.json b/package.json index a35a080..923a5ad 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,6 @@ "dependencies": { "chalk": "4.1.2", "discord-rpc": "^4.0.1", - "eris": "github:abalabahaha/eris#dev" + "oceanic.js": "^1.1.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fd57a7f..274b347 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3,15 +3,47 @@ lockfileVersion: 5.4 specifiers: chalk: 4.1.2 discord-rpc: ^4.0.1 - eris: github:abalabahaha/eris#dev + oceanic.js: ^1.1.2 dependencies: chalk: 4.1.2 discord-rpc: 4.0.1 - eris: github.com/abalabahaha/eris/eb403730855714eafa36c541dbe2cb84c9979158 + oceanic.js: 1.1.2 packages: + /@discordjs/voice/0.11.0: + resolution: {integrity: sha512-6+9cj1dxzBJm7WJ9qyG2XZZQ8rcLl6x2caW0C0OxuTtMLAaEDntpb6lqMTFiBg/rDc4Rd59g1w0gJmib33CuHw==} + engines: {node: '>=16.9.0'} + requiresBuild: true + dependencies: + '@types/ws': 8.5.3 + discord-api-types: 0.36.3 + prism-media: 1.3.4 + tslib: 2.4.0 + ws: 8.9.0 + transitivePeerDependencies: + - '@discordjs/opus' + - bufferutil + - ffmpeg-static + - node-opus + - opusscript + - utf-8-validate + dev: false + optional: true + + /@types/node/18.8.3: + resolution: {integrity: sha512-0os9vz6BpGwxGe9LOhgP/ncvYN5Tx1fNcd2TM3rD/aCGBkysb+ZWpXEocG24h6ZzOi13+VB8HndAQFezsSOw1w==} + dev: false + optional: true + + /@types/ws/8.5.3: + resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==} + dependencies: + '@types/node': 18.8.3 + dev: false + optional: true + /ansi-styles/4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -26,6 +58,13 @@ packages: dev: false optional: true + /busboy/1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + dependencies: + streamsearch: 1.1.0 + dev: false + /chalk/4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -45,6 +84,11 @@ packages: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} dev: false + /discord-api-types/0.36.3: + resolution: {integrity: sha512-bz/NDyG0KBo/tY14vSkrwQ/n3HKPf87a0WFW/1M9+tXYK+vp5Z5EksawfCWo2zkAc6o7CClc0eff1Pjrqznlwg==} + dev: false + optional: true + /discord-rpc/4.0.1: resolution: {integrity: sha512-HOvHpbq5STRZJjQIBzwoKnQ0jHplbEWFWlPDwXXKm/bILh4nzjcg7mNqll0UY7RsjFoaXA7e/oYb/4lvpda2zA==} dependencies: @@ -85,12 +129,47 @@ packages: whatwg-url: 5.0.0 dev: false - /opusscript/0.0.8: - resolution: {integrity: sha512-VSTi1aWFuCkRCVq+tx/BQ5q9fMnQ9pVZ3JU4UHKqTkf0ED3fKEPdr+gKAAl3IA2hj9rrP6iyq3hlcJq3HELtNQ==} - requiresBuild: true + /oceanic.js/1.1.2: + resolution: {integrity: sha512-aABMK2UERHvyiwjWFx5m5ZZY7oPUHmVSOhICadZh/vqyxvGf48p+aqGlRu9bEtN6XZYPZJecQi/9IPN+phXn1Q==} + engines: {node: '>=16.16.0'} + dependencies: + undici: 5.11.0 + ws: 8.9.0 + optionalDependencies: + '@discordjs/voice': 0.11.0 + transitivePeerDependencies: + - '@discordjs/opus' + - bufferutil + - ffmpeg-static + - node-opus + - opusscript + - utf-8-validate + dev: false + + /prism-media/1.3.4: + resolution: {integrity: sha512-eW7LXORkTCQznZs+eqe9VjGOrLBxcBPXgNyHXMTSRVhphvd/RrxgIR7WaWt4fkLuhshcdT5KHL88LAfcvS3f5g==} + peerDependencies: + '@discordjs/opus': ^0.8.0 + ffmpeg-static: ^5.0.2 || ^4.2.7 || ^3.0.0 || ^2.4.0 + node-opus: ^0.3.3 + opusscript: ^0.0.8 + peerDependenciesMeta: + '@discordjs/opus': + optional: true + ffmpeg-static: + optional: true + node-opus: + optional: true + opusscript: + optional: true dev: false optional: true + /streamsearch/1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + dev: false + /supports-color/7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -102,12 +181,18 @@ packages: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} dev: false - /tweetnacl/1.0.3: - resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} - requiresBuild: true + /tslib/2.4.0: + resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} dev: false optional: true + /undici/5.11.0: + resolution: {integrity: sha512-oWjWJHzFet0Ow4YZBkyiJwiK5vWqEYoH7BINzJAJOLedZ++JpAlCbUktW2GQ2DS2FpKmxD/JMtWUUWl1BtghGw==} + engines: {node: '>=12.18'} + dependencies: + busboy: 1.6.0 + dev: false + /webidl-conversions/3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: false @@ -132,8 +217,8 @@ packages: optional: true dev: false - /ws/8.8.1: - resolution: {integrity: sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==} + /ws/8.9.0: + resolution: {integrity: sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -145,21 +230,6 @@ packages: optional: true dev: false - github.com/abalabahaha/eris/eb403730855714eafa36c541dbe2cb84c9979158: - resolution: {tarball: https://codeload.github.com/abalabahaha/eris/tar.gz/eb403730855714eafa36c541dbe2cb84c9979158} - name: eris - version: 0.17.2-dev - engines: {node: '>=10.4.0'} - dependencies: - ws: 8.8.1 - optionalDependencies: - opusscript: 0.0.8 - tweetnacl: 1.0.3 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - dev: false - github.com/devsnek/node-register-scheme/e7cc9a63a1f512565da44cb57316d9fb10750e17: resolution: {tarball: https://codeload.github.com/devsnek/node-register-scheme/tar.gz/e7cc9a63a1f512565da44cb57316d9fb10750e17} name: register-scheme diff --git a/src/commands/afk.js b/src/commands/afk.js index 88931d0..7a3e396 100644 --- a/src/commands/afk.js +++ b/src/commands/afk.js @@ -3,14 +3,13 @@ const {updatePresence} = require("../lib/presence"); addCommand("A", "toggles AFK mode", function () { if (comcord.state.afk == true) { - comcord.state.afk = false; + comcord.client.shards.forEach((shard) => (shard.presence.afk = false)); comcord.client.editStatus("online"); - comcord.client.editAFK(false); console.log(""); } else { comcord.state.afk = true; + comcord.client.shards.forEach((shard) => (shard.presence.afk = true)); comcord.client.editStatus("idle"); - comcord.client.editAFK(true); console.log(""); } diff --git a/src/commands/emote.js b/src/commands/emote.js index aef4b7d..d909c6d 100644 --- a/src/commands/emote.js +++ b/src/commands/emote.js @@ -13,10 +13,10 @@ addCommand("e", "emote", function () { } else { try { process.stdout.write("\n"); - await comcord.client.createMessage( - comcord.state.currentChannel, - `*${input}*` - ); + await comcord.client.guilds + .get(comcord.state.currentGuild) + .channels.get(comcord.state.currentChannel) + .createMessage({content: `*${input}*`}); console.log(`<${comcord.client.user.username} ${input}>`); } catch (err) { console.log(""); diff --git a/src/commands/history.js b/src/commands/history.js index 343b46a..14d123a 100644 --- a/src/commands/history.js +++ b/src/commands/history.js @@ -8,10 +8,10 @@ async function getHistory(limit = 20) { return; } - const messages = await comcord.client.getMessages( - comcord.state.currentChannel, - {limit} - ); + const messages = await comcord.client.guilds + .get(comcord.state.currentGuild) + .channels.get(comcord.state.currentChannel) + .getMessages({limit}); messages.reverse(); console.log("--Beginning-Review".padEnd(72, "-")); diff --git a/src/commands/listChannels.js b/src/commands/listChannels.js index 7d12c3e..7c18345 100644 --- a/src/commands/listChannels.js +++ b/src/commands/listChannels.js @@ -1,5 +1,3 @@ -const Eris = require("eris"); - const {addCommand} = require("../lib/command"); function listChannels() { @@ -9,34 +7,26 @@ function listChannels() { } 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); + const private = !perms.has("VIEW_CHANNEL"); 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(" " + "channel-name".padStart(longest, " ") + " " + "topic"); 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 private = !perms.has("VIEW_CHANNEL"); const name = (private ? "*" : "") + channel.name; @@ -47,11 +37,12 @@ function listChannels() { " " ) + " " + - (topic.length > 80 - longest + 9 + (topic.length > 80 - (longest + 5) ? topic.substring(0, 79 - (longest + 5)) + "\u2026" - : topic.padStart(Math.min(80 - (longest + 5), longestTopic), " ")) + : topic) ); } + console.log("-".repeat(80)); console.log(""); } diff --git a/src/commands/listGuilds.js b/src/commands/listGuilds.js index fc9fd3a..9feffff 100644 --- a/src/commands/listGuilds.js +++ b/src/commands/listGuilds.js @@ -7,7 +7,7 @@ function listGuilds() { 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; + const online = [...guild.members.values()].filter((m) => m.presence).length; guilds.push({name: guild.name, members: guild.memberCount, online}); } @@ -24,6 +24,7 @@ function listGuilds() { guild.members.toString().padStart(5, " ") ); } + console.log("-".repeat(80)); console.log(""); } diff --git a/src/commands/listUsers.js b/src/commands/listUsers.js index acaa2f5..394117b 100644 --- a/src/commands/listUsers.js +++ b/src/commands/listUsers.js @@ -39,12 +39,12 @@ function listUsers() { `\n[you are in '${guild.name}' in '${channel.name}' among ${guild.memberCount}]\n` ); - const online = [...guild.members.values()].filter((m) => m.status); + const online = [...guild.members.values()].filter((m) => m.presence); online.sort((a, b) => a.name - b.name); let longest = 0; for (const member of online) { - const name = member.user.username + "#" + member.user.discriminator; + const name = member.user.tag; if (name.length + 3 > longest) longest = name.length + 3; } @@ -52,8 +52,8 @@ function listUsers() { let index = 0; for (const member of online) { - const name = member.user.username + "#" + member.user.discriminator; - const status = getStatus(member.status); + const name = member.user.tag; + const status = getStatus(member.presence.status); const nameAndStatus = chalk.reset(name) + status; index++; diff --git a/src/commands/send.js b/src/commands/send.js index 2402a5e..2d04907 100644 --- a/src/commands/send.js +++ b/src/commands/send.js @@ -21,10 +21,10 @@ function sendMode() { } else { try { process.stdout.write("\n"); - await comcord.client.createMessage( - comcord.state.currentChannel, - input - ); + await comcord.client.guilds + .get(comcord.state.currentGuild) + .channels.get(comcord.state.currentChannel) + .createMessage({content: input}); if (comcord.state.afk == true) { comcord.state.afk = false; diff --git a/src/index.js b/src/index.js index 1d3f4ed..367043f 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ -const Eris = require("eris"); +const {Client} = require("oceanic.js"); const chalk = require("chalk"); const DiscordRPC = require("discord-rpc"); @@ -21,10 +21,23 @@ global.comcord = { }, commands: {}, }; -const client = new Eris("Bot " + token, { +const client = new Client({ + auth: "Bot " + token, defaultImageFormat: "png", defaultImageSize: 1024, - intents: Eris.Constants.Intents.all, + gateway: { + intents: ["ALL"], + activities: [ + { + name: "comcord", + type: "GAME", + application_id: CLIENT_ID, + timestamps: { + start: comcord.state.startTime, + }, + }, + ], + }, }); comcord.client = client; const rpc = new DiscordRPC.Client({transport: "ipc"}); @@ -51,25 +64,12 @@ process.stdin.setEncoding("utf8"); client.once("ready", function () { console.log( - "Logged in as: " + - chalk.yellow( - `${client.user.username}#${client.user.discriminator} (${client.user.id})` - ) + "Logged in as: " + chalk.yellow(`${client.user.tag} (${client.user.id})`) ); comcord.state.nameLength = client.user.username.length + 2; listGuilds(); - client.editStatus("online", [ - { - application_id: CLIENT_ID, - name: "comcord", - timestamps: { - start: comcord.state.startTime, - }, - }, - ]); - rpc .login({ clientId: CLIENT_ID, diff --git a/src/lib/messages.js b/src/lib/messages.js index 55c035d..17d781d 100644 --- a/src/lib/messages.js +++ b/src/lib/messages.js @@ -181,7 +181,7 @@ function formatMessage({ .replace(REGEX_COMMAND, replaceCommands) .replace(REGEX_TIMESTAMP, replaceTimestamps); if (reply.attachments.length > 0) { - replyContent += `<${reply.attachments.length} attachment${ + replyContent += ` <${reply.attachments.length} attachment${ reply.attachments.length > 1 ? "s" : "" }>`; replyContent = replyContent.trim(); @@ -284,7 +284,7 @@ function formatMessage({ } if (attachments) { - for (const attachment of attachments) { + for (const attachment of attachments.values()) { if (noColor) { console.log(``); } else {