diff --git a/README.md b/README.md index 9479673..aaaf716 100644 --- a/README.md +++ b/README.md @@ -8,24 +8,16 @@ A CLI-based client for Discord inspired by [SDF](https://sdf.org)'s [commode](ht ## Usage 1. `pnpm i` 2. `node src/index.js ` -Your token will be then stored in `.comcordrc` after the first launch. -### User Accounts -User accounts are *partially* supported via `allowUserAccounts=true` in your `.comcordrc`. -This is use at your own risk, despite spoofing the official client. I am not responsible for any banned accounts. +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. +I also don't want to give skids an easy point of reference of how to spoof the client. :^) -#### Guild members not populating -This is due to Oceanic not implementing Lazy Guilds as they are user account specific. **DO NOT bother Oceanic to implement it!** They are purely a bot-focused library. - -If you are willing to implement Lazy Guilds based off of [unofficial documentation](https://luna.gitlab.io/discord-unofficial-docs/lazy_guilds.html) -and my already existing horrible hacks to make user accounts work in the first place, feel free to send a PR (on GitLab, GitHub repo is a read only mirror). - -### Bot Accounts (prefered) You **MUST** grant your bot all Privileged Gateway Intents. ## Design Decisions * Node.js was chosen currently due to familiarity. -* Oceanic was chosen due to familiarity and the nature of everything not being abstracted out to 200 different classes unlike discord.js. +* Eris 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 @@ -46,16 +38,12 @@ You **MUST** grant your bot all Privileged Gateway Intents. - [x] Clear (c) - [ ] Surf channels forwards (>) - [ ] Surf channels backwards (<) - - [x] AFK toggle (A) - - [x] Send DM (s) - - [x] Answer DM (a) - [x] Message Receiving - - [x] Markdown styling + - [ ] Markdown styling - [ ] Common markdown (bold, italic, etc) - [ ] Figure out how spoilers would work - - [x] Emotes????? - - [x] Timestamp parsing - - [x] Mentions parsing + - [ ] Emotes????? + - [ ] Timestamp 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 @@ -64,9 +52,8 @@ You **MUST** grant your bot all Privileged Gateway Intents. - [x] Puts incoming messages into queue whilst in send mode - [ ] Mentions - [ ] Replies -- [x] Configuration - - [x] Default guild/channel - - No way to set in client (yet?), `defaultChannel=` and `defaultGuild=` in your `.comcordrc`. +- [ ] Configuration + - [ ] Default guild/channel - [ ] Threads -- [x] Not have the token just be in argv +- [ ] Not have the token just be in argv - [x] Not have everything in one file diff --git a/package.json b/package.json index 923a5ad..a35a080 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,6 @@ "dependencies": { "chalk": "4.1.2", "discord-rpc": "^4.0.1", - "oceanic.js": "^1.1.2" + "eris": "github:abalabahaha/eris#dev" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 274b347..fd57a7f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3,47 +3,15 @@ lockfileVersion: 5.4 specifiers: chalk: 4.1.2 discord-rpc: ^4.0.1 - oceanic.js: ^1.1.2 + eris: github:abalabahaha/eris#dev dependencies: chalk: 4.1.2 discord-rpc: 4.0.1 - oceanic.js: 1.1.2 + eris: github.com/abalabahaha/eris/eb403730855714eafa36c541dbe2cb84c9979158 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'} @@ -58,13 +26,6 @@ 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'} @@ -84,11 +45,6 @@ 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: @@ -129,47 +85,12 @@ packages: whatwg-url: 5.0.0 dev: false - /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 + /opusscript/0.0.8: + resolution: {integrity: sha512-VSTi1aWFuCkRCVq+tx/BQ5q9fMnQ9pVZ3JU4UHKqTkf0ED3fKEPdr+gKAAl3IA2hj9rrP6iyq3hlcJq3HELtNQ==} + requiresBuild: 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'} @@ -181,18 +102,12 @@ packages: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} dev: false - /tslib/2.4.0: - resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} + /tweetnacl/1.0.3: + resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} + requiresBuild: true 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 @@ -217,8 +132,8 @@ packages: optional: true dev: false - /ws/8.9.0: - resolution: {integrity: sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==} + /ws/8.8.1: + resolution: {integrity: sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -230,6 +145,21 @@ 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 70fc347..88931d0 100644 --- a/src/commands/afk.js +++ b/src/commands/afk.js @@ -4,13 +4,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 d909c6d..aef4b7d 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.guilds - .get(comcord.state.currentGuild) - .channels.get(comcord.state.currentChannel) - .createMessage({content: `*${input}*`}); + await comcord.client.createMessage( + comcord.state.currentChannel, + `*${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 14d123a..343b46a 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.guilds - .get(comcord.state.currentGuild) - .channels.get(comcord.state.currentChannel) - .getMessages({limit}); + const messages = await comcord.client.getMessages( + comcord.state.currentChannel, + {limit} + ); messages.reverse(); console.log("--Beginning-Review".padEnd(72, "-")); diff --git a/src/commands/listChannels.js b/src/commands/listChannels.js index 7c18345..7d12c3e 100644 --- a/src/commands/listChannels.js +++ b/src/commands/listChannels.js @@ -1,3 +1,5 @@ +const Eris = require("eris"); + const {addCommand} = require("../lib/command"); function listChannels() { @@ -7,26 +9,34 @@ 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("VIEW_CHANNEL"); + 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"); + 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("VIEW_CHANNEL"); + const private = !perms.has(Eris.Constants.Permissions.readMessages); const name = (private ? "*" : "") + channel.name; @@ -37,12 +47,11 @@ function listChannels() { " " ) + " " + - (topic.length > 80 - (longest + 5) + (topic.length > 80 - longest + 9 ? topic.substring(0, 79 - (longest + 5)) + "\u2026" - : topic) + : topic.padStart(Math.min(80 - (longest + 5), longestTopic), " ")) ); } - console.log("-".repeat(80)); console.log(""); } diff --git a/src/commands/listGuilds.js b/src/commands/listGuilds.js index 9feffff..fc9fd3a 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.presence).length; + const online = [...guild.members.values()].filter((m) => m.status).length; guilds.push({name: guild.name, members: guild.memberCount, online}); } @@ -24,7 +24,6 @@ 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 27f1bd8..acaa2f5 100644 --- a/src/commands/listUsers.js +++ b/src/commands/listUsers.js @@ -39,23 +39,22 @@ function listUsers() { `\n[you are in '${guild.name}' in '${channel.name}' among ${guild.memberCount}]\n` ); - const online = [...guild.members.values()].filter((m) => m.presence); - online.sort((a, b) => a.tag.localeCompare(b.tag)); + 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.tag; + const name = member.user.username + "#" + member.user.discriminator; if (name.length + 3 > longest) longest = name.length + 3; } - const columns = Math.floor(process.stdout.columns / longest); + const columns = Math.ceil(process.stdout.columns / longest); let index = 0; for (const member of online) { - const name = member.tag; - const status = getStatus(member.presence.status); - const nameAndStatus = - (member.user.bot ? chalk.yellow(name) : chalk.reset(name)) + status; + const name = member.user.username + "#" + member.user.discriminator; + const status = getStatus(member.status); + const nameAndStatus = chalk.reset(name) + status; index++; process.stdout.write( diff --git a/src/commands/privateMessages.js b/src/commands/privateMessages.js deleted file mode 100644 index b7d0d6a..0000000 --- a/src/commands/privateMessages.js +++ /dev/null @@ -1,51 +0,0 @@ -const chalk = require("chalk"); - -const {addCommand} = require("../lib/command"); -const {startPrompt} = require("../lib/prompt"); -const {listUsers} = require("./listUsers"); - -function startDM(user) { - startPrompt(":msg> ", async function (input) { - if (input == "") { - console.log(`\n`); - } else { - try { - const channel = await user.createDM(); - await channel.createMessage({content: input}); - console.log(chalk.bold.green(`\n`)); - } catch (err) { - console.log("\n"); - } - } - }); -} - -addCommand("s", "send private", function () { - console.log("Provide a RECIPIENT"); - startPrompt(":to> ", function (who) { - let target; - for (const user of comcord.client.users.values()) { - if (user.tag == who) { - target = user; - break; - } - } - - if (target) { - console.log(""); - startDM(target); - } else { - listUsers(); - } - }); -}); - -addCommand("a", "answer a send", function () { - if (comcord.state.lastDM) { - console.log(chalk.bold.green(``)); - startDM(comcord.state.lastDM); - } else { - // FIXME: figure out the actual message in com - console.log(""); - } -}); diff --git a/src/commands/send.js b/src/commands/send.js index 2d04907..2402a5e 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.guilds - .get(comcord.state.currentGuild) - .channels.get(comcord.state.currentChannel) - .createMessage({content: input}); + await comcord.client.createMessage( + comcord.state.currentChannel, + input + ); if (comcord.state.afk == true) { comcord.state.afk = false; diff --git a/src/commands/switchGuild.js b/src/commands/switchGuild.js index c072a63..542b954 100644 --- a/src/commands/switchGuild.js +++ b/src/commands/switchGuild.js @@ -56,5 +56,3 @@ function switchGuild(input) { addCommand("G", "goto guild", function () { startPrompt(":guild> ", switchGuild); }); - -module.exports = {switchGuild}; diff --git a/src/index.js b/src/index.js index c95a040..ebab8bb 100644 --- a/src/index.js +++ b/src/index.js @@ -1,36 +1,15 @@ -const {Client, Constants} = require("oceanic.js"); -const DiscordRPC = require("discord-rpc"); +const Eris = require("eris"); const chalk = require("chalk"); -const fs = require("fs"); - -const rcfile = require("./lib/rcfile"); -const config = {}; - -if (fs.existsSync(rcfile.path)) { - console.log("% Reading " + rcfile.path + " ..."); - rcfile.readFile(config); -} +const DiscordRPC = require("discord-rpc"); const CLIENT_ID = "1026163285877325874"; const token = process.argv[2]; -if (!config.token && token) { - console.log("% Writing token to .comcordrc"); - config.token = token; - rcfile.writeFile(config); -} - -if (!config.token && !token) { - console.log("No token provided."); - process.exit(1); -} process.title = "comcord"; global.comcord = { - config, state: { - rpcConnected: false, startTime: Date.now(), currentGuild: null, currentChannel: null, @@ -42,30 +21,10 @@ global.comcord = { }, commands: {}, }; -const client = new Client({ - auth: - (config.allowUserAccounts == "true" ? "" : "Bot ") + - (token ?? config.token), +const client = new Eris("Bot " + token, { defaultImageFormat: "png", defaultImageSize: 1024, - gateway: { - intents: ["ALL"], - maxShards: 1, - concurrency: 1, - presence: { - status: "online", - activities: [ - { - name: "comcord", - type: 0, - application_id: CLIENT_ID, - timestamps: { - start: comcord.state.startTime, - }, - }, - ], - }, - }, + intents: Eris.Constants.Intents.all, }); comcord.client = client; const rpc = new DiscordRPC.Client({transport: "ipc"}); @@ -81,11 +40,10 @@ require("./commands/help"); const {sendMode} = require("./commands/send"); require("./commands/emote"); const {listGuilds} = require("./commands/listGuilds"); -const {switchGuild} = require("./commands/switchGuild"); // loads listChannels and listUsers +require("./commands/switchGuild"); // loads listChannels and listUsers require("./commands/switchChannel"); //loads listUsers require("./commands/history"); // includes extended history require("./commands/afk"); -require("./commands/privateMessages"); process.stdin.setRawMode(true); process.stdin.resume(); @@ -93,118 +51,63 @@ process.stdin.setEncoding("utf8"); client.once("ready", function () { console.log( - "Logged in as: " + chalk.yellow(`${client.user.tag} (${client.user.id})`) + "Logged in as: " + + chalk.yellow( + `${client.user.username}#${client.user.discriminator} (${client.user.id})` + ) ); comcord.state.nameLength = client.user.username.length + 2; listGuilds(); - if (config.defaultGuild) { - const guild = client.guilds.get(config.defaultGuild); - if (guild != null) { - if (config.defaultChannel) { - comcord.state.currentChannel = config.defaultChannel; - comcord.state.lastChannel.set( - config.defaultGuild, - config.defaultChannel - ); - } - switchGuild(guild.name); - } else { - console.log("% This account is not in the defined default guild."); - } - } else { - if (config.defaultChannel) { - console.log("% Default channel defined without defining default guild."); - } - } + client.editStatus("online", [ + { + application_id: CLIENT_ID, + name: "comcord", + timestamps: { + start: comcord.state.startTime, + }, + }, + ]); - if (client.user.bot) { - rpc - .login({ - clientId: CLIENT_ID, - }) - .catch(function () {}); - } + rpc + .login({ + clientId: CLIENT_ID, + }) + .catch(function () {}); }); client.on("error", function () {}); rpc.on("connected", function () { - comcord.state.rpcConnected = true; updatePresence(); }); -let retryingRPC = false; rpc.once("ready", function () { - rpc.transport.on("close", function () { - comcord.state.rpcConnected = false; - if (!retryingRPC) { - retryingRPC = true; - setTimeout(function () { - rpc.transport - .connect() - .then(() => { - retryingRPC = false; - }) - .catch((err) => { - retryingRPC = false; - rpc.transport.emit("close"); - }); - }, 5000); + rpc.transport.on("close", async function () { + try { + await rpc.transport.connect(); + } catch (err) { + rpc.transport.emit("close"); } }); }); rpc.on("error", function () {}); -client.on("messageCreate", async function (msg) { +client.on("messageCreate", function (msg) { if (msg.author.id === client.user.id) return; - if (msg.channelID && !msg.channel) { - try { - const dmChannel = await msg.author.createDM(); - if (dmChannel.id === msg.channelID) { - msg.channel = dmChannel; - } - } catch { - // - } - } - - if ( - (msg.channel ? msg.channel.id : msg.channelID) == - comcord.state.currentChannel || - msg.channel?.recipient != null - ) { + if (msg.channel.id == comcord.state.currentChannel) { if (comcord.state.inPrompt) { comcord.state.messageQueue.push(msg); } else { processMessage(msg); } } - - if (msg.channel?.recipient != null) { - comcord.state.lastDM = msg.author; - } }); -client.on("messageUpdate", async function (msg, old) { +client.on("messageUpdate", function (msg, old) { if (msg.author.id === client.user.id) return; - if (msg.channelID && !msg.channel) { - try { - const dmChannel = await msg.author.createDM(); - if (dmChannel.id === msg.channelID) { - msg.channel = dmChannel; - } - } catch { - // - } - } - - if ( - (msg.channel ? msg.channel.id : msg.channelID) == - comcord.state.currentChannel || - msg.channel?.recipient != null - ) { - if (old && msg.content == old.content) return; + if (msg.channel.id == comcord.state.currentChannel) { + if (msg.content == old.content) return; if (comcord.state.inPrompt) { comcord.state.messageQueue.push(msg); @@ -212,10 +115,6 @@ client.on("messageUpdate", async function (msg, old) { processMessage(msg); } } - - if (msg.channel?.recipient != null) { - comcord.state.lastDM = msg.author; - } }); process.stdin.on("data", async function (key) { @@ -249,89 +148,7 @@ process.stdin.on("data", async function (key) { } }); -if ( - config.allowUserAccounts == "true" && - !(token ?? config.token).startsWith("Bot ") -) { - if (fetch == null) { - console.log("Node v18+ needed for user account support."); - process.exit(1); - } - - (async function () { - comcord.clientSpoof = require("./lib/clientSpoof"); - const superProperties = await comcord.clientSpoof.getSuperProperties(); - - console.log("% Allowing non-bot tokens to connect"); - const connectLines = client.connect.toString().split("\n"); - connectLines.splice(0, 4); - connectLines.splice(-1, 1); - - const newConnect = new client.connect.constructor(connectLines.join("\n")); - client.connect = newConnect.bind(client); - - // gross hack - global.Constants_1 = Constants; - try { - global.Erlpack = require("erlpack"); - } catch { - global.Erlpack = false; - } - - console.log("% Injecting headers into request handler"); - client.rest.handler.options.userAgent = `Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) discord/${superProperties.client_version} Chrome/91.0.4472.164 Electron/13.6.6 Safari/537.36`; - client.rest.handler._request = client.rest.handler.request.bind( - client.rest.handler - ); - client.rest.handler.request = async function (options) { - options.headers = options.headers ?? {}; - options.headers["X-Super-Properties"] = - await comcord.clientSpoof.getSuperPropertiesBase64(); - - return await this._request.apply(this, [options]); - }.bind(client.rest.handler); - - console.log("% Setting gateway connection properties"); - client.shards.options.connectionProperties = superProperties; - - console.log("% Injecting application into READY payload"); - client.shards._spawn = client.shards.spawn.bind(client.shards); - client.shards.spawn = function (id) { - const res = this._spawn.apply(this, [id]); - const shard = this.get(id); - if (shard) { - shard._onDispatch = shard.onDispatch.bind(shard); - shard.onDispatch = async function (packet) { - if (packet.t == "READY") { - packet.d.application = {id: CLIENT_ID, flags: 565248}; - } - - const ret = await this._onDispatch.apply(this, [packet]); - - if (packet.t == "READY") { - for (const guild of packet.d.guilds) { - await this._onDispatch.apply(this, [ - { - t: "GUILD_CREATE", - d: guild, - }, - ]); - } - } - - return ret; - }.bind(shard); - } - - return res; - }.bind(client.shards); - - console.log("% Connecting to gateway now"); - await client.connect(); - })(); -} else { - client.connect(); -} +client.connect(); console.log("COMcord (c)left 2022"); console.log("Type 'h' for Commands"); @@ -380,7 +197,6 @@ setInterval(function () { } else { console.log(timeString); } - comcord.state.nameLength = client.user.username.length + 2; sentTime = true; } else if (seconds > 2 && sentTime) { sentTime = false; diff --git a/src/lib/clientSpoof.js b/src/lib/clientSpoof.js deleted file mode 100644 index d67cf17..0000000 --- a/src/lib/clientSpoof.js +++ /dev/null @@ -1,107 +0,0 @@ -/* - * This single file is **EXCLUDED** from the project license. - * - * (c) 2022 Cynthia Foxwell, all rights reserved. - * Permission is hereby granted to redistribute this file ONLY with copies of comcord. - * You may not reverse engineer, modify, copy, or redistribute this file for any other uses outside of comcord. - */ - -const os = require("os"); - -async function fetchMainPage() { - const res = await fetch("https://discord.com/channels/@me"); - return await res.text(); -} - -async function fetchAsset(assetPath) { - return await fetch("https://discord.com/" + assetPath).then((res) => - res.text() - ); -} - -const MATCH_SCRIPT = '