Compare commits

...

121 Commits
dev ... master

Author SHA1 Message Date
Emily 4241d54efd Merge pull request 'Fixing issue where woomy would endlessly type from an api error' (#2) from ItzRock/woomy:master into master
Reviewed-on: #2
2022-12-17 10:30:00 +00:00
ItzRock eb9c98612a Fixing issue where woomy would endlessly type from an api error 2022-02-19 22:18:39 +00:00
Emily 7cd499e10c Merge pull request 'Update 'resources/other/lyrics.json'' (#1) from f3d0r4/woomy:master into master
Reviewed-on: #1
2021-12-28 07:47:19 +00:00
f3d0r4 bc18ea8abd Update 'resources/other/lyrics.json'
Fixed typos of capitalization in lyrics as this would cause the command to unexpectedly fail
2021-11-25 19:36:15 +00:00
Emily 90a0aea5bf 1.4.8 (music stuff) 2021-10-15 22:29:21 +11:00
Emily ddb81ed114 minor changes to invidious endpoint format 2021-10-15 22:29:12 +11:00
Emily 55c546aa6a remove hardcoded invidious instances 2021-10-15 22:28:24 +11:00
Emily 3e80f2c5a2 updated to 1.4.7 2021-09-17 12:38:34 +10:00
Emily 5289977fb5 fix incorrect help info 2021-09-17 12:38:25 +10:00
Emily 684d49ae5b module updates 2021-09-17 12:38:15 +10:00
Emily 82bfed57aa YOUTHUBE FUCKING DSOTP CHANGING MSHIT FUCKER 2021-05-28 22:26:53 +10:00
Emily 22ac7bee2e include link to message in messageUpdate logs 2021-05-13 09:12:42 +10:00
Emily f24757fedf update deps 2021-05-13 09:01:28 +10:00
Emily 05541fe9be GO AWYA FLIES
AND OTHER GROSS BUGS
2021-04-29 12:22:30 +10:00
Emily 2564f742d4 dont silently fail when API fetch fails 2021-04-28 14:50:58 +10:00
Emily 2481dacb91 WASNT MY FAULT SHIT BROKE BLAME YOUTUBE 2021-04-13 17:25:31 +10:00
Emily f09567b239 THANK YOU FOR UNANNOUNCED API CHANGES 2021-04-13 17:25:16 +10:00
Emily 8f271a9a4e why fix bugs properly when you can ignore them 2021-04-03 15:14:12 +11:00
Emily 67c9fdfd3a bug fixes 2021-04-03 15:13:08 +11:00
Emily 5d9bbb4431 fix user error resp msg 2021-04-03 15:00:56 +11:00
Emily 26a39a76fc stage channels 2021-04-03 15:00:43 +11:00
Emily 878cab71e6 clear music msg channel on dispatcher end 2021-03-18 13:44:03 +11:00
Emily 479eeeea44 SHE CNA FUCKIGN SING AGAIN 2021-03-18 13:02:59 +11:00
Emily 1feb88451c stupid ass bitch bot 2021-03-18 12:10:09 +11:00
Emily fa99b7b1a1 missing config values 2021-03-18 12:09:28 +11:00
Emily c59bf6c245 oopsie 2021-03-01 13:05:47 +11:00
Emily 58c90ddd9d 1.4 - splatoon commands! 2021-03-01 12:58:39 +11:00
Emily 9373d9b2de THINGS 2021-03-01 12:58:28 +11:00
Emily 45d600ab27 add reactions intent 2021-03-01 12:58:11 +11:00
Emily 75b2db1a97 Merge branch 'master' of https://github.com/mudkipscience/woomy 2021-03-01 11:56:39 +11:00
Emily 42bb347bbf update dependencies 2021-03-01 11:56:33 +11:00
flgx 9326a2da3e
Merge pull request #23 from AStainlessSteelSink/master
Bind to SIGINT so Ctrl+C properly shuts down the bot
2021-02-24 08:45:13 +00:00
Lucian 0f587bcfff
Add bind to SIGINT 2021-02-23 12:58:40 -08:00
Emily 8058f3dced
Update README.md 2020-11-09 01:39:36 +00:00
Emily 8fc98efe55 new restart command x2 2020-10-29 20:23:34 +11:00
Emily a2f46051e1 working restart command 2020-10-29 20:16:41 +11:00
Emily 00196b201d new api 2020-10-27 15:06:27 +11:00
Emily 9bf1a81143 update to 1.3.13 2020-10-23 12:34:41 +11:00
Emily 98255e73aa new garfield command 2020-10-23 12:34:20 +11:00
Emily ef0e2d8594 update version 2020-10-23 12:15:05 +11:00
Emily a581f07088 remove fields dependent on presence data 2020-10-23 12:14:40 +11:00
Emily 7112c8ff9d update dependencies 2020-10-23 12:14:31 +11:00
Emily 564814a3de start requesting only the intents we need 2020-10-23 12:14:23 +11:00
Emily 05b35fc207 wtf lol 2020-10-05 18:42:06 +11:00
Emily ffd056972d fix coinflip 2020-10-05 18:38:22 +11:00
Emily 83990e47f1 Merge branch 'master' of https://github.com/mudkipscience/woomy 2020-10-03 10:53:42 +10:00
Emily 1fba1e9a4b 1.3.10 2020-10-03 10:53:38 +10:00
Emily f31f75ae79 no longer crashes when invalid equation is entered 2020-10-03 10:53:16 +10:00
Emily ba4781f0f4 request intents from gateway 2020-10-03 10:53:00 +10:00
FLGX 6d1d4a0441
Do not exit on uncaughtException
I think I forgot this here while testing something
2020-08-29 20:58:35 +02:00
Emily 18db7e597d update version number 2020-08-16 18:21:04 +10:00
Emily 3dcdd1f2ad rate can no longer ping roles 2020-08-16 18:20:26 +10:00
Emily 4bbdac7070 Renamed blacklist to blocklist 2020-08-16 18:19:28 +10:00
Emily 61e6951833 totally didnt steal this fron nyandroid 2020-08-05 17:08:56 +10:00
Emily 90e9793377 update to 1.3.7 2020-08-02 13:35:17 +10:00
Emily 0009d569ca actually fixed fixmusic 2020-08-02 13:35:09 +10:00
Emily d257d6e730 fixed "you cant vote twice" bug 2020-07-30 19:13:44 +10:00
Emily 808659246e say command can no longer mention roles 2020-07-30 19:04:54 +10:00
Emily ce10038a95 update version.json 2020-07-30 19:04:28 +10:00
TheCakeChicken f5a636b527
Disable command 2020-06-28 23:18:16 +01:00
Emily 21d4df30b3 disabled neko/nekogif 2020-06-18 20:46:42 +10:00
Lukáš Horáček 101c1581e9
enable nekogif 2020-06-17 13:55:28 +02:00
Emily 92c27be3be updated version 2020-06-17 18:13:41 +10:00
Emily 0c6e018580 added wag 2020-06-17 18:13:33 +10:00
Emily 514d1d15bc renamed foxgirl kitsune 2020-06-17 18:13:26 +10:00
Emily ab59d90bda re-enabled neko and nekogif 2020-06-17 18:12:41 +10:00
Lukáš H f8d9ec1e2f
remove stack print 2020-06-06 11:24:35 +02:00
Lukáš H 5cf74a65ab
revert 2020-06-06 11:24:12 +02:00
Lukáš H 95ce384eee
add local=true to invidious 2020-06-06 11:15:12 +02:00
Lukáš H d9ac55f8a1
print stack of error 2020-06-06 11:05:11 +02:00
Lukáš H d92f9ffb8b
fix 2020-06-06 10:49:32 +02:00
Lukáš H 6412ea346d
remove debugs 2020-06-06 10:38:00 +02:00
Lukáš H de956b5197
use invidious for music instead of youtube 2020-06-06 10:37:13 +02:00
Lukáš H a155b7dde7
add back highwatermark 2020-06-06 10:24:35 +02:00
Lukáš H 07c9972ce0
use git version of ytdl-core-discord 2020-06-06 10:24:22 +02:00
Lukáš H 52197a939e
remove watermark and see if it works 2020-06-06 10:22:10 +02:00
Lukáš H feab4749b3
more debug 2020-06-06 10:18:53 +02:00
Lukáš H 8de3c6ccad
Music debugs, cant reproduce locally 2020-06-06 10:14:56 +02:00
Lukáš H 8575fb7906
log music dispatcher errors 2020-06-06 10:07:27 +02:00
Lukáš H d585ffa45c
fix music fixer inside of play function 2020-06-06 09:57:46 +02:00
Emily 47f163dcab forgot to remove stuff from v2 2020-05-30 13:59:50 +10:00
Emily 7a1964fb4c pride update cause i couldn't wait until june 2020-05-30 13:55:04 +10:00
Emily dddaeba8e3 fixmusic can be used by users, invidious issues 2020-05-28 17:52:15 +10:00
Emily ac5d3dc78c bot can no longer use @here 2020-05-22 12:16:57 +10:00
agentdoesnotexist ebc0b198f0 Fixed typo 2020-05-20 16:54:20 +02:00
Lukáš H f9d7743caf Merge branch 'master' of github.com:woomyware/woomy 2020-05-12 10:42:03 +02:00
Lukáš H 63f5dbc6d3
message.content: Remove zero-width characters. 2020-05-12 10:41:48 +02:00
Emily 7c33e44e00 disable typing for music 2020-05-09 16:48:25 +10:00
Emily e633c6b65a update version 2020-05-09 16:47:06 +10:00
Emily b6b810b4de fixed skip + rate 2020-05-09 16:43:30 +10:00
Lukáš H 1837e6e751 Merge branch 'master' of github.com:mudkipscience/woomy 2020-05-04 22:04:42 +02:00
Lukáš H 40b9a4dd93
discordapp.com -> discord.com 2020-05-04 22:04:40 +02:00
Emily cc7222bec0 Merge branch 'master' of https://github.com/mudkipscience/woomy 2020-05-02 18:49:03 +10:00
Emily b2b5431ee4 fixed bugs 2020-05-02 18:48:58 +10:00
Emily e60985dbac
Merge pull request #17 from IFcoltransG/patch-1
Spelling mistake in Bohemian Rhapsody description
2020-05-02 12:14:35 +10:00
IFcoltransG bdbea2abb9
Spelling mistake in Bohemian Rhapsody description 2020-05-02 13:14:28 +12:00
Emily fef8c0e5b0 update changelog 2020-04-30 14:48:56 +10:00
Emily 59084b07cb Add new music commands 2020-04-30 14:44:23 +10:00
Emily 42df6b71c7 backport new ship command 2020-04-30 14:11:02 +10:00
Emily 0b8c4ec38d player monitor to hopefully help music break less 2020-04-30 14:06:41 +10:00
Emily 6d60845546 new music module 2020-04-30 14:06:15 +10:00
Emily d1acf688c9 update music commands to support new module 2020-04-30 14:06:09 +10:00
Emily def26feab3 update rip.js to use node-fetch instead of request 2020-04-30 13:32:19 +10:00
Emily d07a680b77 update configTemplate 2020-04-30 13:18:44 +10:00
Emily a5ee79476f update/remove dependencies 2020-04-30 13:16:49 +10:00
Emily 0cb1d15f12 remove music functions from functions.js 2020-04-30 13:10:53 +10:00
Emily 7eab55b981 disabled problematic commands 2020-04-21 17:33:18 +10:00
Emily 64aa46a04b Merge branch 'master' of https://github.com/mudkipscience/woomy 2020-04-21 17:09:32 +10:00
Emily debd47fe02 cmd.conf.enabled actually does something now 2020-04-21 17:09:27 +10:00
Emily 7e4b355627 update version 2020-04-21 17:06:03 +10:00
Emily 5fd8da2702 fixed skip command 2020-04-21 17:05:40 +10:00
Emily 536c6f2b2a
Update package.json 2020-04-20 02:49:36 +00:00
TheCakeChicken f702254603 actually disable potentially NSFW commands 2020-04-19 00:40:05 +01:00
TheCakeChicken 128f12041e Merge branch 'master' of github.com:mudkipscience/Woomy 2020-04-19 00:23:02 +01:00
TheCakeChicken 79b14f60aa Remove potentially NSFW content 2020-04-19 00:22:57 +01:00
FLGX 57ad4914f8
set volume to 25% by default for now before v2 woomy is released 2020-04-18 21:34:41 +02:00
Emily 0662be72d1
why are unhandled rejections trying to log a stack 2020-04-18 04:11:13 +00:00
Emily c188356030 update ytdl-core 2020-04-17 17:14:42 +10:00
FLGX 276c26d3c7
remove member username/id print on command 2020-04-08 11:10:44 +02:00
FLGX c7d3ecd6da
Fix music in v1 woomy 2020-04-08 11:04:52 +02:00
TheCakeChicken b81db48f7b
typo 2020-03-30 23:28:16 +01:00
61 changed files with 1513 additions and 703 deletions

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
node_modules
data
config.js
package-lock.json
package-lock.json
.env

View File

@ -1,10 +1,15 @@
# Woomy
Woomy is a all-purpose discord bot built off the [guidebot](https://github.com/AnIdiotsGuide/guidebot) base and coded in node.js using discord.js.
# How to use
The easiest way to use Woomy is to invite it to your server with [this link.](https://discordapp.com/oauth2/authorize?client_id=435961704145485835&permissions=2134240503&scope=bot) It is hosted 24/7 and automatically updates itself when a new release is made available, making sure you always get the newest features.
# Notice
Woomy v1 (this repository) is currently only being maintained. Bugs and issues will be fixed if they come up, but no new features will be added. Pull requests that add new features to Woomy should instead be contributed to the version 2 codebase, found [here](https://github.com/woomyware/v2).
You can also self-host! Some modificatiomns to the code will need to be made before Woomy will run on your machine, but anyone who can read errors will figure out what needs to be changed pretty quickly :P
When Woomy v2 is released, Woomy v1 will no longer be maintained.
# How to use
The easiest way to use Woomy is to invite it to your server with [this link.](https://discord.com/oauth2/authorize?client_id=435961704145485835&permissions=2134240503&scope=bot) It is hosted 24/7 and automatically updates itself when a new release is made available, making sure you always get the newest features.
You can also self-host! Some modifications to the code will need to be made before Woomy will run on your machine, but anyone who can read errors will figure out what needs to be changed pretty quickly :P
# Requirements
- git

View File

@ -11,8 +11,14 @@ const config = {
// Tokens
"token": "", // Your bot's token.
"devtoken": "", // (optional) another token, meant for a bot used for development
"ytkey": "", // Youtube API key, needed for music searching to work
"dblkey": "", // top.gg key, sends bot statistics to top.gg. You do not need this.
"dblkey": "", // (optional) top.gg key, sends bot statistics to top.gg. You do not need this.
"sentry": "",
"server": "",
// Configurable API endpoints
endpoints: {
invidious: ''
},
// Default per-server settings
"defaultSettings" : {

View File

@ -6,8 +6,17 @@ const Discord = require('discord.js');
const { promisify } = require('util');
const readdir = promisify(require('fs').readdir);
const Enmap = require('enmap');
const sentry = require('@sentry/node');
const chalk = require('chalk');
const client = new Discord.Client();
const client = new Discord.Client({ ws: { intents: [
'GUILDS',
'GUILD_MEMBERS',
'GUILD_EMOJIS',
'GUILD_VOICE_STATES',
'GUILD_MESSAGES',
'DIRECT_MESSAGES',
'GUILD_MESSAGE_REACTIONS',
]}});
try {
client.config = require('./config');
@ -47,6 +56,10 @@ if(client.config.devmodeEnabled == true && process.env['USER'] != 'container') {
const DBL = require("dblapi.js");
const dblapi = new DBL(client.config.dblkey, client);
};
if(client.config.sentry.length > 0) {
sentry.init({ dsn: client.config.sentry });
};
};
client.commands = new Enmap();
@ -90,4 +103,10 @@ const init = async () => {
};
};
init();
process.on('SIGINT', function(){
client.logger.info("Disconnecting...")
client.destroy();
process.exit();
});
init();

View File

@ -1,34 +1,31 @@
{
"name": "woomy",
"version": "1.1.0",
"version": "1.2.3",
"description": "Woomy is a all-purpose discord bot built off the guidebot base and coded in node.js using discord.js.",
"main": "index.js",
"dependencies": {
"@discordjs/opus": "^0.1.0",
"better-sqlite3": "^5.4.1",
"chalk": "^3.0.0",
"dblapi.js": "^2.3.1",
"discord.js": "^12.0.2",
"enmap": "^5.2.4",
"garfield": "^1.1.2",
"get-youtube-id": "^1.0.1",
"@discordjs/opus": "^0.6.0",
"@sentry/node": "^6.12.0",
"better-sqlite3": "^7.4.0",
"chalk": "^4.1.1",
"dblapi.js": "^2.4.1",
"discord-paginator.js": "git+https://gitdab.com/embee/discord-paginator.js",
"discord.js": "^12.5.3",
"enmap": "^5.8.5",
"ffmpeg-static": "^4.3.0",
"hastebin-gen": "^2.0.5",
"moment": "^2.24.0",
"moment": "^2.29.1",
"moment-duration-format": "^2.3.2",
"nekos.life": "^2.0.5",
"node-fetch": "^2.6.0",
"openweather-apis": "^4.2.0",
"prism-media": "^1.2.1",
"randomcolor": "^0.5.4",
"node-fetch": "^2.6.1",
"pretty-ms": "^7.0.1",
"randomcolor": "^0.6.2",
"relevant-urban": "^2.0.0",
"request": "^2.88.2",
"to-zalgo": "^1.0.1",
"urban": "^0.3.2",
"weather-js": "^2.0.0",
"youtube-info": "^1.3.2",
"ytdl-core-discord": "^1.1.0"
"ytdl-core": "^4.9.1"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},

View File

@ -15,19 +15,19 @@
"If I'm not back again this time tomorrow",
"Carry on, carry on as if nothing really matters",
"Too late, my time has come",
"sends shivers down my spine, body's aching all the time",
"Sends shivers down my spine, body's aching all the time",
"Goodbye, everybody, I've got to go",
"Gotta leave you all behind and face the truth",
"Mama, ooh, (Anyway the wind blows)",
"I don't wanna die",
"I sometimes wish I'd never been born at all",
"i see a little silhouetto of a man",
"I see a little silhouetto of a man",
"Scaramouche! Scaramouche! will you do the Fandango?",
"Thunderbolt and lightning, very, very fright'ning me",
"(Galileo) Galileo, (Galileo) Galileo, Galileo Figaro magnifico",
"I'm just a poor boy, nobody loves me",
"He's just a poor boy from a poor family",
"spare him his life from this monstrosity",
"Spare him his life from this monstrosity",
"Easy come, easy go, will you not let me go?",
"Bismillah! No, we will not let you go",
"(Let him go!) Bismillah! We will not let you go",
@ -35,17 +35,17 @@
"(Let me go) Will not let you go",
"(Let me go) Will not let you go",
"(Let me go) Ah",
"no, no, no, no, no, no, no",
"No, no, no, no, no, no, no",
"(Oh mamma mia, mamma mia) Mamma mia, let me go",
"Beelzebub has the devil put aside for me, for me, for me!",
"So you think you can stone me and spit in my eye?",
"so you think you can love me and leave me to die?",
"So you think you can love me and leave me to die?",
"Oh baby, can't do this to me, baby!",
"Just gotta get out, just gotta get right outta here!",
"Nothing really matters, anyone can see",
"nothing really matters",
"Nothing really matters",
"Nothing really matters, to me",
"any way the wind blows"
"Any way the wind blows"
],
"creeper": [

View File

@ -7,7 +7,7 @@ exports.run = async (client, message, [action, ...member]) => {
if(!action) {
return message.channel.send(
`<:error:466995152976871434> You didn't tell me if I was meant to add or remove someone from the blacklist! Usage: \`${client.commands.get(`blacklist`).help.usage}\``
`<:error:466995152976871434> You didn't tell me if I was meant to add or remove someone from the blocklist! Usage: \`${client.commands.get(`blocklist`).help.usage}\``
)
}
@ -15,7 +15,7 @@ exports.run = async (client, message, [action, ...member]) => {
if(!member) {
return message.channel.send(
`<:error:466995152976871434> You didn't tell me who to blacklist! Usage: \`${client.commands.get(`blacklist`).help.usage}\``
`<:error:466995152976871434> You didn't tell me who to add to the blocklist! Usage: \`${client.commands.get(`blocklist`).help.usage}\``
);
};
@ -41,18 +41,18 @@ exports.run = async (client, message, [action, ...member]) => {
};
if (user.id === message.guild.owner.id) {
return message.channel.send("<:error:466995152976871434> You can't blacklist the owner!")
return message.channel.send("<:error:466995152976871434> You can't add the owner to the blocklist!")
};
let admin = message.guild.member(message.author)
if (user.roles.highest.position >= admin.roles.highest.position && admin.user.id !== message.guild.ownerID) {
return message.channel.send(
`<:error:466995152976871434> You can't blacklist people higher ranked than yourself!`
`<:error:466995152976871434> You can't add people higher ranked than yourself to the blocklist!`
);
};
if(user.id === message.member.id) {
return message.channel.send('<:error:466995152976871434> You can\'t blacklist yourself!');
return message.channel.send('<:error:466995152976871434> You can\'t add yourself to the blocklist!');
};
let blacklisted = false;
@ -65,13 +65,13 @@ exports.run = async (client, message, [action, ...member]) => {
});
if(blacklisted == true) {
return message.channel.send('<:error:466995152976871434> This person has already been blacklisted!');
return message.channel.send('<:error:466995152976871434> This person is already on the blocklist!');
};
};
client.settings.push(message.guild.id, user.id, "blacklisted")
return message.channel.send(`<:success:466995111885144095> Blacklisted \`${user.user.tag}\``)
return message.channel.send(`<:success:466995111885144095> Added \`${user.user.tag}\` to the blocklist.`)
};
@ -99,26 +99,26 @@ exports.run = async (client, message, [action, ...member]) => {
});
if(blacklisted != true) {
return message.channel.send('<:error:466995152976871434> This user isn\'t blacklisted!');
return message.channel.send('<:error:466995152976871434> This user isn\'t on the blocklist!');
};
client.settings.remove(message.guild.id, user.id, "blacklisted")
return message.channel.send(`<:success:466995111885144095> Removed \`${user.user.tag}\` from the blacklist.`)
return message.channel.send(`<:success:466995111885144095> Removed \`${user.user.tag}\` from the blocklist.`)
};
};
exports.conf = {
enabled: true,
guildOnly: true,
aliases: [],
aliases: ['bl'],
permLevel: "Administrator",
requiredPerms: []
};
exports.help = {
name: "blacklist",
name: "blocklist",
category: "Moderation",
description: "Allows you to configure Woomy's blacklist. Blacklisted users cannot use commands.",
usage: "blacklist [add/remove] [member]"
description: "Allows you to configure Woomy's blocklist. Users on the blocklist cannot use commands.",
usage: "blocklist [add/remove] [member]"
};

View File

@ -40,6 +40,6 @@ exports.conf = {
exports.help = {
name: "bohemian_rhapsody",
category: "Fun",
description: "Queen kareoke",
description: "Queen karaoke",
usage: "bohemian_rhapsody"
};

View File

@ -1,42 +1,46 @@
var allowed = ["+", "-", "*", "/", "(", ")", " "];
exports.run = (client, message, args) => {
let exercise = args.join(" ");
if (!exercise) {
return message.channel.send(
`<:error:466995152976871434> No equation provided. Usage :\`${client.commands.get(`calculate`).help.usage}\``
);
}
for (var i = 0; i < exercise.length; i++) {
let c = exercise.charAt(i);
let found = allowed.find((element) => element === c);
if(c == "0") found = true;
if(!(Number(c) || found))
{
return message.channel.send(
`<:error:466995152976871434> Invalid equation. Please use \`*\` for multiplication and \`/\` for division!`
);
}
}
let result = (new Function( 'return ' + exercise )());
var allowed = ["+", "-", "*", "/", "(", ")", " "];
exports.run = (client, message, args) => {
let exercise = args.join(" ");
if (!exercise) {
return message.channel.send(
`<:error:466995152976871434> No equation provided. Usage :\`${client.commands.get(`calculate`).help.usage}\``
);
}
message.channel.send(`\`RESULT:\`\n\`\`\`${result}\`\`\``);
};
try {
for (var i = 0; i < exercise.length; i++) {
let c = exercise.charAt(i);
let found = allowed.find((element) => element === c);
if(c == "0") found = true;
if(!(Number(c) || found))
{
return message.channel.send(
`<:error:466995152976871434> Invalid equation. Please use \`*\` for multiplication and \`/\` for division!`
);
}
}
let result = (new Function( 'return ' + exercise )());
exports.conf = {
enabled: true,
guildOnly: false,
aliases: ["calc", "math"],
permLevel: "User",
requiredPerms: []
};
message.channel.send(`\`RESULT:\`\n\`\`\`${result}\`\`\``)
} catch (err) {
message.channel.send('<:error:466995152976871434> Malformed input.')
}
};
exports.help = {
name: "calculate",
category: "Utility",
description: "Solves basic mathematical equations.",
usage: "calculate [equation]"
};
exports.conf = {
enabled: true,
guildOnly: false,
aliases: ["calc", "math"],
permLevel: "User",
requiredPerms: []
};
exports.help = {
name: "calculate",
category: "Utility",
description: "Solves basic mathematical equations.",
usage: "calculate [equation]"
};

View File

@ -5,6 +5,9 @@ exports.run = async (bot, message, args) => {
fetch('https://catfact.ninja/facts')
.then(res => res.json())
.then(json => message.channel.send(`__**Did you know?**__\n${json.data[0].fact}`))
.catch(err => {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
});
} catch(err) {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
};

View File

@ -1,15 +1,4 @@
exports.run = (client, message, args) => {
if(!args[0]) {
return message.channel.send(
`<:error:466995152976871434> Invalid choice. Usage: \`${client.commands.get(`flip`).help.usage}\``
);
};
if(args[0].toLowerCase() != "heads" && args[0].toLowerCase() != "tails") {
return message.channel.send(
`<:error:466995152976871434> Invalid choice. Usage: \`${client.commands.get(`flip`).help.usage}\``
);
};
var coin = [
"Heads!",
"Tails!"
@ -31,5 +20,5 @@ exports.help = {
name: "coinflip",
category: "Fun",
description: "Flips a coin!",
usage: "coinflip [heads/tails]"
usage: "coinflip"
};

View File

@ -12,7 +12,7 @@ exports.run = async (client, message, args, level) => {
embed = new Discord.MessageEmbed();
embed.setTitle(colour)
embed.setColor(colour);
embed.setImage("https://api.alexflipnote.xyz/colour/image/" + colour.replace("#", ""));
embed.setImage(`https://fakeimg.pl/256x256/${colour.replace("#", "")}/?text=%20`);
message.channel.send(embed)
};

View File

@ -4,7 +4,10 @@ exports.run = async (bot, message, args) => {
try{
fetch('https://dog-api.kinduff.com/api/facts')
.then(res => res.json())
.then(json => message.channel.send(`__**Did you know?**__\n ${json.facts[0]}`));
.then(json => message.channel.send(`__**Did you know?**__\n ${json.facts[0]}`))
.catch(err => {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
});
} catch(err) {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
};

75
src/commands/fixmusic.js Normal file
View File

@ -0,0 +1,75 @@
const { getGuild } = require('../modules/music')
module.exports.run = async (client, message, args, level) =>{
guild = getGuild(message.guild.id)
const lvl = client.config.permLevels.find(l => l.level === level)
if (lvl.level >= 1) {
guild.queue = []
guild.playing = false
guild.paused = false
guild.skippers = []
guild.fixers = []
guild.channel = null
if (guild.dispatcher) {
guild.dispatcher.end('silent')
}
guild.fixers = []
message.channel.send(
'<:success:466995111885144095> Music has been fixed!'
)
return
}
const vc = message.guild.members.cache.get(client.user.id).voice.channel
if (guild.fixers.indexOf(message.author.id) === -1) {
guild.fixers.push(message.author.id)
if (guild.fixers.length >= Math.ceil(vc.members.filter(member => !member.user.bot).size / 2)) {
guild.queue = []
guild.playing = false
guild.paused = false
guild.skippers = []
guild.fixers = []
guild.channel = null
if (guild.dispatcher) {
guild.dispatcher.end('silent')
}
guild.fixers = []
message.channel.send(
'<:success:466995111885144095> Music has been fixed!'
)
} else {
message.channel.send(
`<:success:466995111885144095> Your vote has been acknowledged! **${guild.fixers.length + '/' + Math.ceil(vc.members.filter(member => !member.user.bot).size / 2)}**`
)
};
} else {
message.channel.send(
'<:denied:466995195150336020> You cannot vote twice!'
)
}
}
exports.conf = {
enabled: true,
guildOnly: true,
aliases: [],
permLevel: "User",
requiredPerms: []
};
exports.help = {
name: "fixmusic",
category: "Music",
description: 'Fixes music if it breaks.',
usage: 'fixmusic',
};

View File

@ -1,11 +1,18 @@
const { skip, getGuild } = require('../modules/music')
exports.run = (client, message) => {
let guild = client.music.getGuild(message.guild.id);
const guild = getGuild(message.guild.id)
if(guild.queue.length < 1) return message.channel.send(
`<:error:466995152976871434> There is nothing for me to skip!`
);
skip_song(guild);
message.channel.send("<:skip:467216735356059660> Skipped the song!")
if (guild.queue.length < 1 || !guild.playing || !guild.dispatcher) {
return message.channel.send(
'<:error:466995152976871434> Nothing is playing.'
)
}
skip(message.guild, 'skip')
guild.skippers = []
message.channel.send('<:success:466995111885144095> Song skipped.')
};
exports.conf = {
@ -13,7 +20,7 @@ exports.conf = {
guildOnly: true,
aliases: [],
permLevel: "Moderator",
requiredPerms: ["SPEAK"]
requiredPerms: []
};
exports.help = {
@ -22,7 +29,3 @@ exports.help = {
description: "Skips the currently playing song without requiring a vote.",
usage: "forceskip"
};
function skip_song(guild) {
guild.dispatcher.end();
}

View File

@ -1,30 +0,0 @@
const API = require('nekos.life');
const {sfw} = new API();
exports.run = async (client, message) => {
message.channel.startTyping();
try {
sfw.foxGirl().then((json) => {
message.channel.send(json.url)
message.channel.stopTyping();
});
} catch (err) {
client.logger.error("foxgirl.js: " + err);
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`)
message.channel.stopTyping();
};
};
exports.conf = {
enabled: true,
guildOnly: false,
aliases: [],
permLevel: "User",
requiredPerms: ["EMBED_LINKS"]
};
exports.help = {
name: "foxgirl",
category: "Image",
description: "Sends you pictures of fox girls.",
usage: "foxgirl"
};

View File

@ -1,8 +1,26 @@
const garfield = require("garfield");
const fetch = require("node-fetch")
const { MessageEmbed } = require('discord.js')
exports.run = async (client, message) => {
message.channel.send({ files: [garfield.random()] }).catch(() => message.channel.send(
"<:error:466995152976871434> API didn't respond, try again in a few seconds."
));
message.channel.startTyping();
try {
fetch('https://garfield-comics.glitch.me/~SRoMG/?date=xxxx')
.then(res => res.json())
.then(json => {
const embed = new MessageEmbed()
.setTitle(`${json.data.name} (No. ${json.data.number})`)
.setColor(client.embedColour(message))
.setURL('https://www.mezzacotta.net/garfield/?comic=' + json.data.number)
.setImage(json.data.image.src);
message.channel.send(embed)
})
.catch(err => {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
});
message.channel.stopTyping();
} catch (err) {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`)
message.channel.stopTyping();
};
};
exports.conf = {

View File

@ -53,7 +53,7 @@ exports.run = (client, message, args, level) => {
embed.addField(
"Invite me",
"[Click here](https://discordapp.com/oauth2/authorize?client_id=435961704145485835&permissions=8&scope=bot) to add me to your server",
"[Click here](https://discord.com/oauth2/authorize?client_id=435961704145485835&permissions=8&scope=bot) to add me to your server",
true
);
embed.addField(
@ -103,7 +103,7 @@ exports.run = (client, message, args, level) => {
embed.addField(
"Invite me",
"[Click here](https://discordapp.com/oauth2/authorize?client_id=435961704145485835&permissions=8&scope=bot) to add me to your server",
"[Click here](https://discord.com/oauth2/authorize?client_id=435961704145485835&permissions=8&scope=bot) to add me to your server",
true
);
embed.addField(

View File

@ -4,7 +4,10 @@ exports.run = async (client, message) => {
try {
fetch('http://inspirobot.me/api?generate=true')
.then(res => res.text())
.then(body => message.channel.send({files: [new Discord.MessageAttachment(body)]}));
.then(body => message.channel.send({files: [new Discord.MessageAttachment(body)]}))
.catch(err => {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
});
message.channel.stopTyping();
} catch (err) {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`)

View File

@ -1,6 +1,6 @@
exports.run = async (client, message) => {
message.channel.send(
`Use this link to invite me to your server:\n<https://discordapp.com/oauth2/authorize?client_id=${client.user.id}&permissions=2134240503&scope=bot>`
`Use this link to invite me to your server:\n<https://discord.com/oauth2/authorize?client_id=${client.user.id}&permissions=2134240503&scope=bot>`
);
};

View File

@ -15,7 +15,7 @@ exports.run = async (client, message) => {
};
exports.conf = {
enabled: true,
enabled: false,
guildOnly: false,
aliases: [],
permLevel: "User",

31
src/commands/kitsune.js Normal file
View File

@ -0,0 +1,31 @@
const fetch = require("node-fetch")
exports.run = async (client, message, args) => {
message.channel.startTyping();
try{
fetch(`https://purrbot.site/api/img/sfw/kitsune/img/`)
.then(res => res.json())
.then(json => message.channel.send(json.link))
.catch(err => {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
});
message.channel.stopTyping();
} catch(err) {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
message.channel.stopTyping();
};
};
exports.conf = {
enabled: false,
guildOnly: false,
aliases: ['foxgirl'],
permLevel: "User",
requiredPerms: ["EMBED_LINKS"]
};
exports.help = {
name: "kitsune",
category: "Image",
description: "Sends you cute wholesome pictures of foxgirls.",
usage: "kitsune"
};

31
src/commands/lmgtfy.js Normal file
View File

@ -0,0 +1,31 @@
const identities = require ("../../resources/other/identities.json");
exports.run = async (client, message, args) => {
if (!args[0]) {
return message.channel.send("Missing arguments, please provide me with a query!")
}
const query = args.join("+")
let link = ("https://lmgtfy.com/?q=" + query)
if (message.flags.includes('d')) {
link = "https://lmgtfy.com/?q=" + query + "&pp=1&s=d"
}
message.channel.send(link)
};
exports.conf = {
enabled: true,
guildOnly: false,
aliases: [],
permLevel: "User",
requiredPerms: []
};
exports.help = {
name: "lmgtfy",
category: "Fun",
description: "For when you need to remind someone search engines exist..",
usage: "lmgtfy <question>"
};

33
src/commands/movehere.js Normal file
View File

@ -0,0 +1,33 @@
const { getGuild } = require('../modules/music')
const Discord = require("discord.js")
module.exports.run = async (client, message, args, level) =>{
const guild = getGuild(message.guild.id)
if (!guild.playing) {
return message.channel.send('<:error:466995152976871434> Nothing is playing.')
}
if (guild.channel.id === message.channel.id) {
return message.channel.send('<:error:466995152976871434> Music messages are already being sent to this channel.')
}
guild.channel = message.channel
message.channel.send('<:success:466995111885144095> Music messages will now be sent to this channel.')
}
exports.conf = {
enabled: true,
guildOnly: true,
aliases: [],
permLevel: "Moderator",
requiredPerms: []
};
exports.help = {
name: 'movehere',
category: 'Music',
description: 'Moves music related messages to the channel the this command is ran in.',
usage: 'movehere',
};

56
src/commands/movesong.js Normal file
View File

@ -0,0 +1,56 @@
const { getGuild } = require('../modules/music')
exports.run = async (client, message, args) => {
const queue = getGuild(message.guild.id).queue
if (queue.length < 3) {
return message.channel.send('<:error:466995152976871434> Not enough songs are in the queue for this command to work!')
}
if (!args[0]) {
return client.userError(message, exports, 'Missing argument, the `current position` argument is required!')
}
if (!args[1]) {
return client.userError(message, exports, 'Missing argument, the `new position` argument is required!')
}
const oldPosition = +args[0]
const newPosition = +args[1]
if (isNaN(oldPosition) === true) {
return message.channel.send('<:error:466995152976871434> That isn\'t a number! You need to tell me the songs position in the queue (1, 2, etc.)')
}
if (isNaN(newPosition) === true) {
return message.channel.send('<:error:466995152976871434> That isn\'t a number! You need to tell me the songs position in the queue (1, 2, etc.)')
}
if (oldPosition < 1 || oldPosition >= queue.length) {
return message.channel.send('<:error:466995152976871434> Old position is not a valid song ID.')
}
if (newPosition < 1 || newPosition >= queue.length) {
return message.channel.send('<:error:466995152976871434> New position is not a valid song ID.')
}
const songName = queue[oldPosition].video.title
queue.splice(newPosition, 0, queue.splice(oldPosition, 1)[0])
message.channel.send(`<:success:466995111885144095> Moved **${songName}** from position \`${oldPosition}\` to \`${newPosition}\``)
}
exports.conf = {
enabled: true,
guildOnly: true,
aliases: [],
permLevel: "Moderator",
requiredPerms: []
}
exports.help = {
name: 'movesong',
category: 'Music',
description: 'Moves a song to a new position in the queue.',
usage: 'movesong [current position] [new position]'
}

View File

@ -1,7 +1,7 @@
exports.run = (client, message, args) => {
if (!args[0])
return message.channel.send(
`<:error:466995152976871434> No username provided. Usage: \`${client.commands.get(``).help.usage}\``
`<:error:466995152976871434> No username provided. Usage: \`${client.commands.get(`msearch`).help.usage}\``
);
var mlist = "";
var count = 0;

View File

@ -1,21 +1,22 @@
const API = require('nekos.life');
const {sfw} = new API();
exports.run = async (client, message) => {
const fetch = require("node-fetch")
exports.run = async (client, message, args) => {
message.channel.startTyping();
try {
sfw.neko().then((json) => {
message.channel.send(json.url);
try{
fetch(`https://purrbot.site/api/img/sfw/neko/img/`)
.then(res => res.json())
.then(json => message.channel.send(json.link))
.catch(err => {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
});
message.channel.stopTyping();
});
} catch (err) {
client.logger.error("neko.js: " + err);
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`)
} catch(err) {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
message.channel.stopTyping();
};
};
exports.conf = {
enabled: true,
enabled: false,
guildOnly: false,
aliases: ["catgirl"],
permLevel: "User",
@ -25,6 +26,6 @@ exports.conf = {
exports.help = {
name: "neko",
category: "Image",
description: "Sends you pictures of catgirls.",
description: "Sends you cute wholesome pictures of catgirls.",
usage: "neko"
};

View File

@ -1,21 +1,22 @@
const API = require('nekos.life');
const {sfw} = new API();
exports.run = async (client, message) => {
const fetch = require("node-fetch")
exports.run = async (client, message, args) => {
message.channel.startTyping();
try {
sfw.nekoGif().then((json) => {
message.channel.send(json.url);
try{
fetch(`https://purrbot.site/api/img/sfw/neko/gif/`)
.then(res => res.json())
.then(json => message.channel.send(json.link))
.catch(err => {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
});
message.channel.stopTyping();
});
} catch (err) {
client.logger.error("nekogif.js: " + err);
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`)
} catch(err) {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
message.channel.stopTyping();
};
};
exports.conf = {
enabled: true,
enabled: false,
guildOnly: false,
aliases: ["catgirlgif"],
permLevel: "User",

View File

@ -1,31 +1,30 @@
const Discord = require("discord.js");
const { getGuild, createTimestamp } = require('../modules/music')
const { MessageEmbed } = require('discord.js')
exports.run = async (client, message) => {
let guild = client.music.getGuild(message.guild.id);
if(guild.queue.length < 1) {
return message.channel.send("<:error:466995152976871434> Nothing is playing.");
const guild = getGuild(message.guild.id)
if (guild.queue.length < 1) {
return message.channel.send(client.config.emojis.error + ' Nothing is in the queue!')
}
var song = guild.queue[0];
var elapsedTime = client.createTimestamp(guild.dispatcher.streamTime / 1000);
var timestamp;
const s = guild.queue[0]
const elapsedTime = createTimestamp(guild.dispatcher.streamTime / 1000)
let timestamp = `\`[${createTimestamp(s.video.lengthSeconds)}]\``
if(song.duration == 0) {
timestamp = "`[LIVE]`";
} else {
timestamp = `\`[${elapsedTime + "/" + client.createTimestamp(song.duration)}]\``;
};
if (timestamp !== '`[LIVE]`') {
timestamp = `\`[${elapsedTime + '/' + createTimestamp(s.video.lengthSeconds)}]\``
}
embed = new Discord.MessageEmbed();
embed.setTitle("Now playing:")
embed.setThumbnail(song.thumbnail)
embed.setColor(client.embedColour(message));
embed.setDescription(`**[${song.title}](https://www.youtube.com/watch?v=${song.id})**`)
embed.addField("Channel:", song.author, true)
embed.addField("Time:", timestamp, true)
embed.setFooter("Requested by " + song.requestedBy.tag, song.requestedBy.avatarURL({format: "png", dynamic: true, size: 2048}))
const embed = new MessageEmbed()
embed.setTitle('Now playing')
embed.setThumbnail(client.config.endpoints.invidious + s.video.videoThumbnails[1].url)
embed.setColor(client.embedColour(message))
embed.setDescription(`**[${s.video.title}](https://www.youtube.com/watch?v=${s.video.videoId})**`)
embed.addField('Channel:', s.video.author, true)
embed.addField('Time:', timestamp, true)
embed.setFooter('Requested by ' + s.requestedBy.tag, s.requestedBy.avatarURL({ format: 'png', dynamic: true, size: 2048 }))
message.channel.send(embed)
message.channel.send(embed)
};
exports.conf = {

View File

@ -1,15 +1,20 @@
const { getGuild } = require('../modules/music')
exports.run = (client, message, args, level) => {
let guild = client.music.getGuild(message.guild.id);
if(guild.queue.length < 1) {
return message.channel.send("<:error:466995152976871434> Nothing is playing.");
};
const guild = getGuild(message.guild.id)
guild.playing = false;
guild.paused = true;
guild.dispatcher.pause();
message.channel.send("<:pause:467639357961142273> Playback paused!");
if (guild.paused === true) {
return message.channel.send('<:error:466995152976871434> The music has already been paused! Run resume to start the music again.')
}
if (guild.queue.length < 1 || guild.playing === false) {
return message.channel.send('<:error:466995152976871434> Nothing is playing!')
}
guild.playing = false
guild.paused = true
guild.dispatcher.pause()
message.channel.send('<:pause:467639357961142273> Music playback has been paused.')
};
exports.conf = {
@ -17,7 +22,7 @@ exports.conf = {
guildOnly: true,
aliases: [],
permLevel: "Moderator",
requiredPerms: ["CONNECT", "SPEAK"]
requiredPerms: []
};
exports.help = {

View File

@ -1,20 +1,12 @@
const util = require("util")
const { play } = require('../modules/music')
const Discord = require("discord.js")
module.exports.run = (client, message, args, level) =>{
if(!args[0])
{
message.channel.send(`<:error:466995152976871434> You didn't give me a song to play! Usage: \`${client.commands.get(`play`).help.usage}\``);
return;
}
module.exports.run = async (client, message, args, level) =>{
if (!args[0]) {
return message.channel.send(`<:error:466995152976871434> You didn't give me a song name or YouTube URL! Usage: \`${client.commands.get('play').help.usage}\``)
}
let voiceChannel = message.member.voice.channel;
if(!voiceChannel) return message.channel.send('<:error:466995152976871434> You need to be in a voice channel to use this command!');
message.channel.send(`🔎 searching YouTube for \`${args.join(" ")}\``);
client.music.play(message, args.join(" "));
await play(client, message, args.join(' '), false)
}
exports.conf = {
@ -28,6 +20,6 @@ exports.conf = {
exports.help = {
name: "play",
category: "Music",
description: "Plays a song.",
usage: "play [youtube-url] **OR** play [song-name]"
description: 'Plays the song you request, or adds it to the queue.',
usage: 'play [song]',
};

23
src/commands/playnext.js Normal file
View File

@ -0,0 +1,23 @@
const { play } = require('../modules/music')
exports.run = async (client, message, args) => {
if (!args[0]) {
return message.channel.send(`<:error:466995152976871434> You didn't give me a song name or YouTube URL! Usage: \`${client.commands.get('play').help.usage}\``)
}
await play(client, message, args.join(' '), true)
}
exports.conf = {
enabled: true,
guildOnly: true,
aliases: [],
permLevel: "Moderator",
requiredPerms: []
}
exports.help = {
name: 'playnext',
category: 'Music',
description: 'Similar to play, but adds it to the start of the queue instead of the end.',
usage: 'playnext [song]'
}

48
src/commands/pride.js Normal file
View File

@ -0,0 +1,48 @@
// Copyright 2020 Emily J. / mudkipscience and contributors. Subject to the AGPLv3 license.
exports.conf = {
enabled: true,
guildOnly: false,
aliases: [],
permLevel: 'User',
requiredPerms: ['ATTACH_FILES'],
}
exports.help = {
name: 'pride',
category: 'Fun',
description: 'Adds a pride flag ring to your avatar. Available flags are lesbian, gay, bisexual, pansexual, trans, asexual, aromantic and ally.',
usage: '`pride [flag]` - Adds a pride flag overlay to your avatar.\n`pride -g [flag]` - Adds a pride flag gradient on your avatar.',
}
const url = 'https://demirramon.com/gen/pride.png'
const Discord = require('discord.js')
exports.run = (client, message, args) => {
const flag = args[0]
if (!flag) {
return message.channel.send('<:error:466995152976871434> Missing argument, the `flag` argument is required!')
}
const available = ['lesbian', 'gay', 'bisexual', 'pansexual', 'trans', 'asexual', 'aromantic', 'ally']
if (!available.includes(flag.toLowerCase())) {
return message.channel.send(`<:error:466995152976871434> This flag isn't available, sorry ;~;\nAvailable flags: \`${available.join('`, `')}\``)
}
let gradient = 'false'
if (message.flags.includes('g')) {
gradient = 'true'
}
message.channel.startTyping()
const params = `image=${message.author.avatarURL({ format: 'png', size: 2048 })}&flag=${flag.toLowerCase()}&full=true&gradient=${gradient}&background=false&fit=true&v=2019-08-07`
try {
message.channel.stopTyping()
message.channel.send({ files: [new Discord.MessageAttachment(url + '?' + params)] })
} catch (err) {
message.channel.stopTyping()
message.channel.send(`<:error:466995152976871434> Error when generating image: \`${err}\``)
}
}

View File

@ -1,171 +1,162 @@
'use strict';
const Discord = require("discord.js");
const { getGuild, createTimestamp } = require('../modules/music')
const Discord = require('discord.js')
exports.run = (client, message, args) => {
var queue = client.music.getGuild(message.guild.id).queue;
var queue = getGuild(message.guild.id).queue
if(queue.length < 1) {
return message.channel.send("<:error:466995152976871434> Nothing is playing.");
if (queue.length < 1) {
return message.channel.send('<:error:466995152976871434> Nothing is playing.')
}
let lists = [];
const lists = []
function generateList(start, number) {
var list = "";
var timestamp;
var livestream;
function generateList (start, number) {
let list = ''
let timestamp
if(start == 1 && queue.length == 1) {
return ["There's nothing else waiting to be played!", 1];
if (start === 1 && queue.length === 1) {
return ['There\'s nothing else waiting to be played!', 1]
}
if(number == 1 && queue.length + 1 < start) {
return false;
};
let q = queue.slice(start);
let i = 0;
for(i = 0; i < q.length; i++) {
let song = q[i];
if(song.duration == 0) {
timestamp = "LIVE";
livestream = true;
} else {
timestamp = client.createTimestamp(song.duration);
};
let aaa = list + `\`${(i + 1) + start - 1}:\` **[${song.title}](https://www.youtube.com/watch?v=${song.id})** added by ${song.requestedBy} \`[${timestamp}]\`\n`;
if(aaa.length > 1024) {
return [list, start + i - 1];
} else {
list = aaa;
}
//totalDuration = totalDuration + song.duration;
};
return [list, start + i + 1];
};
let songsInQueue = queue.length - 1;
let songsInQueueEnglish = "song";
let timeRemaining = 0;
function generatePage(list, page) {
if(!list || list == "") {
return false;
if (number === 1 && queue.length + 1 < start) {
return false
}
var embed = new Discord.MessageEmbed();
embed.setTitle(`Queue for: ${message.guild.name}`);
embed.setColor(client.embedColour(message));
var elapsedTime = client.music.getGuild(message.guild.id).dispatcher.streamTime / 1000
var totalDuration = queue[0].duration - elapsedTime;
const q = queue.slice(start)
let timeRemaining = "";
for(let i = 1; i < queue.length; i++) {
let b = queue[i];
let i = 0
if(b.duration == 0) {
timeRemaining = "∞";
for (i = 0; i < q.length; i++) {
const song = q[i]
break;
}
timestamp = createTimestamp(song.video.lengthSeconds)
totalDuration += b.duration;
}
if(timeRemaining == "") {
let queueDuration = client.createTimestamp(totalDuration);
const aaa = list + `\`${(i + 1) + start - 1}:\` **[${song.video.title}](https://www.youtube.com/watch?v=${song.video.videoId})** added by ${song.requestedBy} \`[${timestamp}]\`\n`
timeRemaining = queueDuration;
}
let timestamp;
if(queue[0].duration == 0) {
timestamp = "LIVE";
livestream = true;
} else {
timestamp = client.createTimestamp(elapsedTime) + '/' + client.createTimestamp(queue[0].duration);
};
embed.addField(`Now playing:`, `**[${queue[0].title}](https://www.youtube.com/watch?v=${queue[0].id})** added by ${queue[0].requestedBy} \`[${timestamp}]\``)
embed.addField(`Up next:`, list);
if(songsInQueue > 1 || songsInQueue == 0) {
songsInQueueEnglish = "songs";
}
embed.setFooter(`Page ${page}/${lists.length} | ${songsInQueue + " " + songsInQueueEnglish} in queue | ${timeRemaining} time remaining`);
return embed;
};
var myMessage = null;
function displayPage(number) {
let page = generatePage(lists[number - 1], number);
if(page) {
if(myMessage) {
myMessage.edit(page);
if (aaa.length > 1024) {
return [list, start + i - 1]
} else {
myMessage = message.channel.send(page);
list = aaa
}
return true;
} else {
return false;
// totalDuration = totalDuration + song.duration
}
};
function aFunction(start) {
return [list, start + i + 1]
}
const songsInQueue = queue.length - 1
let songsInQueueEnglish = 'song'
function generatePage (list, page) {
if (!list || list === '') {
return false
}
var embed = new Discord.MessageEmbed()
embed.setTitle(`Queue for: ${message.guild.name}`)
embed.setColor(client.embedColour(message))
var elapsedTime = getGuild(message.guild.id).dispatcher.streamTime / 1000
var totalDuration = queue[0].video.lengthSeconds - elapsedTime
let timeRemaining = ''
for (let i = 1; i < queue.length; i++) {
const b = queue[i]
if (b.video.lengthSeconds === 0) {
timeRemaining = '∞'
break
}
totalDuration += b.video.lengthSeconds
}
if (timeRemaining === '') {
const queueDuration = createTimestamp(totalDuration)
timeRemaining = queueDuration
}
let timestamp = `\`${createTimestamp(queue[0].video.lengthSeconds)}\``
if (timestamp !== '`[LIVE]`') {
timestamp = `\`[${createTimestamp(elapsedTime) + '/' + createTimestamp(queue[0].video.lengthSeconds)}]\``
}
embed.addField('Now playing:', `**[${queue[0].video.title}](https://www.youtube.com/watch?v=${queue[0].video.videoId})** added by ${queue[0].requestedBy} ${timestamp}`)
embed.addField('Up next:', list)
if (songsInQueue > 1 || songsInQueue === 0) {
songsInQueueEnglish = 'songs'
}
embed.setFooter(`Page ${page}/${lists.length} | ${songsInQueue + ' ' + songsInQueueEnglish} in queue | ${timeRemaining} time remaining`)
return embed
}
var myMessage = null
function displayPage (number) {
const page = generatePage(lists[number - 1], number)
if (page) {
if (myMessage) {
myMessage.edit(page)
} else {
myMessage = message.channel.send(page)
}
return true
} else {
return false
}
}
function aFunction (start) {
// start - index of song, which we should start with
// end - index of song, which we ended with
let [list, end] = generateList(start, lists.length + 1);
const [list, end] = generateList(start, lists.length + 1)
if(list && list != "") {
lists.push(list);
if(queue[end + 1]) {
aFunction(end + 1);
if (list && list !== '') {
lists.push(list)
if (queue[end + 1]) {
aFunction(end + 1)
}
}
};
}
aFunction(1);
aFunction(1)
let page = 1;
let page = 1
if(args[0]) {
let userPage = Number(args[0]);
if (args[0]) {
const userPage = Number(args[0])
if(userPage) {
page = userPage;
if (userPage) {
page = userPage
} else {
return message.channel.send(
`<:error:466995152976871434> Invalid page. Usage: \`${client.commands.get(`queue`).help.usage}\``
);
`<:error:466995152976871434> Invalid page number. Usage: \`${client.commands.get('queue').help.usage}\``
)
}
};
}
if(displayPage(page)) {
if (displayPage(page)) {
} else {
return message.channel.send(
`<:error:466995152976871434> Page ${page} doesn't exist!`
);
)
}
};
}
exports.conf = {
enabled: true,

View File

@ -3,19 +3,25 @@ exports.run = async (client, message, args) => {
return message.channel.send(
`<:error:466995152976871434> What am I meant to rate? Usage: \`${client.commands.get(`rate`).help.usage}\``
);
var rating = [
"0/10",
"1/10",
"2/10",
"3/10",
"4/10",
"5/10",
"6/10",
"7/10",
"8/10",
"9/10",
"10/10"
];
var rating = [
"0/10",
"1/10",
"2/10",
"3/10",
"4/10",
"5/10",
"6/10",
"7/10",
"8/10",
"9/10",
"10/10"
];
if (message.content.includes("@everyone") || message.content.includes("@here") || message.content.includes("<@&")) {
return message.channel.send('>:(');
};
let mess = rating.random();
message.channel.send(`<:star:618393201501536258> I give ${args.join(" ")} a **${mess}**`);
};

View File

@ -1,36 +1,30 @@
const util = require("util")
const Discord = require("discord.js")
const { getGuild } = require('../modules/music')
module.exports.run = (client, message, args, level) =>{
var queue = client.music.getGuild(message.guild.id).queue;
var queue = getGuild(message.guild.id).queue
if(queue.length < 2) {
return message.channel.send(`<:error:466995152976871434> Not enough songs are in the queue for this command to work!`);
if (queue.length < 2) {
return message.channel.send('<:error:466995152976871434> Not enough songs are in the queue for this command to work!')
}
if(!args[0]) {
return message.channel.send(`<:error:466995152976871434> You didn't tell me what song to remove! Usage: \`${client.commands.get(`removesong`).help.usage}\``);
};
if (!args[0]) {
return message.channel.send(`<:error:466995152976871434> You didn't tell me what song to remove! Usage: \`${client.commands.get('removesong').help.usage}\``)
}
var input = +args[0];
var input = +args[0]
if(isNaN(input) == true) {
return message.channel.send(`<:error:466995152976871434> That isn't a number! You need to tell me the songs position in the queue (1, 2, etc.)`);
};
if (isNaN(input) === true) {
return message.channel.send('<:error:466995152976871434> That isn\'t a number! You need to tell me the songs position in the queue (1, 2, etc.)')
}
if(input >= queue.length) {
return message.channel.send("Invalid (too large)");
};
if (input >= queue.length || input < 1) {
return message.channel.send('<:error:466995152976871434> Input is not a valid song ID.')
}
if(input < 1) {
return message.channel.send("Invalid (too small)");
};
var songName = queue[input].video.title
var songName = queue[input].title;
queue.splice(input, 1)
queue.splice(input, 1);
message.channel.send(`<:success:466995111885144095> Removed from queue: **${songName}**`);
message.channel.send(`<:success:466995111885144095> Removed from queue: **${songName}**`)
};
exports.conf = {
@ -38,7 +32,7 @@ exports.conf = {
guildOnly: true,
aliases: ["rmsong"],
permLevel: "Moderator",
requiredPerms: ["SPEAK"]
requiredPerms: []
};
exports.help = {

View File

@ -1,14 +1,21 @@
exports.run = async (client, message) => {// eslint-disable-line no-unused-vars
const fetch = require('node-fetch');
exports.run = (client, message) => {// eslint-disable-line no-unused-vars
// This actually shuts down the bot, you'll need to use something like pm2 to get it to restart
await message.channel.send("<:reboot:467216876938985482> Restarting...");
message.channel.send("<:reboot:467216876938985482> Restarting...");
client.destroy();
require("util").promisify(setTimeout);
client.commands.forEach( async cmd => {
await client.unloadCommand(cmd);
fetch('https://gamecp.apex.to/api/client/servers/1fc76afa-9a4d-497b-983a-a898795ab5b5/power', {
method: 'post',
body: JSON.stringify({ 'signal': 'restart' }),
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${client.config.server}` }
}).catch(err => {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
});
process.exit();
};
exports.conf = {

View File

@ -1,15 +1,20 @@
const Discord = require("discord.js")
const { getGuild } = require('../modules/music')
exports.run = (client, message, args, level) => {
let guild = client.music.getGuild(message.guild.id);
if(guild.queue.length < 1) {
return message.channel.send("<:error:466995152976871434> Nothing is playing.");
};
guild.playing = true;
guild.paused = false;
guild.dispatcher.resume();
message.channel.send("<:play:467216788187512832> Playback resumed!");
const guild = getGuild(message.guild.id)
if (guild.paused === false) {
return message.channel.send('<:error:466995152976871434> The music is already playing, use pause to pause the music first!')
}
if (guild.queue.length < 1) {
return message.channel.send('<:error:466995152976871434> Nothing is playing!')
}
guild.playing = true
guild.paused = false
guild.dispatcher.resume()
message.channel.send('<:success:466995111885144095> Music playback has been resumed.')
};
exports.conf = {

View File

@ -1,12 +1,18 @@
var request = require('request');
const fetch = require('node-fetch');
const Discord = require("discord.js")
exports.run = (client, message) => {
message.channel.startTyping();
var r = request.get('http://mityurl.com/y/yKsQ/r', function (err, res, body) {
var rip = r.uri.href
message.channel.send(`>:] ${rip}`)
message.channel.stopTyping();
});
try{
fetch('http://mityurl.com/y/yKsQ/r', { redirect: 'follow' })
.then(res => res)
.then(res => message.channel.send(`>:] ${res.url}`))
.catch(err => {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
});
} catch(err) {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
};
message.channel.stopTyping();
}
exports.conf = {

77
src/commands/salmonrun.js Normal file
View File

@ -0,0 +1,77 @@
const Discord = require("discord.js");
const BasePaginator = require('discord-paginator.js');
const fetch = require('node-fetch');
const prettifyMiliseconds = require('pretty-ms');
exports.run = async (client, message, args) =>{
fetch('https://splatoon2.ink/data/coop-schedules.json', { headers: { 'User-Agent': client.config.userAgent }})
.then(res => res.json())
.then(json => {
fetch('https://splatoon2.ink/data/timeline.json', { headers: { 'User-Agent': client.config.userAgent }})
.then(timelineRes => timelineRes.json())
.then(timelineJson => {
const embeds = [];
if ((json.details[0].start_time * 1000) > Date.now() === true) {
embeds.push(
new Discord.MessageEmbed()
.setTitle('Upcoming Salmon Run')
.setColor(client.embedColour(message))
.setImage('https://splatoon2.ink/assets/splatnet/'+json.details[0].stage.image)
.addField('Map', json.details[0].stage.name, true)
.setFooter(`Page 1/2 | Starting in ${prettifyMiliseconds(json.details[0].start_time * 1000 - Date.now(), { secondsDecimalDigits: 0 })} | Data provided by splatoon2.ink`)
);
} else {
embeds.push(
new Discord.MessageEmbed()
.setTitle('Current Salmon Run')
.setColor(client.embedColour(message))
.setThumbnail('https://splatoon2.ink/assets/splatnet'+timelineJson.coop.reward_gear.gear.image)
.setImage('https://splatoon2.ink/assets/splatnet/'+json.details[0].stage.image)
.addField('Map', json.details[0].stage.name, true)
.addField('Reward Gear', timelineJson.coop.reward_gear.gear.name, true)
.addField('Weapons', json.details[0].weapons[0].weapon.name+', '+json.details[0].weapons[1].weapon.name+', '+json.details[0].weapons[2].weapon.name+', '+json.details[0].weapons[3].weapon.name)
.setFooter(`Page 1/2 | Ending in ${prettifyMiliseconds((json.details[0].end_time * 1000) - Date.now(), { secondsDecimalDigits: 0 })} | Data provided by splatoon2.ink`)
);
}
embeds.push(
new Discord.MessageEmbed()
.setTitle('Upcoming Salmon Run')
.setColor(client.embedColour(message))
.setImage('https://splatoon2.ink/assets/splatnet/'+json.details[1].stage.image)
.addField('Map', json.details[1].stage.name, true)
.addField('Weapons', json.details[1].weapons[1].weapon.name+', '+json.details[1].weapons[1].weapon.name+', '+json.details[1].weapons[2].weapon.name+', '+json.details[1].weapons[3].weapon.name)
.setFooter(`Page 2/2 | Starting in ${prettifyMiliseconds(json.details[1].start_time * 1000 - Date.now(), { secondsDecimalDigits: 0 })} | Data provided by splatoon2.ink`)
);
const Paginator = new BasePaginator({
pages: embeds,
timeout: 120000,
filter: (reaction, user) => user.id == message.author.id //to filter the reaction collector
})
Paginator.spawn(message.channel)
});
})
.catch(err => {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
});
};
exports.conf = {
enabled: true,
guildOnly: false,
aliases: [],
permLevel: "User",
requiredPerms: []
};
exports.help = {
name: "salmonrun",
category: "Splatoon",
description: "Get current map, weapons and gear for salmon run.",
usage: "salmonrun"
};

View File

@ -4,8 +4,8 @@ exports.run = (client, message, args, level) => {
`<:error:466995152976871434> No message provided. Usage: \`${client.commands.get(`echo`).help.usage}\``
);
};
if (message.content.includes("@everyone")) {
return message.channel.send(`<@${message.author.id}>`);
if (message.content.includes("@everyone") || message.content.includes("@here") || message.content.includes("<@&")) {
return message.channel.send('>:(');
};
message.delete().catch(O_o => {});
@ -24,5 +24,5 @@ exports.help = {
name: "say",
category: "Fun",
description: "Makes Woomy copy what the user says.",
usage: "echo <-hide> [message]"
usage: "echo [message]"
};

View File

@ -80,7 +80,7 @@ exports.run = async (client, message, args) => {
embed.setAuthor("Settings for: " + message.guild.name, message.guild.iconURL({dynamic: true}))
embed.setColor(message.guild.member(client.user).displayHexColor)
embed.setDescription("You can edit these settings using the commands in the 'configure' section of the help command.")
embed.addFields({ name: "General:", value: `Prefix: \`${prefix}\`\nChat logging: ${chatChan}\nMod logging: ${modChan}\nRaid mode: ${raidMode}\nJoin/leave channel: ${greetChan}\nWelcome message: ${welcomeMessage}\nLeave message: ${leaveMessage}`, inline: true}, {name: "Roles:", value: `Moderator: ${modRole}\nAdministrator: ${adminRole}\nMuted: ${mutedRole}\nBlacklisted: ${blacklist}\nAutorole: ${autorole}`, inline: true})
embed.addFields({ name: "General:", value: `Prefix: \`${prefix}\`\nChat logging: ${chatChan}\nMod logging: ${modChan}\nRaid mode: ${raidMode}\nJoin/leave channel: ${greetChan}\nWelcome message: ${welcomeMessage}\nLeave message: ${leaveMessage}`, inline: true}, {name: "Roles:", value: `Moderator: ${modRole}\nAdministrator: ${adminRole}\nMuted: ${mutedRole}\nBlocklist: ${blacklist}\nAutorole: ${autorole}`, inline: true})
message.channel.send(embed)
};

View File

@ -1,40 +1,58 @@
const Discord = require('discord.js')
exports.run = async (client, message, args) => {
var name, name1;
var rating = Math.floor(Math.random() * 100) + 1;
var rating = Math.floor(Math.random() * 100) + 1
var meter = ['▬', '▬', '▬', '▬', '▬', '▬', '▬', '▬', '▬']
var hearts = [
"❤️",
"🧡",
"💛",
"💚",
"💙",
"💜"
];
if(args.length < 2) {
return message.channel.send(`<:error:466995152976871434> Please include two names/users.`)
'❤️',
'🧡',
'💛',
'💚',
'💙',
'💜'
]
if (!args[0]) {
return message.channel.send(
`<:error:466995152976871434> No message provided. Usage: \`${client.commands.get(`ship`).help.usage}\``
);
}
if(message.guild && message.mentions.members && message.mentions.members.size > 0) {
name = message.mentions.members.first().displayName;
};
if (!args[1]) {
return message.channel.send(
`<:error:466995152976871434> No message provided. Usage: \`${client.commands.get(`ship`).help.usage}\``
);
}
if(message.guild && message.mentions.members && message.mentions.members.size > 1) {
name1 = message.mentions.members.last().displayName;
};
const firstName = args[0]
const secondName = args[1]
if(!name) {
name = args[0];
};
const shipName = firstName.substr(0, firstName.length * 0.5) + secondName.substr(secondName.length * 0.5)
if(!name1) {
name1 = args[1];
};
if (shipName.toLowerCase() === 'teily' || shipName.toLowerCase() === 'emrra') {
rating = '100'
}
shipName = name.substr(0, client.intBetween(1,name.length))+name1.substr(client.intBetween(0,name1.length));
var pos = 0
var under = 9
while (pos < 10) {
if (rating < under) {
meter.splice(pos, 0, hearts.random())
break
}
pos++
under += 10
}
message.channel.send(`__**Ship Generator:**__\n${hearts.random()} Ship Name: \`${shipName}\`\n${hearts.random()} Compatibility rating: \`${rating}%\``)
};
if (rating >= 99) {
meter.splice(9, 0, hearts.random())
}
const embed = new Discord.MessageEmbed()
embed.setTitle(`Original Names: ${firstName}, ${secondName}`)
embed.setColor(client.embedColour(message.guild))
embed.setDescription(`Ship Name: **${shipName}**\nCompatibility: **${rating}%**\n**[**${meter.join('')}**]**`)
message.channel.send(embed)
}
exports.conf = {
enabled: true,
@ -48,6 +66,6 @@ exports.help = {
name: "ship",
category: "Fun",
description: "Ship two people together <3",
usage: "ship [name/user] [name/user]"
usage: "ship [name1] [name2]"
};

34
src/commands/shuffle.js Normal file
View File

@ -0,0 +1,34 @@
const { getGuild } = require('../modules/music')
exports.run = async (client, message) => {
var queue = getGuild(message.guild.id).queue
if (queue.length < 4) {
return message.channel.send('<:error:466995152976871434> There aren\'t enough songs are in the queue for this command to work!')
}
const max = queue.length - 1
const min = 1
for (let i = max; i >= min; i--) {
const randomIndex = Math.floor(Math.random() * (max - min + 1)) + min
const itemAtIndex = queue[randomIndex]
queue[randomIndex] = queue[i]
queue[i] = itemAtIndex
}
message.channel.send('<:success:466995111885144095> Queue shuffled!')
}
exports.conf = {
enabled: true,
guildOnly: true,
aliases: [],
permLevel: "Moderator",
requiredPerms: []
}
exports.help = {
name: 'shuffle',
category: 'Music',
description: 'Mixes up the songs in the queue',
usage: 'shuffle'
}

View File

@ -1,49 +1,54 @@
const Discord = require("discord.js")
const { skip, getGuild } = require('../modules/music')
exports.run = (client, message, args, level) => {
let guild = client.music.getGuild(message.guild.id);
const guild = getGuild(message.guild.id)
if(guild.queue.length < 1 || !guild.playing || !guild.dispatcher) return message.channel.send(
"<:error:466995152976871434> Nothing is playing."
);
let vc = message.guild.members.cache.get(client.user.id).voiceChannel;
if(vc != message.member.voiceChannel) return message.channel.send(
'<:error:466995152976871434> You need to be in my voice channel to use this command!'
);
if(guild.queue[0].requestedBy.id == message.author.id) {
skip_song(guild);
message.channel.send(
`<:skip:467216735356059660> Song has been skipped by the user who requested it.`
);
return;
if (guild.queue.length < 1 || !guild.playing || !guild.dispatcher) {
return message.channel.send(
'<:error:466995152976871434> Nothing is playing.'
)
}
if (guild.skippers.indexOf(message.author.id) == -1) {
guild.skippers.push(message.author.id);
const vc = message.guild.members.cache.get(client.user.id).voice.channel
if (vc !== message.member.voice.channel) {
return message.channel.send(
'<:error:466995152976871434> You need to be in my voice channel to use this command!'
)
}
if (guild.queue[0].requestedBy.id === message.author.id) {
skip(message.guild, 'skip')
guild.skippers = []
message.channel.send(
'<:success:466995111885144095> Song has been skipped by the user who requested it.'
)
return
}
if (guild.skippers.indexOf(message.author.id) === -1) {
guild.skippers.push(message.author.id)
if (guild.skippers.length >= Math.ceil(vc.members.filter(member => !member.user.bot).size / 2)) {
skip_song(guild);
skip(message.guild, 'skip')
guild.skippers = []
message.channel.send(
`<:skip:467216735356059660> Song has been skipped.`
);
'<:skip:467216735356059660> Song skipped.'
)
} else {
message.channel.send(
`<:success:466995111885144095> Your vote has been acknowledged! **${guild.skippers.length + "/" + Math.ceil(vc.members.filter(member => !member.user.bot).size / 2)}**`
);
`<:success:466995111885144095> Your vote has been acknowledged! **${guild.skippers.length + '/' + Math.ceil(vc.members.filter(member => !member.user.bot).size / 2)}**`
)
};
} else {
message.channel.send(
"<:denied:466995195150336020> You cannot vote twice!"
);
};
'<:denied:466995195150336020> You cannot vote twice!'
)
}
};
exports.conf = {
@ -51,7 +56,7 @@ exports.conf = {
guildOnly: true,
aliases: ["voteskip"],
permLevel: "User",
requiredPerms: ["SPEAK"]
requiredPerms: []
};
exports.help = {

46
src/commands/songinfo.js Normal file
View File

@ -0,0 +1,46 @@
const { getGuild, createTimestamp } = require('../modules/music')
const { MessageEmbed } = require('discord.js')
exports.run = async (client, message, args) => {
const guild = getGuild(message.guild.id)
if (guild.queue.length < 1) {
return message.channel.send(client.config.emojis.error + ' Nothing is in the queue!')
}
const songID = +args[0]
if (isNaN(songID) === true) {
return message.channel.send('<:error:466995152976871434> That isn\'t a number! You need to tell me the songs position in the queue (1, 2, etc.)')
}
const s = guild.queue[songID]
if (!s) {
return message.channel.send('<:error:466995152976871434> No song was found in the position you specified.')
}
const embed = new MessageEmbed()
embed.setThumbnail(client.config.endpoints.invidious + s.video.videoThumbnails[1].url)
embed.setColor(client.embedColour(message))
embed.setDescription(`**[${s.video.title}](https://www.youtube.com/watch?v=${s.video.videoId})**`)
embed.addField('Channel:', s.video.author, true)
embed.addField('Length:', '`[' + createTimestamp(s.video.lengthSeconds) + ']`', true)
embed.setFooter('Requested by ' + s.requestedBy.tag, s.requestedBy.avatarURL({ format: 'png', dynamic: true, size: 2048 }))
message.channel.send(embed)
}
exports.conf = {
enabled: true,
guildOnly: true,
aliases: [],
permLevel: "User",
requiredPerms: []
}
exports.help = {
name: "songinfo",
category: "Music",
description: "Sends you information about a song in the queue. Song ID is the song's position in the queue.",
usage: "songinfo [songID]"
}

53
src/commands/splatnet.js Normal file
View File

@ -0,0 +1,53 @@
const Discord = require("discord.js");
const BasePaginator = require('discord-paginator.js');
const fetch = require('node-fetch');
const prettifyMiliseconds = require('pretty-ms');
exports.run = async (client, message, args) =>{
fetch('https://splatoon2.ink//data/merchandises.json', { headers: { 'User-Agent': client.config.userAgent }})
.then(res => res.json())
.then(json => {
const embeds = [];
for ( let i = 0; i < json.merchandises.length; i++ ) {
const embed = new Discord.MessageEmbed()
.setTitle(json.merchandises[i].gear.name)
.setThumbnail('https://splatoon2.ink/assets/splatnet' + json.merchandises[i].gear.image)
.setColor(client.embedColour(message))
.addField('Price', (json.merchandises[i].price).toString(), true)
.addField('Brand', json.merchandises[i].gear.brand.name, true)
.addField('Ability Slots', (json.merchandises[i].gear.rarity + 1).toString(), true)
.addField('Main Ability', json.merchandises[i].skill.name, true)
.addField('Common Ability', json.merchandises[i].gear.brand.frequent_skill.name, true)
.setFooter(`Page ${i+1}/${json.merchandises.length} | Out of stock in ${prettifyMiliseconds(json.merchandises[i].end_time * 1000 - Date.now())} | Data provided by splatoon2.ink`);
embeds.push(embed);
}
const Paginator = new BasePaginator({
pages: embeds,
timeout: 120000,
filter: (reaction, user) => user.id == message.author.id //to filter the reaction collector
})
Paginator.spawn(message.channel)
})
.catch(err => {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
});
};
exports.conf = {
enabled: true,
guildOnly: false,
aliases: [],
permLevel: "User",
requiredPerms: []
};
exports.help = {
name: "splatnet",
category: "Splatoon",
description: "See what is currently on offer in the splatnet shop.",
usage: "splatnet"
};

View File

@ -0,0 +1,60 @@
const Discord = require("discord.js");
const BasePaginator = require('discord-paginator.js');
const fetch = require('node-fetch');
const prettifyMiliseconds = require('pretty-ms');
exports.run = async (client, message, args) =>{
fetch('https://splatoon2.ink/data/schedules.json', { headers: { 'User-Agent': client.config.userAgent }})
.then(res => res.json())
.then(json => {
const embeds = [
new Discord.MessageEmbed()
.setTitle('Current Splatoon 2 Maps')
.setColor(client.embedColour(message))
.addField('<:turf_war:814651383911153692> Turf War', `${json.regular[0].stage_a.name}\n${json.regular[0].stage_b.name}`, true)
.addField(`<:ranked:814651402479468544> Ranked: ${json.gachi[0].rule.name}`, `${json.gachi[0].stage_a.name}\n${json.gachi[0].stage_b.name}`, true)
.addField(`<:league:814651415409590363> League: ${json.league[0].rule.name}`, `${json.league[0].stage_a.name}\n${json.league[0].stage_b.name}`, true)
.setFooter(`Page 1/${json.regular.length} | Maps changing in ${prettifyMiliseconds(json.league[0].end_time * 1000 - Date.now(), { secondsDecimalDigits: 0 })} | Data provided by splatoon2.ink`)
];
for ( let i = 1; i < json.regular.length; i++ ) {
embeds.push(
new Discord.MessageEmbed()
.setTitle('Upcoming Splatoon 2 Maps')
.setColor(client.embedColour(message))
.addField('<:turf_war:814651383911153692> Turf War', `${json.regular[i].stage_a.name}\n${json.regular[i].stage_b.name}`, true)
.addField(`<:ranked:814651402479468544> Ranked: ${json.gachi[i].rule.name}`, `${json.gachi[i].stage_a.name}\n${json.gachi[i].stage_b.name}`, true)
.addField(`<:league:814651415409590363> League: ${json.league[i].rule.name}`, `${json.league[i].stage_a.name}\n${json.league[i].stage_b.name}`, true)
.setFooter(`Page ${i+1}/${json.regular.length} | Available in ${prettifyMiliseconds(json.league[i].start_time * 1000 - Date.now(), { secondsDecimalDigits: 0 })} | Data provided by splatoon2.ink`)
);
}
const Paginator = new BasePaginator({
pages: embeds,
timeout: 120000,
filter: (reaction, user) => user.id == message.author.id //to filter the reaction collector
})
Paginator.spawn(message.channel)
})
.catch(err => {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
});
};
exports.conf = {
enabled: true,
guildOnly: false,
aliases: ['splatoonmodes'],
permLevel: "User",
requiredPerms: []
};
exports.help = {
name: "splatoonmaps",
category: "Splatoon",
description: "Get current and upcoming maps and modes for regular, ranked and league battles.",
usage: "splatoonmaps"
};

View File

@ -1,18 +1,20 @@
const Discord = require("discord.js");
const { getGuild } = require('../modules/music')
exports.run = async (client, message) => {
let guild = client.music.getGuild(message.guild.id);
const guild = getGuild(message.guild.id)
if(guild.queue.length < 1 || !guild.playing || !guild.dispatcher) return message.channel.send("<:error:466995152976871434> Nothing is playing.");
if(!message.member.voice.channel) return message.channel.send('<:error:466995152976871434> You need to be in voice channel to use this command!');
if (guild.queue.length < 1 || !guild.playing || !guild.dispatcher) return message.channel.send('Nothing is playing.')
if (!message.member.voice.channel) return message.channel.send('You need to be in voice channel to use this command!')
guild.playing = false;
guild.paused = false;
guild.queue = [];
guild.dispatcher.end('silent')
guild.dispatcher.end("silent");
guild.queue = []
guild.playing = false
guild.paused = false
guild.skippers = []
guild.fixers = []
guild.channel = null
message.channel.send("<:stop:467639381390262284> Playback stopped!");
message.channel.send('<:success:466995111885144095> Playback stopped!')
};
exports.conf = {

View File

@ -1,8 +1,8 @@
const Discord = require("discord.js");
const coolPeople = require('../../resources/other/coolpeople.json')
exports.run = (client, message, args) => {
var user, guild, status, createdAt, avurl, tag, id;
var nick = "", roles = "", presence = "", badges = "";
var user, guild, createdAt, avurl, tag, id;
var nick = "", roles = "", badges = "";
var coolPerson = false;
var friendos = coolPeople.coolPeople;
@ -74,41 +74,10 @@ exports.run = (client, message, args) => {
createdAt = user.createdAt;
};
if(user.presence.status == "online") {
status = `online <:status_online:685462758023626762>`
};
if(user.presence.status == "idle") {
status = `idle <:status_idle:685462771529154561>`
};
if(user.presence.status == "dnd") {
status = `do not disturb <:status_dnd:685462782963220495>`
};
if(user.presence.status == "offline") {
status = `offline <:status_offline:685462758229016633>`
};
if(user.presence.activities[0]) {
presence = "\n• **Presence:** ";
if(user.presence.activities[0].type == "PLAYING") {
presence += `Playing ${user.presence.activities[0].name}`;
};
if(user.presence.activities[0].type == "STREAMING") {
presence += `Streaming ${user.presence.activities[0].name}`;
};
if(user.presence.activities[0].type == "CUSTOM_STATUS") {
presence += `${user.presence.activities[0].state}`;
};
};
embed = new Discord.MessageEmbed();
embed.setTitle(tag);
embed.setThumbnail(avurl);
embed.setDescription(`${badges}• **ID:** ${id}${nick}\n• **Status:** ${status}${presence}${guild}\n• **Account created:** ${createdAt}`)
embed.setDescription(`${badges}• **ID:** ${id}${nick}${guild}\n• **Account created:** ${createdAt}`)
embed.setColor(colour);
message.channel.send(embed);
};

57
src/commands/volume.js Normal file
View File

@ -0,0 +1,57 @@
const { getGuild, setVolume } = require('../modules/music')
exports.run = async (client, message, args) => {
if (!args[0]) {
return message.channel.send(`<:error:466995152976871434> No input! Usage: \`${client.commands.get('volume').help.usage}\``)
}
const guild = getGuild(message.guild.id)
if (guild.queue.length < 1 || !guild.playing || !guild.dispatcher) {
return message.channel.send(
'<:error:466995152976871434> Nothing is playing.'
)
}
let userVolume = args[0]
if (userVolume.includes('%')) {
userVolume = userVolume.replace('%', '')
}
userVolume = +userVolume
if (isNaN(userVolume) === true) {
return message.channel.send('<:error:466995152976871434> Input must be a number!')
}
if (userVolume > 100 || userVolume < 1) {
return message.channel.send('<:error:466995152976871434> Invalid input, input must be between 1-100')
}
if (userVolume) {
userVolume = Number(userVolume)
userVolume = userVolume / 100
if (userVolume <= 1) {
setVolume(message.guild, userVolume)
message.channel.send('<:success:466995111885144095> Set volume to ' + userVolume * 100 + '%')
}
}
}
exports.conf = {
enabled: true,
guildOnly: true,
aliases: [],
permLevel: "Moderator",
requiredPerms: []
}
exports.help = {
name: 'volume',
category: 'Music',
description: 'Sets volume of currently playing music. (100% = 25% of the actual volume)',
usage: 'volume [volume]'
}

31
src/commands/wag.js Normal file
View File

@ -0,0 +1,31 @@
const fetch = require("node-fetch")
exports.run = async (client, message, args) => {
message.channel.startTyping();
try{
fetch(`https://purrbot.site/api/img/sfw/tail/gif/`)
.then(res => res.json())
.then(json => message.channel.send(json.link))
.catch(err => {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
});
message.channel.stopTyping();
} catch(err) {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
message.channel.stopTyping();
};
};
exports.conf = {
enabled: true,
guildOnly: false,
aliases: [],
permLevel: "User",
requiredPerms: ["EMBED_LINKS"]
};
exports.help = {
name: "wag",
category: "Image",
description: "Wag the tail :3",
usage: "wag"
};

View File

@ -44,6 +44,7 @@ exports.run = async (client, message, args, error) => {
message.channel.send(embed)
});
} catch(err) {
message.channel.stopTyping(); // Previously wasnt here causing an issue where woomy would endlessly type.
return message.channel.send(`<:error:466995152976871434> API error: \`${err}\``)
};
};

View File

@ -9,7 +9,10 @@ exports.run = async (client, message, args) => {
try{
fetch(`http://yoda-api.appspot.com/api/v1/yodish?text=${encodeURIComponent(speech.toLowerCase())}`)
.then(res => res.json())
.then(json => message.channel.send(json.yodish));
.then(json => message.channel.send(json.yodish))
.catch(err => {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);
});
message.channel.stopTyping();
} catch(err) {
message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`);

View File

@ -1,7 +1,8 @@
const cooldown = new Set();
module.exports = async (client, message) => {
if (message.author.bot) return;
if (typeof(message.content) === 'string') message.content = message.content.replace(/\u8203/g,'').replace(/\uB200/g,'').replace("\\uB200",''); // Remove zero-width characters
var settings;
if(message.guild) {
@ -163,10 +164,14 @@ module.exports = async (client, message) => {
return message.author.send(`<:error:466995152976871434> I don't have permission to speak in **#${message.channel.name}**, Please ask a moderator to give me the send messages permission!`);
};
if (!cmd.conf.enabled) {
return message.channel.send('<:error:466995152976871434> This command has been disabled by my developers.')
}
if(message.guild && blacklisted == true) {
try {
return message.author.send(
`<:denied:466995195150336020> You have been blacklisted from using commands in \`${message.guild.name}\``
`<:denied:466995195150336020> You have been blocked from using commands in \`${message.guild.name}\``
);
} catch(err) {
client.logger.log(err, "error")
@ -229,7 +234,7 @@ module.exports = async (client, message) => {
cooldown.delete(message.author.id);
}, 2000);
client.logger.cmd(`${client.config.permLevels.find(l => l.level === level).name} ${message.author.username} (${message.author.id}) ran command ${cmd.help.name}`);
client.logger.cmd(`${client.config.permLevels.find(l => l.level === level).name} ran command ${cmd.help.name}`);
cmd.run(client, message, args, level);
};

View File

@ -3,6 +3,8 @@ const Discord = require("discord.js");
module.exports = (client, message) => {
if (message.author.bot) return;
if(!message.guild) return;
const settings = (message.settings = client.getSettings(message.guild.id));
if (settings.chatlogsChannel !== "off") {

View File

@ -13,6 +13,7 @@ module.exports = (client, omsg, nmsg) => {
);
if (channel) {
if (!nmsg.member) return;
let embed = new Discord.MessageEmbed();
embed.setColor("#fff937");
embed.setAuthor("Message Edited!", nmsg.member.user.avatarURL({dynamic: true}));
@ -29,7 +30,7 @@ module.exports = (client, omsg, nmsg) => {
return;
}
embed.setDescription(`• Author: ${nmsg.member} (${nmsg.member.user.id})\n• Channel: ${nmsg.channel}\n• Old message: ${omsg.content}\n• New message: ${nmsg.content}`)
embed.setDescription(`[Jump to message](https://discord.com/channels/${nmsg.guild.id}/${nmsg.channel.id}/${nmsg.id})\n• Author: ${nmsg.member} (${nmsg.member.user.id})\n• Channel: ${nmsg.channel}\n• Old message: ${omsg.content}\n• New message: ${nmsg.content}`)
try {
channel.send({ embed });
} catch (err) {

View File

@ -0,0 +1,42 @@
// Copyright 2020 Emily J. / mudkipscience and contributors. Subject to the AGPLv3 license.
const music = require('../modules/music')
module.exports = (client, oldState, newState) => {
if (newState.channelID !== oldState.channelID) {
const guild = music.getGuild(newState.guild.id)
// Reset queue, dispatcher, etc if Woomy is forcibly disconnected from the queue
if (guild.voiceChannel && !guild.voiceChannel.members.get(client.user.id) && guild.queue.length > 0) {
guild.queue = []
guild.playing = false
guild.paused = false
guild.skippers = []
}
// Auto-disconnect feature
if (guild.playing && guild.voiceChannel && guild.voiceChannel.id === oldState.channelID) {
if (guild.voiceChannel.members.filter(member => !member.user.bot).size < 1) {
guild.message.channel.send('Everyone has left my voice channel, the music will end in two minutes if no one rejoins.')
.then(msg => {
msg.delete({ timeout: 120000 })
})
setTimeout(() => {
if (guild.dispatcher !== null && guild.voiceChannel.members.filter(member => !member.user.bot).size < 1) {
// Probably should be async? But no need here I think
guild.dispatcher.end('silent')
guild.queue = []
guild.playing = false
guild.paused = false
guild.dispatcher = null
guild.skippers = []
guild.message.channel.send('The music has ended because no one was listening to me ;~;')
}
}, 120000)
}
}
}
}

View File

@ -1,8 +1,3 @@
const ytdl = require('ytdl-core-discord');
const youtubeInfo = require('youtube-info');
const getYoutubeId = require('get-youtube-id');
const fetch = require('node-fetch');
module.exports = client => {
// Permission level function
client.permlevel = message => {
@ -147,177 +142,6 @@ module.exports = client => {
return client.users.cache.get(mention);
}
}
// MUSIC
client.music = {guilds: {}};
client.music.isYoutubeLink = function(input) {
return input.startsWith('https://www.youtube.com/') || input.startsWith('http://www.youtube.com/') || input.startsWith('https://youtube.com/') || input.startsWith('http://youtube.com/') || input.startsWith('https://youtu.be/') || input.startsWith('http://youtu.be/') || input.startsWith('http://m.youtube.com/') || input.startsWith('https://m.youtube.com/');
}
client.music.search = async function(query)
{
return new Promise(function(resolve, reject)
{
try{
fetch("https://www.googleapis.com/youtube/v3/search?part=id&type=video&q=" + encodeURIComponent(query) + "&key=" + client.config.ytkey)
.then(res => res.json())
.then(json => {
if(!json.items) { reject(); return; }
resolve(json.items[0]);
});
} catch (err) {
client.logger.error("Music search err: ", err);
throw err;
};
});
}
client.music.getGuild = function(id)
{
if(client.music.guilds[id]) return client.music.guilds[id];
return client.music.guilds[id] =
{
queue: [],
playing: false,
paused: false,
dispatcher: null,
skippers: []
}
}
client.music.getMeta = async function(id)
{
return new Promise(function(resolve, reject)
{
youtubeInfo(id, function(err, videoInfo)
{
if(err) throw err;
resolve(videoInfo);
});
});
}
client.music.play = async function(message, input, bypassQueue)
{
let voiceChannel = message.member.voice.channel;
if(!voiceChannel) return message.channel.send('<:error:466995152976871434> You need to be in a voice channel to use this command!');
let permissions = voiceChannel.permissionsFor(client.user);
if (!permissions.has('CONNECT')) {
return message.channel.send('<:error:466995152976871434> I do not have permission to join your voice channel.');
}
if (!permissions.has('SPEAK')) {
return message.channel.send('<:error:466995152976871434> I do not have permission to join your voice channel.');
}
if (voiceChannel.joinable != true) {
return message.channel.send("<:error:466995152976871434> I do not have permission to join your voice channel.")
}
let id = undefined;
if(client.music.isYoutubeLink(input))
{
id = await getYoutubeId(input)
} else {
let item = await client.music.search(input);
if(!item) {
return message.channel.send(`<:error:466995152976871434> No results found.`);
};
id = item.id.videoId;
}
if(client.music.getGuild(message.guild.id).queue.length == 0 || bypassQueue)
{
let meta = await client.music.getMeta(id);
if(!bypassQueue) client.music.getGuild(message.guild.id).queue.push({input: input, id: id, requestedBy: message.author, title: meta.title, author: meta.owner, thumbnail: meta.thumbnailUrl, duration: meta.duration});
let connection = await new Promise((resolve, reject) =>
{
voiceChannel.join().then((connection) =>
{
resolve(connection);
});
});
function end(silent)
{
client.music.getGuild(message.guild.id).queue.shift();
client.music.getGuild(message.guild.id).dispatcher = null;
if(client.music.getGuild(message.guild.id).queue.length > 0)
{
client.music.play(message, client.music.getGuild(message.guild.id).queue[0].input, true);
} else {
client.music.getGuild(message.guild.id).playing = false;
if(!silent) {
message.channel.send("<:play:467216788187512832> Queue is empty! Disconnecting from the voice channel.");
}
connection.disconnect();
}
}
client.music.getGuild(message.guild.id).playing = true;
let song = client.music.getGuild(message.guild.id).queue[0];
try
{
let dispatcher = client.music.getGuild(message.guild.id).dispatcher = connection.play(await ytdl("https://www.youtube.com/watch?v=" + id, {highWaterMark: 1024 * 1024 * 32}), {type: 'opus'});
dispatcher.on('finish', (a, b) =>
{
end(a == "silent");
});
} catch(err) {
message.channel.send('<:error:466995152976871434> Failed to play **' + song.title + '** ' + err);
end();
}
client.music.getGuild(message.guild.id).skippers = [];
message.channel.send(`<:play:467216788187512832> Now playing: **${song.title}**`);
} else {
let meta = await client.music.getMeta(id);
let song = {input: input, id: id, requestedBy: message.author, title: meta.title, author: meta.owner, thumbnail: meta.thumbnailUrl, duration: meta.duration};
client.music.getGuild(message.guild.id).queue.push(song);
message.channel.send(`<:success:466995111885144095> Added to queue: **${song.title}**`);
}
}
// MUSIC - TIMESTAMP
client.createTimestamp = function(duration){
hrs = ~~(duration / 60 / 60),
min = ~~(duration / 60) % 60,
sec = ~~(duration - min * 60);
if(String(hrs).length < 2) {
hrs = "0" + String(hrs) + ":";
};
if(String(min).length < 2) {
min = "0" + String(min);
};
if(String(sec).length < 2) {
sec = "0" + String(sec);
};
if(hrs == "00:") {
hrs = "";
}
var time = hrs + min + ":" + sec;
return time;
};
//FIND ROLE
client.findRole = function(input, message) {
@ -373,10 +197,9 @@ module.exports = client => {
process.on("uncaughtException", err => {
const errorMsg = err.stack.replace(new RegExp(`${__dirname}/`, "g"), "./");
client.logger.error(`Uncaught Exception: ${errorMsg}`);
process.exit(1);
});
process.on("unhandledRejection", err => {
client.logger.error(`Unhandled rejection: ${err.stack}`);
client.logger.error(`Unhandled rejection: ${err}`);
});
};

256
src/modules/music.js Normal file
View File

@ -0,0 +1,256 @@
// Copyright 2020 Emily J. / mudkipscience and contributors. Subject to the AGPLv3 license.
const ytdl = require('ytdl-core')
const fetch = require('node-fetch')
const { MessageEmbed } = require('discord.js')
const { utc } = require('moment')
exports.queue = {}
exports.createTimestamp = function (s) {
if (s < 1) {
return 'LIVE'
} else if (s >= 3600) {
return utc(s * 1000).format('HH:mm:ss')
} else {
return utc(s * 1000).format('mm:ss')
}
}
exports.getGuild = function (id) {
let guild = exports.queue[id]
if (!guild) {
guild = {}
guild.queue = []
guild.playing = false
guild.paused = false
guild.dispatcher = null
guild.skippers = []
guild.fixers = []
exports.queue[id] = guild
}
return guild
}
exports.getLinkFromID = function (id) {
return 'https://www.youtube.com/watch?v=' + id
}
exports.getVideoByQuery = async function (client, query, message) {
let res
try {
const id = await ytdl.getURLVideoID(query)
res = await fetch(`${client.config.endpoints.invidious}/api/v1/videos/${id}`)
} catch (err) {
res = await fetch(`${client.config.endpoints.invidious}/api/v1/search?q=${encodeURIComponent(query)}`)
}
const parsed = await res.json().catch(function (e) {
return message.channel.send('<:error:466995152976871434> An error has occured: ' + e)
})
if (parsed) {
const videos = parsed
if (videos) {
return videos
} else {
return false
}
} else {
return false
}
}
exports.play = async function (client, message, query, playNext, ignoreQueue) {
const guild = exports.getGuild(message.guild.id)
guild.message = message
// message.channel.startTyping()
if (!message.member.voice.channel && !guild.voiceChannel) {
message.channel.stopTyping()
return message.channel.send('<:error:466995152976871434> You have to be connected to a voice channel to use this command!')
}
const vc = message.member.voice.channel
let video
let videos
if (!ignoreQueue) {
videos = await exports.getVideoByQuery(client, query, message)
if (!videos[1]) {
if (!videos[0]) {
video = videos
message.channel.stopTyping()
} else {
video = videos[0]
}
}
}
if (videos || ignoreQueue) {
if (!ignoreQueue) {
// Fix the bot if somehow broken
// music "playing", nothing in queue
if ((guild.playing || guild.dispatcher) && guild.queue.length === 0) {
guild.queue = []
guild.playing = false
guild.paused = false
guild.skippers = []
guild.fixers = []
guild.channel = null
// music not playing, something is in queue
} else if ((!guild.playing || !guild.dispatcher) && guild.queue.length > 0) {
guild.queue = []
}
if (!video) {
let output = ''
let i = 0
for (i = 0; i < 5; i++) {
if (!videos[i]) break
output += `\`${i + 1}:\` **[${videos[i].title}](https://www.youtube.com/watch?v=${videos[i].videoId})** \`[${exports.createTimestamp(videos[i].lengthSeconds)}]\`\n`
}
message.channel.stopTyping()
const embed = new MessageEmbed()
embed.setTitle('Please reply with a number `1-' + i + '` to select which song you want to add to the queue.')
embed.setColor(client.embedColour(message))
embed.setDescription(output)
let selection = await client.awaitReply(message, embed)
selection = Number(selection)
switch (selection) {
case 1:
video = videos[0]
break
case 2:
if (videos[1]) {
video = videos[1]
} else {
return message.channel.send('<:error:466995152976871434> Invalid choice.')
}
break
case 3:
if (videos[2]) {
video = videos[2]
} else {
return message.channel.send('<:error:466995152976871434> Invalid choice.')
}
break
case 4:
if (videos[3]) {
video = videos[3]
} else {
return message.channel.send('<:error:466995152976871434> Invalid choice.')
}
break
case 5:
if (videos[4]) {
video = videos[4]
} else {
return message.channel.send('<:error:466995152976871434> Invalid choice.')
}
break
default:
return message.channel.send('<:error:466995152976871434> Invalid choice.')
}
}
if (!video && videos[0]) {
video = videos[0]
} else if (!video) {
video = videos
}
// Add video to queue
if (playNext === true) {
guild.queue.splice(1, 0, { video: video, requestedBy: message.author })
} else {
guild.queue.push({ video: video, requestedBy: message.author })
}
}
// Figure out if the bot should add it to queue or play it right now
if (guild.playing) {
message.channel.send('<:success:466995111885144095> Queued **' + video.title + '** `[' + exports.createTimestamp(video.lengthSeconds) + ']`')
} else {
guild.playing = true
guild.voiceChannel = vc
if (!guild.channel) {
guild.channel = message.channel
}
const connection = await vc.join()
const v = guild.queue[0]
try {
guild.dispatcher = connection.play(ytdl(v.video.videoId, { type: 'opus', bitrate: 'auto' }));
} catch (err) {
if (playNext && playNext === true) {
guild.queue.splice(1, 1)
} else {
guild.queue.pop()
}
client.logger.error(err.stack)
return message.channel.send(`<:error:466995152976871434> An error has occured: \n\`${err}\``)
// return message.channel.send('<:error:466995152976871434> YouTube have made changes to their site that break Woomy\'s music module. An announcement will be made in the development server when this issue is resolved.')
}
guild.dispatcher.setVolume(0.25)
guild.channel.send('<:player:467216674622537748> Now playing: **' + v.video.title + '** `[' + exports.createTimestamp(v.video.lengthSeconds) + ']`')
// play next in queue on end
guild.dispatcher.on('error', (err) => {
console.error('[MUSIC ERROR] ' + String(err));
});
guild.dispatcher.once('finish', () => {
guild.queue.shift()
guild.playing = false
if (guild.queue.length > 0) {
exports.play(client, message, null, false, true)
} else {
guild.queue = []
guild.playing = false
guild.paused = false
guild.skippers = []
guild.fixers = []
guild.channel = null
connection.disconnect()
}
})
}
} else {
return message.channel.send('failed to find the video!')
}
}
exports.setVolume = function (guild, target) {
const g = exports.getGuild(guild.id)
if (g.dispatcher) {
g.dispatcher.setVolume(target)
}
}
exports.skip = function (guild, reason) {
const g = exports.getGuild(guild.id)
if (g.dispatcher) {
g.dispatcher.end(reason)
}
}

View File

@ -1,4 +1,4 @@
{
"number": "1.2.3",
"changelog": "**1.2.0 CHANGELOG:**\n> • Added action commands! (`cuddle`, `feed`, `hug`, `kiss`, `pat`, `poke`, `slap`, `smug`, `tickle`)\n> • Added `fact`\n> • Added `catfact`\n> • Added `dogfact`\n> • Added `yoda`\n> • Added `dice`\n> • Added `spoilerise`\n> • Added `zalgo`\n> • Added `dog`\n> • Added `cat`\n> • Added `lizard`\n> • Added `neko`\n> • Added `nekogif`\n> • Added `kemonomimi`\n> • Added `foxgirl`\n> • Added `identity`\n> • Added `pronouns`\n> • Added `sexuality`\n> • Added `ship`\n> • Renamed `flip to `coinflip` (flip remains as an alias)\n> • Renamed `math` to `calculate` (math is an alias)\n> • @Woomy is now a prefix\n> • Added the `inspire` alias to `inspirobot`\n> • Help now displays the amount of commands in each category\n> • Bots now get a badge in `userinfo`\n> • `roleinfo` now displays what permissions a role has\n> • small changes to `weather`\n> • Woomy now has clear logging of issues that prevent her from starting\n> • request npm module has been swapped out for node-fetch\n**NOTES:**\n> Thank you to Terryiscool160 for creating multiple commands used in this update"
}
"number": "1.4.8",
"changelog": "**1.4 Changelog**\n> • Splatoon commands have been added! check current and upcoming maps and modes with `~splatoonmaps`, current and upcoming salmon run maps, weapons and reward gear with `~salmonrun` and see what gear is on offer in the splatnet shop with `~splatnet`!\n**Notes:**\n> • Music is still broken and likely will be until v2 is released. Fixing v1 would delay v2 a lot, sorry >.<"
}