mirror of
https://github.com/keanuplayz/TravBot-v3.git
synced 2024-08-15 02:33:12 +00:00
Reimplemented music functionality.
...in the most disgusting way possible!
This commit is contained in:
parent
0c0fc083cf
commit
942489630f
4 changed files with 223 additions and 0 deletions
130
docs/MusicStructure.md
Normal file
130
docs/MusicStructure.md
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
# The commands
|
||||||
|
|
||||||
|
```lang-none
|
||||||
|
- "mhelp" - Display a help embed.
|
||||||
|
- "play" - Adds a song to the queue and plays it.
|
||||||
|
- "skip" - Skips the currently playing track.
|
||||||
|
- "queue" - Shows the current queue.
|
||||||
|
- "stop" - Stops currently playing media and leaves the voice channel.
|
||||||
|
- "np" - Displays the currently playing track.
|
||||||
|
- "pause" - Pauses the currently playing track.
|
||||||
|
- "resume" - Resumes the currently paused track.
|
||||||
|
- "volume" - Changes the global volume of the bot.
|
||||||
|
- "loop" - Loops the current queue.
|
||||||
|
- "seek" - Seeks through the queue.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Now that the actual info about the functionality of this thing is out of the way, its storytime!
|
||||||
|
|
||||||
|
## The music structure
|
||||||
|
|
||||||
|
Originally, I, keanucode, aimed to port the music structure of TravBot-v2 to this version.
|
||||||
|
|
||||||
|
This would have been much too difficult of a task for three main reasons:
|
||||||
|
|
||||||
|
1. The original code is written badly.
|
||||||
|
2. The original code is written by *another person*.
|
||||||
|
3. The original code is written in JS.
|
||||||
|
|
||||||
|
These three reasons make porting the structure *considerably* harder.
|
||||||
|
|
||||||
|
So, of course, I resorted to different matters. I present: [discord.js-lavalink-musicbot](https://github.com/BluSpring/discord.js-lavalink-musicbot). ([npmjs.org](https://www.npmjs.com/package/discord.js-lavalink-musicbot))
|
||||||
|
|
||||||
|
This *pre-built* module utilises [Lavalink](https://github.com/Frederikam/Lavalink), which is an audio sending node based on [Lavaplayer](https://github.com/sedmelluq/lavaplayer) and [JDA-Audio](https://github.com/DV8FromTheWorld/JDA-Audio).
|
||||||
|
|
||||||
|
I've previously considered using Lavalink, but it turned out to be more difficult for me to implement than I thought.
|
||||||
|
|
||||||
|
So, I tried again with `discord.js-lavalink-musicbot`.
|
||||||
|
|
||||||
|
*ahem*...
|
||||||
|
|
||||||
|
**The library was written in such a way that it didn't work!**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fixing the broken library
|
||||||
|
|
||||||
|
First off; in the library's interface `LavaLinkNodeOptions`, option `id` was a *required* option:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface LavalinkNodeOptions {
|
||||||
|
host: string;
|
||||||
|
id: string;
|
||||||
|
/* ... */
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here's the catch. `id` was referenced *nowhere* in the library code.
|
||||||
|
It was *literally* useless.
|
||||||
|
|
||||||
|
So, I lazily removed that by adding a `?` to the parameter. (`id?:`)
|
||||||
|
|
||||||
|
Next up:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
declare function LavalinkMusic(client: Client, options: MusicbotOptions) {}
|
||||||
|
```
|
||||||
|
|
||||||
|
First up, the TS compiler reports that: `An implementation cannot be declared in ambient contexts. ts(1183)`
|
||||||
|
|
||||||
|
Secondly, this function, which makes up the entirety of the library, explicitly returns an `any` type. As you can see, the *declared* function returns... no specific type.
|
||||||
|
|
||||||
|
So, that had to be changed to:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
- declare function LavalinkMusic(client: Client, options: MusicbotOptions) {}
|
||||||
|
+ declare function LavalinkMusic(client: Client, options: MusicbotOptions): any
|
||||||
|
```
|
||||||
|
|
||||||
|
...next up:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
try {
|
||||||
|
const res = await axios.get(
|
||||||
|
/* ... */
|
||||||
|
`https://${music.lavalink.restnode.host}:`
|
||||||
|
/* ... */
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
The library tries to fetch the URL of the Lavalink node. With *HTTPS*.
|
||||||
|
|
||||||
|
I think you can see where this is going. An SSL error.
|
||||||
|
|
||||||
|
Changed the `https` to `http`, and all is well.
|
||||||
|
|
||||||
|
I republished the library under the name "[discord.js-lavalink-lib](https://npmjs.org/package/discord.js-lavalink-lib)" so I can easily install the non-broken version.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Implementing the functionality
|
||||||
|
|
||||||
|
There's nothing much to do there, honestly. Only one edit to the original snippet has to be made.
|
||||||
|
|
||||||
|
The original example snippet has the following:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const Discord = require('discord.js');
|
||||||
|
const client = new Discord.Client();
|
||||||
|
client.music = new (require('discord.js-lavalink-musicbot'))(client, {
|
||||||
|
/* ...config... */
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
As you can see, this is... kind of disgusting. And on top of that, incompatible with TS.
|
||||||
|
|
||||||
|
So, we have to change a few things. First off, since TS is strict, it'll tell you that `music` doesn't exist on `client`. Which is true. The `Client` class has no `music` property.
|
||||||
|
|
||||||
|
So, we make `client.` an `any` type using keyword `as`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const Discord = require('discord.js');
|
||||||
|
const client = new Discord.Client();
|
||||||
|
(client as any).music = LavalinkMusic(client, {
|
||||||
|
/* ...config... */
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
And that's about it. Launch up Lavalink, and start the bot.
|
70
package-lock.json
generated
70
package-lock.json
generated
|
@ -19,6 +19,25 @@
|
||||||
"mime-types": "^2.1.12"
|
"mime-types": "^2.1.12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@lavacord/discord.js": {
|
||||||
|
"version": "0.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lavacord/discord.js/-/discord.js-0.0.5.tgz",
|
||||||
|
"integrity": "sha512-qc2lw0zB48fq4SrSlpMJOmogUXIeM5YvufQfPg0ubjp7jqm20JnOXF9fliy1MPdcKPnZ8LwIZ222H0+ghGzP/Q==",
|
||||||
|
"requires": {
|
||||||
|
"lavacord": "^1.1.9"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"lavacord": {
|
||||||
|
"version": "1.1.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/lavacord/-/lavacord-1.1.9.tgz",
|
||||||
|
"integrity": "sha512-haZghbblO1w3Hodc9q63ZWgV5zA/jB6xFKS17fImK5aIdn0PkKuZ6AsJBxMFpR275v8GNYOxg6cTQBYBQ+batQ==",
|
||||||
|
"requires": {
|
||||||
|
"node-fetch": "^2.6.0",
|
||||||
|
"ws": "^7.3.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/color-name": {
|
"@types/color-name": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
|
||||||
|
@ -142,6 +161,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||||
},
|
},
|
||||||
|
"axios": {
|
||||||
|
"version": "0.19.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
|
||||||
|
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
|
||||||
|
"requires": {
|
||||||
|
"follow-redirects": "1.5.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||||
|
@ -373,6 +400,17 @@
|
||||||
"ws": "^7.3.1"
|
"ws": "^7.3.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"discord.js-lavalink-lib": {
|
||||||
|
"version": "0.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/discord.js-lavalink-lib/-/discord.js-lavalink-lib-0.1.5.tgz",
|
||||||
|
"integrity": "sha512-cgQR1JgNav2BiFkuPBV03fNCETm+t70fXaImSiEL0hqookgTdGb+ZxfbRvzmtvGvch6MqfH2AaAYDVvLo5PR4Q==",
|
||||||
|
"requires": {
|
||||||
|
"@lavacord/discord.js": "0.0.5",
|
||||||
|
"axios": "^0.19.2",
|
||||||
|
"discord.js": "^12.2.0",
|
||||||
|
"lavacord": "^1.1.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
"duplexer": {
|
"duplexer": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
|
||||||
|
@ -512,6 +550,29 @@
|
||||||
"is-buffer": "~2.0.3"
|
"is-buffer": "~2.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"follow-redirects": {
|
||||||
|
"version": "1.5.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
|
||||||
|
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
|
||||||
|
"requires": {
|
||||||
|
"debug": "=3.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"debug": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"from": {
|
"from": {
|
||||||
"version": "0.1.7",
|
"version": "0.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
|
||||||
|
@ -781,6 +842,15 @@
|
||||||
"esprima": "^4.0.0"
|
"esprima": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"lavacord": {
|
||||||
|
"version": "1.1.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/lavacord/-/lavacord-1.1.9.tgz",
|
||||||
|
"integrity": "sha512-haZghbblO1w3Hodc9q63ZWgV5zA/jB6xFKS17fImK5aIdn0PkKuZ6AsJBxMFpR275v8GNYOxg6cTQBYBQ+batQ==",
|
||||||
|
"requires": {
|
||||||
|
"node-fetch": "^2.6.0",
|
||||||
|
"ws": "^7.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"locate-path": {
|
"locate-path": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": "^4.1.0",
|
"chalk": "^4.1.0",
|
||||||
"discord.js": "^12.4.0",
|
"discord.js": "^12.4.0",
|
||||||
|
"discord.js-lavalink-lib": "^0.1.5",
|
||||||
"inquirer": "^7.3.1",
|
"inquirer": "^7.3.1",
|
||||||
"moment": "^2.27.0"
|
"moment": "^2.27.0"
|
||||||
},
|
},
|
||||||
|
|
22
src/index.ts
22
src/index.ts
|
@ -3,11 +3,33 @@ import setup from './setup';
|
||||||
import { Config } from './core/structures';
|
import { Config } from './core/structures';
|
||||||
import { loadCommands } from './core/command';
|
import { loadCommands } from './core/command';
|
||||||
import { loadEvents } from './core/event';
|
import { loadEvents } from './core/event';
|
||||||
|
import 'discord.js-lavalink-lib';
|
||||||
|
import LavalinkMusic from 'discord.js-lavalink-lib';
|
||||||
|
|
||||||
// This is here in order to make it much less of a headache to access the client from other files.
|
// This is here in order to make it much less of a headache to access the client from other files.
|
||||||
// This of course won't actually do anything until the setup process is complete and it logs in.
|
// This of course won't actually do anything until the setup process is complete and it logs in.
|
||||||
export const client = new Client();
|
export const client = new Client();
|
||||||
|
|
||||||
|
(client as any).music = LavalinkMusic(client, {
|
||||||
|
lavalink: {
|
||||||
|
restnode: {
|
||||||
|
host: 'localhost',
|
||||||
|
port: 2333,
|
||||||
|
password: 'youshallnotpass',
|
||||||
|
},
|
||||||
|
nodes: [
|
||||||
|
{
|
||||||
|
host: 'localhost',
|
||||||
|
port: 2333,
|
||||||
|
password: 'youshallnotpass',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
prefix: '!!',
|
||||||
|
helpCmd: 'mhelp',
|
||||||
|
admins: ['717352467280691331'],
|
||||||
|
});
|
||||||
|
|
||||||
// Begin the command loading here rather than when it's needed like in the message event.
|
// Begin the command loading here rather than when it's needed like in the message event.
|
||||||
setup.init().then(() => {
|
setup.init().then(() => {
|
||||||
loadCommands();
|
loadCommands();
|
||||||
|
|
Loading…
Reference in a new issue