├── .eslintrc.json ├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── Util.js ├── commands ├── administrator │ ├── Actions.js │ ├── AddAction.js │ ├── AddAuto.js │ ├── AddAutoRole.js │ ├── AddRole.js │ ├── Alert.js │ ├── AllInfo.js │ ├── Ban.js │ ├── Calm.js │ ├── CheckPerms.js │ ├── ClearMutes.js │ ├── Events.js │ ├── Fire.js │ ├── FixRoles.js │ ├── GetLinks.js │ ├── HasPerm.js │ ├── InitRoles.js │ ├── Link.js │ ├── Permissions.js │ ├── RaveBan.js │ ├── RemAuto.js │ ├── RemAutoRole.js │ ├── RemRole.js │ ├── RolePerms.js │ ├── Switch.js │ ├── UnCalm.js │ ├── UnLink.js │ └── UnRaveBan.js ├── locked │ ├── Bother.js │ ├── Change.js │ ├── Commit.js │ ├── Create.js │ ├── DisabR.js │ ├── Echo.js │ ├── Effect.js │ ├── EnabR.js │ ├── Eval.js │ ├── Lua.js │ ├── PSA.js │ ├── Reminder.js │ ├── Set.js │ └── Username.js ├── public │ ├── AutoPlaylist.js │ ├── AutoRoles.js │ ├── Channels.js │ ├── CloseTicket.js │ ├── Commands.js │ ├── Decrypt.js │ ├── Define.js │ ├── Encrypt.js │ ├── GetTickets.js │ ├── GuildInfo.js │ ├── Image.js │ ├── Info.js │ ├── JTranslate.js │ ├── NewDiscord.js │ ├── NowPlaying.js │ ├── Offenses.js │ ├── Ping.js │ ├── PingPong.js │ ├── Play.js │ ├── PlayAuto.js │ ├── Pop.js │ ├── Power.js │ ├── Queue.js │ ├── Roles.js │ ├── StartAuto.js │ ├── StartQueue.js │ ├── Syntax.js │ ├── Text.js │ ├── Ticket.js │ ├── Toggle.js │ ├── Translate.js │ ├── UpdateOwner.js │ └── VoteSkip.js └── staff │ ├── ChangeMute.js │ ├── Clear.js │ ├── ClearQueue.js │ ├── GetBans.js │ ├── HardKick.js │ ├── History.js │ ├── Join.js │ ├── Kick.js │ ├── Leave.js │ ├── Mute.js │ ├── Mutes.js │ ├── Nickname.js │ ├── PlayF.js │ ├── RaidMode.js │ ├── RemQueue.js │ ├── Skip.js │ ├── Stop.js │ ├── TempBan.js │ ├── TempBans.js │ ├── UnBan.js │ ├── UnMute.js │ ├── UnRaidMode.js │ ├── UndoMute.js │ └── UserMutes.js ├── core ├── ManageAdmin.js ├── ManageCommands.js ├── ManageData.js ├── ManageEvents.js ├── ManageMusic.js ├── ManageMusic2.js ├── ManageMutesNew.js └── ManageTrello.js ├── disabled └── Warn.js ├── index.js ├── package-lock.json ├── package.json └── resources ├── images ├── CrabRaveGif.gif └── avatar.png └── music ├── 1-800-273-8255.mp3 ├── AfricAryaN.mp3 ├── America.mp3 ├── Anziety.mp3 ├── Black SpiderMan.mp3 ├── Confess.mp3 ├── Everybody.mp3 ├── Hallelujah.mp3 ├── Ink Blot.mp3 ├── Killing Spree.mp3 ├── Mos Definitely.mp3 ├── Take It Back.mp3 └── Waiting Room.mp3 /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "node": true 4 | }, 5 | "extends": "airbnb", 6 | "globals": { 7 | "index": true, 8 | "has": true, 9 | "selfId": true, 10 | "vaebId": true, 11 | "botDir": true, 12 | "Util": true, 13 | "Data": true, 14 | "Trello": true, 15 | "Admin": true, 16 | "Music": true, 17 | "Music2": true, 18 | "Cmds": true, 19 | "Events": true, 20 | "Discord": true, 21 | "client": true, 22 | "colAction": true, 23 | "colUser": true, 24 | "colMessage": true, 25 | "colCommand": true, 26 | "colGreen": true, 27 | "colBlue": true, 28 | "cmd": true, "args": true, "msgObj": true, "speaker": true, "channel": true, "guild": true 29 | }, 30 | "rules": { 31 | "default-case": "off", 32 | "eqeqeq": "off", 33 | "import/no-dynamic-require": "off", 34 | "indent": ["error", 4], 35 | "func-names": "off", 36 | "global-require": "off", 37 | "jsx-a11y/href-no-hash": "off", 38 | "max-len": "off", 39 | "no-bitwise": "off", 40 | "no-cond-assign": "off", 41 | "no-console": "off", 42 | "no-continue": "off", 43 | "no-control-regex": "off", 44 | "no-eval": "off", 45 | "no-irregular-whitespace": "off", 46 | "no-lonely-if": "off", 47 | "no-mixed-operators": "off", 48 | "no-multi-spaces": ["error", {"ignoreEOLComments": true}], 49 | "no-param-reassign": "off", 50 | "no-plusplus": "off", 51 | "no-restricted-syntax": "off", 52 | "no-underscore-dangle": "off", 53 | "quote-props": "off" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Packages 2 | node_modules/ 3 | yarn.lock 4 | 5 | # Log files 6 | *.log 7 | 8 | # Data Storage 9 | data/autoroles.json 10 | data/history.json 11 | data/mutes.json 12 | data/playlist.json 13 | 14 | # Testing 15 | Auth.js 16 | Test.js 17 | 18 | # ========================= 19 | # Everything below is .gitignore template 20 | # ========================= 21 | 22 | # Miscellaneous 23 | .tmp/ 24 | .vscode/ 25 | 26 | # Windows image file caches 27 | Thumbs.db 28 | ehthumbs.db 29 | 30 | # Folder config file 31 | Desktop.ini 32 | 33 | # Recycle Bin used on file shares 34 | $RECYCLE.BIN/ 35 | 36 | # Windows Installer files 37 | *.cab 38 | *.msi 39 | *.msm 40 | *.msp 41 | 42 | # Windows shortcuts 43 | *.lnk 44 | 45 | # ========================= 46 | # Operating System Files 47 | # ========================= 48 | 49 | # OSX 50 | # ========================= 51 | 52 | .DS_Store 53 | .AppleDouble 54 | .LSOverride 55 | 56 | # Thumbnails 57 | ._* 58 | 59 | # Files that might appear in the root of a volume 60 | .DocumentRevisions-V100 61 | .fseventsd 62 | .Spotlight-V100 63 | .TemporaryItems 64 | .Trashes 65 | .VolumeIcon.icns 66 | 67 | # Directories potentially created on remote AFP share 68 | .AppleDB 69 | .AppleDesktop 70 | Network Trash Folder 71 | Temporary Items 72 | .apdisk 73 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Adam 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VaeBot - A Multi-Purpose Discord Bot 2 | 3 | ## Includes 4 | - Full warn/mute based moderation system 5 | - Powerful anti-raid and anti-spam system 6 | - Hierarchy-based permission reasoning 7 | - Complete music system 8 | - A huge array of commands 9 | 10 | ## Staff-Only Commands 11 | ​ 12 | **;actions** OR **;guild** actions OR **;all** actions - Output all actions that can be used in **;link** 13 | 14 | **;addauto** OR **;adda** OR **;addtoauto** - Adds a song to the music auto-playlist 15 | 16 | **;addrole** - Add a role to a user 17 | 18 | **;alert** OR **;dm** OR **;announce** - Sends a DM to everyone in the guild with a certain role 19 | 20 | **;allinfo** - Get guild, role, channel and permission info in one huge set of messages 21 | 22 | **;ban** OR **;banhammer** OR **;permaban** - Ban a user from the guild 23 | 24 | **;bans** OR **;getbans** - Get all banned users 25 | 26 | **;calm** OR **;calmchat** OR **;slow** OR **;slowchat** - Slows down chat speed 27 | 28 | **;changemute** OR **;change** OR **;setmute** OR altermute - Change details of an active mute 29 | 30 | **;clear** OR **;clean** OR **;wipe** OR **;clearchats** OR **;cleanchats** - Delete the last <1-1000> messages matching a [user | regex-pattern | message-type] in the channel 31 | 32 | **;clearqueue** - Clears VaeBot's queue of music 33 | 34 | **;events** OR **;guild** events OR **;all** events - Output all events that can be used in **;link** 35 | 36 | **;getlinks** OR **;links** OR **;triggers** - Output all created links 37 | 38 | **;hardkick** OR **;hardeject** OR **;softban** - Kick a user from the guild (extra hard) 39 | 40 | **;history** OR **;mutehistory** - Get all users with mute history 41 | 42 | **;join** OR **;summon** - Make VaeBot join a voice channel 43 | 44 | **;kick** OR **;eject** - Kick a user from the guild 45 | 46 | **;leave** OR **;exit** - Make VaeBot leave it's voice channel 47 | 48 | **;link** OR **;addlink** OR **;trigger** OR **;event** - Link an event to an action 49 | 50 | **;mute** OR **;mutehammer** - Mute a user (in all guild channels) and add the mute to their record 51 | 52 | **;mutes** OR **;usermutes** OR **;history** OR **;userhistory** - Get the mute history of a user 53 | 54 | **;mutes** OR **;muted** - Get all currently muted users 55 | 56 | **;nick** OR **;nickname** - Set a user's nickname 57 | 58 | **;playf** - Make VaeBot play some bangin' tunes... from a file :o 59 | 60 | **;remauto** OR **;rema** - Remove a song from the music auto-playlist 61 | 62 | **;remautorole** OR **;delautorole** OR aroledel - Remove an autorole 63 | 64 | **;remqueue** OR **;remq** - Remove a song from the music queue 65 | 66 | **;remrole** OR **;removerole** OR **;delrole** - Remove a role from a user 67 | 68 | **;setautorole** OR **;addautorole** OR **;arole** - Set a new autorole 69 | 70 | **;skip** - Skip to the next song 71 | 72 | **;stop** OR **;silence** - Cancel the party, the bangin' tunes can wait for another day 73 | 74 | **;switch** - Specific command 75 | 76 | **;tempban** OR **;tban** OR **;temporaryban** OR **;timeban** OR **;bantime** - Temporarily ban a user from the guild 77 | 78 | **;tempbans** OR **;tbans** OR **;timebans** OR **;timedbans** - Get all temporarily banned users 79 | 80 | **;unban** OR **;remban** - Unban a user from the guild 81 | 82 | **;uncalm** OR **;uncalmchat** OR **;unslow** OR **;unslowchat** - Removes chat slowdown 83 | 84 | **;undomute** OR **;popmute** - Remove a user's last mute from their record and unmute them if they are muted 85 | 86 | **;unlink** OR **;remlink** OR **;dellink** OR **;untrigger** OR **;unevent** - UnLink an event from an action 87 | 88 | **;unmute** OR **;unwarn** OR **;unmutehammer** - Unmute a user 89 | 90 | **;warn** OR **;warnhammer** - Warns a user and puts the warning on their record 91 | 92 | 93 | ## Public Commands 94 | ​ 95 | **;autoplaylist** OR **;ap** - Output all the bangin' tunes in the auto-playlist 96 | 97 | **;autoroles** - Get all autoroles (roles which users are allowed to assign to themselves) 98 | 99 | **;channels** - Get all guild channels 100 | 101 | **;closeticket** OR **;closesupport** OR **;stopticket** OR **;endticket** OR **;close** - Create a ticket to be viewed by Support 102 | 103 | **;cmds** OR **;commands** OR **;help** - Output all commands 104 | 105 | **;decrypt** - Decrypt text using One Time Pad 106 | 107 | **;define** OR **;urban** - Output the definition for a word/phrase using Urban Dictionary 108 | 109 | **;encrypt** - Encrypt text using One Time Pad 110 | 111 | **;ginfo** OR **;guildinfo** - Get guild info 112 | 113 | **;img** OR **;image** - Output an image for a word/phrase using Google 114 | 115 | **;info** - Get info about a user 116 | 117 | **;nowplaying** OR **;np** - Get info about the currently playing song 118 | 119 | **;offenses** OR **;badoffenses** OR **;listoffenses** OR **;rules** - Output the list of offenses with defined mute times 120 | 121 | **;ping** - Pings a user 122 | 123 | **;play** OR **;add** OR **;addqueue** - Make VaeBot play some bangin' tunes (or add them to the queue if the party's already started) 124 | 125 | **;playauto** OR **;playa** - Plays a tune already stored in the auto-playlist 126 | 127 | **;power** OR **;rank** OR **;rate** - Are you over 9000?! 128 | 129 | **;queue** - List all queued songs 130 | 131 | **;roles** - Get all guild roles 132 | 133 | **;startauto** OR **;startap** - Start playing the auto-playlist music 134 | 135 | **;startqueue** - Start playing the queued music 136 | 137 | **;syntax** OR **;help** OR **;cmd** - Display command information 138 | 139 | **;ticket** OR **;support** OR **;ask** OR **;addticket** OR **;submitticket** OR **;sendticket** OR **;newticket** - Create a ticket to be viewed by Support 140 | 141 | **;tickets** OR **;gettickets** OR **;showtickets** OR **;activetickets** OR **;displaytickets** OR **;supporttickets** - Display all open support tickets 142 | 143 | **;toggle** - Toggle an autorole on the speaker 144 | 145 | **;translate** - Translate a word/sentence into English 146 | 147 | **;txt** OR **;text** OR **;type** - Echo your text with emojis 148 | 149 | **;undo** OR **;pop** - Remove the last song from the queue which was added by the speaker 150 | 151 | **;voteskip** - Vote to skip the current song (will skip when the vote reaches 50% of the users in the voice channel) 152 | -------------------------------------------------------------------------------- /commands/administrator/Actions.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';actions', ';guild actions', ';all actions'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Output all actions that can be used in ;link', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel) => { 18 | const sendEmbedFields = []; 19 | 20 | for (const actionName in Events.Actions) { 21 | if (!has.call(Events.Actions, actionName)) continue; 22 | 23 | sendEmbedFields.push({ name: actionName, value: '​', inline: false }); 24 | } 25 | 26 | Util.sendEmbed(channel, 'Actions', 'All actions which can be used in ;link\n​', Util.makeEmbedFooter(speaker), null, colGreen, sendEmbedFields); 27 | }, 28 | }); 29 | -------------------------------------------------------------------------------- /commands/administrator/AddAction.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';addaction ', ';linkaction ', ';createaction ', ';action '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Creates an action to be used in ;link', 10 | 11 | args: '', 12 | 13 | example: 'EchoMessage (guild, eventName, actionArgs, eventArgs) => { Util.print(channel, ...eventArgs[3]) };', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel) => { 18 | const spaceIndex = args.indexOf(' '); 19 | if (spaceIndex == -1) return Util.commandFailed(channel, speaker, 'Invalid parameters'); 20 | 21 | const actionName = args.substring(0, spaceIndex); 22 | const actionFuncStr = args.substring(spaceIndex + 1); 23 | 24 | const evalStr = `Events.Actions.${actionName} = ${actionFuncStr}`; 25 | 26 | Util.log(evalStr); 27 | 28 | eval(evalStr); 29 | 30 | Util.sendDescEmbed(channel, 'Added Action', `Added action ${actionName} for linking`, Util.makeEmbedFooter(speaker), null, colGreen); 31 | 32 | return true; 33 | }, 34 | }); 35 | -------------------------------------------------------------------------------- /commands/administrator/AddAuto.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';addauto ', ';adda ', ';addtoauto '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Adds a song to the music auto-playlist', 10 | 11 | args: '[song_name]', 12 | 13 | example: 'gonna give you up', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | // if (args.includes('http')) { 19 | // let songId = /[^/=]+$/.exec(args); 20 | // if (songId != null && songId[0]) { 21 | // songId = songId[0]; 22 | // index.YtInfo.getById(songId, (error, result) => { 23 | // const songData = result.items[0]; 24 | // if (songData != null) { 25 | // let autoPlaylist = Data.guildGet(guild, Data.playlist, 'songs'); 26 | // if (autoPlaylist == null) { 27 | // autoPlaylist = []; 28 | // Data.guildSet(guild, Data.playlist, 'songNum', 0); 29 | // Data.guildSet(guild, Data.playlist, 'songs', autoPlaylist); 30 | // } 31 | // autoPlaylist.push([songData, speaker]); 32 | // Data.guildSaveData(Data.playlist); 33 | // Util.sendDescEmbed(channel, `[${autoPlaylist.length}] Auto-Playlist Appended`, songData.snippet.title, Util.makeEmbedFooter(speaker), null, colGreen); 34 | // } else { 35 | // Util.print(channel, 'Audio not found'); 36 | // } 37 | // }); 38 | // } else { 39 | // Util.print(channel, 'Incorrect format for URL'); 40 | // } 41 | // } else { 42 | // index.YtInfo.search(args, 6, (error, result) => { 43 | // if (error) { 44 | // Util.print(channel, error); 45 | // } else { 46 | // const items = result.items; 47 | // let hasFound = false; 48 | // for (let i = 0; i < items.length; i++) { 49 | // const songData = items[i]; 50 | // if (songData != null && has.call(songData, 'id') && songData.id.kind == 'youtube#video') { 51 | // hasFound = true; 52 | // let autoPlaylist = Data.guildGet(guild, Data.playlist, 'songs'); 53 | // if (autoPlaylist == null) { 54 | // autoPlaylist = []; 55 | // Data.guildSet(guild, Data.playlist, 'songNum', 0); 56 | // Data.guildSet(guild, Data.playlist, 'songs', autoPlaylist); 57 | // } 58 | // autoPlaylist.push([songData, speaker]); 59 | // Data.guildSaveData(Data.playlist); 60 | // Util.sendDescEmbed(channel, `[${autoPlaylist.length}] Auto-Playlist Appended`, songData.snippet.title, Util.makeEmbedFooter(speaker), null, colGreen); 61 | // break; 62 | // } 63 | // } 64 | // if (!hasFound) { 65 | // Util.print(channel, 'Audio not found'); 66 | // } 67 | // } 68 | // }); 69 | // } 70 | // // Data.guildSet(guild, playlist, args); 71 | }, 72 | }); 73 | -------------------------------------------------------------------------------- /commands/administrator/AddAutoRole.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";setautorole ", ";addautorole ", ";arole "], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Set a new autorole", 10 | 11 | args: "([role_name]) ([auto_role_name])", 12 | 13 | example: "for-hire hire", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var data = Util.getDataFromString(args, [ 19 | function(str, results) { 20 | return Util.getRole(str, guild); 21 | }, 22 | ], true); 23 | if (!data) return Util.commandFailed(channel, speaker, "Role not found"); 24 | var role = data[0]; 25 | var name = data[1].toLowerCase(); 26 | if (Util.getPosition(speaker) <= role.position) { 27 | Util.commandFailed(channel, speaker, "Role has equal or higher rank"); 28 | return; 29 | } 30 | Data.guildSet(guild, Data.autoRoles, name, role.name); 31 | Util.print(channel, "Added the autorole", Util.fix(name), "for the", role.name, "role"); 32 | } 33 | }); -------------------------------------------------------------------------------- /commands/administrator/AddRole.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';addrole '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Add a role to a user', 10 | 11 | args: '([@user] | [id] | [name]) ([role_name])', 12 | 13 | example: 'vae mod', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const data = Util.getDataFromString( 19 | args, 20 | [ 21 | function (str) { 22 | return Util.getMemberByMixed(str, guild); 23 | }, 24 | function (str) { 25 | return Util.getRole(str, guild); 26 | }, 27 | ], 28 | false, 29 | ); 30 | 31 | if (!data) return Util.commandFailed(channel, speaker, 'Invalid parameters'); 32 | 33 | const user = data[0]; 34 | const role = data[1]; 35 | 36 | if (role.name == 'Vashta-Owner' && !Util.isAdmin(speaker)) { 37 | return Util.commandFailed(channel, speaker, 'You are not allowed to add this role'); 38 | } 39 | 40 | if (speaker != user && Util.getPosition(speaker) <= Util.getPosition(user)) { 41 | Util.commandFailed(channel, speaker, 'User has equal or higher rank'); 42 | return false; 43 | } 44 | 45 | if (Util.getPosition(speaker) <= role.position) { 46 | Util.commandFailed(channel, speaker, 'Role has equal or higher rank'); 47 | return false; 48 | } 49 | user.addRole(role).catch(console.error); 50 | 51 | const sendEmbedFields = [ 52 | { name: 'Username', value: Util.getMention(user) }, 53 | // {name: "Moderator", value: Util.getMention(speaker)}, 54 | { name: 'Role Name', value: role.name }, 55 | ]; 56 | Util.sendEmbed( 57 | channel, // Channel Object 58 | 'Assigned Role', // Title String 59 | null, // Description String 60 | Util.makeEmbedFooter(speaker), // Username + ID String 61 | Util.getAvatar(user), // Avatar URL String 62 | colGreen, // Color Number 63 | sendEmbedFields, 64 | ); 65 | 66 | return true; 67 | }, 68 | }); 69 | -------------------------------------------------------------------------------- /commands/administrator/Alert.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';alert ', ';dm ', ';announce '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Sends a DM to everyone in the guild with a certain role', 10 | 11 | args: '([@role] | [id] | [name]) ([message])', 12 | 13 | example: 'subscribers new update today', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | if (speaker.id !== guild.ownerID && speaker.id !== vaebId) return Util.commandFailed(channel, speaker, 'Command is owner-only'); 19 | 20 | const data = Util.getDataFromString(args, [ 21 | function (strOld) { 22 | let str = strOld; 23 | if (str[0] === '@') str = str.substring(1); 24 | return Util.getRole(str, guild); 25 | }, 26 | function (str) { 27 | return str; 28 | }, 29 | ], false); 30 | 31 | if (!data) return Util.commandFailed(channel, speaker, 'Invalid parameters'); 32 | 33 | const role = data[0]; 34 | const message = data[1]; 35 | 36 | const title = `Alert | ${Util.getMostName(speaker)} | ${guild.name}`; 37 | const footer = Util.makeEmbedFooter(speaker); 38 | 39 | guild.members.forEach((member) => { 40 | if (!Util.hasRole(member, role) || member.id === selfId) return; 41 | Util.log(`Sent DM to ${Util.getFullName(member)}`); 42 | Util.sendDescEmbed(member, title, message, footer, null, colBlue); 43 | }); 44 | 45 | return undefined; 46 | }, 47 | }); 48 | -------------------------------------------------------------------------------- /commands/administrator/AllInfo.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';allinfo'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Get guild, role, channel and permission info in one huge set of messages', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const outStr = ['**Guild Info**\n```']; 19 | outStr.push(`Name: ${guild.name}`); 20 | outStr.push(`ID: ${guild.id}`); 21 | outStr.push(`Owner: ${Util.getName(guild.owner)} (${guild.ownerID})`); 22 | outStr.push(`Icon: ${guild.iconURL}`); 23 | outStr.push(`AFK timeout: ${guild.afkTimeout} seconds`); 24 | outStr.push(`Region: ${guild.region}`); 25 | outStr.push(`Member count: ${guild.memberCount}`); 26 | outStr.push(`Created: ${guild.createdAt}`); 27 | outStr.push(`Main channel: #${guild.defaultChannel.name}`); 28 | outStr.push(`Emojis: ${guild.emojis.size > 0 ? JSON.stringify(guild.emojis.array()) : 'null'}`); 29 | outStr.push('```'); 30 | outStr.push('**Guild Text Channels**\n```'); 31 | Util.getTextChannels(guild).forEach((value) => { 32 | outStr.push( 33 | `Channel: ${value.name} (${value.id}) | Topic: ${value.topic} | Position: ${value.position} | Created: ${value.createdAt}`, 34 | ); 35 | }); 36 | outStr.push('```'); 37 | outStr.push('**Guild Voice Channels**\n```'); 38 | Util.getVoiceChannels(guild).forEach((value) => { 39 | outStr.push( 40 | `Channel: ${value.name} (${value.id}) | Topic: ${value.topic} | Position: ${value.position} | Created: ${ 41 | value.createdAt 42 | } | Bitrate: ${value.bitrate}`, 43 | ); 44 | }); 45 | outStr.push('```'); 46 | outStr.push('**Guild Roles**\n```'); 47 | guild.roles.forEach((value) => { 48 | outStr.push( 49 | `Role: ${value.name} (${value.id}) | Position: ${value.position} | Mentionable: ${value.mentionable} | Color: ${ 50 | value.color 51 | }`, 52 | ); 53 | }); 54 | outStr.push('```'); 55 | outStr.push('**Guild Permissions**\n```'); 56 | guild.roles.forEach((value) => { 57 | outStr.push(`Role: ${value.name} (${value.id})`); 58 | outStr.push(JSON.stringify(Util.getRolePermissions(value))); 59 | outStr.push(''); 60 | }); 61 | outStr.push(''); 62 | outStr.push('-END-'); 63 | outStr.push('```'); 64 | Util.print(channel, outStr.join('\n')); 65 | }, 66 | }); 67 | -------------------------------------------------------------------------------- /commands/administrator/Ban.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';ban ', ';banhammer ', ';permaban '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Ban a user from the guild', 10 | 11 | args: '([user_resolvable) (OPTIONAL: [reason])', 12 | 13 | example: 'vaeb being weird', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | args = args.trim(); 19 | 20 | // const highestRoleLower = speaker.highestRole.name.toLowerCase(); 21 | // if (!highestRoleLower.includes('head ') && /\bmod/g.test(highestRoleLower)) return Util.commandFailed(channel, speaker, 'Moderators are not allowed to use the ban command | Please use tempban instead'); 22 | 23 | const data = Util.getDataFromString( 24 | args, 25 | [ 26 | function (str) { 27 | return Util.getMemberByMixed(str, guild) || Util.isId(str); 28 | }, 29 | ], 30 | true, 31 | ); 32 | if (!data) return Util.commandFailed(channel, speaker, 'User not found'); 33 | 34 | const target = data[0]; 35 | const reason = data[1]; 36 | 37 | Admin.addBan(guild, channel, target, speaker, { reason }); 38 | 39 | // if (guild.id == '168742643021512705') index.dailyBans.push([targId, `${targName}#${target.discriminator}`, reason]); 40 | 41 | return true; 42 | }, 43 | }); 44 | -------------------------------------------------------------------------------- /commands/administrator/Calm.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';calm', ';calmchat', ';slow', ';slowchat'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Slows down chat speed', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | /* func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | if (speaker.id != guild.ownerID && speaker.id != vaebId) return Util.commandFailed(channel, speaker, "Command is owner-only"); 19 | 20 | if (index.slowChat[guild.id]) return; 21 | 22 | var chatQueue = []; 23 | 24 | index.chatQueue[guild.id] = chatQueue; 25 | 26 | index.slowInterval[guild.id] = setInterval(function() { 27 | if (chatQueue.length < 1) return; 28 | 29 | var msgObj = (chatQueue.splice(0, 1))[0]; 30 | 31 | var msgChannel = msgObj.channel; 32 | var msgGuild = msgObj.guild; 33 | var msgSpeaker = msgObj.member; 34 | var msgContent = msgObj.content; 35 | var msgCreatedAt = msgObj.createdAt; 36 | 37 | // Util.sendEmbed(msgChannel, Util.getMostName(msgSpeaker), msgContent, Util.makeEmbedFooter(msgSpeaker, msgCreatedAt), null, colGreen, null); 38 | msgChannel.send(Util.getMostName(msgSpeaker) + ": " + msgContent).catch(console.error); 39 | }, index.calmSpeed); 40 | 41 | index.slowChat[guild.id] = true; 42 | } */ 43 | 44 | func: (cmd, args, msgObj, speaker, channel, guild) => { 45 | // if (speaker.id != guild.ownerID && speaker.id != vaebId) return Util.commandFailed(channel, speaker, 'Command is owner-only'); 46 | 47 | if (index.slowChat[guild.id]) return Util.log('Slow is already active'); 48 | 49 | index.chatNext[guild.id] = +new Date() + index.calmSpeed; 50 | 51 | index.slowChat[guild.id] = true; 52 | 53 | return undefined; 54 | }, 55 | }); 56 | -------------------------------------------------------------------------------- /commands/administrator/CheckPerms.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";perms ", ";checkperms ", ";getperms "], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Get guild and channel permissions for a user", 10 | 11 | args: "([@user] | [id] | [name]) ([reason])", 12 | 13 | example: "vae", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var member = Util.getMemberByMixed(args, guild); 19 | if (member == null) { 20 | Util.commandFailed(channel, speaker, "User not found"); 21 | return; 22 | } 23 | var guildPerms = member.permissions.serialize(); 24 | var channelPerms = member.permissionsIn(channel).serialize(); 25 | 26 | var guildValue = []; 27 | var channelValue = []; 28 | 29 | for (let permName in guildPerms) { 30 | if (!guildPerms.hasOwnProperty(permName)) continue; 31 | let hasPerm = guildPerms[permName]; 32 | if (!hasPerm) continue; 33 | guildValue.push(permName); 34 | } 35 | 36 | for (let permName in channelPerms) { 37 | if (!channelPerms.hasOwnProperty(permName)) continue; 38 | let hasPerm = channelPerms[permName]; 39 | if (!hasPerm) continue; 40 | channelValue.push(permName); 41 | } 42 | 43 | Util.sortPerms(guildValue); 44 | Util.sortPerms(channelValue); 45 | 46 | var sendEmbedFields = [ 47 | {name: "Guild Permissions", value: "​\n" + guildValue.join("\n\n"), inline: false}, 48 | {name: "Channel Permissions", value: "​\n" + channelValue.join("\n\n"), inline: false} 49 | ]; 50 | 51 | Util.sendEmbed(channel, Util.capitalize2(member.displayName + "'s Permissions"), null, Util.makeEmbedFooter(speaker), null, colBlue, sendEmbedFields); 52 | } 53 | }); -------------------------------------------------------------------------------- /commands/administrator/ClearMutes.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';clearmutes ', ';cleanslate ', ';clearhistory '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: "Clear a user's mute history and unmute them if they are muted", 10 | 11 | args: '([@user] | [id] | [name])', 12 | 13 | example: 'vae', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | args = args.trim(); 19 | 20 | Admin.clearMutes(guild, channel, args, speaker); 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /commands/administrator/Events.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";events", ";guild events", ";all events"], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Output all events that can be used in ;link", 10 | 11 | args: "", 12 | 13 | example: "", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var sendEmbedFields = []; 19 | 20 | sendEmbedFields.push({name: "MessageCreate", value: "​", inline: false}); 21 | sendEmbedFields.push({name: "MessageDelete", value: "​", inline: false}); 22 | sendEmbedFields.push({name: "UserJoin", value: "​", inline: false}); 23 | sendEmbedFields.push({name: "UserLeave", value: "​", inline: false}); 24 | sendEmbedFields.push({name: "UserMute", value: "​", inline: false}); 25 | sendEmbedFields.push({name: "UserUnMute", value: "​", inline: false}); 26 | sendEmbedFields.push({name: "UserUnMute", value: "​", inline: false}); 27 | sendEmbedFields.push({name: "UserRoleAdd", value: "​", inline: false}); 28 | sendEmbedFields.push({name: "UserRoleRemove", value: "​", inline: false}); 29 | sendEmbedFields.push({name: "UserNicknameUpdate", value: "​", inline: false}); 30 | 31 | Util.sendEmbed(channel, "Events", "All events which can be used in ;link\n​", Util.makeEmbedFooter(speaker), null, colGreen, sendEmbedFields); 32 | } 33 | }); -------------------------------------------------------------------------------- /commands/administrator/Fire.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';fire '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Set fire to the server', 10 | 11 | args: '(on | off)', 12 | 13 | example: 'on', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | if (!args || !/on|true|off|false/i.test(args)) return; 19 | 20 | const isOn = /on|true/i.test(args); 21 | 22 | if (isOn) { 23 | guild.channels.forEach((c) => { 24 | if (!c.name.endsWith('🔥')) c.setName(`${c.name}🔥`); 25 | }); 26 | } else { 27 | guild.channels.forEach((c) => { 28 | if (c.name.endsWith('🔥')) c.setName(c.name.substr(0, c.name.length - 1)); 29 | }); 30 | } 31 | }, 32 | }); 33 | -------------------------------------------------------------------------------- /commands/administrator/FixRoles.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';fix roles'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Fix new role permissions', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const defRole = Util.getRole('@everyone', guild); 19 | const sendRole = Util.getRole('SendMessages', guild); 20 | const guildRoles = guild.roles; 21 | const defNew = {}; 22 | const sendNew = {}; 23 | 24 | // const newRolePerms = [ 25 | // 'CHANGE_NICKNAME', 26 | // 'EMBED_LINKS', 27 | // 'SEND_MESSAGES', 28 | // 'VIEW_CHANNEL', 29 | // 'READ_MESSAGE_HISTORY', 30 | // 'ADD_REACTIONS', 31 | // 'USE_EXTERNAL_EMOJIS', 32 | // 'CONNECT', 33 | // 'SPEAK', 34 | // 'USE_VAD', 35 | // ]; 36 | 37 | const newRolePerms = ['CHANGE_NICKNAME', 'SEND_MESSAGES', 'VIEW_CHANNEL', 'READ_MESSAGE_HISTORY', 'CONNECT', 'SPEAK', 'USE_VAD']; 38 | 39 | const newRolePermsObj = Util.arrayToObj(newRolePerms); 40 | 41 | sendRole.setPermissions(newRolePerms).catch(error => Util.log(`[E_FixRoles1] ${error}`)); 42 | 43 | guildRoles.forEach((role) => { 44 | if (role.id == sendRole.id) return; 45 | const newPerms = []; 46 | const rolePerms = role.serialize(); 47 | for (const permName in rolePerms) { 48 | if (!rolePerms.hasOwnProperty(permName)) continue; 49 | if (!newRolePermsObj.hasOwnProperty(permName) && rolePerms[permName] == true) { 50 | newPerms.push(permName); 51 | } 52 | } 53 | role.setPermissions(newPerms).catch(error => Util.log(`[E_FixRoles2] ${error}`)); 54 | }); 55 | 56 | /* var textChannels = Util.getTextChannels(guild); 57 | for (var i = 0; i < textChannels.length; i++) { 58 | var channel = textChannels[i]; 59 | Util.setChannelPerms(channel, defRole, defNew); 60 | Util.setChannelPerms(channel, sendRole, sendNew); 61 | } */ 62 | }, 63 | }); 64 | -------------------------------------------------------------------------------- /commands/administrator/GetLinks.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | [ 4 | [ 5 | eventName, 6 | [actionName, [actionArgs]], 7 | [actionName, [actionArgs]], 8 | [actionName, [actionArgs]] 9 | ], 10 | [ 11 | eventName, 12 | [actionName, [actionArgs]], 13 | [actionName, [actionArgs]], 14 | [actionName, [actionArgs]] 15 | ] 16 | ] 17 | 18 | */ 19 | 20 | module.exports = Cmds.addCommand({ 21 | cmds: [";getlinks", ";links", ";triggers"], 22 | 23 | requires: { 24 | guild: true, 25 | loud: false 26 | }, 27 | 28 | desc: "Output all created links", 29 | 30 | args: "", 31 | 32 | example: "", 33 | 34 | /////////////////////////////////////////////////////////////////////////////////////////// 35 | 36 | func: (cmd, args, msgObj, speaker, channel, guild) => { 37 | var guildEvents = Events.getEvents(guild); 38 | 39 | var sendEmbedFields = []; 40 | 41 | for (let i = 0; i < guildEvents.length; i++) { 42 | let eventData = guildEvents[i]; 43 | 44 | let eventName = eventData[0]; 45 | 46 | let actionStr = []; 47 | 48 | for (let j = 1; j < eventData.length; j++) { 49 | let actionData = eventData[j]; 50 | 51 | let actionName = actionData[0]; 52 | let actionArgs = actionData[1]; 53 | 54 | actionStr.push(actionName + " " + actionArgs.join(" ")); 55 | } 56 | 57 | sendEmbedFields.push({name: eventName, value: actionStr.join("\n"), inline: false}); 58 | } 59 | 60 | Util.sendEmbed(channel, "Guild Links", null, Util.makeEmbedFooter(speaker), null, colGreen, sendEmbedFields); 61 | } 62 | }); -------------------------------------------------------------------------------- /commands/administrator/HasPerm.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";haspermission ", ";has permission ", ";hasperm ", ";has perm "], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Checks guild member for permission", 10 | 11 | args: "([@user] | [id] | [name]) ([perm_name])", 12 | 13 | example: "vaeb audit log", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var data = Util.getDataFromString(args, [ 19 | function(str, results) { 20 | return Util.getMemberByMixed(str, guild); 21 | }, 22 | function(str, results) { 23 | return Util.strToPerm(str); 24 | } 25 | ], false); 26 | if (!data) return Util.commandFailed(channel, speaker, "Invalid parameters"); 27 | 28 | var member = data[0]; 29 | var permName = data[1]; 30 | 31 | var hasPermGuild = member.hasPermission(permName, undefined, true, true); 32 | var hasPermChannel = member.permissionsIn(channel).has(permName, true); 33 | 34 | var sendEmbedFields = [ 35 | {name: "Guild", value: Util.boolToAns(hasPermGuild), inline: false} 36 | ]; 37 | 38 | if (Util.textChannelPermissionsObj.hasOwnProperty(permName)) { 39 | sendEmbedFields.push({name: "Channel", value: Util.boolToAns(hasPermChannel), inline: false}); 40 | } 41 | 42 | Util.sendEmbed(channel, Util.capitalize2("Does " + member.displayName + " Have [" + permName + "] ?"), null, Util.makeEmbedFooter(speaker), null, colBlue, sendEmbedFields); 43 | } 44 | }); -------------------------------------------------------------------------------- /commands/administrator/InitRoles.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';setup', ';init roles', ';initroles'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Assign all SendMessages roles', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: async (cmd, args, msgObj, speaker, channel, guild) => { 18 | let sendRole = Util.getRole('SendMessages', guild); 19 | 20 | if (sendRole != null) { 21 | Util.initRoles(sendRole, guild, channel); 22 | return; 23 | } 24 | 25 | const newRolePerms = ['CHANGE_NICKNAME', 'SEND_MESSAGES', 'VIEW_CHANNEL', 'READ_MESSAGE_HISTORY', 'CONNECT', 'SPEAK', 'USE_VAD']; 26 | 27 | try { 28 | sendRole = await guild.createRole({ 29 | name: 'SendMessages', 30 | hoist: false, 31 | position: 1, 32 | permissions: newRolePerms, 33 | mentionable: false, 34 | }); 35 | 36 | Util.initRoles(sendRole, guild, channel); 37 | } catch (err) { 38 | console.log('InitRolesCmd Error:', err); 39 | } 40 | }, 41 | }); 42 | -------------------------------------------------------------------------------- /commands/administrator/Link.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';link ', ';addlink', ';trigger ', ';event '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Link an event to an action', 10 | 11 | args: '({ [event_name_1] ... [event_name_n] }) ({ [action_1_name] [action_1_param_1] ... [action_1_param_o] }) ... ({ [action_p_name] [action_p_param_1] ... [action_p_param_q] })', 12 | // args: "([event_name_1] ... [event_name_n]) (-[action_1_name] [action_1_param_1] ... [action_param_n]) ... (-[action_n_name] [action_n_param_1] ... [action_n_param_o])", 13 | 14 | example: '{ UserJoin UserUnMute } { AddRole SendMessages RandomRole } { DM CmdInfo }', 15 | // example: "UserJoin UserUnMute -AddRole SendMessages RandomRole -DM CmdInfo", 16 | 17 | // ///////////////////////////////////////////////////////////////////////////////////////// 18 | 19 | func: (cmd, args, msgObj, speaker, channel, guild) => { 20 | let event = null; 21 | const actions = []; 22 | 23 | let numOpen = 0; 24 | let lastOpen = 0; 25 | 26 | for (let i = 0; i < args.length; i++) { 27 | const char = args[i]; 28 | 29 | if (char == '{') { 30 | if (numOpen == 0) { 31 | lastOpen = i; 32 | } 33 | 34 | numOpen++; 35 | } else if (char == '}') { 36 | numOpen--; 37 | 38 | if (numOpen == 0) { 39 | const paramStr = args.substring(lastOpen + 1, i); 40 | 41 | if (event == null) { 42 | event = paramStr.trim().split(' '); 43 | } else { 44 | actions.push(paramStr.trim().split(' ')); 45 | } 46 | } 47 | } 48 | } 49 | 50 | if (event == null || event.length == 0) { 51 | return Util.commandFailed(channel, speaker, 'Invalid parameters: Event not provided'); 52 | } else if (actions.length == 0) { 53 | return Util.commandFailed(channel, speaker, 'Invalid parameters: Action(s) not provided'); 54 | } 55 | 56 | Util.log(event); 57 | Util.log(actions); 58 | 59 | for (let i = 0; i < event.length; i++) { 60 | const eventName = event[i]; 61 | 62 | for (let j = 0; j < actions.length; j++) { 63 | const actionData = actions[j]; 64 | 65 | const actionName = actionData[0]; 66 | const actionFunc = Events.Actions[actionName]; 67 | const actionArgs = actionData.splice(1); 68 | 69 | if (!actionFunc) { 70 | Util.sendDescEmbed(channel, 'Action Not Found', actionName, Util.makeEmbedFooter(speaker)); 71 | continue; 72 | } 73 | 74 | Events.addEvent(guild, eventName, actionName, actionFunc, actionArgs); 75 | 76 | const sendEmbedFields = []; 77 | 78 | sendEmbedFields.push({ name: 'Event', value: eventName, inline: false }); 79 | sendEmbedFields.push({ name: 'Action', value: actionName, inline: false }); 80 | 81 | Util.sendEmbed(channel, 'Created Link', null, Util.makeEmbedFooter(speaker), null, colGreen, sendEmbedFields); 82 | } 83 | } 84 | }, 85 | }); 86 | -------------------------------------------------------------------------------- /commands/administrator/Permissions.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';perms '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Get guild and channel permissions for a user', 10 | 11 | args: '([@user] | [id] | [name])', 12 | 13 | example: 'vae', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const member = Util.getMemberByMixed(args, guild); 19 | if (member == null) { 20 | Util.commandFailed(channel, speaker, 'User not found'); 21 | return; 22 | } 23 | const guildPerms = member.permissions.serialize(); 24 | const channelPerms = member.permissionsIn(channel).serialize(); 25 | 26 | const guildValue = []; 27 | const channelValue = []; 28 | 29 | for (const [permName, hasPerm] of Object.entries(guildPerms)) { 30 | if (!hasPerm) continue; 31 | guildValue.push(permName); 32 | } 33 | 34 | for (const [permName, hasPerm] of Object.entries(channelPerms)) { 35 | if (!hasPerm) continue; 36 | channelValue.push(permName); 37 | } 38 | 39 | Util.sortPerms(guildValue); 40 | Util.sortPerms(channelValue); 41 | 42 | const sendEmbedFields = [ 43 | { name: 'Guild Permissions', value: `​\n${guildValue.join('\n\n')}`, inline: false }, 44 | { name: 'Channel Permissions', value: `​\n${channelValue.join('\n\n')}`, inline: false }, 45 | ]; 46 | 47 | Util.sendEmbed(channel, Util.capitalize2(`${member.displayName}'s Permissions`), null, Util.makeEmbedFooter(speaker), null, colBlue, sendEmbedFields); 48 | }, 49 | }); 50 | -------------------------------------------------------------------------------- /commands/administrator/RaveBan.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';raveban ', ';crabban ', ';crabrave ', ';rave '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Crab rave a user from the guild', 10 | 11 | args: '([user_resolvable) (OPTIONAL: [reason])', 12 | 13 | example: 'vaeb being weird', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | /* 18 | 19 | Include: 20 | -Server gets renamed [DONE] 21 | -Server icon changes 22 | -Channel(s) get renamed 23 | -Channel descriptions change 24 | -Spam crab rave gif 25 | -(TTS?) MSG: USER IS GONE [DONE] 26 | -Target role gets role: [MID] 27 | -Name: USER IS GONE [DONE] 28 | -Rave colours 29 | -Whenever they speak VaeBot sends a reply message? 30 | 31 | */ 32 | 33 | func: async (cmd, args, msgObj, speaker, channel, guild) => { 34 | args = args.trim(); 35 | 36 | const data = Util.getDataFromString( 37 | args, 38 | [ 39 | function (str) { 40 | return Util.getMemberByMixed(str, guild) || Util.isId(str); 41 | }, 42 | ], 43 | true, 44 | ); 45 | if (!data) return Util.commandFailed(channel, speaker, 'User not found'); 46 | 47 | const target = data[0]; 48 | const reason = data[1]; 49 | 50 | index.crabRave.goneId = target.id; 51 | index.crabRave.goneName = target.displayName.toUpperCase(); 52 | index.crabRave.goneGuild = guild.id; 53 | 54 | await Admin.addBan(guild, channel, target, speaker, { reason }); // Don't actually ban them for now... 55 | 56 | const crabRaveGif = './resources/images/CrabRaveGif.gif'; 57 | 58 | const goneRole = guild.roles.find(r => / gone(?: \S*)?$/i.test(r.name)); 59 | 60 | await goneRole.setName(`🦀 ${index.crabRave.goneName} IS GONE 🦀`); 61 | 62 | target.addRole(goneRole).catch(console.error); // YOUSEEF IS GONE 63 | 64 | let count = 0; 65 | 66 | const intervalFunc = () => { 67 | channel.send(`🦀 ${index.crabRave.goneName} IS GONE 🦀`, { tts: count++ % 1 == 0, files: [crabRaveGif] }).catch(console.error); 68 | }; 69 | 70 | index.crabRave.interval = setInterval(intervalFunc, 5000); 71 | 72 | channel.setName('🦀🦀🦀').catch(console.error); 73 | channel.setTopic(`🦀 ${index.crabRave.goneName} IS GONE 🦀`).catch(console.error); 74 | 75 | guild.setName(`🦀 ${index.crabRave.goneName} IS GONE 🦀`).catch(console.error); 76 | 77 | intervalFunc(); 78 | 79 | return true; 80 | }, 81 | }); 82 | -------------------------------------------------------------------------------- /commands/administrator/RemAuto.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';remauto ', ';rema '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Remove a song from the music auto-playlist', 10 | 11 | args: '[song_name]', 12 | 13 | example: 'gonna give you up', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | // args = args.toLowerCase(); 19 | // var autoPlaylist = Data.guildGet(guild, Data.playlist); 20 | // var autoSongs = autoPlaylist.songs; 21 | // for (var i = autoSongs.length-1; i >= 0; i--) { 22 | // var newSong = autoSongs[i]; 23 | // var songData = newSong[0]; 24 | // var author = newSong[1]; 25 | // var title = songData.snippet.title; 26 | // if (title.toLowerCase().indexOf(args) >= 0) { 27 | // Util.print(channel, "Removed", title, "from the auto-playlist"); 28 | // autoSongs.splice(i, 1); 29 | // } 30 | // } 31 | // Data.guildSaveData(Data.playlist); 32 | }, 33 | }); 34 | -------------------------------------------------------------------------------- /commands/administrator/RemAutoRole.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";remautorole ", ";delautorole ", "aroledel "], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Remove an autorole", 10 | 11 | args: "([auto_role_name])", 12 | 13 | example: "hire", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var prop = args.toLowerCase(); 19 | var guildAutoRoles = Data.guildGet(guild, Data.autoRoles); 20 | if (!guildAutoRoles.hasOwnProperty(prop)) { 21 | Util.commandFailed(channel, speaker, "AutoRole not found"); 22 | return; 23 | } 24 | Data.guildDelete(guild, Data.autoRoles, prop); 25 | saveAutoRoles(); 26 | Util.print(channel, "Removed the", Util.fix(prop), "autorole"); 27 | } 28 | }); 29 | -------------------------------------------------------------------------------- /commands/administrator/RemRole.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';remrole ', ';removerole ', ';delrole '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Remove a role from a user', 10 | 11 | args: '([@user] | [id] | [name]) ([role_name])', 12 | 13 | example: 'vae mod', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const data = Util.getDataFromString( 19 | args, 20 | [ 21 | function (str) { 22 | return Util.getMemberByMixed(str, guild); 23 | }, 24 | function (str) { 25 | return Util.getRole(str, guild); 26 | }, 27 | ], 28 | false, 29 | ); 30 | 31 | if (!data) return Util.commandFailed(channel, speaker, 'Invalid parameters'); 32 | 33 | const user = data[0]; 34 | const role = data[1]; 35 | 36 | if (role.name == 'Vashta-Owner' && !Util.isAdmin(speaker)) { 37 | return Util.commandFailed(channel, speaker, 'You are not allowed to remove this role'); 38 | } 39 | 40 | if (speaker != user && Util.getPosition(speaker) <= Util.getPosition(user)) { 41 | Util.commandFailed(channel, speaker, 'User has equal or higher rank'); 42 | return false; 43 | } 44 | 45 | if (Util.getPosition(speaker) <= role.position) { 46 | Util.commandFailed(channel, speaker, 'Role has equal or higher rank'); 47 | return false; 48 | } 49 | user.removeRole(role).catch(console.error); 50 | 51 | const sendEmbedFields = [{ name: 'Username', value: Util.getMention(user) }, { name: 'Role Name', value: role.name }]; 52 | Util.sendEmbed( 53 | channel, // Channel Object 54 | 'Removed Role', // Title String 55 | null, // Description String 56 | Util.makeEmbedFooter(speaker), // Username + ID String 57 | Util.getAvatar(user), // Avatar URL String 58 | colGreen, // Color Number 59 | sendEmbedFields, 60 | ); 61 | 62 | return true; 63 | }, 64 | }); 65 | -------------------------------------------------------------------------------- /commands/administrator/RolePerms.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";roleperms", ";rolepermissions", ";gperms"], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Get all role permissions", 10 | 11 | args: "", 12 | 13 | example: "", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var outStr = []; 19 | outStr.push("**Guild permissions:**\n```"); 20 | guild.roles.forEach(function(value, index, self) { 21 | outStr.push("Role: " + value.name + " (" + value.id + ")"); 22 | outStr.push(JSON.stringify(value.serialize())); 23 | outStr.push(""); 24 | }); 25 | outStr.push("```"); 26 | Util.print(channel, outStr.join("\n")); 27 | } 28 | }); -------------------------------------------------------------------------------- /commands/administrator/Switch.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';switch'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Specific command', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | if (guild.id === '477270527535480834' && (speaker.id === vaebId || speaker.id === '75743432164773888' || speaker.id === '87185859949899776')) { 19 | const salesChannel = Util.findChannel('477270527535480834', guild); 20 | if (salesChannel) { 21 | if (salesChannel.name.includes('open')) { 22 | salesChannel.setName('sales_closed') 23 | .catch(console.error); 24 | } else { 25 | salesChannel.setName('sales_open') 26 | .catch(console.error); 27 | } 28 | } 29 | } 30 | }, 31 | }); 32 | -------------------------------------------------------------------------------- /commands/administrator/UnCalm.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';uncalm', ';uncalmchat', ';unslow', ';unslowchat'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Removes chat slowdown', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | /* func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | if (speaker.id != guild.ownerID && speaker.id != vaebId) return Util.commandFailed(channel, speaker, "Command is owner-only"); 19 | 20 | if (!index.slowChat[guild.id]) return; 21 | 22 | index.slowChat[guild.id] = null; 23 | index.chatQueue[guild.id] = null; 24 | clearInterval(index.slowInterval[guild.id]); 25 | index.slowInterval[guild.id] = null; 26 | } */ 27 | 28 | func: (cmd, args, msgObj, speaker, channel, guild) => { 29 | // if (speaker.id != guild.ownerID && speaker.id != vaebId) return Util.commandFailed(channel, speaker, "Command is owner-only"); 30 | 31 | if (!index.slowChat[guild.id]) return; 32 | 33 | index.slowChat[guild.id] = null; 34 | index.chatNext[guild.id] = null; 35 | }, 36 | }); 37 | -------------------------------------------------------------------------------- /commands/administrator/UnLink.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';unlink ', ';remlink ', ';dellink ', ';untrigger ', ';unevent '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'UnLink an event from an action', 10 | 11 | args: '({ [event_name_1] ... [event_name_n] }) ({ [action_1_name] }) ... ({ [action_o_name] })', 12 | // args: "([event_name_1] ... [event_name_n]) (-[action_1_name] [action_1_param_1] ... [action_param_n]) ... (-[action_n_name] [action_n_param_1] ... [action_n_param_o])", 13 | 14 | example: '{ UserJoin UserUnMute } { AddRole } { DM }', 15 | // example: "UserJoin UserUnMute -AddRole SendMessages RandomRole -DM CmdInfo", 16 | 17 | // ///////////////////////////////////////////////////////////////////////////////////////// 18 | 19 | func: (cmd, args, msgObj, speaker, channel, guild) => { 20 | let event = null; 21 | const actions = []; 22 | 23 | let numOpen = 0; 24 | let lastOpen = 0; 25 | 26 | for (let i = 0; i < args.length; i++) { 27 | const char = args[i]; 28 | 29 | if (char == '{') { 30 | if (numOpen == 0) { 31 | lastOpen = i; 32 | } 33 | 34 | numOpen++; 35 | } else if (char == '}') { 36 | numOpen--; 37 | 38 | if (numOpen == 0) { 39 | const paramStr = args.substring(lastOpen + 1, i); 40 | 41 | if (event == null) { 42 | event = paramStr.trim().split(' '); 43 | } else { 44 | actions.push(paramStr.trim().split(' ')); 45 | } 46 | } 47 | } 48 | } 49 | 50 | if (event == null || event.length == 0) { 51 | return Util.commandFailed(channel, speaker, 'Invalid parameters: Event not provided'); 52 | } 53 | 54 | Util.log(event); 55 | Util.log(actions); 56 | 57 | for (let i = 0; i < event.length; i++) { 58 | const eventName = event[i]; 59 | 60 | const sendEmbedFields = []; 61 | 62 | sendEmbedFields.push({ name: 'Event', value: eventName, inline: false }); 63 | 64 | if (actions.length == 0) { 65 | Events.remEvent(guild, eventName); 66 | } else { 67 | for (let j = 0; j < actions.length; j++) { 68 | const actionData = actions[i]; 69 | const actionName = actionData[0]; 70 | 71 | Events.remEvent(guild, eventName, actionName); 72 | 73 | sendEmbedFields.push({ name: 'Action', value: actionName, inline: false }); 74 | } 75 | } 76 | 77 | Util.sendEmbed(channel, 'Removed Link', null, Util.makeEmbedFooter(speaker), null, colGreen, sendEmbedFields); 78 | } 79 | }, 80 | }); 81 | -------------------------------------------------------------------------------- /commands/administrator/UnRaveBan.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';unraveban', ';uncrabban', ';uncrabrave', ';unrave'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Stop the party', 10 | 11 | args: '', 12 | 13 | example: 'vaeb being weird', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const target = guild.members.get(index.crabRave.goneId); 19 | 20 | if (target) { 21 | const goneRole = guild.roles.find(r => / gone(?: \S*)?$/i.test(r.name)); 22 | target.removeRole(goneRole).catch(console.error); 23 | } 24 | 25 | index.crabRave.goneId = null; 26 | index.crabRave.goneName = null; 27 | index.crabRave.goneGuild = null; 28 | 29 | clearInterval(index.crabRave.interval); 30 | index.crabRave.interval = null; 31 | 32 | channel.setName('general').catch(console.error); 33 | channel 34 | .setTopic("Main channel. Avoid using bot commands here if they're getting spammy or are annoying users.") 35 | .catch(console.error); 36 | 37 | guild.setName('Vashta').catch(console.error); 38 | 39 | return true; 40 | }, 41 | }); 42 | -------------------------------------------------------------------------------- /commands/locked/Bother.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';bother '], 3 | 4 | requires: { 5 | guild: false, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Hi friend', 10 | 11 | args: '([@user] | [id] | [name])', 12 | 13 | example: 'vae', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const target = Util.getEitherByMixed(args, guild); 19 | 20 | if (target == null) return Util.commandFailed(channel, speaker, 'User not found'); 21 | 22 | const targName = Util.getName(target); 23 | 24 | Util.print(channel, 'Bothering', targName); 25 | 26 | let n = 0; 27 | 28 | const interval = setInterval(() => { 29 | if (n > 50) { 30 | clearInterval(interval); 31 | return; 32 | } 33 | 34 | let sendStr = []; 35 | 36 | while (true) { 37 | let rand = String(Math.random()); 38 | const dotPos = rand.indexOf('.'); 39 | if (dotPos) rand = rand.substring(dotPos + 1); 40 | const subStr = 'HI FRIEND!'; 41 | if ((sendStr.join('\n') + '\n' + subStr).length >= 2000) break; 42 | sendStr.push(subStr); 43 | } 44 | 45 | sendStr = sendStr.join('\n'); 46 | 47 | try { 48 | Util.print(target, sendStr); 49 | } catch (err) { 50 | Util.log(`BOTHER ERROR: ${err}`); 51 | } 52 | n += 1; 53 | }, 50); 54 | 55 | return undefined; 56 | }, 57 | }); 58 | -------------------------------------------------------------------------------- /commands/locked/Change.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';changeperms '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Change an existing something', 10 | 11 | args: '([channelId]) ([memberOrRoleId]) ([permEnable1]) ([permEnable2]) ([permEnable3])', 12 | 13 | example: '123456789 987654321 SEND_MESSAGES VIEW_CHANNEL', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const data = Util.getDataFromString( 19 | args, 20 | [ 21 | function (str) { 22 | return Util.findChannel(str, guild); 23 | }, 24 | function (str) { 25 | return Util.getMemberOrRoleByMixed(str, guild); 26 | }, 27 | function (str) { 28 | return str; 29 | }, 30 | ], 31 | false, 32 | ); 33 | if (!data) return Util.commandFailed(channel, speaker, 'Invalid parameters'); 34 | 35 | const newChannel = data[0]; 36 | const userOrRole = data[1]; 37 | const permStr = data[2]; 38 | 39 | const permSplit = permStr.split(' '); 40 | const permObj = {}; 41 | 42 | for (let i = 0; i < permSplit.length; i++) { 43 | const keySplit = permSplit[i].split(':'); 44 | if (keySplit.length == 2) { 45 | const keyUpper = keySplit[0].toUpperCase(); 46 | const valLower = keySplit[1].toLowerCase(); 47 | if (valLower == 'true') { 48 | Util.log(`Changing ${keyUpper} to ${valLower}`); 49 | permObj[keyUpper] = true; 50 | } else if (valLower == 'false') { 51 | Util.log(`Changing ${keyUpper} to ${valLower}`); 52 | permObj[keyUpper] = false; 53 | } 54 | } 55 | } 56 | 57 | Util.setChannelPerms(newChannel, userOrRole, permObj); 58 | 59 | return true; 60 | }, 61 | }); 62 | -------------------------------------------------------------------------------- /commands/locked/Commit.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';commit ', ';editr '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Commit some changes', 10 | 11 | args: '([roleName]) ([newName]) ([newColor]) ([newHoist]) ([newMentionable]) ([newPosition])', 12 | 13 | example: 'Vaeben Gaeben 0xFF0000 null null 3', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const data = Util.getDataFromString(args, [ 19 | function (str) { 20 | return Util.getRole(str, guild); 21 | }, 22 | function (str) { 23 | return str; 24 | }, 25 | function (str) { 26 | if (str === 'null') return str; 27 | return Util.getNum(str); 28 | }, 29 | function (str) { 30 | if (str === 'null') return str; 31 | return Util.toBoolean(str); 32 | }, 33 | function (str) { 34 | if (str === 'null') return str; 35 | return Util.toBoolean(str); 36 | }, 37 | function (str) { 38 | if (str === 'null') return str; 39 | return Util.getNum(str); 40 | }, 41 | ], false); 42 | if (!data) return Util.commandFailed(channel, speaker, 'Invalid parameters'); 43 | 44 | for (let i = 1; i < data.length; i++) { 45 | data[i] = data[i] !== 'null' ? data[i] : null; 46 | } 47 | 48 | const role = data[0]; 49 | const name = data[1]; 50 | const color = data[2]; 51 | const hoist = data[3]; 52 | const mentionable = data[4]; 53 | const pos = data[5]; 54 | 55 | if (!role) { 56 | return Util.commandFailed(channel, speaker, 'Invalid parameters'); 57 | } 58 | 59 | if (name) { 60 | role.setName(name) 61 | .catch(error => Util.log(`[E_RoleComm1] ${error}`)); 62 | } 63 | 64 | if (color) { 65 | role.setColor(color) 66 | .catch(error => Util.log(`[E_RoleComm2] ${error}`)); 67 | } 68 | 69 | if (hoist) { 70 | role.setHoist(hoist) 71 | .catch(error => Util.log(`[E_RoleComm3] ${error}`)); 72 | } 73 | 74 | if (mentionable) { 75 | role.setMentionable(mentionable) 76 | .catch(error => Util.log(`[E_RoleComm4] ${error}`)); 77 | } 78 | 79 | if (pos) { 80 | role.setPosition(pos) 81 | .catch(error => Util.log(`[E_RoleComm5] ${error}`)); 82 | } 83 | 84 | return undefined; 85 | }, 86 | }); 87 | -------------------------------------------------------------------------------- /commands/locked/Create.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";create ", ";make "], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Create something new", 10 | 11 | args: "([newColor]) ([newHoist]) ([newPosition]) ([newName])", 12 | 13 | example: "0xFF0000 false 3 Vaeben", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var data = Util.getDataFromString(args, [ 19 | function(str, results) { 20 | return Util.getNum(str); 21 | }, 22 | function(str, results) { 23 | return Util.toBoolean(str); 24 | }, 25 | function(str, results) { 26 | return Util.getNum(str); 27 | }, 28 | function(str, results) { 29 | return str; 30 | } 31 | ], false); 32 | if (!data) return Util.commandFailed(channel, speaker, "Invalid parameters"); 33 | 34 | var color = data[0]; 35 | var hoist = data[1]; 36 | var pos = data[2]; 37 | var name = data[3]; 38 | 39 | Util.log(pos); 40 | 41 | guild.createRole({ 42 | name: name, 43 | color: color, 44 | hoist: hoist, 45 | mentionable: true, 46 | permissions: [], 47 | position: pos 48 | }) 49 | .then(role => { 50 | role.setPosition(pos) 51 | .catch(console.error); 52 | }) 53 | .catch(error => Util.log("[E_CreateRole2] " + error)); 54 | } 55 | }); -------------------------------------------------------------------------------- /commands/locked/DisabR.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';disabr '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Change even more existing somethings', 10 | 11 | args: '([guildId]) ([roleName]) ([permEnable1]) ([permEnable2]) ([permEnable3])', 12 | 13 | example: '123456789 Vaeben SEND_MESSAGES VIEW_CHANNEL', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const data = Util.getDataFromString( 19 | args, 20 | [ 21 | function (str, results) { 22 | return client.guilds.get(str); 23 | }, 24 | function (str, results) { 25 | return Util.getRole(str, results[0]); 26 | }, 27 | ], 28 | true, 29 | ); 30 | if (!data) return Util.commandFailed(channel, speaker, 'Invalid parameters'); 31 | const newGuild = data[0]; 32 | const newRole = data[1]; 33 | const newPerms = data[2]; 34 | 35 | const setPerms = []; 36 | const pattern = /[\w_]+/g; 37 | 38 | let matchData; 39 | const allMatches = {}; 40 | 41 | while ((matchData = pattern.exec(newPerms))) { 42 | const permName = matchData[0]; 43 | if (Util.rolePermissionsObj[permName]) { 44 | Util.log(`Disabled ${permName} permission for ${newRole.name} role`); 45 | allMatches[permName] = true; 46 | } 47 | } 48 | 49 | for (let i = 0; i < Util.rolePermissions.length; i++) { 50 | const permName = Util.rolePermissions[i]; 51 | if (newRole.hasPermission(permName) && !allMatches.hasOwnProperty(permName)) { 52 | setPerms.push(permName); 53 | } 54 | } 55 | 56 | newRole.setPermissions(setPerms).catch(error => Util.log(`[E_DisabR] ${error}`)); 57 | }, 58 | }); 59 | -------------------------------------------------------------------------------- /commands/locked/Echo.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";echo "], 3 | 4 | requires: { 5 | guild: false, 6 | loud: false 7 | }, 8 | 9 | desc: "Echo text into another channel", 10 | 11 | args: "", 12 | 13 | example: "", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var channels = client.channels; 19 | var data = Util.getDataFromString(args, [ 20 | function(str, results) { 21 | var newChannel = channels.get(str); 22 | return newChannel; 23 | }, 24 | function(str, results) { 25 | return str; 26 | } 27 | ], false); 28 | if (!data) return Util.commandFailed(channel, speaker, "User not found"); 29 | //msgObj.delete(); 30 | var newChannel = data[0]; 31 | var msg = data[1]; 32 | Util.log("echo'd " + msg); 33 | Util.print(newChannel, msg); 34 | } 35 | }); -------------------------------------------------------------------------------- /commands/locked/Effect.js: -------------------------------------------------------------------------------- 1 | function byte2Hex(n) { 2 | const nybHexString = '0123456789ABCDEF'; 3 | return String(nybHexString.substr((n >> 4) & 0x0F, 1)) + nybHexString.substr(n & 0x0F, 1); 4 | } 5 | 6 | function RGB2Color(r, g, b) { 7 | return `#${byte2Hex(r)}${byte2Hex(g)}${byte2Hex(b)}`; 8 | } 9 | 10 | function colorText(i, maxExclusive, phaseParam) { 11 | let phase = phaseParam; 12 | if (phase == null) phase = 0; 13 | 14 | const center = 128; 15 | const width = 127; 16 | const frequency = (Math.PI * 2) / maxExclusive; 17 | 18 | const red = Math.sin(frequency * i + 2 + phase) * width + center; 19 | const green = Math.sin(frequency * i + 0 + phase) * width + center; 20 | const blue = Math.sin(frequency * i + 4 + phase) * width + center; 21 | 22 | const hexColor = RGB2Color(red, green, blue); 23 | 24 | return hexColor; 25 | } 26 | 27 | function setRoleColor(role, i, maxExclusive) { 28 | let nowIter = i; 29 | 30 | const newColor = colorText(nowIter, maxExclusive, 0); 31 | 32 | nowIter++; 33 | 34 | if (nowIter === maxExclusive) nowIter = 0; 35 | 36 | // role.setColor(newColor) 37 | // .catch(console.error); // 168, 184, 560, 175, 231, 179 38 | 39 | // setTimeout(setRoleColor, 50, role, nowIter, maxExclusive); 40 | 41 | role.setColor(newColor) 42 | .then(() => setRoleColor(role, nowIter, maxExclusive)) 43 | .catch((err) => { 44 | Util.log(err); 45 | Util.log('^ This is from setRoleColor'); 46 | }); 47 | } 48 | 49 | module.exports = Cmds.addCommand({ 50 | cmds: [';effect', ';color', ';addeffect'], 51 | 52 | requires: { 53 | guild: true, 54 | loud: false, 55 | }, 56 | 57 | desc: 'Magic', 58 | 59 | args: '', 60 | 61 | example: '', 62 | 63 | // ///////////////////////////////////////////////////////////////////////////////////////// 64 | 65 | func: (cmd, args, msgObj, speaker, channel, guild) => { 66 | const Vaeben = Util.getRole('Vaeben', guild); 67 | setRoleColor(Vaeben, 0, 100); 68 | }, 69 | }); 70 | -------------------------------------------------------------------------------- /commands/locked/EnabR.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';enabr ', ';setr '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Change more existing somethings', 10 | 11 | args: '([guildId]) ([roleName]) ([permEnable1]) ([permEnable2]) ([permEnable3])', 12 | 13 | example: '123456789 Vaeben SEND_MESSAGES VIEW_CHANNEL', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const data = Util.getDataFromString( 19 | args, 20 | [ 21 | function (str, results) { 22 | return client.guilds.get(str); 23 | }, 24 | function (str, results) { 25 | return Util.getRole(str, results[0]); 26 | }, 27 | ], 28 | true, 29 | ); 30 | if (!data) return Util.commandFailed(channel, speaker, 'Invalid parameters'); 31 | 32 | const newGuild = data[0]; 33 | const newRole = data[1]; 34 | const newPerms = data[2]; 35 | 36 | const rolePerms = newRole.serialize(); 37 | 38 | const setPerms = []; 39 | 40 | const pattern = /[\w_]+/g; 41 | 42 | for (const permName in rolePerms) { 43 | if (!rolePerms.hasOwnProperty(permName)) continue; 44 | if (rolePerms[permName]) { 45 | setPerms.push(permName); 46 | } 47 | } 48 | 49 | let matchData; 50 | while ((matchData = pattern.exec(newPerms))) { 51 | const permName = matchData[0]; 52 | if (Util.rolePermissionsObj[permName] && !newRole.hasPermission(permName)) { 53 | setPerms.push(permName); 54 | Util.log(`Enabled ${permName} permission for ${newRole.name} role`); 55 | } 56 | } 57 | 58 | Util.log(setPerms); 59 | 60 | newRole.setPermissions(setPerms).catch(console.error); 61 | }, 62 | }); 63 | -------------------------------------------------------------------------------- /commands/locked/Eval.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';eval ', ';run ', ';exec '], 3 | 4 | requires: { 5 | guild: false, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Execute JavaScript code', 10 | 11 | args: '[code]', 12 | 13 | example: 'return 5*2;', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const print = (...args2) => Util.print(channel, ...args2); 19 | args = `(async function() {\n${args}\n})()`; 20 | const outStr = ['**Output:**']; 21 | eval(args) 22 | .then((result) => { 23 | Util.log('Eval result:', result); 24 | outStr.push('```'); 25 | outStr.push(Util.format(result)); 26 | outStr.push('```'); 27 | if (result !== undefined) Util.print(channel, outStr.join('\n')); 28 | }) 29 | .catch((err) => { 30 | Util.log('Eval Error:'); 31 | Util.log(err); 32 | }); 33 | }, 34 | }); 35 | -------------------------------------------------------------------------------- /commands/locked/Lua.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";lua "], 3 | 4 | requires: { 5 | guild: false, 6 | loud: false 7 | }, 8 | 9 | desc: "Execute Lua code", 10 | 11 | args: "[code]", 12 | 13 | example: "print(\"Hello, world!\")", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | if (args.substr(0, 3) == "-h ") { 19 | var url = args.substring(3); 20 | index.Request(url, function(error, response, body) { 21 | if (error) { 22 | Util.print(channel, "[HTTP]", error); 23 | } else { 24 | Util.runLua(body, channel); 25 | } 26 | }); 27 | } else { 28 | Util.runLua(args, channel); 29 | } 30 | } 31 | }); -------------------------------------------------------------------------------- /commands/locked/PSA.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";psa"], 3 | 4 | requires: { 5 | guild: false, 6 | loud: false 7 | }, 8 | 9 | desc: "PSA when restarting the bot for an update", 10 | 11 | args: "", 12 | 13 | example: "", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | Util.sendDescEmbed(channel, null, "Restarting the bot for an update, it will be down for a few seconds", null, null, null); 19 | } 20 | }); -------------------------------------------------------------------------------- /commands/locked/Reminder.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";reminder"], 3 | 4 | requires: { 5 | guild: false, 6 | loud: false 7 | }, 8 | 9 | desc: "Note to self", 10 | 11 | args: "", 12 | 13 | example: "", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var sendEmbedFields = []; 19 | 20 | sendEmbedFields.push({name: "Create", value: ";create newColor newHoist newPosition newName", inline: false}); 21 | sendEmbedFields.push({name: "Commit", value: ";commit roleName newName newColor newHoist newMentionable newPosition", inline: false}); 22 | sendEmbedFields.push({name: "EnabR", value: ";enabr guildId roleName permEnable1 permEnable2 permEnable3", inline: false}); 23 | sendEmbedFields.push({name: "DisabR", value: ";disabr guildId roleName permEnable1 permEnable2 permEnable3", inline: false}); 24 | sendEmbedFields.push({name: "Set", value: ";set channelId memberId permEnable1 permEnable2 permEnable3", inline: false}); 25 | sendEmbedFields.push({name: "Change", value: ";change channelId memberId permEnable1 permEnable2 permEnable3", inline: false}); 26 | 27 | Util.sendEmbed(channel, "Reminder", null, Util.makeEmbedFooter(speaker), null, colGreen, sendEmbedFields); 28 | } 29 | }); -------------------------------------------------------------------------------- /commands/locked/Set.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';set '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Change an existing something', 10 | 11 | args: '([channelId]) ([memberOrRoleId]) ([permEnable1]) ([permEnable2]) ([permEnable3])', 12 | 13 | example: '123456789 987654321 SEND_MESSAGES VIEW_CHANNEL', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const data = Util.getDataFromString( 19 | args, 20 | [ 21 | function (str, results) { 22 | return Util.findChannel(str, guild); 23 | }, 24 | function (str, results) { 25 | return Util.getMemberOrRoleByMixed(str, guild); 26 | }, 27 | function (str, results) { 28 | return str; 29 | }, 30 | ], 31 | false, 32 | ); 33 | if (!data) return Util.commandFailed(channel, speaker, 'Invalid parameters'); 34 | 35 | const newChannel = data[0]; 36 | const userOrRole = data[1]; 37 | const permStr = data[2]; 38 | 39 | const permSplit = permStr.split(' '); 40 | const permObj = {}; 41 | 42 | for (var i = 0; i < permSplit.length; i++) { 43 | const keySplit = permSplit[i].split(':'); 44 | if (keySplit.length == 2) { 45 | const keyUpper = keySplit[0].toUpperCase(); 46 | const valLower = keySplit[1].toLowerCase(); 47 | if (valLower == 'true') { 48 | Util.log(`Setting ${keyUpper} to ${valLower}`); 49 | permObj[keyUpper] = true; 50 | } else if (valLower == 'false') { 51 | Util.log(`Setting ${keyUpper} to ${valLower}`); 52 | permObj[keyUpper] = false; 53 | } 54 | } 55 | } 56 | 57 | for (var i = 0; i < Util.textChannelPermissions.length; i++) { 58 | const permName = Util.textChannelPermissions[i]; 59 | if (!permObj.hasOwnProperty(permName)) permObj[permName] = null; 60 | } 61 | 62 | Util.setChannelPerms(newChannel, userOrRole, permObj); 63 | }, 64 | }); 65 | -------------------------------------------------------------------------------- /commands/locked/Username.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";username "], 3 | 4 | requires: { 5 | guild: false, 6 | loud: false 7 | }, 8 | 9 | desc: "Set VaeBot's username", 10 | 11 | args: "[username]", 12 | 13 | example: "VaeBot9000", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | client.user.setUsername(args) 19 | .catch(console.error); 20 | Util.print(channel, "Set username to " + args); 21 | } 22 | }); -------------------------------------------------------------------------------- /commands/public/AutoPlaylist.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";autoplaylist", ";ap"], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Output all the bangin' tunes in the auto-playlist", 10 | 11 | args: "", 12 | 13 | example: "", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var autoPlaylist = Data.guildGet(guild, Data.playlist); 19 | var autoSongs = autoPlaylist.songs; 20 | 21 | var sendEmbedFields = []; 22 | 23 | for (var i = 0; i < autoSongs.length; i++) { 24 | var songData = autoSongs[i][0]; 25 | var author = autoSongs[i][1]; 26 | sendEmbedFields.push({name: "[" + (i+1) + "] " + songData.snippet.title, value: "​", inline: false}); 27 | } 28 | 29 | Util.sendEmbed(channel, "Auto-Playlist", null, Util.makeEmbedFooter(speaker), null, colGreen, sendEmbedFields); 30 | } 31 | }); -------------------------------------------------------------------------------- /commands/public/AutoRoles.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";autoroles"], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Get all autoroles (roles which users are allowed to assign to themselves)", 10 | 11 | args: "", 12 | 13 | example: "", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var sendEmbedFields = []; 19 | var guildAutoRoles = Data.guildGet(guild, Data.autoRoles); 20 | 21 | for (var name in guildAutoRoles) { 22 | if (!guildAutoRoles.hasOwnProperty(name)) continue; 23 | sendEmbedFields.push({name: name, value: "Role: " + guildAutoRoles[name], inline: false}); 24 | } 25 | 26 | Util.sendEmbed(channel, "AutoRoles", null, Util.makeEmbedFooter(speaker), null, colGreen, sendEmbedFields); 27 | } 28 | }); -------------------------------------------------------------------------------- /commands/public/Channels.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';channels'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Get all guild channels', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const outStr = []; 19 | outStr.push('**Guild text channels:**\n```'); 20 | Util.getTextChannels(guild).forEach((tChannel) => { 21 | outStr.push( 22 | `Channel: ${tChannel.name} (${tChannel.id}) | Topic: ${tChannel.topic} | Position: ${tChannel.position} | Created: ${ 23 | tChannel.createdAt 24 | }`, 25 | ); 26 | }); 27 | outStr.push('```'); 28 | outStr.push('**Guild voice channels:**\n```'); 29 | Util.getVoiceChannels(guild).forEach((vChannel) => { 30 | outStr.push( 31 | `Channel: ${vChannel.name} (${vChannel.id}) | Topic: ${vChannel.topic} | Position: ${vChannel.position} | Created: ${ 32 | vChannel.createdAt 33 | } | Bitrate: ${vChannel.bitrate}`, 34 | ); 35 | }); 36 | outStr.push('```'); 37 | Util.print(channel, outStr.join('\n')); 38 | }, 39 | }); 40 | -------------------------------------------------------------------------------- /commands/public/CloseTicket.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';closeticket ', ';closesupport ', ';stopticket ', ';endticket ', ';close '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Create a ticket to be viewed by Support', 10 | 11 | args: '([ticket_details])', 12 | 13 | example: 'Am I able to give away my whitelist?', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: async (cmd, args, msgObj, speaker, channel, guild) => { 18 | if (!Util.checkStaff(guild, speaker) && !Util.hasRoleName(speaker, 'Support')) { 19 | return Util.commandFailed(channel, speaker, 'This command can only be used by Support and above'); 20 | } 21 | 22 | const data = Util.getDataFromString(args, [ 23 | function (str) { 24 | return (str.match(/\d*(?:\.\d+)?/) || [])[0]; 25 | }, 26 | ], false); 27 | 28 | if (!data) return Util.commandFailed(channel, speaker, 'Invalid parameters'); 29 | 30 | const numTicket = data[0]; 31 | 32 | const foundTicket = ((await Data.getRecords(guild, 'tickets', { ticket_id: numTicket })) || [])[0]; 33 | 34 | if (!foundTicket) return Util.commandFailed(channel, speaker, `Ticket #${numTicket} does not exist`); 35 | if (!foundTicket.active) return Util.commandFailed(channel, speaker, `Ticket #${numTicket} is already closed`); 36 | 37 | Data.updateRecords(guild, 'tickets', { 38 | ticket_id: numTicket, 39 | }, { 40 | active: 0, 41 | }); 42 | 43 | const sendEmbedFields = [ 44 | { name: 'Ticket User', value: `<@${foundTicket.user_id}>`, inline: false }, 45 | { name: 'Ticket Info', value: `${foundTicket.description}`, inline: false }, 46 | { name: 'Ticket Opened', value: Util.getDateString(new Date(foundTicket.open_tick)), inline: false }, 47 | ]; 48 | Util.sendEmbed(channel, `Closed Ticket #${foundTicket.ticket_id}`, null, Util.makeEmbedFooter(speaker), null, colGreen, sendEmbedFields); 49 | 50 | return true; 51 | }, 52 | }); 53 | -------------------------------------------------------------------------------- /commands/public/Commands.js: -------------------------------------------------------------------------------- 1 | const commands = Cmds.commands; 2 | 3 | module.exports = Cmds.addCommand({ 4 | cmds: [';cmds', ';commands', ';help'], 5 | 6 | requires: { 7 | guild: false, 8 | loud: true, 9 | }, 10 | 11 | desc: 'Output all commands', 12 | 13 | args: '', 14 | 15 | example: '', 16 | 17 | // ///////////////////////////////////////////////////////////////////////////////////////// 18 | 19 | func: (cmd, args, msgObj, speaker, channel, guild) => { 20 | if (Util.isLoud(channel) && !Util.checkStaff(guild, speaker)) return; 21 | 22 | const separator = ' OR '; 23 | 24 | const botUser = Util.getMemberById(selfId, guild); 25 | 26 | const sendEmbedFields1 = []; 27 | const sendEmbedFields2 = []; 28 | const sendEmbedFields3 = []; 29 | const sendEmbedFields4 = []; 30 | 31 | for (let i = 0; i < commands.length; i++) { 32 | const cmdData = commands[i]; 33 | 34 | const cmdNames = cmdData[0]; 35 | const cmdRequires = cmdData[2]; 36 | const cmdDesc = cmdData[3]; 37 | 38 | const trimCmds = []; 39 | 40 | for (let c = 0; c < cmdNames.length; c++) { 41 | trimCmds.push(cmdNames[c].trim()); 42 | } 43 | 44 | const embedField = { name: trimCmds.join(separator), value: cmdDesc, inline: false }; 45 | 46 | if (cmdRequires.vaeb) { 47 | sendEmbedFields1.push(embedField); 48 | } else if (cmdRequires.administrator) { 49 | sendEmbedFields4.push(embedField); 50 | } else if (cmdRequires.staff) { 51 | sendEmbedFields2.push(embedField); 52 | } else { 53 | sendEmbedFields3.push(embedField); 54 | } 55 | } 56 | 57 | Util.sendEmbed(channel, 'Locked Commands', null, 'Locked Commands', null, 0xf44336, sendEmbedFields1); 58 | Util.sendEmbed(channel, 'Administrator Commands', null, 'Administrator Commands', null, 0xffeb3b, sendEmbedFields4); 59 | Util.sendEmbed(channel, 'Staff Commands', null, 'Staff Commands', null, 0x4caf50, sendEmbedFields2); 60 | Util.sendEmbed(channel, 'Public Commands', null, 'Public Commands', null, 0x2196f3, sendEmbedFields3); 61 | }, 62 | }); 63 | -------------------------------------------------------------------------------- /commands/public/Decrypt.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';decrypt '], 3 | 4 | requires: { 5 | guild: false, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Decrypt text using One Time Pad', 10 | 11 | args: '([encryption]) ([key])', 12 | 13 | example: '1000110100000110010111000000010111000011011111 1100010000100110000101100001010101101110111111', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const mix = args.split(' '); 19 | const encBits = mix[0]; 20 | const keyBits = mix[1]; 21 | let msgBits = ''; 22 | let msgStr = ''; 23 | 24 | if (encBits == null || keyBits == null) { 25 | Util.commandFailed(channel, speaker, 'Required syntax: `;decrypt result key`'); 26 | return; 27 | } 28 | 29 | for (let i = 0; i < encBits.length; i++) { 30 | msgBits += Util.doXOR(encBits[i], keyBits[i]); 31 | if ((i + 1) % 8 == 0) { 32 | msgStr += String.fromCharCode(parseInt(msgBits.substr(i - 7, 8), 2).toString(10)); 33 | } 34 | } 35 | Util.print(channel, `Result: ${msgStr}`); 36 | }, 37 | }); 38 | -------------------------------------------------------------------------------- /commands/public/Define.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';define ', ';urban '], 3 | 4 | requires: { 5 | guild: false, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Output the definition for a word/phrase using Urban Dictionary', 10 | 11 | args: '([keyword])', 12 | 13 | example: 'yorkshire', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const definitions = index.Urban(args); 19 | 20 | definitions.first((data) => { 21 | if (data == null) { 22 | Util.commandFailed(channel, speaker, 'No definition found'); 23 | return; 24 | } 25 | 26 | const sendEmbedFields = []; 27 | 28 | let desc = Util.safeEveryone(data.definition); 29 | let example = Util.safeEveryone(data.example); 30 | 31 | if (desc.length > 2048) { 32 | desc = `**[This message was shortened due to excessive length]** ${desc}`.substr(0, 2048); 33 | } 34 | 35 | if (example.length > 512) { 36 | example = `**[This message was shortened due to excessive length]** ${example}`.substr(0, 512); 37 | } 38 | 39 | sendEmbedFields.push({ name: '​', value: '​', inline: false }); 40 | sendEmbedFields.push({ name: 'Example', value: example, inline: false }); 41 | 42 | Util.sendEmbed(channel, Util.capitalize(data.word), desc, Util.makeEmbedFooter(speaker), null, colGreen, sendEmbedFields); 43 | }); 44 | }, 45 | }); 46 | -------------------------------------------------------------------------------- /commands/public/Encrypt.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';encrypt '], 3 | 4 | requires: { 5 | guild: false, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Encrypt text using One Time Pad', 10 | 11 | args: '[message]', 12 | 13 | example: 'yo dawg', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | let encBits = ''; 19 | let keyBits = ''; 20 | for (let c = 0; c < args.length; c++) { 21 | let bit = args[c].charCodeAt(0).toString(2); 22 | while (bit.length < 8) { 23 | bit = `0${bit}`; 24 | } 25 | for (let b = 0; b < 8; b++) { 26 | const keyBit = Util.getRandomInt(0, 1); 27 | keyBits += keyBit; 28 | encBits += Util.doXOR(bit[b], keyBit); 29 | } 30 | } 31 | Util.print(channel, `Encryption: ${encBits}`); 32 | Util.print(channel, `Key: ${keyBits}`); 33 | }, 34 | }); 35 | -------------------------------------------------------------------------------- /commands/public/GetTickets.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';tickets', ';gettickets', ';showtickets', ';activetickets', ';displaytickets', ';supporttickets'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Display all open support tickets', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: async (cmd, args, msgObj, speaker, channel, guild) => { 18 | if (!Util.checkStaff(guild, speaker) && !Util.hasRoleName(speaker, 'Support')) { 19 | return Util.commandFailed(channel, speaker, 'This command can only be used by Support and above'); 20 | } 21 | 22 | const activeTickets = await Data.getRecords(guild, 'tickets', { active: 1 }); 23 | 24 | const sendEmbedFields = []; 25 | 26 | for (let i = 0; i < activeTickets.length; i++) { 27 | const record = activeTickets[i]; 28 | const ticketNum = record.ticket_id; 29 | const userId = record.user_id; 30 | const openTick = record.open_tick; 31 | const description = record.description; 32 | 33 | const openDateStr = Util.getDateString(new Date(openTick)); 34 | 35 | sendEmbedFields.push({ name: `Ticket #${ticketNum}`, value: `​User: <@${userId}>\nDescription: ${description}\nCreated: ${openDateStr}​`, inline: false }); 36 | } 37 | 38 | Util.sendEmbed(channel, 'Open Tickets', null, Util.makeEmbedFooter(speaker), null, colBlue, sendEmbedFields); 39 | 40 | return true; 41 | }, 42 | }); 43 | -------------------------------------------------------------------------------- /commands/public/GuildInfo.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';ginfo', ';guildinfo'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Get guild info', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const createdStr = Util.getDateString(guild.createdAt); 19 | 20 | const sendEmbedFields = []; 21 | 22 | sendEmbedFields.push({ name: 'ID', value: guild.id }); 23 | sendEmbedFields.push({ name: 'Name', value: guild.name }); 24 | sendEmbedFields.push({ name: 'Owner', value: guild.owner.toString() }); 25 | sendEmbedFields.push({ name: 'Region', value: Util.capitalize(guild.region) }); 26 | sendEmbedFields.push({ name: 'Members', value: guild.memberCount }); 27 | sendEmbedFields.push({ name: 'Text Channels', value: Util.getTextChannels(guild).size }); 28 | sendEmbedFields.push({ name: 'Voice Channels', value: Util.getVoiceChannels(guild).size }); 29 | sendEmbedFields.push({ name: 'Roles', value: guild.roles.size }); 30 | sendEmbedFields.push({ name: 'AFK Timeout', value: `${guild.afkTimeout} seconds` }); 31 | sendEmbedFields.push({ name: 'Created', value: createdStr }); 32 | sendEmbedFields.push({ name: 'Icon', value: guild.iconURL }); 33 | 34 | sendEmbedFields.sort((a, b) => (String(a.name) + String(a.value)).length - (String(b.name) + String(b.value)).length); 35 | 36 | Util.sendEmbed(channel, 'Guild Info', null, Util.makeEmbedFooter(speaker), guild.iconURL, colGreen, sendEmbedFields); 37 | }, 38 | }); 39 | -------------------------------------------------------------------------------- /commands/public/Image.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';img ', ';image '], 3 | 4 | requires: { 5 | guild: false, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Output an image for a word/phrase using Google', 10 | 11 | args: '([keyword])', 12 | 13 | example: 'puppy', 14 | 15 | func: (cmd, args, msgObj, speaker, channel, guild) => { 16 | const searchStart = Util.getRandomInt(1, 20); 17 | const searchURL = `https://www.googleapis.com/customsearch/v1?q=${args}&num=1&start=${searchStart}&searchType=image&key=AIzaSyBNXuJaoDMdnlLFxZ20ykf68gT2Qk4eG4s&cx=003838813173771542491%3A0bxpubr42jq`; 18 | 19 | index.Request(searchURL, (error, response, body) => { 20 | if (error) { 21 | Util.log(`[HTTP] ${error}`); 22 | } else { 23 | try { 24 | const bodyData = JSON.parse(body); 25 | if (has.call(bodyData, 'items')) { 26 | const imgURL = bodyData.items[0].link; 27 | // Util.log(imgURL); 28 | Util.print(channel, imgURL); 29 | if (channel.name.toLowerCase().includes('nsfw') && !index.warnedImage[speaker.id]) { 30 | index.warnedImage[speaker.id] = true; 31 | Util.print( 32 | channel, 33 | `${speaker.toString()} is using me to post images in a nsfw channel; if the images are nsfw remember to ban them <@107593015014486016>!`, 34 | ); 35 | } 36 | } else { 37 | Util.print(channel, 'No image found'); 38 | } 39 | } catch (err) { 40 | Util.print(channel, 'Image search errored (invalid JSON)'); 41 | } 42 | } 43 | }); 44 | }, 45 | }); 46 | -------------------------------------------------------------------------------- /commands/public/Info.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';info '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Get info about a user', 10 | 11 | args: '([@user] | [id] | [name])', 12 | 13 | example: 'vae', 14 | 15 | func: async (cmd, args, msgObj, speaker, channel, guild) => { 16 | const target = Util.getEitherByMixed(args, guild); 17 | if (target == null) return Util.commandFailed(channel, speaker, 'User not found'); 18 | 19 | const isMuted = Admin.checkMuted(guild, target.id); 20 | const numMutes = await Util.getNumMutes(target.id, guild); 21 | const historyStr = `${numMutes} mute${numMutes == 1 ? '' : 's'}`; 22 | 23 | const createdAt = target.createdAt || target.user.createdAt; 24 | // const timeStr = `${Util.getYearStr(createdAt)}-${Util.getMonthStr(createdAt)}-${Util.getDayStr(createdAt)}`; 25 | const highestRole = Util.getHighestRole(target); 26 | const powerRating = `${Util.toFixedCut(Util.getPermRating(guild, target), 3)}%`; 27 | 28 | const guildMembers = Array.from(guild.members.values()); 29 | guildMembers.sort((a, b) => a.joinedTimestamp - b.joinedTimestamp); 30 | const joinOrder = guildMembers.map(member => member.id); 31 | const joinPos = joinOrder.indexOf(target.id) + 1; 32 | const joinPosStr = `${Util.getSuffix(joinPos)} (${guild.members.size} Total)`; 33 | 34 | const joinedAtStr = (target.joinedAt != null ? Util.getDateString(target.joinedAt) : 'N/A'); 35 | 36 | const sendEmbedFields = []; 37 | 38 | sendEmbedFields.push({ name: 'ID', value: target.id }); 39 | sendEmbedFields.push({ name: 'Username', value: target.toString() }); 40 | sendEmbedFields.push({ name: 'Nickname', value: (target.nickname != null ? Util.safe(target.nickname) : 'N/A') }); 41 | sendEmbedFields.push({ name: 'Discriminator', value: target.discriminator }); 42 | sendEmbedFields.push({ name: 'Staff', value: Util.capitalize(Util.checkStaff(guild, target)) }); 43 | sendEmbedFields.push({ name: 'Rank', value: highestRole ? `${highestRole.name} (${highestRole.position})` : 'None' }); 44 | sendEmbedFields.push({ name: 'Power', value: powerRating }); 45 | sendEmbedFields.push({ name: 'Status', value: Util.capitalize(target.presence.status) }); 46 | sendEmbedFields.push({ name: 'Bot', value: Util.capitalize(target.bot || target.user.bot) }); 47 | sendEmbedFields.push({ name: 'Game', value: (target.presence.game != null) ? Util.capitalize(target.presence.game.name) : 'N/A' }); 48 | sendEmbedFields.push({ name: 'Muted', value: Util.capitalize(isMuted) }); 49 | sendEmbedFields.push({ name: 'Mute History', value: historyStr }); 50 | sendEmbedFields.push({ name: 'Mic Muted', value: Util.capitalize(target.selfMute) }); 51 | sendEmbedFields.push({ name: 'Deafened', value: Util.capitalize(target.selfDeaf) }); 52 | sendEmbedFields.push({ name: 'Server Mic Muted', value: Util.capitalize(target.serverMute) }); 53 | sendEmbedFields.push({ name: 'Server Deafened', value: Util.capitalize(target.serverDeaf) }); 54 | sendEmbedFields.push({ name: 'Registered', value: (createdAt != null ? Util.getDateString(createdAt) : 'N/A') }); 55 | sendEmbedFields.push({ name: `Joined ${guild.name}`, value: `${joinedAtStr} | ${joinPosStr}` }); 56 | sendEmbedFields.push({ name: 'Avatar', value: Util.getAvatar(target, true) }); 57 | 58 | // var newDesc = Util.getAvatar(target, true) // + "\n" + */("+").repeat(numSep); 59 | 60 | Util.sendEmbed(channel, 'User Info', null, Util.makeEmbedFooter(speaker), Util.getAvatar(target), colGreen, sendEmbedFields); 61 | 62 | return undefined; 63 | }, 64 | }); 65 | -------------------------------------------------------------------------------- /commands/public/JTranslate.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';translatej '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Translate a Japanese word/sentence into English, allowing for Romaji', 10 | 11 | args: '([word] | [sentence])', 12 | 13 | example: 'Sayonara!', 14 | 15 | // export GOOGLE_APPLICATION_CREDENTIALS="/home/einsteink/VaebVPS-4cce7d4f015f.json" 16 | 17 | func: async (cmd, args, msgObj, speaker, channel, guild) => { 18 | const useText = index.Hepburn.toHiragana(index.Hepburn.cleanRomaji(args)); 19 | 20 | index.Translate.translate(useText, 'ja', 'en', (err, res) => { 21 | if (err) return console.log(err); 22 | 23 | const embFields = [ 24 | { name: `[${res.detectedSourceLanguage}] Original`, value: res.originalText || args, inline: false }, 25 | { name: '[en] Translation', value: res.translatedText, inline: false }, 26 | ]; 27 | 28 | Util.sendEmbed(channel, 'Translated', null, Util.makeEmbedFooter(speaker), null, colGreen, embFields); 29 | 30 | return null; 31 | }); 32 | 33 | // const projectId = 'vaebvps'; 34 | // const location = 'global'; 35 | 36 | // const request = { 37 | // parent: index.TranslateClient.locationPath(projectId, location), // projects/vaebvps/locations/global 38 | // contents: [useText], 39 | // mimeType: 'text/plain', // mime types: text/plain, text/html 40 | // sourceLanguageCode: 'ja', 41 | // targetLanguageCode: 'en-US', 42 | // }; 43 | 44 | // const [response] = await index.TranslateClient.translateText(request); 45 | 46 | // for (const translation of response.translations) { 47 | // const embFields = [ 48 | // { name: '[ja] Original', value: `${translation.originalText || args} (${useText})`, inline: false }, 49 | // { name: '[en] Translation', value: translation.translatedText, inline: false }, 50 | // ]; 51 | 52 | // Util.sendEmbed(channel, 'Translated', null, Util.makeEmbedFooter(speaker), null, colGreen, embFields); 53 | // } 54 | }, 55 | }); 56 | -------------------------------------------------------------------------------- /commands/public/NewDiscord.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';newdiscord'], 3 | 4 | requires: { 5 | guild: false, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Update your connected Discord account', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel) => { 18 | Util.print(channel, 'This command is currently disabled'); 19 | // Util.print(speaker, `Click this **personal** link to update your Veil Discord account: https://veil.pkamara.me/linkdiscord.php?discordid=${speaker.id}`); 20 | // Util.sendDescEmbed(channel, speaker.displayName, 'Update link sent, please check your Discord Messages.', null, null, null); 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /commands/public/NowPlaying.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";nowplaying", ";np"], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Get info about the currently playing song", 10 | 11 | args: "", 12 | 13 | example: "", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var guildMusicInfo = Music.guildMusicInfo[guild.id]; 19 | if (guildMusicInfo.activeSong != null) { 20 | Util.sendDescEmbed(channel, "Now Playing", guildMusicInfo.activeSong.title, Util.makeEmbedFooter(speaker), null, colGreen); 21 | } else { 22 | Util.sendDescEmbed(channel, "Now Playing", "No songs are being played", Util.makeEmbedFooter(speaker), null, colGreen); 23 | } 24 | } 25 | }); -------------------------------------------------------------------------------- /commands/public/Offenses.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';offenses', ';badoffenses', ';listoffenses', ';rules'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Output the list of offenses with defined mute times', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: async (cmd, args, msgObj, speaker, channel, guild) => { 18 | const sendEmbedFields = []; 19 | 20 | for (let i = 0; i < Admin.badOffenses.length; i++) { 21 | const offenseData = Admin.badOffenses[i]; 22 | 23 | const offenseStr = offenseData.offense; 24 | const timeStr = Util.formatTime(offenseData.time); 25 | 26 | sendEmbedFields.push({ name: `Tag: [${i}]`, value: `Offense: ${offenseStr}\nDefined Time: ${timeStr}​`, inline: false }); 27 | } 28 | 29 | Util.sendEmbed(channel, 'Bad Offenses', 'If a user commits an offense listed here, their maximum mute time is whichever is larger: The defined time for the offense or their next default mute time.\n\nPut an offense tag at the start of a mute reason to tag it as that offense.', Util.makeEmbedFooter(speaker), null, colBlue, sendEmbedFields); 30 | }, 31 | }); 32 | -------------------------------------------------------------------------------- /commands/public/Ping.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';ping '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Pings a user', 10 | 11 | args: '([@user] | [id] | [name]) ([message])', 12 | 13 | example: 'vaeb fix your bot', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const data = Util.getDataFromString(args, [ 19 | function (str) { 20 | return Util.getMemberByMixed(str, guild); 21 | }, 22 | ], true); 23 | if (!data) return Util.commandFailed(channel, speaker, 'User not found'); 24 | // msgObj.delete(); 25 | const user = data[0]; 26 | const msg = data[1]; 27 | let pingMsg = `${user.toString()} - Ping from ${Util.getName(speaker)} (${speaker.id})`; 28 | if (msg.length > 0) { 29 | pingMsg += ` - ${Util.safe(msg)}`; 30 | } 31 | Util.print(channel, pingMsg); 32 | }, 33 | }); 34 | -------------------------------------------------------------------------------- /commands/public/PingPong.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: ['ping'], 3 | 4 | requires: { 5 | guild: false, 6 | loud: true, 7 | }, 8 | 9 | desc: 'pong', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel) => { 18 | Util.sendDescEmbed(channel, null, 'pong', null, null, null); 19 | }, 20 | }); 21 | -------------------------------------------------------------------------------- /commands/public/Play.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';play ', ';add ', ';addqueue '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: "Make VaeBot play some bangin' tunes (or add them to the queue if the party's already started)", 10 | 11 | args: '([song_name] | [youtube_id] | [youtube_url])', 12 | 13 | example: 'never gonna give you up', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | if (has.call(Music.noPlay, speaker.id)) return; 19 | 20 | Music.joinMusic(guild, channel, () => { 21 | if (args.includes('http')) { 22 | let songId = /[^/=]+$/.exec(args); 23 | if (songId != null && songId[0]) { 24 | songId = songId[0]; 25 | index.YtInfo.getById(songId, (error, result) => { 26 | const songData = result.items[0]; 27 | if (songData != null) { 28 | Music.addSong(speaker, guild, channel, Music.formatSong(songData, false)); 29 | } else { 30 | Util.print(channel, 'Audio not found'); 31 | } 32 | }); 33 | } else { 34 | Util.print(channel, 'Incorrect format for URL'); 35 | } 36 | } else { 37 | index.YtInfo.search(args, 6, (error, result) => { 38 | if (error) { 39 | Util.print(channel, error); 40 | } else { 41 | const items = result.items; 42 | let hasFound = false; 43 | for (let i = 0; i < items.length; i++) { 44 | const songData = items[i]; 45 | if (songData != null && has.call(songData, 'id') && songData.id.kind == 'youtube#video') { 46 | hasFound = true; 47 | Music.addSong(speaker, guild, channel, Music.formatSong(songData, false)); 48 | break; 49 | } 50 | } 51 | if (!hasFound) { 52 | Util.print(channel, 'Audio not found'); 53 | } 54 | } 55 | }); 56 | } 57 | }); 58 | }, 59 | }); 60 | -------------------------------------------------------------------------------- /commands/public/PlayAuto.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";playauto ", ";playa "], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Plays a tune already stored in the auto-playlist", 10 | 11 | args: "[song_name]", 12 | 13 | example: "gonna give you up", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | args = args.toLowerCase(); 19 | var autoPlaylist = Data.guildGet(guild, Data.playlist); 20 | var autoSongs = autoPlaylist.songs; 21 | for (var i = 0; i < autoSongs.length; i++) { 22 | var newSong = autoSongs[i]; 23 | var songData = newSong[0]; 24 | var author = newSong[1]; 25 | var title = songData.snippet.title; 26 | if (title.toLowerCase().indexOf(args) >= 0) { 27 | Music.joinMusic(guild, channel, (connection) => { 28 | Music.addSong(speaker, guild, channel, Music.formatSong(songData, false)); 29 | }); 30 | break; 31 | } 32 | } 33 | } 34 | }); -------------------------------------------------------------------------------- /commands/public/Pop.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";undo", ";pop"], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Remove the last song from the queue which was added by the speaker", 10 | 11 | args: "", 12 | 13 | example: "", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var guildQueue = Music.guildQueue[guild.id]; 19 | Util.log("pop"); 20 | // Util.log(guildQueue); 21 | Util.log("-------POP---------"); 22 | if (guildQueue.length > 0) { 23 | for (var i = guildQueue.length-1; i >= 0; i--) { 24 | var lastSong = guildQueue[i]; 25 | Util.log("Checking " + i + "_" + typeof(lastSong)); 26 | if (lastSong[1].id == speaker.id) { 27 | var title = lastSong[0].title; 28 | Util.print(channel, "Removed", title, "from the queue"); 29 | var connection = guild.voiceConnection; 30 | guildQueue.splice(i, 1); 31 | if (connection != null && Music.guildMusicInfo[guild.id].activeSong != null && title == Music.guildMusicInfo[guild.id].activeSong.title) Music.playNextQueue(guild, channel, true); 32 | break; 33 | } 34 | } 35 | } 36 | } 37 | }); -------------------------------------------------------------------------------- /commands/public/Power.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";power ", ";rank ", ";rate "], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Are you over 9000?!", 10 | 11 | args: "([@user] | [id] | [name])", 12 | 13 | example: "vae", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var target = Util.getMemberByMixed(args, guild); 19 | if (target == null) return Util.commandFailed(channel, speaker, "User not found"); 20 | 21 | var highestRole = Util.getHighestRole(target); 22 | var powerRating = Util.toFixedCut(Util.getPermRating(guild, target), 3) + "%"; 23 | 24 | var sendEmbedFields = []; 25 | 26 | sendEmbedFields.push({name: "Username", value: target.toString()}); 27 | sendEmbedFields.push({name: "Staff", value: Util.capitalize(Util.checkStaff(guild, target))}); 28 | sendEmbedFields.push({name: "Rank", value: highestRole.name + " (" + highestRole.position + ")"}); 29 | sendEmbedFields.push({name: "Power", value: powerRating}); 30 | 31 | Util.sendEmbed(channel, "User Power Ranking", null, Util.makeEmbedFooter(speaker), Util.getAvatar(target), colGreen, sendEmbedFields); 32 | } 33 | }); -------------------------------------------------------------------------------- /commands/public/Queue.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";queue"], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "List all queued songs", 10 | 11 | args: "", 12 | 13 | example: "", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var guildQueue = Music.guildQueue[guild.id]; 19 | 20 | var sendEmbedFields = []; 21 | 22 | for (var i = 0; i < guildQueue.length; i++) { 23 | var songData = guildQueue[i][0]; 24 | var author = guildQueue[i][1]; 25 | sendEmbedFields.push({name: "[" + (i+1) + "] " + songData.title, value: "Added by " + Util.safeEveryone(author.toString()), inline: false}); 26 | } 27 | 28 | Util.sendEmbed(channel, "Audio Queue", null, Util.makeEmbedFooter(speaker), null, colGreen, sendEmbedFields); 29 | } 30 | }); -------------------------------------------------------------------------------- /commands/public/Roles.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";roles"], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Get all guild roles", 10 | 11 | args: "", 12 | 13 | example: "", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var sendEmbedFields = []; 19 | var guildRoles = Util.getGuildRoles(guild); 20 | 21 | for (var i = 0; i < guildRoles.length; i++) { 22 | var nowRole = guildRoles[i]; 23 | sendEmbedFields.push({name: nowRole.name, value: "Position: " + nowRole.position + " | Mentionable: " + nowRole.mentionable + " | Color: " + nowRole.color, inline: false}); 24 | } 25 | 26 | Util.sendEmbed(channel, "Guild Roles", null, Util.makeEmbedFooter(speaker), null, colGreen, sendEmbedFields); 27 | } 28 | }); -------------------------------------------------------------------------------- /commands/public/StartAuto.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";startauto", ";startap"], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Start playing the auto-playlist music", 10 | 11 | args: "", 12 | 13 | example: "", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | Music.joinMusic(guild, channel, connection => { 19 | var autoPlaylist = Data.guildGet(guild, Data.playlist); 20 | if (autoPlaylist.hasOwnProperty("songs") && autoPlaylist.songs.length > 0) { 21 | Util.log("Cmd, Playing Next Auto"); 22 | Music.playNextAuto(guild, channel, true); 23 | } else { 24 | Util.print(channel, "No songs in the auto-playlist"); 25 | } 26 | }); 27 | } 28 | }); -------------------------------------------------------------------------------- /commands/public/StartQueue.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";startqueue"], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Start playing the queued music", 10 | 11 | args: "", 12 | 13 | example: "", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | Music.joinMusic(guild, channel, connection => { 19 | var guildQueue = Music.guildQueue[guild.id]; 20 | if (guildQueue.length > 0) { 21 | Music.playNextQueue(guild, channel, true); 22 | } else { 23 | Util.print(channel, "No songs in queue"); 24 | } 25 | }); 26 | } 27 | }); -------------------------------------------------------------------------------- /commands/public/Syntax.js: -------------------------------------------------------------------------------- 1 | const commands = Cmds.commands; 2 | 3 | module.exports = Cmds.addCommand({ 4 | cmds: [';syntax ', ';help ', ';cmd '], 5 | 6 | requires: { 7 | guild: false, 8 | loud: true, 9 | }, 10 | 11 | desc: 'Display command information', 12 | 13 | args: '', 14 | 15 | example: '', 16 | 17 | // ///////////////////////////////////////////////////////////////////////////////////////// 18 | 19 | func: (cmd, args, msgObj, speaker, channel, guild) => { 20 | let hasFound = false; 21 | 22 | for (let i = 0; i < commands.length; i++) { 23 | const sendEmbedFields = []; 24 | const cmdData = commands[i]; 25 | 26 | const fullCmds = cmdData[0]; 27 | const trimCmds = []; 28 | let isMatch = false; 29 | 30 | for (let c = 0; c < fullCmds.length; c++) { 31 | const nowTrim = fullCmds[c].trim(); 32 | trimCmds.push(nowTrim); 33 | if (nowTrim == args || (nowTrim.substr(0, 1) == ';' && nowTrim.substring(1) == args)) { 34 | isMatch = true; 35 | } 36 | } 37 | 38 | if (!isMatch) continue; 39 | 40 | const cmdRequires = cmdData[2]; 41 | const cmdDesc = cmdData[3]; 42 | const cmdSyntax = cmdData[4]; 43 | const cmdExample = cmdData[5]; 44 | 45 | let cmdType; 46 | 47 | if (cmdRequires.administrator) { 48 | cmdType = 'Administrator'; 49 | } else if (cmdRequires.staff) { 50 | cmdType = 'Staff'; 51 | } else if (cmdRequires.vaeb) { 52 | cmdType = 'Vaeb'; 53 | } else { 54 | cmdType = 'Public'; 55 | } 56 | 57 | sendEmbedFields.push({ name: 'Commands', value: trimCmds.join(' | '), inline: false }); 58 | sendEmbedFields.push({ name: 'Permission Level', value: cmdType, inline: false }); 59 | sendEmbedFields.push({ name: 'Description', value: cmdDesc, inline: false }); 60 | sendEmbedFields.push({ name: 'Syntax', value: `${trimCmds[0]} ${cmdSyntax}`, inline: false }); 61 | sendEmbedFields.push({ name: 'Example', value: `${trimCmds[0]} ${cmdExample}`, inline: false }); 62 | 63 | Util.sendEmbed(channel, 'Command Syntax', null, Util.makeEmbedFooter(speaker), null, colGreen, sendEmbedFields); 64 | 65 | hasFound = true; 66 | 67 | // break; 68 | } 69 | 70 | if (!hasFound) { 71 | Util.sendDescEmbed(channel, 'Command Syntax', 'Command not found', Util.makeEmbedFooter(speaker), null, colGreen); 72 | } 73 | }, 74 | }); 75 | -------------------------------------------------------------------------------- /commands/public/Text.js: -------------------------------------------------------------------------------- 1 | const charToId = { 2 | a: '244832142956298240', 3 | b: '244832158290673664', 4 | c: '244832181501820928', 5 | d: '244832192197296128', 6 | e: '244832201395535873', 7 | f: '244832212535607296', 8 | g: '244832220513042432', 9 | h: '244832228880678913', 10 | i: '244832236463980545', 11 | j: '244832243342639106', 12 | k: '244832250963820545', 13 | l: '244832258274492416', 14 | m: '244832265270591489', 15 | n: '244832272253976577', 16 | o: '244832280281874433', 17 | p: '244832289052164096', 18 | q: '244832298552262657', 19 | r: '244832306878087169', 20 | s: '244832315174420480', 21 | t: '244832323529342976', 22 | u: '244832374343335936', 23 | v: '244832383998754818', 24 | w: '244832392873771019', 25 | x: '244832402856214543', 26 | y: '244832411366588416', 27 | z: '244832419079782400', 28 | }; 29 | 30 | module.exports = Cmds.addCommand({ 31 | cmds: [';txt ', ';text ', ';type '], 32 | 33 | requires: { 34 | guild: false, 35 | loud: false, 36 | }, 37 | 38 | desc: 'Echo your text with emojis', 39 | 40 | args: '([message])', 41 | 42 | example: 'hello there', 43 | 44 | // ///////////////////////////////////////////////////////////////////////////////////////// 45 | 46 | func: (cmd, args, msgObj, speaker, channel, guild) => { 47 | const argsLower = args.toLowerCase(); 48 | 49 | for (let i = 0; i < index.bannedLetters.length; i++) { 50 | if (argsLower.includes(index.bannedLetters[i].toLowerCase())) { 51 | Util.print(channel, 'Nope: The letter `F` is now banned.'); 52 | return; 53 | } 54 | } 55 | 56 | let str = ''; 57 | let wasChar = false; 58 | for (let i = 0; i < args.length; i++) { 59 | let char = args[i]; 60 | const charl = char.toLowerCase(); 61 | if (charToId.hasOwnProperty(charl)) { 62 | char = `<:${charl}_:${charToId[charl]}>`; 63 | if (wasChar) { 64 | char = ` ${char}`; 65 | wasChar = false; 66 | } 67 | } else { 68 | wasChar = true; 69 | } 70 | str += char; 71 | } 72 | // str = str.replace(/@/g, "@​"); 73 | str = Util.safe(str); 74 | Util.print(channel, str); 75 | }, 76 | }); 77 | -------------------------------------------------------------------------------- /commands/public/Ticket.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';ticket ', ';support ', ';ask ', ';addticket ', ';submitticket ', ';sendticket ', ';newticket '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Create a ticket to be viewed by Support', 10 | 11 | args: '([ticket_details])', 12 | 13 | example: 'Am I able to give away my whitelist?', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | if (!channel.name.toLowerCase().includes('support') && !channel.name.toLowerCase().includes('staff') && speaker.id !== vaebId && speaker.id !== guild.ownerID) { 19 | return Util.commandFailed(channel, speaker, 'Support tickets can only be generated in #support'); 20 | } 21 | 22 | const nextTicketNum = Data.nextIncGet('tickets'); 23 | 24 | const newRow = { 25 | user_id: speaker.id, 26 | description: args, 27 | open_tick: +new Date(), 28 | active: 1, 29 | }; 30 | Data.addRecord(guild, 'tickets', newRow); 31 | 32 | const sendEmbedFields = [ 33 | { name: 'Ticket User', value: Util.resolveMention(speaker), inline: false }, 34 | { name: 'Ticket Info', value: args, inline: false }, 35 | ]; 36 | Util.sendEmbed(channel, `Generated Support Ticket #${nextTicketNum}`, null, Util.makeEmbedFooter(speaker), null, colGreen, sendEmbedFields); 37 | 38 | const roleSupport = Util.getRole('Support', guild); 39 | 40 | if (roleSupport) { 41 | const roleTrialSupport = Util.getRole('Trial Support', guild); 42 | const mentionSupport = roleTrialSupport ? `${roleSupport.toString()} ${roleTrialSupport.toString()}` : roleSupport.toString(); 43 | Util.print(channel, `${mentionSupport} A new support ticket has been generated by ${Util.resolveMention(speaker)}!`); 44 | } 45 | 46 | return true; 47 | }, 48 | }); 49 | -------------------------------------------------------------------------------- /commands/public/Toggle.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';toggle '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Toggle an autorole on the speaker', 10 | 11 | args: '([auto_role_name_1] .. [auto_role_name_n])', 12 | 13 | example: 'hire', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const guildAutoRoles = Data.guildGet(guild, Data.autoRoles); 19 | const props = args 20 | .toLowerCase() 21 | .trim() 22 | .split(' '); 23 | const rolesAdded = []; 24 | const rolesRemoved = []; 25 | 26 | for (let i = 0; i < props.length; i++) { 27 | const prop = props[i]; 28 | 29 | if (!Object.prototype.hasOwnProperty.call(guildAutoRoles, prop)) { 30 | return; 31 | } 32 | 33 | const roleName = guildAutoRoles[prop]; 34 | const roleObj = Util.getRole(roleName, guild); 35 | 36 | if (!Util.hasRole(speaker, roleObj)) { 37 | speaker.addRole(roleObj).catch(console.error); 38 | rolesAdded.push(roleObj.name); 39 | } else { 40 | speaker.removeRole(roleObj).catch(console.error); 41 | rolesRemoved.push(roleObj.name); 42 | } 43 | } 44 | 45 | const sendEmbedFields = []; 46 | 47 | if (rolesAdded.length > 0) { 48 | sendEmbedFields.push({ name: 'Roles Added', value: rolesAdded.join('\n') }); 49 | } 50 | 51 | if (rolesRemoved.length > 0) { 52 | sendEmbedFields.push({ name: 'Roles Removed', value: rolesRemoved.join('\n') }); 53 | } 54 | 55 | Util.sendEmbed( 56 | channel, 57 | 'User Roles Altered', 58 | null, 59 | Util.makeEmbedFooter(speaker), 60 | Util.getAvatar(speaker), 61 | colGreen, 62 | sendEmbedFields, 63 | ); 64 | }, 65 | }); 66 | -------------------------------------------------------------------------------- /commands/public/Translate.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';translate '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Translate a word/sentence into English', 10 | 11 | args: '([word] | [sentence])', 12 | 13 | example: 'Hola mis amigos', 14 | 15 | func: (cmd, args, msgObj, speaker, channel, guild) => { 16 | index.Translate.translate(args, 'en', (err, res) => { 17 | if (err) return console.log(err); 18 | 19 | const embFields = [ 20 | { name: `[${res.detectedSourceLanguage}] Original`, value: res.originalText || args, inline: false }, 21 | { name: '[en] Translation', value: res.translatedText, inline: false }, 22 | ]; 23 | 24 | Util.sendEmbed(channel, 'Translated', null, Util.makeEmbedFooter(speaker), null, colGreen, embFields); 25 | }); 26 | 27 | return undefined; 28 | }, 29 | 30 | // export GOOGLE_APPLICATION_CREDENTIALS="/home/einsteink/VaebVPS-4cce7d4f015f.json" 31 | 32 | // func: async (cmd, args, msgObj, speaker, channel, guild) => { 33 | // const projectId = 'vaebvps'; 34 | // const location = 'global'; 35 | 36 | // const request = { 37 | // parent: index.TranslateClient.locationPath(projectId, location), // projects/vaebvps/locations/global 38 | // contents: [args], 39 | // mimeType: 'text/plain', // mime types: text/plain, text/html 40 | // targetLanguageCode: 'en-US', 41 | // }; 42 | 43 | // const [response] = await index.TranslateClient.translateText(request); 44 | 45 | // for (const translation of response.translations) { 46 | // const embFields = [ 47 | // { name: `[${translation.detectedSourceLanguage}] Original`, value: translation.originalText || args, inline: false }, 48 | // { name: '[en] Translation', value: translation.translatedText, inline: false }, 49 | // ]; 50 | 51 | // Util.sendEmbed(channel, 'Translated', null, Util.makeEmbedFooter(speaker), null, colGreen, embFields); 52 | // } 53 | // }, 54 | }); 55 | -------------------------------------------------------------------------------- /commands/public/UpdateOwner.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';updateowner'], 3 | 4 | requires: { 5 | guild: false, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Update your Vashta Owner role', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | Util.print(channel, 'This command is currently disabled'); 19 | 20 | // const newBuyer = guild.roles.find('name', 'Vashta-Owner'); 21 | 22 | // Data.query(`SELECT * FROM whitelist WHERE Disabled IS NULL AND DiscordId=${speaker.id};`, null, Data.connectionVeil).then( 23 | // (whitelistData) => { 24 | // if (whitelistData.length > 0) { 25 | // Util.sendDescEmbed(channel, speaker.displayName, 'Vashta owner confirmed, role given.', null, null, null); 26 | 27 | // speaker.addRole(newBuyer).catch(console.error); 28 | // } else { 29 | // // Util.sendDescEmbed(channel, speaker.displayName, 'You are not registered as a Vashta owner, if you do own Veil please say `;newdiscord` and follow the given link before using this command.', null, null, null); 30 | // Util.sendDescEmbed(channel, speaker.displayName, 'You are not registered as a Vashta owner.', null, null, null); 31 | 32 | // if (Util.hasRole(speaker, newBuyer)) { 33 | // speaker.removeRole(newBuyer).catch(console.error); 34 | // } 35 | // } 36 | // }, 37 | // ); 38 | }, 39 | }); 40 | -------------------------------------------------------------------------------- /commands/public/VoteSkip.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';voteskip'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Vote to skip the current song (will skip when the vote reaches 50% of the users in the voice channel)', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | const connection = guild.voiceConnection; 19 | if (connection) { 20 | const allChannels = guild.channels; 21 | const voiceChannel = allChannels.find((c) => { 22 | if (!c.type == 'voice') return false; 23 | const hasMember = c.members.find(o => o.id == selfId); 24 | if (hasMember != null) return true; 25 | return false; 26 | }); 27 | const voiceMembers = voiceChannel.members; 28 | const numMembers = voiceMembers.size - 1; 29 | if (!voiceMembers.find(o => o.id == speaker.id)) { 30 | Util.print(channel, 'You are not in the voice channel'); 31 | return; 32 | } 33 | let alreadyExists = false; 34 | const guildMusicInfo = Music.guildMusicInfo[guild.id]; 35 | const voteSkips = guildMusicInfo.voteSkips; 36 | for (let i = 0; i < voteSkips.length; i++) { 37 | if (voteSkips[i] == speaker.id) { 38 | alreadyExists = true; 39 | break; 40 | } 41 | } 42 | if (alreadyExists == true) { 43 | Util.print(channel, "You can't vote more than once!"); 44 | return; 45 | } 46 | voteSkips.push(speaker.id); 47 | const numVotes = voteSkips.length; 48 | const voteStr = numVotes == 1 ? 'vote' : 'votes'; 49 | Util.print(channel, 'Vote skip:', numVotes, voteStr); 50 | Util.log(`Vote skip: ${numVotes / numMembers}`); 51 | if (numVotes / numMembers >= 0.5) { 52 | const guildQueue = Music.guildQueue[guild.id]; 53 | const autoPlaylist = Data.guildGet(guild, Data.playlist); 54 | const firstInQueue = guildQueue[0]; 55 | if (guildMusicInfo.isAuto == false && guildQueue.length > 0 && guildMusicInfo.activeSong != null && guildMusicInfo.activeSong.title == firstInQueue[0].title) guildQueue.splice(0, 1); 56 | Music.playNextQueue(guild, channel, true); 57 | } 58 | } 59 | }, 60 | }); 61 | -------------------------------------------------------------------------------- /commands/staff/ChangeMute.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';changemute ', ';change ', ';setmute ', 'altermute '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Change details of an active mute', 10 | 11 | args: '([user_resolvable]) (OPTIONAL: [mute_length]) (OPTIONAL: [mute_length_format]) (OPTIONAL: [reason])', 12 | 13 | example: 'vae 3 spamming multiple channels', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | args = args.trim(); 19 | 20 | const data = Util.getDataFromString(args, 21 | [ 22 | [ 23 | function (str) { 24 | return Util.getMemberByMixed(str, guild) || Util.isId(str); 25 | }, 26 | ], 27 | [ 28 | function (str) { 29 | const timeHours = Util.matchWholeNumber(str); 30 | return timeHours; 31 | }, 32 | ], 33 | [ 34 | function (str) { 35 | let mult; 36 | str = str.toLowerCase(); 37 | if (str.substr(str.length - 1, 1) == 's' && str != 'ms' && str != 's') str = str.substr(0, str.length - 1); 38 | if (str == 'millisecond' || str == 'ms') mult = 1 / 60 / 60 / 1000; 39 | if (str == 'second' || str == 's' || str == 'sec') mult = 1 / 60 / 60; 40 | if (str == 'minute' || str == 'm' || str == 'min') mult = 1 / 60; 41 | if (str == 'hour' || str == 'h') mult = 1; 42 | if (str == 'day' || str == 'd') mult = 24; 43 | if (str == 'week' || str == 'w') mult = 24 * 7; 44 | if (str == 'month' || str == 'mo') mult = 24 * 30.42; 45 | if (str == 'year' || str == 'y') mult = 24 * 365.2422; 46 | return mult; 47 | }, 48 | ], 49 | ] 50 | , true); 51 | 52 | if (!data) { 53 | return Util.sendEmbed(channel, 'ChangeMute Failed', 'User not found', Util.makeEmbedFooter(speaker), null, colGreen, null); 54 | } 55 | 56 | Util.log(`Change Arg Data: ${data}`); 57 | 58 | const member = data[0]; 59 | const mult = data[2] || 1; 60 | const time = data[1] ? data[1] * 1000 * 60 * 60 * mult : null; 61 | const reason = data[3]; 62 | 63 | Admin.changeMute(guild, channel, member, speaker, { 'time': time, 'reason': reason }); 64 | 65 | return true; 66 | }, 67 | }); 68 | -------------------------------------------------------------------------------- /commands/staff/Clear.js: -------------------------------------------------------------------------------- 1 | const checkFuncs = { 2 | user: ((msgObj, userId) => msgObj.author.id === userId), 3 | 4 | regex: ((msgObj, regexObj) => regexObj.test(msgObj.content)), 5 | 6 | all: (() => true), 7 | 8 | cmd: (msgObj => msgObj.author.id === selfId || Cmds.getCommand(msgObj.content) != null), 9 | 10 | bot: (msgObj => msgObj.author.bot === true), 11 | 12 | hook: (msgObj => msgObj.author.bot === true), 13 | 14 | image: ((msgObj) => { 15 | const embeds = msgObj.embeds || []; 16 | const attachments = msgObj.attachments || []; 17 | 18 | for (let i = 0; i < embeds.length; i++) { 19 | const nowEmbed = embeds[i]; 20 | if (nowEmbed.type === 'image' || nowEmbed.type === 'gifv' || nowEmbed.type === 'gif' || nowEmbed.type === 'webm') { 21 | return true; 22 | } 23 | } 24 | 25 | for (let i = 0; i < attachments.length; i++) { 26 | const nowAtt = attachments[i]; 27 | if (has.call(nowAtt, 'width')) { 28 | return true; 29 | } 30 | } 31 | 32 | return false; 33 | }), 34 | 35 | file: ((msgObj) => { 36 | const attachments = msgObj.attachments != null ? msgObj.attachments : []; 37 | 38 | for (let i = 0; i < attachments.length; i++) { 39 | const nowAtt = attachments[i]; 40 | if (!has.call(nowAtt, 'width')) { 41 | return true; 42 | } 43 | } 44 | 45 | return false; 46 | }), 47 | 48 | link: ((msgObj) => { 49 | if (Util.checkURLs(msgObj.content).length > 0) return true; 50 | 51 | const embeds = msgObj.embeds != null ? msgObj.embeds : []; 52 | 53 | for (let i = 0; i < embeds.length; i++) { 54 | const nowEmbed = embeds[i]; 55 | if (nowEmbed.type === 'link') { 56 | return true; 57 | } 58 | } 59 | 60 | return false; 61 | }), 62 | 63 | mention: ((msgObj) => { 64 | const mentions = msgObj.mentions; 65 | 66 | return mentions.length > 0; 67 | }), 68 | }; 69 | 70 | module.exports = Cmds.addCommand({ 71 | cmds: [';clear ', ';clean ', ';wipe ', ';clearchats ', ';cleanchats '], 72 | 73 | requires: { 74 | guild: true, 75 | loud: false, 76 | }, 77 | 78 | desc: 'Delete the last <1-1000> messages matching a [user | regex-pattern | message-type] in the channel', 79 | 80 | args: '([userResolvable] | [/regex/] | [all | bots | hooks | images | files | links | mentions]) (<1-1000>)', 81 | 82 | example: 'vaeb 30', 83 | 84 | // ///////////////////////////////////////////////////////////////////////////////////////// 85 | 86 | func: async (cmd, args, msgObj, speaker, channel, guild) => { 87 | const data = Util.getDataFromString(args, [ 88 | function (str) { 89 | let lower = str.toLowerCase(); 90 | if (lower.substring(lower.length - 1) === 's') lower = lower.substr(0, lower.length - 1); 91 | // types 92 | if (lower === 'all' || lower === 'cmd' || lower === 'bot' || lower === 'hook' || lower === 'image' || lower === 'file' || lower === 'link' || lower === 'mention') { 93 | return [lower]; 94 | } 95 | // regex 96 | const regMatch = /^\/(.+)\/$/.exec(str); 97 | if (regMatch) return ['regex', regMatch[1]]; 98 | // member 99 | const member = Util.getMemberByMixed(str, guild); 100 | if (member) return ['member', member]; 101 | // user id 102 | const userId = Util.isId(str); 103 | if (userId) return ['id', userId]; 104 | return undefined; 105 | }, 106 | function (str) { 107 | let numArgs = Number(str); 108 | if (!isNaN(numArgs) && numArgs >= 1) { 109 | numArgs = Util.round(numArgs, 1); 110 | numArgs = Math.min(numArgs, 1000); 111 | return numArgs; 112 | } 113 | return undefined; 114 | }, 115 | ], true); 116 | if (!data) { 117 | return Util.commandFailed(channel, speaker, 'Invalid parameters'); 118 | } 119 | 120 | const matchData = data[0]; 121 | let numArgs = data[1]; 122 | // const scope = data[2]; 123 | const matchType = matchData[0]; 124 | const matchVal = matchData[1]; 125 | 126 | let funcData; 127 | if (matchType === 'member') { 128 | funcData = matchVal.id; 129 | } else if (matchType === 'id') { 130 | funcData = matchVal; 131 | } else if (matchType === 'regex') { 132 | funcData = new RegExp(matchVal, 'gim'); 133 | } 134 | 135 | let includeSelf = false; 136 | 137 | if (matchType === 'all' || funcData === speaker.id) { 138 | includeSelf = true; 139 | numArgs++; 140 | } 141 | 142 | let checkFunc; 143 | 144 | if (matchType === 'member' || matchType === 'id') { 145 | checkFunc = checkFuncs.user; 146 | } else { 147 | checkFunc = checkFuncs[matchType]; 148 | } 149 | 150 | let numSearch = matchType !== 'all' ? numArgs * 30 : numArgs; 151 | numSearch = Math.min(numSearch, 1000); 152 | 153 | let last = null; 154 | if (matchType === 'cmd') { 155 | last = msgObj; 156 | numArgs *= 2; 157 | } 158 | 159 | const msgStore = []; 160 | 161 | // +++++++++++++++++++++ MESSAGE SCANNING +++++++++++++++++++++ 162 | 163 | await Util.fetchMessagesEx(channel, numSearch, msgStore, last); 164 | Util.log(`Messages checked: ${msgStore.length}`); 165 | 166 | const msgStoreUser = []; 167 | for (let i = 0; i < msgStore.length; i++) { 168 | const nowMsgObj = msgStore[i]; 169 | if ((includeSelf || nowMsgObj.id !== msgObj.id) && checkFunc(nowMsgObj, funcData)) { 170 | msgStoreUser.push(nowMsgObj); 171 | if (msgStoreUser.length >= numArgs) break; 172 | } 173 | } 174 | 175 | const storeLength = msgStoreUser.length; 176 | const chunkLength = 99; 177 | Util.log(`Matches found: ${msgStoreUser.length}`); 178 | 179 | for (let i = 0; i < storeLength; i += chunkLength) { 180 | const chunk = msgStoreUser.slice(i, i + chunkLength); 181 | 182 | if (chunk.length > 1) { 183 | channel.bulkDelete(chunk) 184 | .then(() => Util.log(`Cleared ${chunk.length} messages`)) 185 | .catch(Util.logErr); 186 | } else { 187 | chunk[0].delete() 188 | .then(() => Util.log('Cleared 1 message')) 189 | .catch(Util.logErr); 190 | } 191 | } 192 | 193 | return undefined; 194 | }, 195 | }); 196 | -------------------------------------------------------------------------------- /commands/staff/ClearQueue.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';clearqueue'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: "Clears VaeBot's queue of music", 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | Music.clearQueue(guild); 19 | Util.print(channel, 'Cleared queue'); 20 | }, 21 | }); 22 | -------------------------------------------------------------------------------- /commands/staff/GetBans.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';bans', ';getbans'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Get all banned users', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | guild.fetchBans().then((bans) => { 19 | const outStr = ['**Guild bans:**\n```']; 20 | bans.forEach((user) => { 21 | outStr.push(`Username: ${Util.getName(user)}`); 22 | }); 23 | outStr.push('```'); 24 | Util.print(channel, outStr.join('\n')); 25 | }); 26 | }, 27 | }); 28 | -------------------------------------------------------------------------------- /commands/staff/HardKick.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';hardkick ', ';hardeject ', ';softban '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Kick a user from the guild (extra hard)', // Does this command even do anything????????????????? 10 | 11 | args: '([@user] | [id] | [name]) ([reason])', 12 | 13 | example: 'vaeb being weird', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | if (speaker.id == '138274235435974656') return Util.commandFailed(channel, speaker, 'Temporarily disabled kick permissions for this moderator as a precaution due to complaints'); 19 | const data = Util.getDataFromString(args, [ 20 | function (str) { 21 | return Util.getMemberByMixed(str, guild); 22 | }, 23 | ], true); 24 | if (!data) return Util.commandFailed(channel, speaker, 'User not found'); 25 | const target = data[0]; 26 | const reason = data[1]; 27 | if (Util.getPosition(speaker) <= Util.getPosition(target)) { 28 | Util.commandFailed(channel, speaker, 'User has equal or higher rank'); 29 | return false; 30 | } 31 | const targName = Util.getName(target); 32 | const targId = Util.safe(target.id); 33 | 34 | const outStr = ['**You have been hard-kicked**\n```']; 35 | outStr.push(`Guild: ${guild.name}`); 36 | outStr.push(`Reason: ${reason}`); 37 | outStr.push('What is a hardkick: Hardkicks ban and instantly unban the user, causing their recent messages to be deleted and possibly causing Discord to temporarily cache their IP as banned.'); 38 | outStr.push('```'); 39 | Util.print(target, outStr.join('\n')); 40 | 41 | guild.ban(target.id, { days: 1, reason }) 42 | .then(() => { 43 | guild.unban(target.id) 44 | .catch(Util.logErr); 45 | }) 46 | .catch(Util.logErr); 47 | 48 | Util.print(channel, 'Hard Kicked', Util.fix(targName), `(${targId}) for`, Util.fix(reason)); 49 | if (guild.id == '168742643021512705') index.dailyKicks.push([targId, `${targName}#${target.discriminator}`, reason]); 50 | 51 | const sendLogData = [ 52 | 'Guild Hard Kick', 53 | guild, 54 | target, 55 | { name: 'Username', value: target.toString() }, 56 | { name: 'Moderator', value: speaker.toString() }, 57 | { name: 'Kick Reason', value: reason }, 58 | ]; 59 | Util.sendLog(sendLogData, colAction); 60 | 61 | return true; 62 | }, 63 | }); 64 | -------------------------------------------------------------------------------- /commands/staff/History.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';history', ';mutehistory'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Get all users with mute history', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: async (cmd, args, msgObj, speaker, channel, guild) => { 18 | const sendEmbedFields = []; 19 | 20 | const allMutes = await Data.getRecords(guild, 'mutes'); 21 | 22 | const numMutesKeys = {}; 23 | const numMutesArr = []; 24 | 25 | const splitMutesKeys = {}; 26 | const splitMutesArr = []; 27 | 28 | for (let i = 0; i < allMutes.length; i++) { 29 | const record = allMutes[i]; 30 | const userId = record.user_id; 31 | if (!has.call(numMutesKeys, userId)) numMutesKeys[userId] = numMutesArr.push([`<@${userId}>`, 0]) - 1; 32 | ++numMutesArr[numMutesKeys[userId]][1]; 33 | } 34 | 35 | for (let i = 0; i < numMutesArr.length; i++) { 36 | const userMention = numMutesArr[i][0]; 37 | const numMutes = numMutesArr[i][1]; 38 | if (!has.call(splitMutesKeys, numMutes)) { 39 | const chunk = []; 40 | chunk.numMutes = numMutes; 41 | splitMutesKeys[numMutes] = splitMutesArr.push(chunk) - 1; 42 | } 43 | splitMutesArr[splitMutesKeys[numMutes]].push(userMention); 44 | } 45 | 46 | splitMutesArr.sort((a, b) => a.numMutes - b.numMutes); 47 | 48 | for (let i = 0; i < splitMutesArr.length; i++) { 49 | const splitMutesChunk = splitMutesArr[i]; 50 | const numMutes = splitMutesChunk.numMutes; 51 | sendEmbedFields.push({ name: `${numMutes} Mute${numMutes == 1 ? '' : 's'}`, value: splitMutesChunk.join('\n'), inline: false }); 52 | } 53 | 54 | Util.sendEmbed(channel, 'Mute History', null, Util.makeEmbedFooter(speaker), null, colBlue, sendEmbedFields); 55 | }, 56 | }); 57 | 58 | -------------------------------------------------------------------------------- /commands/staff/Join.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";join ", ";summon "], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Make VaeBot join a voice channel", 10 | 11 | args: "([voice_channel_name])", 12 | 13 | example: "gaming", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var vChannel = Util.getVoiceChannels(guild).find(channel => args == "<#" + channel.id + ">" || channel.name.toLowerCase().indexOf(args.toLowerCase()) >= 0); 19 | if (vChannel) { 20 | vChannel.join() 21 | .then(connection => Util.print(channel, "Joined", vChannel.name)) 22 | .catch(error => Util.log("[E_JoinCmd] addRole: " + error)); 23 | } else { 24 | Util.print(channel, "Voice channel not found"); 25 | } 26 | } 27 | }); -------------------------------------------------------------------------------- /commands/staff/Kick.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';kick ', ';eject '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Kick a user from the guild', 10 | 11 | args: '([@user] | [id] | [name]) ([reason])', 12 | 13 | example: 'vaeb being weird', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: async (cmd, args, msgObj, speaker, channel, guild) => { 18 | if (speaker.id == '138274235435974656') { 19 | return Util.commandFailed( 20 | channel, 21 | speaker, 22 | 'Temporarily disabled kick permissions for this moderator as a precaution due to complaints', 23 | ); 24 | } 25 | const data = Util.getDataFromString( 26 | args, 27 | [ 28 | function (str) { 29 | return Util.getMemberByMixed(str, guild); 30 | }, 31 | ], 32 | true, 33 | ); 34 | if (!data) return Util.commandFailed(channel, speaker, 'User not found'); 35 | const target = data[0]; 36 | const reason = data[1]; 37 | if (Util.getPosition(speaker) <= Util.getPosition(target)) { 38 | Util.commandFailed(channel, speaker, 'User has equal or higher rank'); 39 | return false; 40 | } 41 | const targName = Util.getName(target); 42 | const targId = Util.safe(target.id); 43 | 44 | const outStr = ['**You have been kicked**\n```']; 45 | outStr.push(`Guild: ${guild.name}`); 46 | outStr.push(`Reason: ${reason}`); 47 | outStr.push('```'); 48 | await Util.print(target, outStr.join('\n')); 49 | 50 | Util.kickMember(target, speaker, reason); 51 | 52 | Util.print(channel, 'Kicked', Util.fix(targName), `(${targId}) for`, Util.fix(reason)); 53 | if (guild.id == '168742643021512705') index.dailyKicks.push([targId, `${targName}#${target.discriminator}`, reason]); 54 | 55 | const sendLogData = [ 56 | 'Guild Kick', 57 | guild, 58 | target, 59 | { name: 'Username', value: target.toString() }, 60 | { name: 'Moderator', value: speaker.toString() }, 61 | { name: 'Kick Reason', value: reason }, 62 | ]; 63 | Util.sendLog(sendLogData, colAction); 64 | 65 | return true; 66 | }, 67 | }); 68 | -------------------------------------------------------------------------------- /commands/staff/Leave.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";leave", ";exit"], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Make VaeBot leave it's voice channel", 10 | 11 | args: "", 12 | 13 | example: "", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | Music.clearQueue(guild); 19 | var connection = guild.voiceConnection; 20 | if (!connection) return Util.commandFailed(channel, speaker, "Not in a voice channel"); 21 | var voiceChannel = connection.channel; 22 | connection.disconnect(); 23 | Util.sendDescEmbed(channel, "Left Voice Channel", voiceChannel.name, Util.makeEmbedFooter(speaker), null, colGreen); 24 | } 25 | }); -------------------------------------------------------------------------------- /commands/staff/Mute.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';mute ', ';mutehammer ', ';arrest '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Mute a user (in all guild channels) and add the mute to their record', 10 | 11 | args: '([user_resolvable]) (OPTIONAL: [mute_length]) (OPTIONAL: [mute_length_format]) (OPTIONAL: [reason])', 12 | 13 | example: 'vae 2 minutes being weird', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: async (cmd, args, msgObj, speaker, channel, guild) => { 18 | args = args.trim(); 19 | 20 | const data = Util.getDataFromString( 21 | args, 22 | [ 23 | [ 24 | function (str) { 25 | return Util.getMemberByMixed(str, guild) || Util.isId(str); 26 | }, 27 | ], 28 | [ 29 | function (str) { 30 | return Util.matchWholeNumber(str); 31 | }, 32 | ], 33 | [ 34 | function (str) { 35 | let timeMult; 36 | str = str.toLowerCase(); 37 | if (str.substr(str.length - 1, 1) == 's' && str.length > 2) str = str.substr(0, str.length - 1); 38 | if (str == 'millisecond' || str == 'ms') timeMult = 1 / 60 / 60 / 1000; 39 | if (str == 'second' || str == 's' || str == 'sec') timeMult = 1 / 60 / 60; 40 | if (str == 'minute' || str == 'm' || str == 'min') timeMult = 1 / 60; 41 | if (str == 'hour' || str == 'h') timeMult = 1; 42 | if (str == 'day' || str == 'd') timeMult = 24; 43 | if (str == 'week' || str == 'w') timeMult = 24 * 7; 44 | if (str == 'month' || str == 'mo') timeMult = 24 * 30.42; 45 | if (str == 'year' || str == 'y') timeMult = 24 * 365.2422; 46 | return timeMult; 47 | }, 48 | ], 49 | ], 50 | true, 51 | ); 52 | 53 | if (!data) { 54 | return Util.sendEmbed(channel, 'Mute Failed', 'User not found', Util.makeEmbedFooter(speaker), null, colGreen, null); 55 | } 56 | 57 | Util.log(`Change Arg Data: ${data}`); 58 | 59 | const member = data[0]; 60 | const mult = data[2] || 1 / 60; 61 | const time = data[1] ? data[1] * 1000 * 60 * 60 * mult : null; 62 | const reason = data[3]; 63 | 64 | let success; 65 | 66 | /* if (speaker.id == '119203482598244356') { 67 | member = speaker; 68 | speaker = speaker.displayName; 69 | } */ 70 | 71 | if (Admin.checkMuted(guild, member.id)) { 72 | Util.print( 73 | channel, 74 | `<@${ 75 | speaker.id 76 | }> Are you sure you want to re-mute that guy instead of using \`;changemute\`...?\n\n You only need to re-mute if it's a separate offense.`, 77 | ); 78 | 79 | const isResponse = msgObjTemp => msgObjTemp.author.id == speaker.id; 80 | 81 | channel 82 | .awaitMessages(isResponse, { max: 1, time: 1000 * 25, errors: ['time'] }) 83 | .then(async (collected) => { 84 | const response = collected.first(); 85 | const responseMsg = response.content; 86 | 87 | if (/y[aeiouy]+?[shp]|y[aeiy]+?\b|\by\b/.test(responseMsg.toLowerCase())) { 88 | Util.print(channel, 'Well okay then, your will is my command...'); 89 | success = await Admin.addMute(guild, channel, member, speaker, { time, reason }); 90 | } else { 91 | Util.print(channel, 'Guess you made a mistake eh... Well fine, your request has been cancelled.'); 92 | } 93 | }) 94 | .catch(() => { 95 | Util.print( 96 | channel, 97 | `What a drag, I've been waiting far too long for an answer <@${speaker.id}>, snails get stitches...`, 98 | ); 99 | Admin.addMute(guild, channel, speaker, 'System', { time: 1000 * 60 * 1.5, reason: 'Snails get stitches' }); 100 | }); 101 | } else { 102 | success = await Admin.addMute(guild, channel, member, speaker, { time, reason }); 103 | } 104 | 105 | if (time === null && success === true) { 106 | Util.print( 107 | channel, 108 | `This user was muted for their default mute time (based on their mute history), do you want to change it <@${ 109 | speaker.id 110 | }>? If you do, just tell me the new time now...`, 111 | ); 112 | 113 | const isResponse = msgObjTemp => msgObjTemp.author.id == speaker.id; 114 | 115 | channel 116 | .awaitMessages(isResponse, { max: 1, time: 1000 * 25, errors: ['time'] }) 117 | .then((collected) => { 118 | const response = collected.first(); 119 | let responseMsg = response.content; 120 | 121 | responseMsg = responseMsg 122 | .replace(/<@.?\d+?>\s*/g, '') 123 | .replace(/[^\sa-z0-9]+/gi, '') 124 | .trim(); 125 | 126 | if (/\bno|no\b|\bcancel|\bkeep|\bdont|^n$/i.test(responseMsg)) { 127 | Util.print(channel, 'Got it!'); 128 | return; 129 | } 130 | 131 | const data2 = Util.getDataFromString( 132 | responseMsg, 133 | [ 134 | [ 135 | function (str) { 136 | return Util.matchWholeNumber(str); 137 | }, 138 | ], 139 | [ 140 | function (str) { 141 | let timeMult; 142 | str = str.toLowerCase(); 143 | if (str.substr(str.length - 1, 1) == 's' && str.length > 2) str = str.substr(0, str.length - 1); 144 | if (str == 'millisecond' || str == 'ms') timeMult = 1 / 60 / 60 / 1000; 145 | if (str == 'second' || str == 's' || str == 'sec') timeMult = 1 / 60 / 60; 146 | if (str == 'minute' || str == 'm' || str == 'min') timeMult = 1 / 60; 147 | if (str == 'hour' || str == 'h') timeMult = 1; 148 | if (str == 'day' || str == 'd') timeMult = 24; 149 | if (str == 'week' || str == 'w') timeMult = 24 * 7; 150 | if (str == 'month' || str == 'mo') timeMult = 24 * 30.42; 151 | if (str == 'year' || str == 'y') timeMult = 24 * 365.2422; 152 | return timeMult; 153 | }, 154 | ], 155 | ], 156 | true, 157 | ); 158 | 159 | if (!data2) return; 160 | 161 | Util.log(`Change Arg Data New: ${data2}`); 162 | 163 | const mult2 = data2[1] || 1 / 60; 164 | const time2 = data2[0] ? data2[0] * 1000 * 60 * 60 * mult2 : null; 165 | 166 | if (time2 == null) return; 167 | 168 | Admin.changeMute(guild, channel, member, speaker, { time: time2 }); 169 | }) 170 | .catch(console.log); 171 | } 172 | 173 | return true; 174 | }, 175 | }); 176 | -------------------------------------------------------------------------------- /commands/staff/Mutes.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';mutes', ';muted'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Get all currently muted users', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: async (cmd, args, msgObj, speaker, channel, guild) => { 18 | const activeMutes = await Data.getRecords(guild, 'mutes', { active: 1 }); 19 | 20 | const nowDate = +new Date(); 21 | 22 | const sendEmbedFields = []; 23 | 24 | for (let i = 0; i < activeMutes.length; i++) { 25 | const muteRecord = activeMutes[i]; 26 | const targetId = muteRecord.user_id; 27 | const modId = muteRecord.mod_id; 28 | const startTime = muteRecord.start_tick; 29 | const endTime = muteRecord.end_tick; 30 | const reason = muteRecord.mute_reason; 31 | 32 | const remaining = endTime - nowDate; 33 | const timeStr = Util.formatTime(remaining); 34 | // const targUser = Util.getUserById(targetId); 35 | // const targName = targUser == null ? targetId : Util.getMostName(targUser); 36 | const muteDate = new Date(startTime); 37 | const muteDateStr = Util.getDateString(muteDate); 38 | 39 | sendEmbedFields.push({ name: `[${i + 1}] ${muteDateStr}`, value: `​User: <@${targetId}>\nReason: ${reason}\nModerator: <@${modId}>\nRemaining: ${timeStr}​`, inline: false }); 40 | } 41 | 42 | Util.sendEmbed(channel, 'Active Mutes', null, Util.makeEmbedFooter(speaker), null, colBlue, sendEmbedFields); 43 | }, 44 | }); 45 | -------------------------------------------------------------------------------- /commands/staff/Nickname.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";nick ", ";nickname "], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Set a user's nickname", 10 | 11 | args: "([@user] | [id] | [name]) ([new_nickname])", 12 | 13 | example: "vae vaeben", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var data = Util.getDataFromString(args, [ 19 | function(str, results) { 20 | return Util.getMemberByMixed(str, guild); 21 | } 22 | ], true); 23 | 24 | if (!data) return Util.commandFailed(channel, speaker, "Invalid parameters"); 25 | 26 | var member = data[0]; 27 | var nick = data[1]; 28 | 29 | if ((member.id == vaebId || member.id == selfId) && speaker.id != vaebId) { 30 | Util.commandFailed(channel, speaker, "You are not allowed to set developer nicknames"); 31 | return; 32 | } 33 | 34 | if (Util.getPosition(speaker) <= Util.getPosition(member) && member != speaker) { 35 | Util.commandFailed(channel, speaker, "User has equal or higher rank"); 36 | return; 37 | } 38 | 39 | var previousNick = member.nickname; 40 | 41 | member.setNickname(nick); 42 | 43 | var sendEmbedFields = [ 44 | {name: "Username", value: member.toString()}, 45 | {name: "Old Nickname", value: previousNick}, 46 | {name: "New Nickname", value: nick} 47 | ]; 48 | 49 | Util.sendEmbed(channel, "Nickname Updated", null, Util.makeEmbedFooter(speaker), Util.getAvatar(member), colGreen, sendEmbedFields); 50 | 51 | var sendLogData = [ 52 | "Set Nickname", 53 | guild, 54 | member, 55 | {name: "Username", value: member.toString()}, 56 | {name: "Moderator", value: speaker.toString()}, 57 | {name: "Nickname", value: nick} 58 | ]; 59 | 60 | Util.sendLog(sendLogData, colAction); 61 | } 62 | }); -------------------------------------------------------------------------------- /commands/staff/PlayF.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";playf "], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Make VaeBot play some bangin' tunes... from a file :o", 10 | 11 | args: "([file_name])", 12 | 13 | example: "never gonna give you up", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | //Music.playFile(args, guild, channel); 19 | Music.addSong(speaker, guild, channel, Music.formatSong(args, true)); 20 | } 21 | }); -------------------------------------------------------------------------------- /commands/staff/RaidMode.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';raidmode', ';start raidmode', ';enable raidmode'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Activate raid mode', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | if (index.raidMode[guild.id]) { 19 | Util.log('Raid mode is already active'); 20 | Util.print(channel, 'Raid mode is already active'); 21 | return; 22 | } 23 | 24 | const joinStamp = +new Date(); 25 | 26 | index.recentMembers = index.recentMembers.filter(memberData => joinStamp - memberData.joinStamp < index.newMemberTime); 27 | index.recentMembers2 = index.recentMembers2.filter(memberData => joinStamp - memberData.joinStamp < index.newMemberTime2); 28 | index.activateRaidMode(guild, channel); 29 | }, 30 | }); 31 | -------------------------------------------------------------------------------- /commands/staff/RemQueue.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";remqueue ", ";remq "], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Remove a song from the music queue", 10 | 11 | args: "[song_name]", 12 | 13 | example: "gonna give you up", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | args = args.toLowerCase(); 19 | var guildQueue = Music.guildQueue[guild.id]; 20 | for (var i = guildQueue.length-1; i >= 0; i--) { 21 | var newSong = guildQueue[i]; 22 | var songData = newSong[0]; 23 | var author = newSong[1]; 24 | var title = songData.title; 25 | if (title.toLowerCase().indexOf(args) >= 0) { 26 | Util.print(channel, "Removed", title, "from the queue"); 27 | var connection = guild.voiceConnection; 28 | guildQueue.splice(i, 1); 29 | if (connection != null && Music.guildMusicInfo[guild.id].activeSong != null && title == Music.guildMusicInfo[guild.id].activeSong.title) Music.playNextQueue(guild, channel, true); 30 | } 31 | } 32 | } 33 | }); 34 | -------------------------------------------------------------------------------- /commands/staff/Skip.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";skip"], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Skip to the next song", 10 | 11 | args: "[song_name]", 12 | 13 | example: "gonna give you up", 14 | 15 | func: (cmd, args, msgObj, speaker, channel, guild) => { 16 | var connection = guild.voiceConnection; 17 | if (connection) { 18 | var guildQueue = Music.guildQueue[guild.id]; 19 | var autoPlaylist = Data.guildGet(guild, Data.playlist); 20 | var guildMusicInfo = Music.guildMusicInfo[guild.id]; 21 | var firstInQueue = guildQueue[0]; 22 | Util.log("Num songs in queue: " + guildQueue.length); 23 | if (Util.checkStaff(guild, speaker) || (guildMusicInfo.isAuto == false && guildMusicInfo.activeAuthor.id == speaker.id)) { 24 | if (guildMusicInfo.isAuto == false && guildQueue.length > 0 && guildMusicInfo.activeSong != null && guildMusicInfo.activeSong.title == firstInQueue[0].title) guildQueue.splice(0, 1); 25 | Util.log(guildMusicInfo.isAuto == false + " | " + guildQueue.length + " | " + guildMusicInfo.activeSong + " | " + ((guildMusicInfo.activeSong && firstInQueue) ? guildMusicInfo.activeSong.title == firstInQueue[0].title : "N/A") + " | " + (guildMusicInfo.activeSong ? guildMusicInfo.activeSong.title : "N/A") + " | " + (firstInQueue ? firstInQueue[0].title : "N/A")) 26 | Music.playNextQueue(guild, channel, true); 27 | } else { 28 | Util.print(channel, "You are not staff and you did not add this song"); 29 | } 30 | } 31 | } 32 | }); -------------------------------------------------------------------------------- /commands/staff/Stop.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [";stop", ";silence"], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false 7 | }, 8 | 9 | desc: "Cancel the party, the bangin' tunes can wait for another day", 10 | 11 | args: "[song_name]", 12 | 13 | example: "gonna give you up", 14 | 15 | /////////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | var guildQueue = Music.guildQueue[guild.id]; 19 | var guildMusicInfo = Music.guildMusicInfo[guild.id]; 20 | var connection = guild.voiceConnection; 21 | if (connection) { 22 | if (Music.isPlaying[guild.id]) { 23 | if (guildMusicInfo.isAuto == false) guildQueue.splice(0, 1); 24 | Music.stopMusic(guild); 25 | Util.print(channel, "Stopping audio"); 26 | } else { 27 | Util.print(channel, "No audio playing"); 28 | } 29 | } else { 30 | Util.print(channel, "No audio found"); 31 | } 32 | } 33 | }); -------------------------------------------------------------------------------- /commands/staff/TempBan.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';tempban ', ';tban ', ';temporaryban ', ';timeban ', ';bantime '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Temporarily ban a user from the guild', 10 | 11 | args: '([user_resolvable]) (OPTIONAL: [ban_length]) (OPTIONAL: [ban_length_format]) (OPTIONAL: [reason])', 12 | 13 | example: 'vae 2 days repeatedly breaking rules', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: async (cmd, args, msgObj, speaker, channel, guild) => { 18 | args = args.trim(); 19 | 20 | const data = Util.getDataFromString(args, 21 | [ 22 | [ 23 | function (str) { 24 | return Util.getMemberByMixed(str, guild) || Util.isId(str); 25 | }, 26 | ], 27 | [ 28 | function (str) { 29 | return Util.matchWholeNumber(str); 30 | }, 31 | ], 32 | [ 33 | function (str) { 34 | let mult; 35 | str = str.toLowerCase(); 36 | if (str.substr(str.length - 1, 1) == 's' && str.length > 2) str = str.substr(0, str.length - 1); 37 | if (str == 'millisecond' || str == 'ms') mult = 1 / 60 / 60 / 1000; 38 | if (str == 'second' || str == 's' || str == 'sec') mult = 1 / 60 / 60; 39 | if (str == 'minute' || str == 'm' || str == 'min') mult = 1 / 60; 40 | if (str == 'hour' || str == 'h') mult = 1; 41 | if (str == 'day' || str == 'd') mult = 24; 42 | if (str == 'week' || str == 'w') mult = 24 * 7; 43 | if (str == 'month' || str == 'mo') mult = 24 * 30.42; 44 | if (str == 'year' || str == 'y') mult = 24 * 365.2422; 45 | return mult; 46 | }, 47 | ], 48 | ] 49 | , true); 50 | 51 | if (!data) { 52 | return Util.sendEmbed(channel, 'Ban Failed', 'User not found', Util.makeEmbedFooter(speaker), null, colGreen, null); 53 | } 54 | 55 | Util.log(`Change Arg Data: ${data}`); 56 | 57 | const member = data[0]; 58 | const mult = data[2] || 1; 59 | const time = data[1] ? data[1] * 1000 * 60 * 60 * mult : null; 60 | const reason = data[3]; 61 | 62 | Admin.addBan(guild, channel, member, speaker, { time, reason, temp: true }); 63 | 64 | return true; 65 | }, 66 | }); 67 | -------------------------------------------------------------------------------- /commands/staff/TempBans.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';tempbans', ';tbans', ';timebans', ';timedbans'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Get all temporarily banned users', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: async (cmd, args, msgObj, speaker, channel, guild) => { 18 | const activeBans = await Data.getRecords(guild, 'bans', { active: 1 }); 19 | 20 | const nowDate = +new Date(); 21 | 22 | const sendEmbedFields = []; 23 | 24 | for (let i = 0; i < activeBans.length; i++) { 25 | const record = activeBans[i]; 26 | const targetId = record.user_id; 27 | const modId = record.mod_id; 28 | const startTime = record.start_tick; 29 | const endTime = record.end_tick; 30 | const reason = record.ban_reason; 31 | 32 | const remaining = endTime - nowDate; 33 | const timeStr = Util.formatTime(remaining); 34 | // const targUser = Util.getUserById(targetId); 35 | // const targName = targUser == null ? targetId : Util.getMostName(targUser); 36 | const startDate = new Date(startTime); 37 | const startDateStr = Util.getDateString(startDate); 38 | 39 | sendEmbedFields.push({ name: `[${i + 1}] ${startDateStr}`, value: `​User: <@${targetId}>\nReason: ${reason}\nModerator: <@${modId}>\nRemaining: ${timeStr}​`, inline: false }); 40 | } 41 | 42 | Util.sendEmbed(channel, 'Temporary Bans', null, Util.makeEmbedFooter(speaker), null, colBlue, sendEmbedFields); 43 | }, 44 | }); 45 | -------------------------------------------------------------------------------- /commands/staff/UnBan.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';unban ', ';remban '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Unban a user from the guild', 10 | 11 | args: '([user_resolvable])', 12 | 13 | example: 'vae', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | guild.fetchBans().then((bans) => { 19 | // Collection 20 | // bans = bans.map(o => o.user); 21 | const target = Util.searchUserPartial(bans, args); 22 | if (target == null) { 23 | Util.commandFailed(channel, speaker, 'User not found'); 24 | return; 25 | } 26 | 27 | Admin.unBan(guild, channel, target, speaker); 28 | }); 29 | }, 30 | }); 31 | -------------------------------------------------------------------------------- /commands/staff/UnMute.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';unmute ', ';unwarn ', ';unmutehammer ', ';free '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Unmute a user', 10 | 11 | args: '([user_resolvable])', 12 | 13 | example: 'vae', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | args = args.trim(); 19 | 20 | Admin.unMute(guild, channel, args, speaker); 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /commands/staff/UnRaidMode.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';unraidmode', ';stopraidmode', ';stop raidmode', ';disable raidmode'], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Disable raid mode', 10 | 11 | args: '', 12 | 13 | example: '', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | if (!index.raidMode[guild.id]) { 19 | Util.log('Raid mode is already disabled'); 20 | Util.print(channel, 'Raid mode is already disabled'); 21 | return; 22 | } 23 | 24 | index.disableRaidMode(guild, channel); 25 | }, 26 | }); 27 | -------------------------------------------------------------------------------- /commands/staff/UndoMute.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';undomute ', ';popmute '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: "Remove a user's last mute from their record and unmute them if they are muted", 10 | 11 | args: '([user_resolvable])', 12 | 13 | example: 'vae', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | args = args.trim(); 19 | 20 | Admin.remMute(guild, channel, args, speaker); 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /commands/staff/UserMutes.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';mutes ', ';usermutes ', ';history ', ';userhistory '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Get the mute history of a user', 10 | 11 | args: '([@user] | [id] | [name])', 12 | 13 | example: 'vae', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: async (cmd, args, msgObj, speaker, channel, guild) => { 18 | const data = Util.getDataFromString( 19 | args, 20 | [ 21 | function (str) { 22 | return Util.getMemberByMixed(str, guild) || Util.isId(str); 23 | }, 24 | ], 25 | false, 26 | ); 27 | if (!data) return Util.commandFailed(channel, speaker, 'User not found'); 28 | 29 | const member = data[0]; 30 | 31 | let memberId = member; 32 | let memberName = member; 33 | 34 | if (typeof member === 'object') { 35 | memberId = member.id; 36 | memberName = Util.getMostName(member); 37 | } else { 38 | memberName = `<@${member}>`; 39 | } 40 | 41 | const pastMutes = await Data.getRecords(guild, 'mutes', { user_id: memberId }); 42 | 43 | const sendEmbedFields = []; 44 | 45 | for (let i = 0; i < pastMutes.length; i++) { 46 | const record = pastMutes[i]; 47 | 48 | const muteDate = new Date(record.start_tick); 49 | const muteLength = record.end_tick - record.start_tick; 50 | const moderatorId = record.mod_id; 51 | const active = record.active == 1; 52 | 53 | const reason = record.mute_reason; 54 | const muteDateStr = Util.getDateString(muteDate); 55 | const muteLengthStr = Util.formatTime(muteLength); 56 | const modMention = Util.resolveUserMention(guild, moderatorId); 57 | const activeStr = active ? 'Yes' : 'No'; 58 | 59 | sendEmbedFields.push({ 60 | name: `[${i + 1}] ${muteDateStr}`, 61 | value: `​Reason: ${reason}\nLength: ${muteLengthStr}\nModerator: ${modMention}\nActive: ${activeStr}`, 62 | inline: false, 63 | }); 64 | } 65 | 66 | Util.sendEmbed(channel, `Mute History: ${memberName}`, null, Util.makeEmbedFooter(speaker), null, colBlue, sendEmbedFields); 67 | 68 | return true; 69 | }, 70 | }); 71 | -------------------------------------------------------------------------------- /core/ManageCommands.js: -------------------------------------------------------------------------------- 1 | exports.commands = []; 2 | 3 | const quietChannels = { 4 | '477270527535480834': true, 5 | '289447389251502080': true, 6 | '285040042001432577': true, 7 | '284746888715042818': true, 8 | '294244239485829122': true, 9 | '290228574273798146': true, 10 | }; 11 | 12 | function isQuiet(channel, speaker) { 13 | if (quietChannels[channel.id] && !Util.checkStaff(channel.guild, speaker)) { 14 | return true; 15 | } 16 | return false; 17 | } 18 | 19 | exports.addCommand = function (structure) { 20 | const cmds = structure.cmds; 21 | const fixedCmds = []; 22 | 23 | for (let i = 0; i < cmds.length; i++) { 24 | fixedCmds.push(cmds[i].toLowerCase()); 25 | } 26 | 27 | const cmdData = [fixedCmds, structure.func, structure.requires, structure.desc, structure.args, structure.example]; 28 | 29 | exports.commands.push(cmdData); 30 | exports.commands.sort(); 31 | 32 | return cmdData; 33 | }; 34 | 35 | exports.getCommand = function (contentParam) { 36 | let content = contentParam; 37 | 38 | if (content.substr(0, 5) === 'sudo ') content = content.substring(5); 39 | 40 | const contentLower = content.toLowerCase(); 41 | 42 | for (let i = 0; i < exports.commands.length; i++) { 43 | const cmdData = exports.commands[i]; 44 | const cmdNames = cmdData[0]; 45 | 46 | for (let i2 = 0; i2 < cmdNames.length; i2++) { 47 | const cmd = cmdNames[i2]; 48 | const cmdLength = cmd.length; 49 | const hasParameters = cmd[cmdLength - 1] === ' '; 50 | if ((hasParameters && contentLower.substr(0, cmdLength) === cmd) || (!hasParameters && contentLower === cmd)) { 51 | return cmdData; 52 | } 53 | } 54 | } 55 | 56 | return null; 57 | }; 58 | 59 | exports.initCommands = function () { 60 | Util.bulkRequire(`${__dirname}/../commands/`); 61 | }; 62 | 63 | exports.checkMessage = (msgObj, speaker, channel, guild, content, contentLower, authorId, isStaff) => { 64 | if ( 65 | channel.id !== '168743219788644352' || 66 | authorId === vaebId /* && (guild.id != "257235915498323969" || channel.id == "257244216772526092") */ || 67 | authorId === '126710973737336833' 68 | ) { 69 | // script-builders 70 | for (let i = 0; i < exports.commands.length; i++) { 71 | const cmdData = exports.commands[i]; 72 | const cmdNames = cmdData[0]; 73 | const cmdFunc = cmdData[1]; 74 | const cmdRequires = cmdData[2]; 75 | 76 | for (let i2 = 0; i2 < cmdNames.length; i2++) { 77 | const cmd = cmdNames[i2]; 78 | const cmdLength = cmd.length; 79 | const hasParameters = cmd[cmdLength - 1] === ' '; 80 | if ((hasParameters && contentLower.substr(0, cmdLength) === cmd) || (!hasParameters && contentLower === cmd)) { 81 | if (cmdRequires.staff && !isStaff) { 82 | Util.sendEmbed( 83 | channel, 84 | 'Restricted', 85 | 'This command can only be used by Staff', 86 | Util.makeEmbedFooter(speaker), 87 | null, 88 | colGreen, 89 | null, 90 | ); 91 | } else if (cmdRequires.administrator && (guild == null || !speaker.hasPermission('ADMINISTRATOR'))) { 92 | Util.sendEmbed( 93 | channel, 94 | 'Restricted', 95 | 'This command can only be used by Administrators', 96 | Util.makeEmbedFooter(speaker), 97 | null, 98 | colGreen, 99 | null, 100 | ); 101 | } else if (cmdRequires.vaeb && authorId !== vaebId && authorId !== '126710973737336833') { 102 | Util.sendEmbed( 103 | channel, 104 | 'Restricted', 105 | 'This command can only be used by Vaeb', 106 | Util.makeEmbedFooter(speaker), 107 | null, 108 | colGreen, 109 | null, 110 | ); 111 | } else if (cmdRequires.guild && guild == null) { 112 | Util.sendEmbed( 113 | channel, 114 | 'Restricted', 115 | 'This command can only be used in Guilds', 116 | Util.makeEmbedFooter(speaker), 117 | null, 118 | colGreen, 119 | null, 120 | ); 121 | } else if (cmdRequires.loud && isQuiet(channel, speaker)) { 122 | Util.sendEmbed( 123 | channel, 124 | 'Quiet Channel', 125 | 'This command cannot be used in this Channel (use #bot-commands)', 126 | Util.makeEmbedFooter(speaker), 127 | null, 128 | colGreen, 129 | null, 130 | ); 131 | } else { 132 | const args = content.substring(cmdLength); 133 | const argStr = args.length < 1 ? 'None' : args; 134 | const guildData = guild != null ? `${guild.name} (${guild.id})` : 'NoGuild'; 135 | let outLog = `\n> ${Util.getName(speaker)} (${speaker.id}) | ${channel.name} (${ 136 | channel.id 137 | }) | ${guildData}\n Command Executed: ${cmd.trim()}`; 138 | if (hasParameters) outLog += ` | Arguments: ${argStr}`; 139 | Util.log(outLog); 140 | 141 | if (cmdRequires.staff && guild != null) { 142 | const sendLogData = [ 143 | 'Command Entry', 144 | guild, 145 | speaker, 146 | { name: 'Username', value: Util.resolveMention(speaker) }, 147 | { name: 'Channel Name', value: channel.toString() }, 148 | { name: 'Command Name', value: cmd }, 149 | ]; 150 | 151 | if (hasParameters) { 152 | sendLogData.push({ name: 'Command Argument(s)', value: argStr }); 153 | } else { 154 | sendLogData.push({ name: 'Command Argument(s)', value: 'N/A' }); 155 | } 156 | 157 | Util.sendLog(sendLogData, colCommand); 158 | } 159 | 160 | try { 161 | cmdFunc(cmd, args, msgObj, speaker, channel, guild, isStaff); 162 | } catch (err) { 163 | Util.log(`COMMAND ERROR: ${err.stack}`); 164 | } 165 | } 166 | 167 | return; 168 | } 169 | } 170 | } 171 | } 172 | }; 173 | -------------------------------------------------------------------------------- /core/ManageEvents.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | AddRole 4 | RemRole 5 | DM 6 | Mute 7 | UnMute 8 | Kick 9 | Ban 10 | DeleteMessage 11 | 12 | eventData 13 | Guild 14 | eventName 15 | actionName, actionFunc, actionArgs 16 | 17 | */ 18 | 19 | const allEvents = {}; 20 | 21 | exports.Actions = {}; 22 | 23 | exports.getEvents = function (guild, checkEventName) { 24 | if (!allEvents[guild.id]) allEvents[guild.id] = {}; 25 | 26 | const fullInfo = []; 27 | 28 | const guildEventsObj = allEvents[guild.id]; 29 | 30 | if (!checkEventName) { 31 | for (const [eventName, actionDataEvent] of Object.entries(guildEventsObj)) { 32 | if (guildEventsObj[eventName] != null) { 33 | const eventInfo = [eventName]; 34 | 35 | for (let i = 0; i < actionDataEvent.length; i++) { 36 | const nowData = actionDataEvent[i]; 37 | 38 | const actionName = nowData[0]; 39 | const actionArgs = nowData[2]; 40 | 41 | eventInfo.push([actionName, actionArgs]); 42 | } 43 | 44 | fullInfo.push(eventInfo); 45 | } 46 | } 47 | } else { 48 | const actionDataEvent = guildEventsObj[checkEventName]; 49 | 50 | if (actionDataEvent) { 51 | for (let i = 0; i < actionDataEvent.length; i++) { 52 | const nowData = actionDataEvent[i]; 53 | 54 | const actionName = nowData[0]; 55 | const actionArgs = nowData[2]; 56 | 57 | fullInfo.push([actionName, actionArgs]); 58 | } 59 | } 60 | } 61 | 62 | return fullInfo; 63 | }; 64 | 65 | exports.addEvent = function (guild, eventName, actionName, actionFunc, actionArgs) { 66 | if (!allEvents[guild.id]) allEvents[guild.id] = {}; 67 | 68 | const actionDataGuild = allEvents[guild.id]; 69 | 70 | let actionDataEvent = actionDataGuild[eventName]; 71 | 72 | if (!actionDataEvent) { 73 | actionDataEvent = []; 74 | actionDataGuild[eventName] = actionDataEvent; 75 | } 76 | 77 | Util.log(`Added event linking ${eventName} to ${actionName}`); 78 | 79 | actionDataEvent.push([actionName, actionFunc, actionArgs]); 80 | }; 81 | 82 | exports.remEvent = function (guild, eventName, actionName) { 83 | if (!allEvents[guild.id]) allEvents[guild.id] = {}; 84 | 85 | const actionDataEvent = allEvents[guild.id][eventName]; 86 | 87 | if (!actionDataEvent || actionDataEvent.length === 0) { 88 | return Util.log(`Event ${eventName} not found`); 89 | } 90 | 91 | for (let i = actionDataEvent.length - 1; i >= 0; i--) { 92 | const nowData = actionDataEvent[i]; 93 | 94 | if (actionName == null || nowData[0] === actionName) { 95 | Util.log(`Removed event linking ${eventName} to ${actionName}`); 96 | 97 | actionDataEvent.splice(i, 1); 98 | } 99 | } 100 | 101 | if (actionDataEvent.length === 0) { 102 | allEvents[guild.id][eventName] = undefined; 103 | } 104 | 105 | return undefined; 106 | }; 107 | 108 | exports.emit = function (guild, eventName, ...eventArgs) { 109 | if (!guild) return; 110 | 111 | if (!allEvents[guild.id]) allEvents[guild.id] = {}; 112 | 113 | const actionDataEvent = allEvents[guild.id][eventName]; 114 | 115 | if (!actionDataEvent || actionDataEvent.length === 0) return; 116 | 117 | for (let i = 0; i < actionDataEvent.length; i++) { 118 | const nowData = actionDataEvent[i]; 119 | 120 | const actionName = nowData[0]; 121 | const actionFunc = nowData[1]; 122 | const actionArgs = nowData[2]; 123 | 124 | Util.log(`Calling action "${actionName}" linked to ${eventName}`); 125 | 126 | actionFunc(guild, eventName, actionArgs, eventArgs); 127 | } 128 | }; 129 | 130 | exports.Actions.AddRole = (guild, eventName, actionArgs, eventArgs) => { 131 | const member = eventArgs[0]; 132 | 133 | for (let i = 0; i < actionArgs.length; i++) { 134 | const roleName = actionArgs[i]; 135 | const roleObj = Util.getRole(roleName, guild); 136 | 137 | if (!roleObj) { 138 | Util.log(`[A_AddRole] ${roleName} not found`); 139 | } else { 140 | member.addRole(roleObj) 141 | .catch(console.error); 142 | } 143 | } 144 | }; 145 | 146 | exports.Actions.RemRole = (guild, eventName, actionArgs, eventArgs) => { 147 | const member = eventArgs[0]; 148 | 149 | for (let i = 0; i < actionArgs.length; i++) { 150 | const roleName = actionArgs[i]; 151 | const roleObj = Util.getRole(roleName, guild); 152 | 153 | if (!roleObj) { 154 | Util.log(`[A_RemRole] ${roleName} not found`); 155 | } else { 156 | member.removeRole(roleObj) 157 | .catch(console.error); 158 | } 159 | } 160 | }; 161 | 162 | exports.Actions.DM = (guild, eventName, actionArgs, eventArgs) => { 163 | const member = eventArgs[0]; 164 | 165 | Util.print(member, ...actionArgs); 166 | }; 167 | -------------------------------------------------------------------------------- /core/ManageMusic2.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | -exports.queue = { 4 | guildId: { 5 | canPlay, 6 | textChannel, 7 | playing, 8 | dispatcher, 9 | volume, 10 | songs: [ 11 | songData { 12 | source // Stream URL or File location 13 | type // 'stream' or 'file' 14 | name // Song name 15 | addedBy // Guild member who added song or 'AutoPlaylist' 16 | }, 17 | ... 18 | ] 19 | }, 20 | ... 21 | } 22 | 23 | -exports.autoPlaylist = { 24 | guildId: [ 25 | songData {}, 26 | ... 27 | ], 28 | ... 29 | } 30 | 31 | -exports.textChannel(guild, channelResolvable) 32 | -exports.triggerPlay(guild) // Plays the song at start of queue or auto playlist, stops current song if playing (causing it to start the next one) 33 | -exports.addSong(guild, channel, nameResolvable, position) 34 | -exports.remSong(guild, channel, positionResolvable) 35 | -exports.setPosition(guild, channel, oldPositionResolvable, newPositionResolvable, trigger) 36 | -exports.pause(guild, channel) 37 | -exports.resume(guild, channel) 38 | -exports.stop(guild, channel) 39 | -exports.skip(guild, channel) 40 | -exports.voteSkip(guild, channel) 41 | -exports.getTime(guild) 42 | -exports.getStatus(guild) 43 | -exports.setVolume(guild, channel, newVolume, addVolume) 44 | -exports.join(guild, channel, channelResolvable) 45 | -exports.leave(guild, channel) 46 | -exports.addSongAuto(guild, channel, nameResolvable, position) 47 | -exports.remSongAuto(guild, channel, positionResolvable) 48 | 49 | -exports.triggerPlay(guild) 50 | -Check guild queue exists 51 | -Set textChannel variable to guild queue textChannel or guild default channel 52 | -Check guild queue has canPlay enabled 53 | -If no guild voice connection (not in voice channel) 54 | -[Await] Join voice channel 55 | -return exports.triggerPlay(guild) 56 | -If already playing 57 | -End current dispatcher 58 | -Return true 59 | -Set songData to first song in queue or random auto-playlist song 60 | -Get stream if songData is of type URL 61 | -Set dispatcher 62 | -Set playing 63 | -On dispatcher end 64 | // Remember that canPlay may be disabled at this point 65 | -Reset playing & dispatcher 66 | -exports.triggerPlay(guild) 67 | -On dispatcher error 68 | // Remember that canPlay may be disabled at this point 69 | -Reset playing & dispatcher 70 | -Output error 71 | -exports.triggerPlay(guild) 72 | -Return true 73 | 74 | -Call: exports.triggerPlay(guild) 75 | 76 | */ 77 | 78 | exports.queue = {}; 79 | exports.autoPlaylist = {}; 80 | 81 | exports.initGuild = async function (guild) { 82 | Util.log(`Initialising music queue for ${guild.name}`); 83 | 84 | exports.queue[guild.id] = { 85 | canPlay: true, 86 | textChannel: null, 87 | playing: false, 88 | dispatcher: null, 89 | volume: 50, // *100 90 | songs: [], 91 | }; 92 | 93 | exports.autoPlaylist[guild.id] = []; 94 | 95 | const autoPlaylistData = Util.cloneObj(await Data.getRecords(guild, 'autoplaylist')); 96 | 97 | for (let i = 0; i < autoPlaylistData.length; i++) { 98 | exports.autoPlaylist[guild.id].push(autoPlaylistData[i]); 99 | } 100 | }; 101 | 102 | exports.textChannel = function (guild, channelResolvable) { 103 | if (!has.call(exports.queue, guild.id)) return Util.commandFailed(guild.defaultTextChannel, 'System', 'Internal Error', 'Guild queue not initialized'); 104 | const guildQueue = exports.queue[guild.id]; 105 | const newTextChannel = Util.findTextChannel(channelResolvable, guild); 106 | if (!newTextChannel) return Util.commandFailed(guildQueue.textChannel || guild.defaultTextChannel, 'System', 'Channel not found'); 107 | guildQueue.textChannel = newTextChannel; 108 | return true; 109 | }; 110 | 111 | exports.join = async function (guild, channel, voiceChannelResolvable) { 112 | if (voiceChannelResolvable == null) voiceChannelResolvable = Util.findVoiceChannel('music', guild); 113 | if (voiceChannelResolvable == null) return Util.commandFailed(channel, 'System', 'Default (music) channel not found'); 114 | if (typeof voiceChannelResolvable === 'string') voiceChannelResolvable = Util.findVoiceChannel(voiceChannelResolvable, guild); 115 | if (voiceChannelResolvable == null) return Util.commandFailed(channel, 'System', 'Channel not found'); 116 | return voiceChannelResolvable.join(); 117 | }; 118 | 119 | exports.triggerPlay = async function (guild) { 120 | if (!has.call(exports.queue, guild.id)) await exports.initGuild(guild); 121 | 122 | const guildQueue = exports.queue[guild.id]; 123 | const guildAuto = exports.autoPlaylist[guild.id]; 124 | const textChannel = guildQueue.textChannel || guild.defaultTextChannel; // defaultTextChannel? 125 | 126 | if (!guildQueue.canPlay) return false; 127 | 128 | if (!guild.voiceConnection) { 129 | await exports.join(guild, textChannel); 130 | return exports.triggerPlay(guild); 131 | } 132 | 133 | if (guildQueue.playing) { 134 | guildQueue.dispatcher.end(); 135 | return true; 136 | } 137 | 138 | const songData = guildQueue.songs[0] || guildAuto[Util.getRandomInt(0, guildAuto.length)]; 139 | 140 | if (songData.type === 'stream') { 141 | const streamData = index.Ytdl(songData.source, { filter: 'audioonly' }); 142 | guildQueue.dispatcher = guild.voiceConnection.playStream(streamData, { volume: guildQueue.volume / 100 }); 143 | } else if (songData.type === 'file') { 144 | guildQueue.dispatcher = guild.voiceConnection.playFile(songData.source); 145 | } else { 146 | return Util.commandFailed(textChannel, 'System', 'Errr something\'s not quite right with the songData typing here'); 147 | } 148 | 149 | guildQueue.playing = true; 150 | 151 | guildQueue.dispatcher.on('end', () => { 152 | guildQueue.playing = false; 153 | guildQueue.dispatcher = null; 154 | exports.triggerPlay(guild); 155 | }); 156 | 157 | guildQueue.dispatcher.on('error', (err) => { 158 | guildQueue.playing = false; 159 | guildQueue.dispatcher = null; 160 | Util.commandFailed(textChannel, 'System', 'Internal Music Error', err); 161 | exports.triggerPlay(guild); 162 | }); 163 | 164 | return true; 165 | }; 166 | 167 | exports.formatSong = function (data, isFile) { 168 | if (!data) return 'Audio not found'; 169 | 170 | if (isFile) data = { id: data, snippet: { title: data } }; 171 | 172 | const songData = { 173 | source: typeof (data.id) === 'object' ? data.id.videoId : data.id, 174 | type: isFile ? 'file' : 'stream', 175 | name: data.snippet.title, 176 | addedBy: null, 177 | }; 178 | 179 | return songData; 180 | }; 181 | 182 | exports.getSong = function (nameResolvable) { // Cross your fingers and hope for promisify 183 | if (nameResolvable.includes('http')) { 184 | let songId = /[^/=]+$/.exec(nameResolvable); 185 | if (songId != null && songId[0]) { 186 | songId = songId[0]; 187 | index.YtInfo.getById(songId, (error, result) => { 188 | const songData = result.items[0]; 189 | return exports.formatSong(songData, false); 190 | }); 191 | } else { 192 | return 'Incorrect format for URL'; 193 | } 194 | } else { 195 | index.YtInfo.search(nameResolvable, 6, (error, result) => { 196 | if (error) return error; 197 | const items = result.items; 198 | for (let i = 0; i < items.length; i++) { 199 | const songData = items[i]; 200 | if (songData != null && has.call(songData, 'id') && songData.id.kind == 'youtube#video') { 201 | return exports.formatSong(songData, false); 202 | } 203 | } 204 | return 'Audio not found'; 205 | }); 206 | } 207 | }; 208 | 209 | exports.addSong = function (guild, channel, nameResolvable, position) { 210 | if (!has.call(exports.queue, guild.id)) return Util.commandFailed(guild.defaultTextChannel, 'System', 'Internal Error', 'Guild queue not initialized'); 211 | const guildQueue = exports.queue[guild.id]; 212 | if (position == null) position = guildQueue.songs.length; 213 | return true; 214 | }; 215 | -------------------------------------------------------------------------------- /disabled/Warn.js: -------------------------------------------------------------------------------- 1 | module.exports = Cmds.addCommand({ 2 | cmds: [';warn ', ';warnhammer '], 3 | 4 | requires: { 5 | guild: true, 6 | loud: false, 7 | }, 8 | 9 | desc: 'Warns a user and puts the warning on their record', 10 | 11 | args: '([@user] | [id] | [name]) (OPT: [reason])', 12 | 13 | example: 'vae spamming the chat', 14 | 15 | // ///////////////////////////////////////////////////////////////////////////////////////// 16 | 17 | func: (cmd, args, msgObj, speaker, channel, guild) => { 18 | args = args.trim(); 19 | 20 | const data = Util.getDataFromString(args, 21 | [ 22 | [ 23 | function (str) { 24 | return Util.getMemberByMixed(str, guild) || Util.isId(str); 25 | }, 26 | ], 27 | ] 28 | , true); 29 | 30 | if (!data) { 31 | return Util.sendEmbed(channel, 'Warn Failed', 'User not found', Util.makeEmbedFooter(speaker), null, colGreen, null); 32 | } 33 | 34 | Util.log(`Change Arg Data: ${data}`); 35 | 36 | const member = data[0]; 37 | const reason = data[1]; 38 | 39 | Admin.addWarning(guild, channel, member, speaker, reason); 40 | 41 | return true; 42 | }, 43 | }); 44 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vaebot", 3 | "version": "1.1.0", 4 | "description": "Discord bot for everything from moderation to music.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node index.js", 9 | "prod": "forever -c \"nodemon --exitcrash\" index.js" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/Vaeb/VaeBot.git" 14 | }, 15 | "keywords": [ 16 | "Vaeb", 17 | "VaeBot", 18 | "Discord", 19 | "Bot" 20 | ], 21 | "author": "Vaeb", 22 | "license": "ISC", 23 | "bugs": { 24 | "url": "https://github.com/Vaeb/VaeBot/issues" 25 | }, 26 | "homepage": "https://github.com/Vaeb/VaeBot#readme", 27 | "dependencies": { 28 | "@google-cloud/translate": "^4.1.3", 29 | "bufferutil": "^4.0.0", 30 | "dateformat": "^3.0.3", 31 | "discord.js": "^11.4.2", 32 | "google-translate": "^2.3.0", 33 | "hepburn": "^1.1.1", 34 | "libsodium-wrappers": "^0.7.3", 35 | "mysql": "^2.16.0", 36 | "node-opus": "^0.3.0", 37 | "node-trello": "^1.2.1", 38 | "request": "^2.87.0", 39 | "request-promise-native": "^1.0.5", 40 | "urban": "^0.3.1", 41 | "uws": "^99.0.0", 42 | "youtube-node": "^1.3.0", 43 | "youtube-search": "^1.0.10", 44 | "ytdl-core": "^0.15.2" 45 | }, 46 | "devDependencies": { 47 | "eslint": "^4.18.2", 48 | "eslint-config-airbnb": "^15.1.0", 49 | "eslint-config-airbnb-base": "^11.3.1", 50 | "eslint-plugin-import": "^2.7.0", 51 | "eslint-plugin-jsx-a11y": "^6.0.2", 52 | "eslint-plugin-react": "^7.1.0" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /resources/images/CrabRaveGif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vaeb/VaeBot/45e140430e4158ba29940b9b97bf268771d3de41/resources/images/CrabRaveGif.gif -------------------------------------------------------------------------------- /resources/images/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vaeb/VaeBot/45e140430e4158ba29940b9b97bf268771d3de41/resources/images/avatar.png -------------------------------------------------------------------------------- /resources/music/1-800-273-8255.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vaeb/VaeBot/45e140430e4158ba29940b9b97bf268771d3de41/resources/music/1-800-273-8255.mp3 -------------------------------------------------------------------------------- /resources/music/AfricAryaN.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vaeb/VaeBot/45e140430e4158ba29940b9b97bf268771d3de41/resources/music/AfricAryaN.mp3 -------------------------------------------------------------------------------- /resources/music/America.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vaeb/VaeBot/45e140430e4158ba29940b9b97bf268771d3de41/resources/music/America.mp3 -------------------------------------------------------------------------------- /resources/music/Anziety.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vaeb/VaeBot/45e140430e4158ba29940b9b97bf268771d3de41/resources/music/Anziety.mp3 -------------------------------------------------------------------------------- /resources/music/Black SpiderMan.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vaeb/VaeBot/45e140430e4158ba29940b9b97bf268771d3de41/resources/music/Black SpiderMan.mp3 -------------------------------------------------------------------------------- /resources/music/Confess.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vaeb/VaeBot/45e140430e4158ba29940b9b97bf268771d3de41/resources/music/Confess.mp3 -------------------------------------------------------------------------------- /resources/music/Everybody.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vaeb/VaeBot/45e140430e4158ba29940b9b97bf268771d3de41/resources/music/Everybody.mp3 -------------------------------------------------------------------------------- /resources/music/Hallelujah.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vaeb/VaeBot/45e140430e4158ba29940b9b97bf268771d3de41/resources/music/Hallelujah.mp3 -------------------------------------------------------------------------------- /resources/music/Ink Blot.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vaeb/VaeBot/45e140430e4158ba29940b9b97bf268771d3de41/resources/music/Ink Blot.mp3 -------------------------------------------------------------------------------- /resources/music/Killing Spree.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vaeb/VaeBot/45e140430e4158ba29940b9b97bf268771d3de41/resources/music/Killing Spree.mp3 -------------------------------------------------------------------------------- /resources/music/Mos Definitely.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vaeb/VaeBot/45e140430e4158ba29940b9b97bf268771d3de41/resources/music/Mos Definitely.mp3 -------------------------------------------------------------------------------- /resources/music/Take It Back.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vaeb/VaeBot/45e140430e4158ba29940b9b97bf268771d3de41/resources/music/Take It Back.mp3 -------------------------------------------------------------------------------- /resources/music/Waiting Room.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vaeb/VaeBot/45e140430e4158ba29940b9b97bf268771d3de41/resources/music/Waiting Room.mp3 --------------------------------------------------------------------------------