diff --git a/LICENSE.md b/LICENSE.md index f82dfa5..4e230a1 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,7 @@ MIT License -Copyright (c) 2020 mudkipscience +Copyright (c) 2018 YorkAARGH +Copyright (c) 2018-2020 mudkipscience Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/changes.txt b/changes.txt deleted file mode 100644 index e91c096..0000000 --- a/changes.txt +++ /dev/null @@ -1,10 +0,0 @@ -Added a yodish command and made catfact and dogfact say if the api errors (terry) -Links to avatars now lead to the original file size -Bots now get a bot badge in the userinfo command -Added dogfact and catfact command (terry) -index.js now has better logging of when things fail to load/initialize (terry) -added `dice`, rolls a 6 sided die (terry) -Help command changed, the amount of commands in each category and overall is now displayed -added `inspire` as an alias for inspirobot -ship command -added find by mention to functions \ No newline at end of file diff --git a/configTemplate.js b/configTemplate.js index 3828ed8..b6e96c3 100644 --- a/configTemplate.js +++ b/configTemplate.js @@ -2,6 +2,12 @@ const config = { // ID's "owners": [], // Adding your ID here will give you access to dangerous commands like eval. Please be careful with who you add here! Eval can be used to modify the host machine. + // Host options + "devmodeEnabled": false, // true or false + "loggingServer": "", // server ID, or blank to disable + "startupLogs": "", // Channel ID, or blank to disable + "consoleLogs": "", // Channel ID, or blank to disable + // Tokens "token": "", // Your bot's token. "devtoken": "", // (optional) another token, meant for a bot used for development diff --git a/index.js b/index.js index 4e535ee..49d5326 100644 --- a/index.js +++ b/index.js @@ -1,84 +1,58 @@ +if (Number(process.version.slice(1).split(".")[0]) < 12) { + throw new Error("Node 12.0.0 or higher is required. Please update Node on your system."); +}; + const Discord = require('discord.js'); const { promisify } = require('util'); const readdir = promisify(require('fs').readdir); const Enmap = require('enmap'); const chalk = require('chalk'); -const DBL = require("dblapi.js"); const client = new Discord.Client(); try { -client.config = require('./config'); + client.config = require('./config'); } catch (err) { - console.log('Could not load config.js: \n', err); - process.exit(); -} + console.log('Failed to load config.js:', err); + process.exit(); +}; try{ -client.version = require('./version.json'); + client.version = require('./version.json'); } catch (err) { - console.log('Could not load version.json: \n', err); - process.exit(); -} + console.log('Failed to load version.json:', err); + process.exit(); +}; try{ -client.logger = require('./src/modules/Logger'); + client.logger = require('./src/modules/Logger'); } catch (err) { - console.log('Could not load Logger.js: \n', err); - process.exit(); -} + console.log('Failed to load Logger.js:', err); + process.exit(); +}; -try{ -require("./src/modules/functions")(client); -} catch (err) { - console.log('Could not load functions.js: \n', err); - process.exit(); -} - -try{ client.logger.setClient(client); -} catch (err) { - console.log('Logger failed to initialize: \n', err); - process.exit(1); -} -if(process.env['USER'] != 'container') { +try{ + require("./src/modules/functions")(client); +} catch (err) { + console.log('Failed to load functions.js:', err); + process.exit(); +}; + +if(client.config.devmodeEnabled == true && process.env['USER'] != 'container') { client.devmode = true; } else { client.devmode = false; - if(client.config.dblkey.length == 0) { + if(client.config.dblkey.length > 0) { + const DBL = require("dblapi.js"); const dblapi = new DBL(client.config.dblkey, client); - } -} + }; +}; -try{ client.commands = new Enmap(); -} catch (err) { - console.log('Failed to create the commands database: \n', err); - process.exit(); -} - -try{ client.aliases = new Enmap(); -} catch (err) { - console.log('Failed to create the aliases database: \n', err); - process.exit(); -} - -try{ client.settings = new Enmap({name: 'settings'}); -} catch (err) { - console.log('Failed to initialize the settings database: \n', err); - process.exit(); -} -try{ -client.blacklist = new Enmap({name: 'blacklist'}); -} catch (err) { - console.log('Failed to initialize the blacklist database: \n', err); - process.exit(1); -} - -try{ const init = async () => { const cmdFiles = await readdir("./src/commands/"); client.logger.info(`Loading ${cmdFiles.length} commands.`); @@ -103,30 +77,17 @@ const init = async () => { client.on(eventName, event.bind(null, client)); }); - try{ client.levelCache = {}; for (let i = 0; i < client.config.permLevels.length; i++) { const thisLevel = client.config.permLevels[i]; client.levelCache[thisLevel.name] = thisLevel.level; }; -} catch (err) { - console.log('Level cache failed to initialize: \n', err); - process.exit(); -} - try{ if(client.devmode === true) { client.login(client.config.devtoken); } else { client.login(client.config.token); }; -} catch (err) { - console.log('Could not login to Discord: \n', err); - process.exit(1); -} }; -init(); -} catch (err) { - console.log('Initialization failed: \n', err); - process.exit(1); -} + +init(); \ No newline at end of file diff --git a/package.json b/package.json index 7210610..891ab34 100644 --- a/package.json +++ b/package.json @@ -4,23 +4,26 @@ "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.1", + "discord.js": "^12.0.2", "enmap": "^5.2.4", "garfield": "^1.1.2", "get-youtube-id": "^1.0.1", "hastebin-gen": "^2.0.5", "moment": "^2.24.0", "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", - "request": "^2.88.2", "relevant-urban": "^2.0.0", + "request": "^2.88.2", + "to-zalgo": "^1.0.1", "urban": "^0.3.2", - "url-unshort": "^5.0.0", - "url-unshorten": "^1.0.6", "weather-js": "^2.0.0", "youtube-info": "^1.3.2", "ytdl-core-discord": "^1.1.0" diff --git a/resources/images/attackhelicopter.jpg b/resources/images/attackhelicopter.jpg new file mode 100644 index 0000000..c077f0d Binary files /dev/null and b/resources/images/attackhelicopter.jpg differ diff --git a/resources/other/coolpeople.json b/resources/other/coolpeople.json new file mode 100644 index 0000000..d5f335c --- /dev/null +++ b/resources/other/coolpeople.json @@ -0,0 +1,21 @@ +{ + "coolPeople": [ + "448354605617643520", + "433790467830972417", + "231777839576252417", + "285992938314661899", + "231704701433937931", + "324937993972350976", + "336492042299637771", + "273867501006225419", + "331870539897372672", + "304000458144481280", + "239787232666451980", + "264970229514371072", + "254310746450690048", + "358390849807319040", + "211011138656272386", + "266472557740425216", + "102943767346057216" + ] +} \ No newline at end of file diff --git a/resources/other/genders.json b/resources/other/genders.json deleted file mode 100644 index 3b50663..0000000 --- a/resources/other/genders.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "cisgender": "Someone who identifies with their assigned gender at birth.", - "transgender": "Someone who identifies with a gender that is not their assigned gender at birth." -} \ No newline at end of file diff --git a/resources/other/identities.json b/resources/other/identities.json new file mode 100644 index 0000000..4afd11a --- /dev/null +++ b/resources/other/identities.json @@ -0,0 +1,110 @@ +{ + "agender": { + "name": "agender", + "description": "A gender identity used by someone who has no gender, or sometimes by someone whose gender is neutral." + }, + "androgyne": { + "name": "androgyne", + "description": "A gender identity associated with androgyny. Androgynes have a gender which is simultaneously feminine and masculine, although not necessarily in equal amounts." + }, + "androgynous": { + "name": "androgynous", + "description": "A term used to refer to people who have both feminine and masculine characteristics." + }, + "aporagender": { + "name": "aporagender", + "description": "A gender that is not male, female, or anything in between that still has a distinct gendered feeling." + }, + "bigender": { + "name": "bigender", + "description": "Having two gender identities, either simultaneously or varying between the two." + }, + "cisgender": { + "name": "cisgender", + "description": "Someone who identifies with their assigned gender at birth." + }, + "demiboy": { + "name": "demiboy", + "description": "Someone who identifies as partially male and partially another gender." + }, + "demiflux": { + "name": "demiflux", + "description": "A gender where one part of someone’s gender is static, and the other part fluctuates in intensity." + }, + "demigender": { + "name": "demigender", + "description": "Someone who identifies as partially one gender, and partially another." + }, + "demigirl": { + "name": "demigirl", + "description": "Someone who identifies as partially female and partially another gender." + }, + "dyadic": { + "name": "dyadic", + "description": "A word used to refer to people who are not intersex" + }, + "enby": { + "name": "enby", + "description": "Shortened term for “nonbinary”. Used as a noun, like “boy” or “girl” but for nonbinary people." + }, + "fluidflux": { + "name": "fluidflux", + "description": "A gender identity which refers to someone with a gender that moves between two or more genders and also fluctuates in intensity." + }, + "genderfluid": { + "name": "genderfluid", + "description": "Someone whose gender varies over time. This might be fluctuating between different genders, or expressing multiple aspects of various genders at the same time." + }, + "genderflux": { + "name": "genderflux", + "description": "Someone whose gender fluctuates, usually between agender and something else." + }, + "genderqueer": { + "name": "genderqueer", + "description": "An umbrella term for all the nonbinary genders. Genderqueer can be a standalone identity, or can refer to a more specific gender identity." + }, + "gendervoid": { + "name": "gendervoid", + "description": "Someone who does not experience gender, or who feels an absence or void in the place of gender." + }, + "intersex": { + "name": "intersex", + "description": "An intersex person is someone with sex characteristics (sexual anatomy, reproductive organs, chromosomal patterns, etc.) that do not align with the typical descriptions of male and female." + }, + "libragender": { + "name": "libragender", + "description": "A gender identity that is mostly agender, but has a connection to masculinity and/or femininity and/or other gendered feelings. That connection may be static (libragender, librafeminine, libramasculine, etc) or fluid, where one feels that the gender one experiences changes (librafluid)." + }, + "neutrois": { + "name": "neutrois", + "description": "Having a null or neutral gender." + }, + "nonbinary": { + "name": "nonbinary", + "description": "An umbrella term for all the gender identities that aren't male or female (the binary genders)" + }, + "non-gendered": { + "name": "non-gendered", + "description": "Having no gender." + }, + "polygender": { + "name": "polygender", + "description": "Having more than one gender, either at the same time or at different times. A polygender person may identify with any combination of binary and nonbinary genders." + }, + "pangender": { + "name": "pangender", + "description": "Having more than one gender, especially someone who identifies as all genders." + }, + "transfeminine": { + "name": "transfeminine", + "description": "A transgender person who identifies with femininity, either as a binary female or a fem-leaning nonbinary identity." + }, + "transgender": { + "name": "transgender", + "description": "Someone whose identity differs from their assigned gender at birth." + }, + "transmasculine": { + "name": "transmasculine", + "description": "A transgender person who identifies with masculinity, either as a binary male or a masc-leaning nonbinary identity." + } +} \ No newline at end of file diff --git a/resources/other/pronouns.json b/resources/other/pronouns.json index 544b7b4..fa65ece 100644 --- a/resources/other/pronouns.json +++ b/resources/other/pronouns.json @@ -1,3 +1,154 @@ { - + "ae/aer": { + "name": "ae/aer", + "examples": "• **Ae** went to the park.\n• I went with **aer**.\n• **Ae** brought **aer** frisbee.\n• At least I think it was **aers.**\n• **Ae** threw a frisbee to **aerself**." + }, + "e/em": { + "name": "e/em", + "examples": "• **E** went to the park.\n• I went with **em**.\n• **E** brought **eir** frisbee.\n• At least I think it was **eirs**.\n• **E** threw a frisbee to **emself**." + }, + "ey/em": { + "name": "ey/em", + "examples": "• **Ey** went to the park.\n• I went with **em**.\n• **Ey** brought **eir** frisbee.\n• At least I think it was **eirs**.\n• **Ey** threw a frisbee to **eirself**." + }, + "fae/faer": { + "name": "fae/faer", + "examples": "• **Fae** went to the park.\n• I went with **faer**.\n• **Fae** brought **faer** frisbee.\n• At least I think it was **faers**.\n• **Fae** threw a frisbee to **faerself**." + }, + "fey/fem": { + "name": "fey/fem", + "examples": "• **Fey** went to the park.\n• I went with **fem**.\n• **Fey** brought **feir** frisbee.\n• At least I think it was **feirs**.\n• **Fey** threw a frisbee to **feirself**." + }, + "he/him": { + "name": "he/him", + "examples": "• **He** went to the park.\n• I went with **him**.\n• **He** brought **his** frisbee.\n• At least I think it was **his**.\n• **He** threw a frisbee to **himself**." + }, + "hu/hum": { + "name": "hu/hum", + "examples": "• **Hu** went to the park.\n• I went with **hum**.\n• **Hu** brought **hus** frisbee.\n• At least I think it was **hus**.\n• **Hu** threw a frisbee to **humself**." + }, + "it/its": { + "name": "it/its", + "examples": "• **It** went to the park.\n• I went with **it**.\n• **It** brought **its** frisbee.\n• At least I think it was **its**.\n• **It** threw a frisbee to **itself**." + }, + "jee/jem": { + "name": "je/jem", + "examples": "• **Jee** went to the park.\n• I went with **jem**.\n• **Jee** brought **jeir** frisbee.\n• At least I think it was **jeirs**.\n• **Jee** threw a frisbee to **jemself**." + }, + "kit/kits": { + "name": "kit/kits", + "examples": "• **Kit** went to the park.\n• I went with **kit**.\n• **Kit** brought **kits** frisbee.\n• At least I think it was **kits**.\n• **Kit** threw a frisbee to **kitself**." + }, + "ne/nem": { + "name": "ne/nem", + "examples": "• **Ne** went to the park.\n• I went with **nem**.\n• **Ne** brought **nir** frisbee.\n• At least I think it was **nirs**.\n• **Ne** threw a frisbee to **nemself**." + }, + "peh/pehm": { + "name": "pe/pehm", + "examples": "• **Peh** went to the park.\n• I went with **pehm**.\n• **Peh** brought **peh's** frisbee.\n• At least I think it was **peh's**.\n• **Peh** threw a frisbee to **pehself**." + }, + "per": { + "name": "per/per", + "examples": "• **Per** went to the park.\n• I went with **per**.\n• **Per** brought **per** frisbee.\n• At least I think it was **pers**.\n• **Per** threw a frisbee to **perself**." + }, + "sie/hir": { + "name": "sie/hir", + "examples": "• **Sie** went to the park.\n• I went with **hir**.\n• **Sie** brought **hir** frisbee.\n• At least I think it was **hirs**.\n• **Sie* threw a frisbee to **hirself**." + }, + "se/sim": { + "name": "se/sim", + "examples": "• **Se** went to the park.\n• I went with **sim**.\n• **Se** brought **ser** frisbee.\n• At least I think it was **sers**.\n• **Se** threw a frisbee to **serself**." + }, + "shi/hir": { + "name": "shi/her", + "examples": "• **Shi** went to the park.\n• I went with **hir**.\n• **Shi** brought **shir** frisbee.\n• At least I think it was **hirs**.\n• **Shi** threw a frisbee to **hirself**." + }, + "si/hyr": { + "name": "si/hyr", + "examples": "• **Si** went to the park.\n• I went with **hyr**.\n• **Si** brought **hyr** frisbee.\n• At least I think it was **hyrs**.\n• **Si** threw a frisbee to **hyrself**." + }, + "they/them": { + "name": "they/them", + "examples": "• **They** went to the park.\n• I went with **them**.\n• **They** brought **their** frisbee.\n• At least I think it was **theirs**.\n• **They** threw a frisbee to **themself**." + }, + "thon": { + "name": "thon/thon", + "examples": "• **Thon** went to the park.\n• I went with **thon**.\n• **Thon** brought **thons** frisbee.\n• At least I think it was **thons**.\n• **Thon** threw a frisbee to **thonself**." + }, + "she/her": { + "name": "she/her", + "examples": "• **She** went to the park.\n• I went with **her**.\n• **She** brought **her** frisbee.\n• At least I think it was **hers**.\n• **She** threw a frisbee to **herself**." + }, + "ve/ver": { + "name": "ve/ver", + "examples": "• **Ve** went to the park.\n• I went with **ver**.\n• **Ve** brought **vis** frisbee.\n• At least I think it was **vis**.\n• **Ve** threw a frisbee to **verself**." + }, + "ve/vem": { + "name": "ve/vem", + "examples": "• **Ve** went to the park.\n• I went with **vem**.\n• **Ve** brought **vir** frisbee.\n• At least I think it was **virs**.\n• **Ve** threw a frisbee to **vemself**." + }, + "vi/ver": { + "name": "vi/ver", + "examples": "• **Vi** went to the park.\n• I went with **ver**.\n• **Vi** brought **ver** frisbee.\n• At least I think it was **vers**.\n• **Vi** threw a frisbee to **verself**." + }, + "vi/vim/vir": { + "name": "vi/vim/vir", + "examples": "• **Vi** went to the park.\n• I went with **vim**.\n• **Vi** brought **vir** frisbee.\n• At least I think it was **virs**.\n• **Vi** threw a frisbee to **vimself**." + }, + "vi/vim/vim": { + "name": "vi/vim/vim", + "examples": "• **Vi** went to the park.\n• I went with **vim**.\n• **Vi** brought **vim** frisbee.\n• At least I think it was **vims**.\n• **Vi** threw a frisbee to **vimself**." + }, + "xie/xer": { + "name": "xie/xer", + "examples": "• **Xie** went to the park.\n• I went with **xer**.\n• **Xie** brought **xer** frisbee.\n• At least I think it was **xers**.\n• **Xie** threw a frisbee to **xerself**." + }, + "xe/xem": { + "name": "xe/xem", + "examples": "• **Xe** went to the park.\n• I went with **xem**.\n• **Xe** brought **xyr** frisbee.\n• At least I think it was **xyrs**.\n• **Xe** threw a frisbee to **xemself**." + }, + "xey/xem": { + "name": "xey/xem", + "examples": "• **Xey** went to the park.\n• I went with **xem**.\n• **Xey** brought **xeir** frisbee.\n• At least I think it was **xeirs**.\n• **Xey** threw a frisbee to **xemself**." + }, + "yo": { + "name": "yo", + "examples": "• **Yo** went to the park.\n• I went with **yo**.\n• **Yo** brought **yos** frisbee.\n• At least I think it was **yos**.\n• **Yo** threw a frisbee to **yosself**." + }, + "ze/hir": { + "name": "ze/hir", + "examples": "• **Ze** went to the park.\n• I went with **hir**.\n• **Ze** brought **hir** frisbee.\n• At least I think it was **hirs**.\n• **Ze** threw a frisbee to **hirself**." + }, + "ze/zem": { + "name": "ze/zem", + "examples": "• **Ze** went to the park.\n• I went with **zem**.\n• **Ze** brought **zes** frisbee.\n• At least I think it was **zes**.\n• **Ze** threw a frisbee to **zirself**." + }, + "ze/mer": { + "name": "ze/mer", + "examples": "• **Ze** went to the park.\n• I went with **mer**.\n• **Ze** brought **zer** frisbee.\n• At least I think it was **zers**.\n• **Ze** threw a frisbee to **zemself**." + }, + "zee/zed": { + "name": "zee/zed", + "examples": "• **Zee** went to the park.\n• I went with **zed**.\n• **Zee** brought **zeta** frisbee.\n• At least I think it was **zetas**.\n• **Zee** threw a frisbee to **zedself**." + }, + "ze/zir": { + "name": "ze/zir", + "examples": "• **Ze** went to the park.\n• I went with **zir**.\n• **Ze** brought **zir** frisbee.\n• At least I think it was **zirs**.\n• **Ze** threw a frisbee to **zirself**." + }, + "zie/zir": { + "name": "zie/zir", + "examples": "• **Zie** went to the park.\n• I went with **zir**.\n• **Zie** brought **zir** frisbee.\n• At least I think it was **zirs**.\n• **Zie** threw a frisbee to **zirself**." + }, + "zie/zem": { + "name": "zie/zem", + "examples": "• **Zie** went to the park.\n• I went with **zem**.\n• **Zie** brought **zes** frisbee.\n• At least I think it was **zes**.\n• **Zie** threw a frisbee to **zirself**." + }, + "zie/hir": { + "name": "zie/hir", + "examples": "• **Zie** went to the park.\n• I went with **hir**.\n• **Zie** brought **hir** frisbee.\n• At least I think it was **hirs**.\n• **Zie** threw a frisbee to **hirself**." + }, + "zme/zmyr": { + "name": "zme/zmyr", + "examples": "• **Zme** went to the park.\n• I went with **zmyr**.\n• **Zme** brought **zmyr** frisbee.\n• At least I think it was **zmyrs**.\n• **Zme** threw a frisbee to **zmyrself**." + } } \ No newline at end of file diff --git a/resources/other/sexualities.json b/resources/other/sexualities.json index 544b7b4..a8805ed 100644 --- a/resources/other/sexualities.json +++ b/resources/other/sexualities.json @@ -1,3 +1,102 @@ { - + "aesthetic attraction": { + "name": "aesthetic attraction", + "description": "Getting pleasure from the appearance of a specific individual like you would from watching beautiful scenery." + }, + "platonic attraction": { + "name": "platonic attraction", + "description": "A desire to have a platonic relationship or friendship with a specific individual." + }, + "romantic attraction": { + "name": "romantic attraction", + "description": "A desire to have a romantic relationship with a specific individual." + }, + "sensual attraction": { + "name": "sensual attraction", + "description": "A desire for physical intimacy with a specific individual. Cuddling, hand holding, etc." + }, + "sexual attraction": { + "name": "sexual attraction", + "description": "A desire for sexual contact with a specific individual." + }, + "abrosexual": { + "name": "abrosexual", + "description": "Someone whose sexuality changes frequently. They experience different sexualities over time." + }, + "androgynosexual": { + "name": "androgynosexual", + "description": "Someone who is attracted to both men and women, particularly those who are androgynous in appearance." + }, + "androsexual": { + "name": "androsexual", + "description": "Someone who is attracted to men and/or masculine people." + }, + "aromantic": { + "name": "aromantic", + "description": "Someone who does not experience romantic attraction. They do not have to also be asexual however as they may still experience other types of attraction." + }, + "asexual": { + "name": "asexual", + "description": "Someone who feels little to no sexual attraction to anyone." + }, + "bisexual": { + "name": "bisexual", + "description": "Someone who is attracted to more than one gender." + }, + "ceterosexual": { + "name": "ceterosexual", + "description": "Someone who is attracted to non-binary people." + }, + "demisexual": { + "name": "demisexual", + "description": "Someone who doesn't experience sexual/romantic attraction towards someone until they form an emotional connection." + }, + "finsexual": { + "name": "finsexual", + "description": "Someone who is attracted to women and/or feminine people." + }, + "gay": { + "name": "gay", + "description": "Someone who is homosexual (attracted to ones own gender)" + }, + "gynosexual": { + "name": "gynosexual", + "description": "Someone who as attracted to women and/or feminity." + }, + "grey-romantic": { + "name": "grey-romantic", + "description": "Someone with a romantic orentiation that is somewhere between aromantic and romantic." + }, + "heterosexual": { + "name": "heterosexual", + "description": "Someone who is attracted to people of the opposite gender." + }, + "homosexual": { + "name": "homosexual", + "description": "Someone attracted to people of ones own gender." + }, + "lesbian": { + "name": "lesbian", + "description": "A woman who is attracted to other women." + }, + "omnisexual": { + "name": "omnisexual", + "description": "Someone who is attracted to all genders." + }, + "pansexual": { + "name": "pansexual", + "description": "Someone who is attracted towards people regardless of their gender identity." + }, + "pomosexual": { + "name": "pomosexual", + "description": "Someone who does not fit into any sexual orientation label." + }, + "polysexual": { + "name": "polysexual", + "description": "Someone who is attracted to some, but not all genders." + }, + "straight": { + "name": "straight", + "description": "Someone who is heterosexual (attracted to people of the opposite gender)" + } } \ No newline at end of file diff --git a/src/commands/about.js b/src/commands/about.js index 5c1538f..2049bfa 100644 --- a/src/commands/about.js +++ b/src/commands/about.js @@ -26,9 +26,9 @@ exports.run = (client, message) => { } embed = new Discord.MessageEmbed(); - embed.setTitle(`Woomy`); embed.setColor(client.embedColour(message)); embed.setThumbnail(client.user.avatarURL({format: "png", dynamic: true, size: 2048})) + embed.setTitle("About Woomy") embed.addField( "General:", `• users: \`${client.users.cache.size}\`\n• channels: \`${client.channels.cache.size}\`\n• servers: \`${client.guilds.cache.size}\`\n• commands: \`${client.commands.size}\`\n• uptime: \`${duration}\``,true ); @@ -45,7 +45,7 @@ exports.run = (client, message) => { exports.conf = { enabled: true, guildOnly: false, - aliases: ["stats"], + aliases: ["stats", "botinfo"], permLevel: "User", requiredPerms: [] }; diff --git a/src/commands/math.js b/src/commands/calculate.js similarity index 92% rename from src/commands/math.js rename to src/commands/calculate.js index 05f0d78..e7737b3 100644 --- a/src/commands/math.js +++ b/src/commands/calculate.js @@ -29,14 +29,14 @@ exports.run = (client, message, args) => { exports.conf = { enabled: true, guildOnly: false, - aliases: ["calculate", "calc"], + aliases: ["calc", "math"], permLevel: "User", requiredPerms: [] }; exports.help = { - name: "math", + name: "calculate", category: "Utility", description: "Solves basic mathematical equations.", - usage: "math [equation]" + usage: "calculate [equation]" }; \ No newline at end of file diff --git a/src/commands/cat.js b/src/commands/cat.js new file mode 100644 index 0000000..afd627f --- /dev/null +++ b/src/commands/cat.js @@ -0,0 +1,30 @@ +const API = require('nekos.life'); +const {sfw} = new API(); +exports.run = async (client, message) => { + message.channel.startTyping(); + try { + sfw.meow().then((json) => { + message.channel.send(json.url) + message.channel.stopTyping(); + }); + } catch (err) { + client.logger.error("cat.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: "cat", + category: "Image", + description: "Sends you cat pics.", + usage: "cat" +}; diff --git a/src/commands/catfact.js b/src/commands/catfact.js index 437541f..366999e 100644 --- a/src/commands/catfact.js +++ b/src/commands/catfact.js @@ -1,14 +1,12 @@ -const request = require("request"); - +const fetch = require("node-fetch") exports.run = async (bot, message, args) => { message.channel.startTyping(); try{ - request({ uri: "https://catfact.ninja/facts", json: true }, (error, response, body) => { - message.channel.send(`**Did you know?**\n ${body.data[0].fact}`); - message.channel.startTyping(); - }); + 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> API error: ${err}`); + message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`); }; message.channel.stopTyping(); }; diff --git a/src/commands/flip.js b/src/commands/coinflip.js similarity index 90% rename from src/commands/flip.js rename to src/commands/coinflip.js index 99ba778..418a996 100644 --- a/src/commands/flip.js +++ b/src/commands/coinflip.js @@ -22,14 +22,14 @@ exports.run = (client, message, args) => { exports.conf = { enabled: true, guildOnly: false, - aliases: [], + aliases: ["flip"], permLevel: "User", requiredPerms: [] }; exports.help = { - name: "flip", + name: "coinflip", category: "Fun", description: "Flips a coin!", - usage: "flip [heads/tails]" + usage: "coinflip [heads/tails]" }; diff --git a/src/commands/credits.js b/src/commands/credits.js index b3f8516..5eb48ce 100644 --- a/src/commands/credits.js +++ b/src/commands/credits.js @@ -1,6 +1,6 @@ exports.run = async (client, message, args) => { message.channel.send( - `**Credits:**\n• \`mudkipscience#8904\` and \`FLGX#9896\`for developing the bot\n• \`An Idiots Guide\` for the Guidebot bot base\n• \`dellannie#6057\` for helping with the music commands\n• \`TheCakeChicken#9088\` and \`Tina the Cyclops girl#0064\` for helping me not suck at coding\n• \`AirVentTrent\` for the icon, find him on Instagram` + `__**Credits:**__\n• \`mudkipscience#8904\`, \`FLGX#9896\` and \`TheCakeChicken#9088\` for developing the bot\n• \`An Idiots Guide\` for the Guidebot bot base\n• \`Tina the Cyclops girl#0064\` for helping me not suck at coding\n• \`AirVentTrent\` for the icon, find him on Instagram\n• \`Terryiscool160\` for contributing to Woomy.` ); }; @@ -14,7 +14,7 @@ exports.conf = { exports.help = { name: "credits", - category: "Miscellaneous", + category: "Utility", description: "Cool people", usage: "credits" }; diff --git a/src/commands/cuddle.js b/src/commands/cuddle.js new file mode 100644 index 0000000..63263ae --- /dev/null +++ b/src/commands/cuddle.js @@ -0,0 +1,69 @@ +const API = require('nekos.life'); +const {sfw} = new API(); +exports.run = async (client, message, args) => { + if(!args[0]) { + return message.channel.send(`<:error:466995152976871434> You didn't say who you wanted to cuddle! Usage: \`${client.commands.get(`cuddle`).help.usage}\``) + }; + + var people = ""; + + for (var i = 0; i < args.length; i++) { + var user = client.getUserFromMention(args[i]) + if (user) { + user = message.guild.members.cache.get(user.id).displayName; + } else { + users = client.searchForMembers(message.guild, args[i]); + if (users.length > 1) + return message.channel.send( + "<:error:466995152976871434> Found multiple users for `" + args[i] + "`, Please be more specific or mention the user instead." + ); + else if (users.length == 0) + return message.channel.send( + "<:error:466995152976871434> That user doesn't seem to exist. Try again!" + ); + user = users[0].displayName; + }; + if(i+1 == args.length && args.length > 1) { + people += `**and** ${user}!` + } else if(args.length < 2) { + people += `${user}!`; + } else if(args.length == 2 && i == 0) { + people += `${user} `; + } else { + people += `${user}, `; + }; + }; + + + + message.channel.startTyping(); + try { + sfw.cuddle().then((json) => { + embed = new Discord.MessageEmbed(); + embed.setImage(json.url) + embed.setColor(client.embedColour(message)); + embed.setDescription(`**${message.guild.members.cache.get(message.author.id).displayName}** cuddled **${people}**`) + message.channel.send(embed) + message.channel.stopTyping(); + }); + } catch (err) { + client.logger.error("cuddle.js: " + err); + message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`) + message.channel.stopTyping(); + }; +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: [], + permLevel: "User", + requiredPerms: ["EMBED_LINKS"] +}; + +exports.help = { + name: "cuddle", + category: "Action", + description: "cuddle someone!", + usage: "cuddle [@user/user] (you can cuddle as many people as you want!)" +}; diff --git a/src/commands/diceroll.js b/src/commands/dice.js similarity index 90% rename from src/commands/diceroll.js rename to src/commands/dice.js index b307d4e..be9edcf 100644 --- a/src/commands/diceroll.js +++ b/src/commands/dice.js @@ -1,27 +1,27 @@ -exports.run = async (bot, message, args) => { - if (args.length === 0) { - message.channel.send(`🎲 You rolled a ${Array.from(Array(6).keys()).random() + 1}!`); - } else { - if (args[0].match(/^\d+$/)) { - message.channel.send(`🎲 You rolled a ${Array.from(Array(parseInt(args[0])).keys()).random() + 1}!`); - } else { - message.channel.send(`🎲 You rolled a ${Array.from(Array(6).keys()).random() + 1}!`); - } - } - }; - - exports.conf = { - enabled: true, - guildOnly: false, - aliases: ["diceroll"], - permLevel: "User", - requiredPerms: [] - }; - - exports.help = { - name: "dice", - category: "Fun", - description: "Rolls a dice.", - usage: "dice" - }; - +exports.run = async (bot, message, args) => { + if (args.length === 0) { + message.channel.send(`🎲 You rolled a ${Array.from(Array(6).keys()).random() + 1}!`); + } else { + if (args[0].match(/^\d+$/)) { + message.channel.send(`🎲 You rolled a ${Array.from(Array(parseInt(args[0])).keys()).random() + 1}!`); + } else { + message.channel.send(`🎲 You rolled a ${Array.from(Array(6).keys()).random() + 1}!`); + } + } + }; + + exports.conf = { + enabled: true, + guildOnly: false, + aliases: ["diceroll", "roll"], + permLevel: "User", + requiredPerms: [] + }; + + exports.help = { + name: "dice", + category: "Fun", + description: "Rolls a dice.", + usage: "dice " + }; + diff --git a/src/commands/dog.js b/src/commands/dog.js new file mode 100644 index 0000000..39ce25c --- /dev/null +++ b/src/commands/dog.js @@ -0,0 +1,30 @@ +const API = require('nekos.life'); +const {sfw} = new API(); +exports.run = async (client, message) => { + message.channel.startTyping(); + try { + sfw.woof().then((json) => { + message.channel.send(json.url) + message.channel.stopTyping(); + }); + } catch (err) { + client.logger.error("dog.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: "dog", + category: "Image", + description: "Sends you dog pics.", + usage: "dog" +}; diff --git a/src/commands/dogfact.js b/src/commands/dogfact.js index 586f323..fca8a62 100644 --- a/src/commands/dogfact.js +++ b/src/commands/dogfact.js @@ -1,13 +1,12 @@ -const request = require("request"); - +const fetch = require("node-fetch"); exports.run = async (bot, message, args) => { message.channel.startTyping(); try{ - request({ uri: "https://dog-api.kinduff.com/api/facts", json: true }, (error, response, body) => { - message.channel.send(`**Did you know?**\n ${body.facts[0]}`); - }); + fetch('https://dog-api.kinduff.com/api/facts') + .then(res => res.json()) + .then(json => message.channel.send(`__**Did you know?**__\n ${json.facts[0]}`)); } catch(err) { - message.channel.send(`<:error:466995152976871434> API error: ${err}`); + message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`); }; message.channel.stopTyping(); }; diff --git a/src/commands/emoji.js b/src/commands/emoji.js index 795686c..ab6907b 100644 --- a/src/commands/emoji.js +++ b/src/commands/emoji.js @@ -11,7 +11,6 @@ exports.run = async (client, message, args) => { format = ".gif" }; - console.log(string.length) if(string.length > 18) { ID = string.slice(string.length - 18); } else { diff --git a/src/commands/emojify.js b/src/commands/emojify.js index 058faa3..46dfa35 100644 --- a/src/commands/emojify.js +++ b/src/commands/emojify.js @@ -34,7 +34,7 @@ exports.run = (client, message, args) => { if(emojified.length > 2000) { return message.channel.send("<:error:466995152976871434> The emojified message exceeds 2000 characters.") - } + }; message.channel.send(emojified); }; diff --git a/src/commands/fact.js b/src/commands/fact.js new file mode 100644 index 0000000..0e351a6 --- /dev/null +++ b/src/commands/fact.js @@ -0,0 +1,30 @@ +const API = require('nekos.life'); +const {sfw} = new API(); +exports.run = async (client, message) => { + message.channel.startTyping(); + try { + sfw.fact().then((json) => { + message.channel.send("__**Did you know?**__\n" + json.fact + "."); + message.channel.stopTyping(); + }); + } catch (err) { + client.logger.error("fact.js: " + err); + message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`) + message.channel.stopTyping(); + }; +}; + +exports.conf = { + enabled: true, + guildOnly: false, + aliases: ["randomfact"], + permLevel: "User", + requiredPerms: [] +}; + +exports.help = { + name: "fact", + category: "Fun", + description: "Sends you a random fact.", + usage: "fact" +}; diff --git a/src/commands/feed.js b/src/commands/feed.js new file mode 100644 index 0000000..9749f45 --- /dev/null +++ b/src/commands/feed.js @@ -0,0 +1,69 @@ +const API = require('nekos.life'); +const {sfw} = new API(); +exports.run = async (client, message, args) => { + if(!args[0]) { + return message.channel.send(`<:error:466995152976871434> You didn't say who you wanted to feed! Usage: \`${client.commands.get(`feed`).help.usage}\``) + }; + + var people = ""; + + for (var i = 0; i < args.length; i++) { + var user = client.getUserFromMention(args[i]) + if (user) { + user = message.guild.members.cache.get(user.id).displayName; + } else { + users = client.searchForMembers(message.guild, args[i]); + if (users.length > 1) + return message.channel.send( + "<:error:466995152976871434> Found multiple users for `" + args[i] + "`, Please be more specific or mention the user instead." + ); + else if (users.length == 0) + return message.channel.send( + "<:error:466995152976871434> That user doesn't seem to exist. Try again!" + ); + user = users[0].displayName; + }; + if(i+1 == args.length && args.length > 1) { + people += `**and** ${user}!` + } else if(args.length < 2) { + people += `${user}!`; + } else if(args.length == 2 && i == 0) { + people += `${user} `; + } else { + people += `${user}, `; + }; + }; + + + + message.channel.startTyping(); + try { + sfw.feed().then((json) => { + embed = new Discord.MessageEmbed(); + embed.setImage(json.url) + embed.setColor(client.embedColour(message)); + embed.setDescription(`**${message.guild.members.cache.get(message.author.id).displayName}** fed **${people}**`) + message.channel.send(embed) + message.channel.stopTyping(); + }); + } catch (err) { + client.logger.error("feed.js: " + err); + message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`) + message.channel.stopTyping(); + }; +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: [], + permLevel: "User", + requiredPerms: ["EMBED_LINKS"] +}; + +exports.help = { + name: "feed", + category: "Action", + description: "feed someone!", + usage: "feed [@user/user] (you can feed as many people as you want!)" +}; diff --git a/src/commands/feedback.js b/src/commands/feedback.js index 9f4e436..6b4512b 100644 --- a/src/commands/feedback.js +++ b/src/commands/feedback.js @@ -22,7 +22,7 @@ exports.conf = { exports.help = { name: "feedback", - category: "Miscellaneous", + category: "Utility", description: "Send feedback to my developer.", usage: "feedback [message]" }; diff --git a/src/commands/foxgirl.js b/src/commands/foxgirl.js new file mode 100644 index 0000000..f3f3312 --- /dev/null +++ b/src/commands/foxgirl.js @@ -0,0 +1,30 @@ +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" +}; diff --git a/src/commands/help.js b/src/commands/help.js index beeda6d..5c07963 100644 --- a/src/commands/help.js +++ b/src/commands/help.js @@ -15,7 +15,7 @@ exports.run = (client, message, args, level) => { }; if(!args[0]) { - embed.setTitle(`Commands [${client.commands.size}]`); + embed.setTitle(`Command list`); embed.setDescription(`⁣For more information on a specific command use \`${prefix}help \`\nFor the full command list use \`${prefix}help all\`\n`); const myCommands = message.guild ? client.commands.filter( @@ -35,21 +35,21 @@ exports.run = (client, message, args, level) => { ); sorted.forEach( c => { - const cat = c.help.category.toProperCase(); + const cat = c.help.category; if (currentCategory !== cat) { if(ran == true) { - embed.addField(currentCategory + ` [${commands}]`, output.slice(0, -2)) + embed.addField(currentCategory + ` [${commands}]`, output) output = ""; commands = 0; } currentCategory = cat; ran = true } - output += `\`${prefix}${c.help.name}\`, `; + output += `\`${c.help.name}\` `; commands = commands + 1; }); - embed.addField(currentCategory + ` [${commands}]`, output.slice(0, -2)); + embed.addField(currentCategory + ` [${commands}]`, output); embed.addField( "Invite me", @@ -68,7 +68,7 @@ exports.run = (client, message, args, level) => { }; if(args[0].toLowerCase() == "all") { - embed.setTitle(`Commands [${client.commands.size}]`); + embed.setTitle(`Command list`); embed.setDescription(`⁣For more information on a specific command use \`${prefix}help \`\nFor the full command list use \`${prefix}help all\`\n`); const myCommands = client.commands @@ -84,21 +84,22 @@ exports.run = (client, message, args, level) => { ); sorted.forEach( c => { - const cat = c.help.category.toProperCase(); + const cat = c.help.category; if (currentCategory !== cat) { if(ran == true) { - embed.addField(currentCategory + ` [${commands}]`, output.slice(0, -2)) + embed.addField(currentCategory + ` [${commands}]`, output) output = ""; commands = 0; } currentCategory = cat; ran = true } - output += `\`${prefix}${c.help.name}\`, `; + output += `\`${c.help.name}\` `; commands = commands + 1; }); - embed.addField(currentCategory + ` [${commands}]`, output.slice(0, -2)); + + embed.addField(currentCategory + ` [${commands}]`, output); embed.addField( "Invite me", diff --git a/src/commands/hug.js b/src/commands/hug.js new file mode 100644 index 0000000..30ef214 --- /dev/null +++ b/src/commands/hug.js @@ -0,0 +1,69 @@ +const API = require('nekos.life'); +const {sfw} = new API(); +exports.run = async (client, message, args) => { + if(!args[0]) { + return message.channel.send(`<:error:466995152976871434> You didn't say who you wanted to hug! Usage: \`${client.commands.get(`hug`).help.usage}\``) + }; + + var people = ""; + + for (var i = 0; i < args.length; i++) { + var user = client.getUserFromMention(args[i]) + if (user) { + user = message.guild.members.cache.get(user.id).displayName; + } else { + users = client.searchForMembers(message.guild, args[i]); + if (users.length > 1) + return message.channel.send( + "<:error:466995152976871434> Found multiple users for `" + args[i] + "`, Please be more specific or mention the user instead." + ); + else if (users.length == 0) + return message.channel.send( + "<:error:466995152976871434> That user doesn't seem to exist. Try again!" + ); + user = users[0].displayName; + }; + if(i+1 == args.length && args.length > 1) { + people += `**and** ${user}!` + } else if(args.length < 2) { + people += `${user}!`; + } else if(args.length == 2 && i == 0) { + people += `${user} `; + } else { + people += `${user}, `; + }; + }; + + + + message.channel.startTyping(); + try { + sfw.hug().then((json) => { + embed = new Discord.MessageEmbed(); + embed.setImage(json.url) + embed.setColor(client.embedColour(message)); + embed.setDescription(`**${message.guild.members.cache.get(message.author.id).displayName}** hugged **${people}**`) + message.channel.send(embed) + message.channel.stopTyping(); + }); + } catch (err) { + client.logger.error("hug.js: " + err); + message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`) + message.channel.stopTyping(); + }; +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: [], + permLevel: "User", + requiredPerms: ["EMBED_LINKS"] +}; + +exports.help = { + name: "hug", + category: "Action", + description: "Hug someone!", + usage: "hug [@user/user] (you can hug as many people as you want!)" +}; diff --git a/src/commands/identity.js b/src/commands/identity.js new file mode 100644 index 0000000..b7f3809 --- /dev/null +++ b/src/commands/identity.js @@ -0,0 +1,36 @@ +const identities = require ("../../resources/other/identities.json"); +exports.run = async (client, message, args) => { + var output = ""; + if(!args[0]) { + for (var key of Object.keys(identities)) { + output += `${key}, ` + }; + return message.channel.send(`__**Identities**__\n${output.slice(0, -2)}`); + } else { + if(args.join(" ").toLowerCase() == "attack helicopter" || args.join(" ").toLowerCase() == "apache attack helicopter" || args.join(" ").toLowerCase() == "apache") { + return message.channel.send({ + files: [new Discord.MessageAttachment("./resources/images/attackhelicopter.jpg")] + }); + } + output = identities[args.join(" ").toLowerCase()]; + if(!output) { + return message.channel.send("<:error:466995152976871434> No results for that query."); + }; + return message.channel.send(`__**${output.name.toProperCase()}**__\n${output.description}`); + }; +}; + +exports.conf = { + enabled: true, + guildOnly: false, + aliases: ["identities"], + permLevel: "User", + requiredPerms: [] +}; + +exports.help = { + name: "identity", + category: "Fun", + description: "Gives you information about the specified identity.", + usage: "identity [identity]" +}; diff --git a/src/commands/inspirobot.js b/src/commands/inspirobot.js index 5ba4e0a..17a028f 100644 --- a/src/commands/inspirobot.js +++ b/src/commands/inspirobot.js @@ -1,20 +1,15 @@ -const request = require('request') +const fetch = require("node-fetch") exports.run = async (client, message) => { message.channel.startTyping(); - request({ - url: "http://inspirobot.me/api?generate=true" - }, - function(error, res, body) { - if(body.length > 0) { - message.channel.send({ - files: [new Discord.MessageAttachment(body)] - }); - message.channel.stopTyping(); - } else { - message.channel.send('<:error:466995152976871434> API error, please retry.') - message.channel.stopTyping(); - }; - }); + try { + fetch('http://inspirobot.me/api?generate=true') + .then(res => res.text()) + .then(body => message.channel.send({files: [new Discord.MessageAttachment(body)]})); + message.channel.stopTyping(); + } catch (err) { + message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`) + message.channel.stopTyping(); + }; }; exports.conf = { diff --git a/src/commands/kemonomimi.js b/src/commands/kemonomimi.js new file mode 100644 index 0000000..3c4b70e --- /dev/null +++ b/src/commands/kemonomimi.js @@ -0,0 +1,30 @@ +const API = require('nekos.life'); +const {sfw} = new API(); +exports.run = async (client, message) => { + message.channel.startTyping(); + try { + sfw.kemonomimi().then((json) => { + message.channel.send(json.url) + message.channel.stopTyping(); + }); + } catch (err) { + client.logger.error("kemonomimi.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: "kemonomimi", + category: "Image", + description: "Sends you pictures of people with animal characteristics.", + usage: "kemonomimi" +}; diff --git a/src/commands/kiss.js b/src/commands/kiss.js new file mode 100644 index 0000000..495ee62 --- /dev/null +++ b/src/commands/kiss.js @@ -0,0 +1,69 @@ +const API = require('nekos.life'); +const {sfw} = new API(); +exports.run = async (client, message, args) => { + if(!args[0]) { + return message.channel.send(`<:error:466995152976871434> You didn't say who you wanted to kiss! Usage: \`${client.commands.get(`kiss`).help.usage}\``) + }; + + var people = ""; + + for (var i = 0; i < args.length; i++) { + var user = client.getUserFromMention(args[i]) + if (user) { + user = message.guild.members.cache.get(user.id).displayName; + } else { + users = client.searchForMembers(message.guild, args[i]); + if (users.length > 1) + return message.channel.send( + "<:error:466995152976871434> Found multiple users for `" + args[i] + "`, Please be more specific or mention the user instead." + ); + else if (users.length == 0) + return message.channel.send( + "<:error:466995152976871434> That user doesn't seem to exist. Try again!" + ); + user = users[0].displayName; + }; + if(i+1 == args.length && args.length > 1) { + people += `**and** ${user}!` + } else if(args.length < 2) { + people += `${user}!`; + } else if(args.length == 2 && i == 0) { + people += `${user} `; + } else { + people += `${user}, `; + }; + }; + + + + message.channel.startTyping(); + try { + sfw.kiss().then((json) => { + embed = new Discord.MessageEmbed(); + embed.setImage(json.url) + embed.setColor(client.embedColour(message)); + embed.setDescription(`**${message.guild.members.cache.get(message.author.id).displayName}** kissed **${people}**`) + message.channel.send(embed) + message.channel.stopTyping(); + }); + } catch (err) { + client.logger.error("kiss.js: " + err); + message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`) + message.channel.stopTyping(); + }; +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: [], + permLevel: "User", + requiredPerms: ["EMBED_LINKS"] +}; + +exports.help = { + name: "kiss", + category: "Action", + description: "Kiss someone!", + usage: "kiss [@user/user] (you can kiss as many people as you want!)" +}; diff --git a/src/commands/lizard.js b/src/commands/lizard.js new file mode 100644 index 0000000..f476704 --- /dev/null +++ b/src/commands/lizard.js @@ -0,0 +1,30 @@ +const API = require('nekos.life'); +const {sfw} = new API(); +exports.run = async (client, message) => { + message.channel.startTyping(); + try { + sfw.lizard().then((json) => { + message.channel.send(json.url) + message.channel.stopTyping(); + }); + } catch (err) { + client.logger.error("lizard.js: " + err); + message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`) + message.channel.stopTyping(); + }; +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: [], + permLevel: "User", + requiredPerms: ["EMBED_LINKS"] +}; + +exports.help = { + name: "lizard", + category: "Image", + description: "Sends pictures of lizards.", + usage: "lizard" +}; diff --git a/src/commands/mute.js b/src/commands/mute.js index a59f72d..a52e7c5 100644 --- a/src/commands/mute.js +++ b/src/commands/mute.js @@ -85,7 +85,7 @@ exports.run = async (client, message, [args, ...reason], level) => { if (channel) { let embed = new Discord.MessageEmbed(); embed.setColor("#a652bb"); - embed.setAuthor("User muted!", user.user.avatarURL({format: "png", dynamic: true})); + embed.setAuthor("User muted!", user.user.avatarURL({format: "png", dynamic: true, size: 2048})); embed.setDescription( `• User: ${user} (${user.user.id})\n• Mod: ${message.author} (${message.author.id})\n• Reason: ${muteReason}` ); diff --git a/src/commands/neko.js b/src/commands/neko.js new file mode 100644 index 0000000..7ce0d6b --- /dev/null +++ b/src/commands/neko.js @@ -0,0 +1,30 @@ +const API = require('nekos.life'); +const {sfw} = new API(); +exports.run = async (client, message) => { + message.channel.startTyping(); + try { + sfw.neko().then((json) => { + message.channel.send(json.url); + message.channel.stopTyping(); + }); + } catch (err) { + client.logger.error("neko.js: " + err); + message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`) + message.channel.stopTyping(); + }; +}; + +exports.conf = { + enabled: true, + guildOnly: false, + aliases: ["catgirl"], + permLevel: "User", + requiredPerms: ["EMBED_LINKS"] +}; + +exports.help = { + name: "neko", + category: "Image", + description: "Sends you pictures of catgirls.", + usage: "neko" +}; diff --git a/src/commands/nekogif.js b/src/commands/nekogif.js new file mode 100644 index 0000000..0df6917 --- /dev/null +++ b/src/commands/nekogif.js @@ -0,0 +1,30 @@ +const API = require('nekos.life'); +const {sfw} = new API(); +exports.run = async (client, message) => { + message.channel.startTyping(); + try { + sfw.nekoGif().then((json) => { + message.channel.send(json.url); + message.channel.stopTyping(); + }); + } catch (err) { + client.logger.error("nekogif.js: " + err); + message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`) + message.channel.stopTyping(); + }; +}; + +exports.conf = { + enabled: true, + guildOnly: false, + aliases: ["catgirlgif"], + permLevel: "User", + requiredPerms: ["EMBED_LINKS"] +}; + +exports.help = { + name: "nekogif", + category: "Image", + description: "Sends you gifs of catgirls.", + usage: "nekogif" +}; diff --git a/src/commands/owoify.js b/src/commands/owoify.js index ae8b9a5..9587a6f 100644 --- a/src/commands/owoify.js +++ b/src/commands/owoify.js @@ -13,8 +13,8 @@ exports.run = (client, message, args) => { owoified = owoified.replace(/!+/g, ' ' + faces[~~(Math.random() * faces.length)] + ' ') if(owoified.length > 2000) { - return message.channel.send("<:error:466995152976871434> The owoified message exceeds 2000 characters.") - } + owoified = owoified.slice(0, -Math.abs(owoified.length - 2000)) + }; message.channel.send(owoified) }; diff --git a/src/commands/pat.js b/src/commands/pat.js new file mode 100644 index 0000000..fee469b --- /dev/null +++ b/src/commands/pat.js @@ -0,0 +1,69 @@ +const API = require('nekos.life'); +const {sfw} = new API(); +exports.run = async (client, message, args) => { + if(!args[0]) { + return message.channel.send(`<:error:466995152976871434> You didn't say who you wanted to pat! Usage: \`${client.commands.get(`pat`).help.usage}\``) + }; + + var people = ""; + + for (var i = 0; i < args.length; i++) { + var user = client.getUserFromMention(args[i]) + if (user) { + user = message.guild.members.cache.get(user.id).displayName; + } else { + users = client.searchForMembers(message.guild, args[i]); + if (users.length > 1) + return message.channel.send( + "<:error:466995152976871434> Found multiple users for `" + args[i] + "`, Please be more specific or mention the user instead." + ); + else if (users.length == 0) + return message.channel.send( + "<:error:466995152976871434> That user doesn't seem to exist. Try again!" + ); + user = users[0].displayName; + }; + if(i+1 == args.length && args.length > 1) { + people += `**and** ${user}!` + } else if(args.length < 2) { + people += `${user}!`; + } else if(args.length == 2 && i == 0) { + people += `${user} `; + } else { + people += `${user}, `; + }; + }; + + + + message.channel.startTyping(); + try { + sfw.pat().then((json) => { + embed = new Discord.MessageEmbed(); + embed.setImage(json.url) + embed.setColor(client.embedColour(message)); + embed.setDescription(`**${message.guild.members.cache.get(message.author.id).displayName}** patted **${people}**`) + message.channel.send(embed) + message.channel.stopTyping(); + }); + } catch (err) { + client.logger.error("pat.js: " + err); + message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`) + message.channel.stopTyping(); + }; +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: ["headpat"], + permLevel: "User", + requiredPerms: ["EMBED_LINKS"] +}; + +exports.help = { + name: "pat", + category: "Action", + description: "pat someone!", + usage: "pat [@user/user] (you can pat as many people as you want!)" +}; diff --git a/src/commands/poke.js b/src/commands/poke.js new file mode 100644 index 0000000..07c48bc --- /dev/null +++ b/src/commands/poke.js @@ -0,0 +1,69 @@ +const API = require('nekos.life'); +const {sfw} = new API(); +exports.run = async (client, message, args) => { + if(!args[0]) { + return message.channel.send(`<:error:466995152976871434> You didn't say who you wanted to poke! Usage: \`${client.commands.get(`poke`).help.usage}\``) + }; + + var people = ""; + + for (var i = 0; i < args.length; i++) { + var user = client.getUserFromMention(args[i]) + if (user) { + user = message.guild.members.cache.get(user.id).displayName; + } else { + users = client.searchForMembers(message.guild, args[i]); + if (users.length > 1) + return message.channel.send( + "<:error:466995152976871434> Found multiple users for `" + args[i] + "`, Please be more specific or mention the user instead." + ); + else if (users.length == 0) + return message.channel.send( + "<:error:466995152976871434> That user doesn't seem to exist. Try again!" + ); + user = users[0].displayName; + }; + if(i+1 == args.length && args.length > 1) { + people += `**and** ${user}!` + } else if(args.length < 2) { + people += `${user}!`; + } else if(args.length == 2 && i == 0) { + people += `${user} `; + } else { + people += `${user}, `; + }; + }; + + + + message.channel.startTyping(); + try { + sfw.poke().then((json) => { + embed = new Discord.MessageEmbed(); + embed.setImage(json.url) + embed.setColor(client.embedColour(message)); + embed.setDescription(`**${message.guild.members.cache.get(message.author.id).displayName}** poked **${people}**`) + message.channel.send(embed) + message.channel.stopTyping(); + }); + } catch (err) { + client.logger.error("poke.js: " + err); + message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`) + message.channel.stopTyping(); + }; +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: [], + permLevel: "User", + requiredPerms: ["EMBED_LINKS"] +}; + +exports.help = { + name: "poke", + category: "Action", + description: "poke someone!", + usage: "poke [@user/user] (you can poke as many people as you want!)" +}; diff --git a/src/commands/prefix.js b/src/commands/prefix.js index 774a22b..1d72e74 100644 --- a/src/commands/prefix.js +++ b/src/commands/prefix.js @@ -1,10 +1,4 @@ exports.run = async (client, message, args) => { - if(client.devmode === true) { - return message.channel.send( - "<:error:466995152976871434> This command has been disabled because Woomy is in development mode." - ); - }; - const settings = message.settings; if (!client.settings.has(message.guild.id)) client.settings.set(message.guild.id, {}); diff --git a/src/commands/pronoun.js b/src/commands/pronoun.js new file mode 100644 index 0000000..0d4b36a --- /dev/null +++ b/src/commands/pronoun.js @@ -0,0 +1,36 @@ +const pronouns = require ("../../resources/other/pronouns.json"); +exports.run = async (client, message, args) => { + var output = ""; + if(!args[0]) { + for (var key of Object.keys(pronouns)) { + output += `${key}, ` + }; + return message.channel.send(`__**Pronouns:**__\n${output.slice(0, -2)}`); + } else { + if(args.join(" ").toLowerCase() == "attack helicopter" || args.join(" ").toLowerCase() == "apache attack helicopter" || args.join(" ").toLowerCase() == "apache") { + return message.channel.send({ + files: [new Discord.MessageAttachment("./resources/images/attackhelicopter.jpg")] + }); + }; + output = pronouns[args.join(" ").toLowerCase()]; + if(!output) { + return message.channel.send("<:error:466995152976871434> No results for that query."); + }; + return message.channel.send(`__**Example sentences using ${output.name}:**__\n${output.examples}`); + }; +}; + +exports.conf = { + enabled: true, + guildOnly: false, + aliases: ["pronouns"], + permLevel: "User", + requiredPerms: [] +}; + +exports.help = { + name: "pronoun", + category: "Fun", + description: "Gives you information on how to use the specified pronoun.", + usage: "pronoun [pronoun]" +}; diff --git a/src/commands/raidmode.js b/src/commands/raidmode.js index 976d2ae..68a70ec 100644 --- a/src/commands/raidmode.js +++ b/src/commands/raidmode.js @@ -43,7 +43,7 @@ exports.run = async (client, message, args, level) => { if (channel) { let embed = new Discord.MessageEmbed(); embed.setColor(embColour); - embed.setAuthor(raidToggle, message.author.avatarURL({dynamic: true})); + embed.setAuthor(raidToggle, message.author.avatarURL({format: "png", dynamic: true, size: 2048})); embed.setDescription(`• Mod: ${message.author} (${message.author.id})`) try { channel.send({ embed }); diff --git a/src/commands/roleinfo.js b/src/commands/roleinfo.js index f6fd0e0..10d8c4d 100644 --- a/src/commands/roleinfo.js +++ b/src/commands/roleinfo.js @@ -15,17 +15,47 @@ exports.run = async (client, message, args, level) => { return message.channel.send(`<:error:466995152976871434> Role not found.`) } - if(role.hoist === true) { - var hoist = `Yes` - } else { - var hoist = `No` - } + var permissions = "```"; + if(role.permissions.has("ADMINISTRATOR")) permissions += "ADMINISTRATOR, "; + if(role.permissions.has("CREATE_INSTANT_INVITE")) permissions += "CREATE_INSTANT_INVITE, "; + if(role.permissions.has("KICK_MEMBERS")) permissions += "KICK_MEMBERS, "; + if(role.permissions.has("BAN_MEMBERS")) permissions += "BAN_MEMBERS, "; + if(role.permissions.has("MANAGE_CHANNELS")) permissions += "MANAGE_CHANNELS, "; + if(role.permissions.has("MANAGE_GUILD")) permissions += "MANAGE_GUILD, "; + if(role.permissions.has("ADD_REACTIONS")) permissions += "ADD_REACTIONS, "; + if(role.permissions.has("VIEW_AUDIT_LOG")) permissions += "VIEW_AUDIT_LOG, "; + if(role.permissions.has("PRIORITY_SPEAKER")) permissions += "PRIORITY_SPEAKER, "; + if(role.permissions.has("STREAM")) permissions += "STREAM, "; + if(role.permissions.has("VIEW_CHANNEL")) permissions += "VIEW_CHANNEL, "; + if(role.permissions.has("SEND_MESSAGES")) permissions += "SEND_MESSAGES, "; + if(role.permissions.has("SEND_TTS_MESSAGES")) permissions += "SEND_TTS_MESSAGES, "; + if(role.permissions.has("MANAGE_MESSAGES")) permissions += "MANAGE_MESSAGES, "; + if(role.permissions.has("EMBED_LINKS")) permissions += "EMBED_LINKS, "; + if(role.permissions.has("ATTACH_FILES")) permissions += "ATTACH_FILES, "; + if(role.permissions.has("READ_MESSAGE_HISTORY")) permissions += "READ_MESSAGE_HISTORY, "; + if(role.permissions.has("MENTION_EVERYONE")) permissions += "MENTION_EVERYONE, "; + if(role.permissions.has("USE_EXTERNAL_EMOJIS")) permissions += "USE_EXTERNAL_EMOJIS, "; + if(role.permissions.has("CONNECT")) permissions += "CONNECT, "; + if(role.permissions.has("SPEAK")) permissions += "SPEAK, "; + if(role.permissions.has("MUTE_MEMBERS")) permissions += "MUTE_MEMBERS, "; + if(role.permissions.has("DEAFEN_MEMBERS")) permissions += "DEAFEN_MEMBERS, "; + if(role.permissions.has("MOVE_MEMBERS")) permissions += "MOVE_MEMBERS, "; + if(role.permissions.has("USE_VAD")) permissions += "USE_VAD, "; + if(role.permissions.has("CHANGE_NICKNAME")) permissions += "CHANGE_NICKNAME, "; + if(role.permissions.has("MANAGE_NICKNAMES")) permissions += "MANAGE_NICKNAMES, "; + if(role.permissions.has("MANAGE_ROLES")) permissions += "MANAGE_ROLES, "; + if(role.permissions.has("MANAGE_WEBHOOKS")) permissions += "MANAGE_WEBHOOKS, "; + if(role.permissions.has("MANAGE_EMOJIS")) permissions += "MANAGE_EMOJIS, "; + permissions = permissions.slice(0, -2); + permissions += "```"; var embed = new Discord.MessageEmbed(); - embed.setColor(role.color) + embed.setColor(role.color); + embed.setTitle(role.name); embed.setDescription( - `• **Name:** ${role.name}\n• **ID:** ${role.id}\n• **Hex:** ${role.hexColor}\n• **Members:** ${role.members.size}\n• **Position:** ${role.position}\n• **Hoisted:** ${hoist}` + `• **ID:** ${role.id}\n• **Hex:** ${role.hexColor}\n• **Members:** ${role.members.size}\n• **Position:** ${role.position}\n• **Hoisted:** ${role.hoist}` ); + embed.addField(`**Permissions:**`, permissions) message.channel.send(embed) }; diff --git a/src/commands/sexuality.js b/src/commands/sexuality.js new file mode 100644 index 0000000..c41930b --- /dev/null +++ b/src/commands/sexuality.js @@ -0,0 +1,36 @@ +const sexualities = require ("../../resources/other/sexualities.json"); +exports.run = async (client, message, args) => { + var output = ""; + if(!args[0]) { + for (var key of Object.keys(sexualities)) { + output += `${key}, ` + }; + return message.channel.send(`__**Sexualities:**__\n${output.slice(0, -2)}`); + } else { + if(args.join(" ").toLowerCase() == "attack helicopter" || args.join(" ").toLowerCase() == "apache attack helicopter" || args.join(" ").toLowerCase() == "apache") { + return message.channel.send({ + files: [new Discord.MessageAttachment("./resources/images/attackhelicopter.jpg")] + }); + } + output = sexualities[args.join(" ").toLowerCase()]; + if(!output) { + return message.channel.send("<:error:466995152976871434> No results for that query."); + }; + return message.channel.send(`__**${output.name.toProperCase()}:**__\n${output.description}`); + }; +}; + +exports.conf = { + enabled: true, + guildOnly: false, + aliases: ["sexualities"], + permLevel: "User", + requiredPerms: [] +}; + +exports.help = { + name: "sexuality", + category: "Fun", + description: "Gives you information about the specified sexuality.", + usage: "sexuality [sexuality]" +}; diff --git a/src/commands/ship.js b/src/commands/ship.js index cd187b9..3850d87 100644 --- a/src/commands/ship.js +++ b/src/commands/ship.js @@ -1,23 +1,39 @@ -const request = require('request') exports.run = async (client, message, args) => { - message.channel.startTyping(); - var user = client.getUserFromMention(args[0]) - var user2 = client.getUserFromMention(args[1]) + var name, name1; + var rating = Math.floor(Math.random() * 100) + 1; + var hearts = [ + "❤️", + "🧡", + "💛", + "💚", + "💙", + "💜" + ]; - var secondLength = Math.floor(user2.username.length / 2); + if(args.length < 2) { + return message.channel.send(`<:error:466995152976871434> Please include two names/users.`) + } - var first = user.username.substr(0, user.username.length / 2) - var second = user2.username.substr(secondLength, user2.username.length / 2) - - try { - var attachment = new Discord.MessageAttachment(`https://api.alexflipnote.dev/ship?user=${user.avatarURL({format: "png"})}&user2=${user2.avatarURL({format: "png"})}`) - message.channel.send(`Your ship name is **${first+second}!**`, attachment) - message.channel.stopTyping(); - } catch(err) { - message.channel.send(`<:error:466995152976871434> API error: ${err}`); - message.channel.stopTyping(); + if(message.guild && message.mentions.members && message.mentions.members.size > 0) { + name = message.mentions.members.first().displayName; }; + + if(message.guild && message.mentions.members && message.mentions.members.size > 1) { + name1 = message.mentions.members.last().displayName; + }; + + if(!name) { + name = args[0]; + }; + + if(!name1) { + name1 = args[1]; + }; + + shipName = name.substr(0, client.intBetween(1,name.length))+name1.substr(client.intBetween(0,name1.length)); + + message.channel.send(`__**Ship Generator:**__\n${hearts.random()} Ship Name: \`${shipName}\`\n${hearts.random()} Compatibility rating: \`${rating}%\``) }; exports.conf = { @@ -32,6 +48,6 @@ exports.help = { name: "ship", category: "Fun", description: "Ship two people together <3", - usage: "ship name name2" + usage: "ship [name/user] [name/user]" }; diff --git a/src/commands/slap.js b/src/commands/slap.js new file mode 100644 index 0000000..2e5189c --- /dev/null +++ b/src/commands/slap.js @@ -0,0 +1,69 @@ +const API = require('nekos.life'); +const {sfw} = new API(); +exports.run = async (client, message, args) => { + if(!args[0]) { + return message.channel.send(`<:error:466995152976871434> You didn't say who you wanted to slap! Usage: \`${client.commands.get(`kiss`).help.usage}\``) + }; + + var people = ""; + + for (var i = 0; i < args.length; i++) { + var user = client.getUserFromMention(args[i]) + if (user) { + user = message.guild.members.cache.get(user.id).displayName; + } else { + users = client.searchForMembers(message.guild, args[i]); + if (users.length > 1) + return message.channel.send( + "<:error:466995152976871434> Found multiple users for `" + args[i] + "`, Please be more specific or mention the user instead." + ); + else if (users.length == 0) + return message.channel.send( + "<:error:466995152976871434> That user doesn't seem to exist. Try again!" + ); + user = users[0].displayName; + }; + if(i+1 == args.length && args.length > 1) { + people += `**and** ${user}!` + } else if(args.length < 2) { + people += `${user}!`; + } else if(args.length == 2 && i == 0) { + people += `${user} `; + } else { + people += `${user}, `; + }; + }; + + + + message.channel.startTyping(); + try { + sfw.slap().then((json) => { + embed = new Discord.MessageEmbed(); + embed.setImage(json.url) + embed.setColor(client.embedColour(message)); + embed.setDescription(`**${message.guild.members.cache.get(message.author.id).displayName}** slapped **${people}**`) + message.channel.send(embed) + message.channel.stopTyping(); + }); + } catch (err) { + client.logger.error("slap.js: " + err); + message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`) + message.channel.stopTyping(); + }; +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: [], + permLevel: "User", + requiredPerms: ["EMBED_LINKS"] +}; + +exports.help = { + name: "slap", + category: "Action", + description: "Slap someone >:3", + usage: "slap [@user/user] (you can slap as many people as you want!)" +}; diff --git a/src/commands/smug.js b/src/commands/smug.js new file mode 100644 index 0000000..011f2bd --- /dev/null +++ b/src/commands/smug.js @@ -0,0 +1,33 @@ +const API = require('nekos.life'); +const {sfw} = new API(); +exports.run = async (client, message) => { + message.channel.startTyping(); + try { + sfw.smug().then((json) => { + embed = new Discord.MessageEmbed(); + embed.setImage(json.url) + embed.setColor(client.embedColour(message)); + message.channel.send(embed) + message.channel.stopTyping(); + }); + } catch (err) { + client.logger.error("smug.js: " + err); + message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`) + message.channel.stopTyping(); + }; +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: [], + permLevel: "User", + requiredPerms: ["EMBED_LINKS"] +}; + +exports.help = { + name: "smug", + category: "Action", + description: "Sends a smug gif.", + usage: "smug" +}; diff --git a/src/commands/spoilerise.js b/src/commands/spoilerise.js new file mode 100644 index 0000000..25ab221 --- /dev/null +++ b/src/commands/spoilerise.js @@ -0,0 +1,28 @@ +exports.run = async (client, message, args) => { + if(!args[0]) { + return message.channel.send(`<:error:466995152976871434> You didn't provide any text! Usage: \`${client.commands.get(`spoiler`).help.usage}\``) + }; + + var output = `||${[...message.cleanContent.substring(9)].join("||||")}||`; + + if(output.length > 2000) { + output = output.slice(0, -Math.abs(output.length - 2000)) + }; + + message.channel.send(output) +}; + +exports.conf = { + enabled: true, + guildOnly: false, + aliases: ["spoilerize", "spoiler"], + permLevel: "User", + requiredPerms: [] +}; + +exports.help = { + name: "spoilerise", + category: "Fun", + description: "Spoilers every letter in the provided text.", + usage: "spoiler [text]" +}; diff --git a/src/commands/support.js b/src/commands/support.js index 8fad6b2..c15de88 100644 --- a/src/commands/support.js +++ b/src/commands/support.js @@ -12,7 +12,7 @@ exports.conf = { exports.help = { name: "support", - category: "utility", + category: "Utility", description: "Sends a link to Woomy's support/development server.", usage: "support" }; diff --git a/src/commands/tickle.js b/src/commands/tickle.js new file mode 100644 index 0000000..e75a771 --- /dev/null +++ b/src/commands/tickle.js @@ -0,0 +1,69 @@ +const API = require('nekos.life'); +const {sfw} = new API(); +exports.run = async (client, message, args) => { + if(!args[0]) { + return message.channel.send(`<:error:466995152976871434> You didn't say who you wanted to tickle! Usage: \`${client.commands.get(`tickle`).help.usage}\``) + }; + + var people = ""; + + for (var i = 0; i < args.length; i++) { + var user = client.getUserFromMention(args[i]) + if (user) { + user = message.guild.members.cache.get(user.id).displayName; + } else { + users = client.searchForMembers(message.guild, args[i]); + if (users.length > 1) + return message.channel.send( + "<:error:466995152976871434> Found multiple users for `" + args[i] + "`, Please be more specific or mention the user instead." + ); + else if (users.length == 0) + return message.channel.send( + "<:error:466995152976871434> That user doesn't seem to exist. Try again!" + ); + user = users[0].displayName; + }; + if(i+1 == args.length && args.length > 1) { + people += `**and** ${user}!` + } else if(args.length < 2) { + people += `${user}!`; + } else if(args.length == 2 && i == 0) { + people += `${user} `; + } else { + people += `${user}, `; + }; + }; + + + + message.channel.startTyping(); + try { + sfw.tickle().then((json) => { + embed = new Discord.MessageEmbed(); + embed.setImage(json.url) + embed.setColor(client.embedColour(message)); + embed.setDescription(`**${message.guild.members.cache.get(message.author.id).displayName}** tickled **${people}**`) + message.channel.send(embed) + message.channel.stopTyping(); + }); + } catch (err) { + client.logger.error("tickle.js: " + err); + message.channel.send(`<:error:466995152976871434> An error has occurred: ${err}`) + message.channel.stopTyping(); + }; +}; + +exports.conf = { + enabled: true, + guildOnly: true, + aliases: [], + permLevel: "User", + requiredPerms: ["EMBED_LINKS"] +}; + +exports.help = { + name: "tickle", + category: "Action", + description: "Tickle someone!", + usage: "tickle [@user/user] (you can tickle as many people as you want!)" +}; diff --git a/src/commands/unmute.js b/src/commands/unmute.js index 448df4d..abf38f1 100644 --- a/src/commands/unmute.js +++ b/src/commands/unmute.js @@ -63,7 +63,7 @@ exports.run = async (client, message, args, level) => { if (channel) { let embed = new Discord.MessageEmbed(); embed.setColor("#7a2f8f"); - embed.setAuthor("User unmuted!", user.user.avatarURL({format: "png", dynamic: true})); + embed.setAuthor("User unmuted!", user.user.avatarURL({format: "png", dynamic: true, size: 2048})); embed.setDescription(`• User: ${user} (${user.user.id})\n• Mod: ${message.author} (${message.author.id})`) try { channel.send({ embed }); diff --git a/src/commands/userinfo.js b/src/commands/userinfo.js index 8d7008b..c5dcbac 100644 --- a/src/commands/userinfo.js +++ b/src/commands/userinfo.js @@ -1,18 +1,10 @@ const Discord = require("discord.js"); - +const coolPeople = require('../../resources/other/coolpeople.json') exports.run = (client, message, args) => { - var user; - var guild; - var nick = ""; - var roles = ""; - var presence = ""; - var badges = ""; - var status; - var createdAt; - var avurl; - var tag; - var id; - var bot; + var user, guild, status, createdAt, avurl, tag, id; + var nick, roles, presence, badges = ""; + var coolPerson = false; + var friendos = coolPeople.coolPeople; if(message.guild) { user = message.mentions.members.first(); @@ -39,6 +31,15 @@ exports.run = (client, message, args) => { nick = `\n• **Nickname:** ${user.nickname}`; }; + for (var i = 0; i < friendos.length; i++) { + if (user.user.id == friendos[i]) + coolPerson = true; + }; + + if(coolPerson == true) { + badges += "🌟" + } + if(user.user.id == message.guild.ownerID) { badges += "<:owner:685703193694306331>" } @@ -46,6 +47,7 @@ exports.run = (client, message, args) => { if(user.user.bot) { badges += "<:bot:686489601678114859>" } + if(badges.length > 0) { badges += "\n" diff --git a/src/commands/weather.js b/src/commands/weather.js index f5fc362..ef01bc8 100644 --- a/src/commands/weather.js +++ b/src/commands/weather.js @@ -5,46 +5,47 @@ exports.run = async (client, message, args, error) => { `<:error:466995152976871434> You didn't give me a location. Usage: \`${client.commands.get(`weather`).help.usage}\`` ); }; - - if(args.join(" ").toLowerCase() == "antarctica") { - return; - } message.channel.startTyping(); - - weather.find({search: args.join(" "), degreeType: 'C'}, function(err, result) { - if(err) client.logger.log(`weather.js error: ${JSON.stringify(error)}`, "error") - if(result.length < 2 || !result) { + + try { + weather.find({search: args.join(" "), degreeType: 'C'}, function(err, result) { + if(err) return message.channel.send(`<:error:466995152976871434> API error: \`${error}\``) + if(result.length < 2 || !result) { + message.channel.stopTyping(); + return message.channel.send("<:error:466995152976871434> City not found!"); + }; + + var location = result[0].location; + var current = result[0].current; + + var warning = (`${location.alert}` || "No warnings"); + + var embedColour; + if (current.temperature < 0) { + embedColour = "#addeff"; + }else if (current.temperature < 20) { + embedColour = "#4fb8ff"; + }else if (current.temperature < 26) { + embedColour = "#ffea4f"; + }else if (current.temperature < 31) { + embedColour = "#ffa14f" + } else { + embedColour = "#ff614f" + }; + + embed = new Discord.MessageEmbed(); + embed.setAuthor(`Weather for ${location.name}:`) + embed.setDescription(`• **Condition:** ${current.skytext}\n• **Temperature:** ${current.temperature}°C\n• **Feels like:** ${current.feelslike}°C\n• **Humidity:** ${current.humidity}%\n• **Wind:** ${current.winddisplay}\n• **Warnings:** ${warning}`) + embed.setThumbnail(current.imageUrl) + embed.setFooter(`Last updated at ${current.observationtime} ${current.date}`) + embed.setColor(embedColour) message.channel.stopTyping(); - return message.channel.send("<:error:466995152976871434> City not found!"); - }; - - var location = result[0].location; - var current = result[0].current; - - var warning = (`${location.alert}` || "No warnings"); - - var embedColour; - if (current.temperature < 0) { - embedColour = "#addeff"; - }else if (current.temperature < 20) { - embedColour = "#4fb8ff"; - }else if (current.temperature < 26) { - embedColour = "#ffea4f"; - }else if (current.temperature < 31) { - embedColour = "#ffa14f" - } else { - embedColour = "#ff614f" - }; - - embed = new Discord.MessageEmbed(); - embed.addField(`Weather for ${location.name}:`, `**Condition:** ${current.skytext}\n**Temperature:** ${current.temperature}C°\n**Feels like:** ${current.feelslike}C°\n**Humidity:** ${current.humidity}%\n**Wind:** ${current.winddisplay}\n**Warnings:** ${warning}`) - embed.setThumbnail(current.imageUrl) - embed.setFooter(`Last updated at ${current.observationtime} ${current.date}`) - embed.setColor(embedColour) - message.channel.stopTyping(); - message.channel.send(embed) - }); + message.channel.send(embed) + }); + } catch(err) { + return message.channel.send(`<:error:466995152976871434> API error: \`${err}\``) + }; }; exports.conf = { diff --git a/src/commands/yoda.js b/src/commands/yoda.js index 293d786..496b929 100644 --- a/src/commands/yoda.js +++ b/src/commands/yoda.js @@ -1,32 +1,33 @@ -const request = require('request') +const fetch = require("node-fetch") exports.run = async (client, message, args) => { - const speech = args.join(' '); - if (!args[0]) { - return message.channel.send(`<:error:466995152976871434> Please include text for me to convert to yodish. Yes.`) - } - try { - const { text } = request({ uri: `http://yoda-api.appspot.com/api/v1/yodish?text=${encodeURIComponent(speech.toLowerCase())}`, json: true }, (error, response, body) => { - message.channel.send(JSON.parse(text).yodish) - }); - } catch(err) { - message.channel.send(`<:error:466995152976871434> API error: ${err}`); - message.channel.stopTyping(); - } - -} + const speech = args.join(' '); + if (!speech) { + return message.channel.send(`<:error:466995152976871434> Please include text for me to convert to yodish. Yes.`) + }; + message.channel.startTyping(); + 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)); + 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: ["yoda","yodasay"], - permLevel: "User", - requiredPerms: [] - }; - + enabled: true, + guildOnly: false, + aliases: [], + permLevel: "User", + requiredPerms: [] +}; + exports.help = { - name: "yodish", - category: "Fun", - description: "Turns any text you input into yodish. Yes.", - usage: "yodish " - }; \ No newline at end of file + name: "yoda", + category: "Fun", + description: "Turns any text you input into yodish. Yes.", + usage: "yoda " +}; \ No newline at end of file diff --git a/src/commands/zalgo.js b/src/commands/zalgo.js new file mode 100644 index 0000000..e34d404 --- /dev/null +++ b/src/commands/zalgo.js @@ -0,0 +1,30 @@ +const zalgo = require("to-zalgo") +exports.run = async (client, message, args) => { + if(!args[0]) { + return message.channel.send(`<:error:466995152976871434> You didn't provide any text! Usage: \`${client.commands.get(`zalgo`).help.usage}\``) + }; + + var output = zalgo(args.join(" ")) + + if(output.length > 2000) { + output = output.slice(0, -Math.abs(output.length - 2000)) + }; + + message.channel.send(output) + }; + + exports.conf = { + enabled: false, + guildOnly: false, + aliases: [], + permLevel: "User", + requiredPerms: [] + }; + + exports.help = { + name: "zalgo", + category: "Fun", + description: "Spoilers every letter in the provided text.", + usage: "zalgo [text]" + }; + \ No newline at end of file diff --git a/src/events/message.js b/src/events/message.js index 3505c1c..7c399a8 100644 --- a/src/events/message.js +++ b/src/events/message.js @@ -1,4 +1,4 @@ -const commandRanRecently = new Set(); +const cooldown = new Set(); module.exports = async (client, message) => { if (message.author.bot) return; @@ -131,11 +131,17 @@ module.exports = async (client, message) => { }; }; - const prefixMention = new RegExp(`^<@!?${client.user.id}>( |)$`); - - if (message.content.match(prefixMention)) { - return message.channel.send(`Current prefix: \`${prefix}\``); - } + //const prefixMention = new RegExp(`^<@!?${client.user.id}>( |)$`); + const myMention = `<@&${client.user.id}>`; + const myMention2 = `<@!${client.user.id}>`; + + if (message.content.startsWith(myMention) || message.content.startsWith(myMention2)) { + if(message.content.length > myMention.length + 1 && (message.content.substr(0, myMention.length + 1) == myMention + ' ' || message.content.substr(0, myMention2.length + 1) == myMention2 + ' ')) { + prefix = message.content.substr(0, myMention.length) + ' '; + } else { + return message.channel.send(`Current prefix: \`${prefix}\``); + }; + }; if (message.content.indexOf(prefix) !== 0) return; @@ -145,14 +151,15 @@ module.exports = async (client, message) => { if (!cmd) return; - if (commandRanRecently.has(message.author.id)) { + if (cooldown.has(message.author.id)) { return message.channel.send( - `⏱️ You are being ratelimited. Please try again in 2 seconds.` - ) - .then(m => m.delete(2000)); + `⏱️ You are being ratelimited. Please try again in 2 seconds.` + ).then(msg => { + msg.delete({timeout: 2000}); + }); }; - if (!perms.has('SEND_MESSAGES')) { + if (message.guild && !perms.has('SEND_MESSAGES')) { 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!`); }; @@ -216,12 +223,13 @@ module.exports = async (client, message) => { message.flags.push(args.shift().slice(1)); }; - commandRanRecently.add(message.author.id); + cooldown.add(message.author.id); + setTimeout(() => { - commandRanRecently.delete(message.author.id); - }, {timeout: 2000}); + 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}`); cmd.run(client, message, args, level); -}; \ No newline at end of file +}; diff --git a/src/events/ready.js b/src/events/ready.js index 4a3ce44..532cd8c 100644 --- a/src/events/ready.js +++ b/src/events/ready.js @@ -6,28 +6,55 @@ module.exports = client => { client.lockActivity = false; - client.logger.log(`Connected to Discord as ${client.user.tag} | v${client.version.number}`, 'ready'); + let guild, channel, channel1; - let channel; - let channel1; + if(client.config.loggingServer.length > 0) { + try { + guild = client.guilds.cache.get(client.config.loggingServer) + } catch(err) { + client.logger.error("Could not find loggingServer server (is the ID valid?):\n" + err); + process.exit(1); + }; - try { channel = client.guilds.cache.get('410990517841690625').channels.cache.get('570963998342643732'); } catch(err) {}; - try { channel1 = client.guilds.cache.get('410990517841690625').channels.cache.get('570963481189154822'); } catch(err) {}; + if(client.config.consoleLogs.length > 0) { + try { + channel1 = guild.channels.cache.get(client.config.consoleLogs) + } catch(err) { + client.logger.error("Could not find consoleLogs channel (is the ID valid?):\n" + err); + process.exit(1); + }; + }; + + if(client.config.startupLogs.length > 0) { + try { + channel = guild.channels.cache.get(client.config.startupLogs) + } catch(err) { + client.logger.error("Could not find startupLogs channel (is the ID valid?):\n" + err); + process.exit(1); + }; + }; + }; if(client.devmode == true) { client.logger.warn("Running in development mode.") prefix = client.config.defaultSettings.devprefix; } else { prefix = client.config.defaultSettings.prefix; - channel.send(`\`${timestamp}\`: Ready event fired! Connected to ${client.users.cache.size} users in ${client.guilds.cache.size} guilds.`); - channel1.send(`\`${timestamp}\`: **Ready event fired**`); - } + if(channel) { + channel.send(`Bot started at \`${timestamp}\``); + }; + }; let randomActivity = activityArray.random(); client.user.setActivity(`${prefix + randomActivity} | v${client.version.number}`, {type: "PLAYING"}); + setInterval(() => { randomActivity = activityArray.random(); - if(client.lockActivity == false) client.user.setActivity(`${prefix + randomActivity} | v${client.version.number}`, {type: "PLAYING"}); + if(client.lockActivity == false) { + client.user.setActivity(`${prefix + randomActivity} | v${client.version.number}`, {type: "PLAYING"}); + }; }, 30000); + + client.logger.log(`Connected to Discord as ${client.user.tag} | v${client.version.number}`, 'ready'); }; diff --git a/src/modules/Logger.js b/src/modules/Logger.js index 0c8614f..e924961 100644 --- a/src/modules/Logger.js +++ b/src/modules/Logger.js @@ -2,17 +2,25 @@ const chalk = require("chalk"); const moment = require("moment"); exports.log = (content, type = "log") => { - const timestamp = chalk.grey(`[${moment().format("YYYY-MM-DD HH:mm:ss")}]`); + const timestamp = `[${moment().format("YYYY-MM-DD HH:mm:ss")}]`; let channel; + + try { + channel = client.guilds.cache.get(client.config.loggingServer).channels.cache.get(client.config.consoleLogs); + } catch(err) {}; - try { channel = client.guilds.cache.get('410990517841690625').channels.cache.get('570963481189154822'); } catch(err) {} + var logToServer = false; + + if(client.devmode === false && channel && client.guilds.cache.get(client.config.loggingServer).available) { + logToServer = true; + }; switch (type) { case "info": { try { - if (client.devmode == false) { - channel.send(`\`${timestamp}\`: ` + content); + if (logToServer == true) { + channel.send(`\`${timestamp}\` \`[${type.toUpperCase()}]\` ` + content); }; } catch(err) {}; return console.log(`${timestamp} ${chalk.cyanBright(`[${type.toUpperCase()}]`)} ${content} `); @@ -20,8 +28,8 @@ exports.log = (content, type = "log") => { case "warn": { try { - if (client.devmode == false) { - channel.send(`\`${timestamp}\`: ` + content); + if (logToServer == true) { + channel.send(`\`${timestamp}\` \`[${type.toUpperCase()}]\` ` + content); }; } catch(err) {}; return console.log(`${timestamp} ${chalk.yellowBright(`[${type.toUpperCase()}]`)} ${content} `); @@ -29,8 +37,8 @@ exports.log = (content, type = "log") => { case "error": { try { - if (client.devmode == false) { - channel.send(`\`${timestamp}\`: ` + content); + if (logToServer == true) { + channel.send(`\`${timestamp}\` \`[${type.toUpperCase()}]\` ` + content); }; } catch(err) {} return console.log(`${timestamp} ${chalk.redBright(`[${type.toUpperCase()}]`)} ${content} `); @@ -38,8 +46,8 @@ exports.log = (content, type = "log") => { case "debug": { try { - if (client.devmode == false) { - channel.send(`\`${timestamp}\`: ` + content); + if (logToServer == true) { + channel.send(`\`${timestamp}\` \`[${type.toUpperCase()}]\` ` + content); }; } catch(err) {}; return console.log(`${timestamp} ${chalk.magentaBright(`[${type.toUpperCase()}]`)} ${content} `); @@ -47,14 +55,19 @@ exports.log = (content, type = "log") => { case "cmd": { try { - if (client.devmode == false) { - channel.send(`\`${timestamp}\` ` + content); + if (logToServer == true) { + channel.send(`\`${timestamp}\` \`[${type.toUpperCase()}]\` ` + content); }; } catch(err) {}; return console.log(`${timestamp} ${chalk.whiteBright(`[${type.toUpperCase()}]`)} ${content}`); }; case "ready": { + try { + if (logToServer == true) { + channel.send(`\`${timestamp}\` \`[${type.toUpperCase()}]\` ` + content); + }; + } catch(err) {}; return console.log(`${timestamp} ${chalk.greenBright (`[${type.toUpperCase()}]`)} ${content}`); }; diff --git a/src/modules/functions.js b/src/modules/functions.js index 98cf223..a30dd4b 100644 --- a/src/modules/functions.js +++ b/src/modules/functions.js @@ -1,7 +1,7 @@ const ytdl = require('ytdl-core-discord'); const youtubeInfo = require('youtube-info'); const getYoutubeId = require('get-youtube-id'); -const request = require('request'); +const fetch = require('node-fetch'); module.exports = client => { // Permission level function @@ -160,14 +160,17 @@ module.exports = client => { { return new Promise(function(resolve, reject) { - request("https://www.googleapis.com/youtube/v3/search?part=id&type=video&q=" + encodeURIComponent(query) + "&key=" + client.config.ytkey, function(error, response, body) - { - if(error) throw error; - - var json = JSON.parse(body); + 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; + }; }); } @@ -340,6 +343,12 @@ module.exports = client => { }; }; + // FIND RANDOM INT BETWEEN TWO INTEGERS + client.intBetween = function(min, max){ + return Math.round((Math.random() * (max - min))+min); + }; + + // .toPropercase() returns a proper-cased string Object.defineProperty(String.prototype, "toProperCase", { value: function() { diff --git a/version.json b/version.json index 3e289f1..19b07db 100644 --- a/version.json +++ b/version.json @@ -1,4 +1,4 @@ { - "number": "1.2.0", - "changelog": "**1.1.0 CHANGELOG:**\n> • Added `~softban`, bans and unbans a user to clear messages\n> • Added `~emoji`, enlarges custom emojis\n> • Added `~inspirobot`, generates an inspirational quote\n> • `~serverinfo` has been changed to be more consistent, and also now displays boosts and if the server is partnered and stuff\n> • `~userinfo` has been changed to be more consistent, also added some stuff\n> • `~about` has been changed, added a thumbnail and removed the description\n> • `~colour` has been changed, it can now generate colours from text\n> • `~hackban` no longer has its own embed\n> • `~eval` now logs to hastebin if output is too large\n> • role names are no longer case sensitive\n> • `~echo` renamed `~say`\n> • Users with the ADMINISTRATOR permission now automatically recieve woomy admin\n> • Fixed `~flip`, `~purge`, `~bohemian_rhapsody` and `~creeper`\n> • Guild join/leave messages no longer include the guild name\n> • Some emojis have been changed\n> • Woomy now supports discord.js v12\n> • Files have been restructured\n> • Logger now logs error stack\n> • Restart now exits with code 0" + "number": "1.2.2", + "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" }