diff --git a/assets/audio/WOOMY.mp3 b/assets/audio/WOOMY.mp3 new file mode 100644 index 0000000..9b39891 Binary files /dev/null and b/assets/audio/WOOMY.mp3 differ diff --git a/assets/img/attackhelicopter.jpg b/assets/img/attackhelicopter.jpg new file mode 100644 index 0000000..c077f0d Binary files /dev/null and b/assets/img/attackhelicopter.jpg differ diff --git a/assets/img/fax.png b/assets/img/fax.png new file mode 100644 index 0000000..a616839 Binary files /dev/null and b/assets/img/fax.png differ diff --git a/assets/json/coolpeople.json b/assets/json/coolpeople.json new file mode 100644 index 0000000..86100fa --- /dev/null +++ b/assets/json/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/assets/json/identities.json b/assets/json/identities.json new file mode 100644 index 0000000..4afd11a --- /dev/null +++ b/assets/json/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/assets/json/lyrics.json b/assets/json/lyrics.json new file mode 100644 index 0000000..cd753d2 --- /dev/null +++ b/assets/json/lyrics.json @@ -0,0 +1,122 @@ +{ + "bohemian_rhapsody": [ + "Is this the real life?", + "Is this just fantasy?", + "Caught in a landslide, no escape from reality", + "Open your eyes, look up to the skies and see", + "I'm just a poor boy, I need no sympathy", + "Because I'm easy come, easy go, little high, little low", + "Any way the wind blows doesn't really matter to me, to me", + "Mama, just killed a man", + "Put a gun against his head, pulled my trigger, now he's dead", + "Mama, life had just begun", + "But now I've gone and thrown it all away", + "Mama, ooh, didn't mean to make you cry", + "If I'm not back again this time tomorrow", + "Carry on, carry on as if nothing really matters", + "Too late, my time has come", + "sends shivers down my spine, body's aching all the time", + "Goodbye, everybody, I've got to go", + "Gotta leave you all behind and face the truth", + "Mama, ooh, (Anyway the wind blows)", + "I don't wanna die", + "I sometimes wish I'd never been born at all", + "i see a little silhouetto of a man", + "Scaramouche! Scaramouche! will you do the Fandango?", + "Thunderbolt and lightning, very, very fright'ning me", + "(Galileo) Galileo, (Galileo) Galileo, Galileo Figaro magnifico", + "I'm just a poor boy, nobody loves me", + "He's just a poor boy from a poor family", + "spare him his life from this monstrosity", + "Easy come, easy go, will you not let me go?", + "Bismillah! No, we will not let you go", + "(Let him go!) Bismillah! We will not let you go", + "(Let him go!) Bismillah! We will not let you go", + "(Let me go) Will not let you go", + "(Let me go) Will not let you go", + "(Let me go) Ah", + "no, no, no, no, no, no, no", + "(Oh mamma mia, mamma mia) Mamma mia, let me go", + "Beelzebub has the devil put aside for me, for me, for me!", + "So you think you can stone me and spit in my eye?", + "so you think you can love me and leave me to die?", + "Oh baby, can't do this to me, baby!", + "Just gotta get out, just gotta get right outta here!", + "Nothing really matters, anyone can see", + "nothing really matters", + "Nothing really matters, to me", + "any way the wind blows" + ], + + "creeper": [ + "Aw man", + "So we back in the mine", + "Got our pickaxe swinging from side to side", + "Side side to side", + "This task a grueling one", + "Hope to find some diamonds tonight night night", + "Diamonds tonight", + "Heads up", + "You hear a sound turn around and look up", + "Total shock fills your body", + "Oh no it's you again", + "I can never forget those eyes eyes eyes", + "Eyes-eye-eyes", + "Cause baby tonight", + "The creeper's tryna steal all our stuff again", + "Cause baby tonight", + "You grab your pick, shovel and bolt again", + "And run run until it's done done", + "Until the sun comes up in the morn", + "Cause baby tonight", + "The creeper's tryna steal all our stuff again", + "Just when you think you're safe", + "Overhear some hissing from right behind", + "Right right behind", + "That's a nice life you have", + "Shame it's gotta end at this time time time", + "Time-time-time-time", + "Blows up", + "Then your health bar drops and you could use a one up", + "Get inside, don't be tardy", + "So now you're stuck in there", + "Half a heart is left, but don't die die die", + "Die-die-die", + "Cause baby tonight", + "The creeper's tryna steal all our stuff again", + "Cause baby tonight", + "You grab your pick shovel and bolt again", + "And run run until it's done done", + "Until the sun comes up in the morn", + "Cause baby tonight?", + "The creeper's tryna steal all our stuff again", + "Dig up diamonds and craft those diamonds", + "And make some armor, get it baby", + "Go and forge that like you so MLG pro", + "The sword's made of diamonds, so come at me bro, huh", + "Training in your room under the torchlight", + "Hone that form to get you ready for the big fight", + "Every single day and the whole night", + "Creeper's out prowlin', hoo, alright", + "Look at me, look at you", + "Take my revenge, that's what I'm gonna do", + "I'm a warrior baby, what else is new", + "And my blade's gonna tear through you, bring it", + "Cause baby tonight", + "The creeper's tryna steal all our stuff again", + "(Gather your stuff, yeah, let's take back the world)", + "Yeah baby tonight", + "Grab your sword armor and go", + "Take your revenge", + "So fight fight like it's the last last night", + "Of your life life show them your bite", + "Cause baby tonight", + "The creeper's tryna steal all our stuff again", + "Cause baby tonight", + "You grab your pick shovel and bolt again", + "And run run until it's done done", + "Until the sun comes up in the morn", + "Cause baby tonight", + "The creeper's tryna steal all our stuff again" + ] +} \ No newline at end of file diff --git a/assets/json/pronouns.json b/assets/json/pronouns.json new file mode 100644 index 0000000..fa65ece --- /dev/null +++ b/assets/json/pronouns.json @@ -0,0 +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/assets/json/sexualities.json b/assets/json/sexualities.json new file mode 100644 index 0000000..2ff29ca --- /dev/null +++ b/assets/json/sexualities.json @@ -0,0 +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/assets/placeholder b/assets/placeholder deleted file mode 100644 index e69de29..0000000 diff --git a/commands/level.js b/commands/level.js new file mode 100644 index 0000000..ec9ad8f --- /dev/null +++ b/commands/level.js @@ -0,0 +1,24 @@ +exports.conf = { + enabled: true, + guildOnly: false, + aliases: ['plevel', 'permlevel'], + permLevel: 'User', + requiredPerms: [], + cooldown: 2000 +} + +exports.help = { + name: 'level', + category: 'Utility', + description: 'Returns your permission level.', + usage: 'level' +} + +exports.run = async (client, message, args, level) => { + try { + const friendly = client.config.permLevels.find(l => l.level === level).name + message.reply(`your permission level is ${level} (${friendly}).`) + } catch (err) { + message.channel.send('There was an error!\n' + err).catch() + } +} diff --git a/commands/ping.js b/commands/ping.js index ea1ead3..56c76a7 100644 --- a/commands/ping.js +++ b/commands/ping.js @@ -4,7 +4,7 @@ exports.conf = { aliases: [], permLevel: 'User', requiredPerms: [], - cooldown: 5000 + cooldown: 2000 } exports.help = { @@ -17,6 +17,6 @@ exports.help = { exports.run = async (client, message) => { const msg = await message.channel.send('Pinging...') msg.edit( - `Pong! \`${msg.createdTimestamp - message.createdTimestamp}ms\` (💗\`${Math.round(client.ws.ping)}ms\`)` + `Pong! \`${msg.createdTimestamp - message.createdTimestamp}ms\` (💗 \`${Math.round(client.ws.ping)}ms\`)` ) } diff --git a/config.js b/config.js index 6aa9c53..5cebe98 100644 --- a/config.js +++ b/config.js @@ -13,13 +13,43 @@ const config = { systemNotice: true }, - // + // Permission levels permLevels: [ { level: 0, name: 'User', - check: () => true + }, + + { + level: 1, + name: 'Moderator', + check: (message) => { + try { + if (message.member.roles.cache.has(message.settings.modRole)) return true + } catch (e) { + return false + } + } + }, + + { + level: 2, + name: 'Administrator', + check: (message) => { + try { + if (message.member.roles.cache.has(message.settings.adminRole) || message.member.permissions.has('ADMINISTRATOR')) return true + } catch (e) { + return false + } + } + }, + + { + level: 3, + name: 'Server Owner', + + check: (message) => message.channel.type === 'text' ? (message.guild.ownerID === message.author.id) : false } ] } diff --git a/events/message.js b/events/message.js index 75d3401..d6579f9 100644 --- a/events/message.js +++ b/events/message.js @@ -30,6 +30,13 @@ module.exports = async (client, message) => { return message.channel.send('This command is unavailable via private message. Please run this command in a guild.') } + // Dev perm level is separate so dev's don't get owner perms where they shouldn't have them + if (cmd.conf.permLevel === 'Developer') { + if (!message.client.config.owners.includes(message.author.id)) { + return message.channel.send('You don\'t have permission to run this command!') + } + } + if (level < client.levelCache[cmd.conf.permLevel]) { return message.channel.send('You don\'t have permission to run this command!') } @@ -51,6 +58,7 @@ module.exports = async (client, message) => { message.author.permLevel = level + // Might use this message.flags = [] while (args[0] && args[0][0] === '-') { message.flags.push(args.shift().slice(1)) diff --git a/index.js b/index.js index e31d882..b5119d0 100644 --- a/index.js +++ b/index.js @@ -18,25 +18,20 @@ client.logger = require('tracer').colorConsole({ format: [ '{{timestamp}} [{{title}}] {{file}}: {{message}}', { - log: `{{timestamp}} ${'[{{title}}]'.white} {{file}}: {{message}}`, - debug: `{{timestamp}} ${'[{{title}}]'.magenta} {{file}}: {{message}}`, - info: `{{timestamp}} ${'[{{title}}]'.cyan} {{file}}: {{message}}`, - ready: `{{timestamp}} ${'[{{title}}]'.green} {{file}}: {{message}}`, - warn: `{{timestamp}} ${'[{{title}}]'.yellow} {{file}}: {{message}}`, - error: `{{timestamp}} ${'[{{title}}]'.red} {{file}}: {{message}}`, - fatal: `{{timestamp}} ${'[{{title}}]'.red.bold} {{file}}: {{message}}` + debug: `{{timestamp}} ${'<{{title}}>'.magenta} {{file}}:{{line}} {{message}}`, + log: `{{timestamp}} ${'<{{title}}>'.white} {{file}}:{{line}} {{message}}`, + info: `{{timestamp}} ${'<{{title}}>'.cyan} {{file}}:{{line}} {{message}}`, + ready: `{{timestamp}} ${'<{{title}}>'.green} {{file}}:{{line}} {{message}}`, + warn: `{{timestamp}} ${'<{{title}}>'.yellow} {{file}}:{{line}} {{message}}`, + error: `{{timestamp}} ${'<{{title}}>'.red} {{file}}:{{line}} {{message}}`, + fatal: `{{timestamp}} ${'<{{title}}>'.red.bold} {{file}}:{{line}} {{message}}` } ], - dateformat: 'yyyy-mm-dd HH:MM:ss', + dateformat: 'yyyy-mm-dd"T"HH:MM:ss', methods: ['log', 'debug', 'info', 'ready', 'warn', 'error', 'fatal'], filters: [colors.white] }) -// Load modules -require('./modules/functions')(client) -require('./modules/music')(client) -require('./modules/botlists')(client) - // Checks to make sure config.js and .env exist if (fs.existsSync('./.env') === false) { client.logger.fatal('The .env file is missing! Please create a .env file.') @@ -48,49 +43,32 @@ if (fs.existsSync('./config.js') === false) { process.exit() } -require('dotenv').config() client.config = require('./config') +require('dotenv').config() +require('./modules/functions')(client) +require('./modules/music')(client) +require('./modules/botlists')(client) -if (process.env.DEV_MODE === 'true') { +if (process.env.DEV_MODE) { client.devmode = true client.logger.warn('Running in development mode.') } else { client.devmode = false - // load botlist stuff here eventually } -// Collections that +client.levelCache = {} client.commands = new Discord.Collection() client.cooldown = new Discord.Collection() client.aliases = new Discord.Collection() // Initialization function const init = async () => { - // Load events - fs.readdir('./events', (err, files) => { - if (err) { - client.logger.fatal('Failed to get files in events directory: ' + err) - process.exit() - }; - - client.logger.info(`Loading ${files.length} events.`) - files.forEach(file => { - if (!file.endsWith('.js')) { - return - } - const event = require(`./events/${file}`) - client.on(file.substr(0, file.length - 3), event.bind(null, client)) - }) - }) - - // Load commands + // Command handler fs.readdir('./commands', (err, files) => { if (err) { client.logger.fatal('Failed to get files in commands directory: ' + err) - process.exit() }; - client.logger.info(`Loading ${files.length} commands.`) files.forEach(file => { if (!file.endsWith('.js')) { @@ -103,17 +81,30 @@ const init = async () => { }) }) - // Level cache - client.levelCache = {} + // Event handler + fs.readdir('./events', (err, files) => { + if (err) { + client.logger.fatal('Failed to get files in events directory: ' + err) + process.exit() + }; + client.logger.info(`Loading ${files.length} events.`) + files.forEach(file => { + if (!file.endsWith('.js')) { + return + } + const event = require(`./events/${file}`) + client.on(file.substr(0, file.length - 3), event.bind(null, client)) + }) + }) + + // Cache client permissions for (let i = 0; i < client.config.permLevels.length; i++) { const thisLevel = client.config.permLevels[i] client.levelCache[thisLevel.name] = thisLevel.level } - // Login into Discord - client.login(process.env.TOKEN) - - if(client.devmode === true) { + // Log into Discord + if (client.devmode === true) { client.login(process.env.DEVTOKEN) } else { client.login(process.env.TOKEN) diff --git a/modules/functions.js b/modules/functions.js index 6c3e61c..e3c3064 100644 --- a/modules/functions.js +++ b/modules/functions.js @@ -1,5 +1,4 @@ module.exports = client => { - client.permlevel = message => { let permlvl = 0 @@ -34,6 +33,102 @@ module.exports = client => { } } + client.unloadCommand = async (commandName) => { + let command + if (client.commands.has(commandName)) { + command = client.commands.get(commandName) + } else if (client.aliases.has(commandName)) { + command = client.commands.get(client.aliases.get(commandName)) + } + if (!command) return `The command \`${commandName}\` doesn"t seem to exist, nor is it an alias. Try again!` + + if (command.shutdown) { + await command.shutdown(client) + } + const mod = require.cache[require.resolve(`../commands/${command.help.name}`)] + delete require.cache[require.resolve(`../commands/${command.help.name}.js`)] + for (let i = 0; i < mod.parent.children.length; i++) { + if (mod.parent.children[i] === mod) { + mod.parent.children.splice(i, 1) + break + } + } + return false + } + + client.getUser = async function (search) { + let user = null + if (!search || typeof search !== 'string') return + // Try ID search + if (search.match(/^<@!?(\d+)>$/)) { + const id = search.match(/^<@!?(\d+)>$/)[1] + user = this.users.fetch(id).catch(() => {}) + if (user) return user + } + // Try username search + if (search.match(/^!?(\w+)#(\d+)$/)) { + const username = search.match(/^!?(\w+)#(\d+)$/)[0] + const discriminator = search.match(/^!?(\w+)#(\d+)$/)[1] + user = this.users.find((u) => u.username === username && u.discriminator === discriminator) + if (user) return user + } + user = await this.users.fetch(search).catch(() => {}) + return user + } + + client.getMembers = function (guild, query) { + if (!query) return + query = query.toLowerCase() + + var a = [] + var b + + // MAKE IT SO IT CAN TAKE AN ID + + try { + b = guild.members.cache.find(x => x.displayName.toLowerCase() === query) + if (!b) guild.members.cache.find(x => x.user.username.toLowerCase() === query) + } catch (err) {} + if (b) a.push(b) + guild.members.cache.forEach(member => { + if ( + (member.displayName.toLowerCase().startsWith(query) || + member.user.tag.toLowerCase().startsWith(query)) && + member.id !== (b && b.id) + ) { + a.push(member) + } + }) + return a + } + + client.getUsers = function (guild, query) { + if (!query) return + query = query.toLowerCase() + + var a = [] + var b + + // MAKE IT SO IT CAN TAKE AN ID + + try { + b = guild.members.cache.find(x => x.displayName.toLowerCase() === query) + if (!b) guild.members.cache.find(x => x.user.username.toLowerCase() === query) + } catch (err) {} + if (b) a.push(b) + guild.members.cache.forEach(member => { + if ( + (member.displayName.toLowerCase().startsWith(query) || + member.user.tag.toLowerCase().startsWith(query)) && + member.id !== (b && b.id) + ) { + a.push(member) + } + }) + return a + } + + // Both of these functions catch errors and log them process.on('uncaughtException', (err) => { const errorMsg = err.stack.replace(new RegExp(`${__dirname}/`, 'g'), './') client.logger.fatal(`Uncaught Exception: ${errorMsg}`) diff --git a/package-lock.json b/package-lock.json index e7ae8ee..0a654cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -443,15 +443,6 @@ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, "cheerio": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.19.0.tgz", @@ -984,6 +975,27 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" } } }, @@ -1046,11 +1058,6 @@ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1495,17 +1502,6 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=" }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", @@ -1740,11 +1736,6 @@ "strip-ansi": "^6.0.0" } }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, "stringstream": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz",