├── .github └── FUNDING.yml ├── LICENSE ├── config.json ├── index.js ├── package.json ├── ranking.js └── readme.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: ['milrato.eu', 'dc.milrato.eu', 'bero.milrato.eu', 'bittmax.milrato.eu' ] 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "TOKEN": "NzQ4MDk2Masd2wNjk3NTU1OTY5.X0Yc2g.masd2pFasdasd2Urh3X0S_2yuBo", 3 | "PREFIX": "?", 4 | 5 | "maximum_leaderboard": "50", 6 | "embedcolor": "#118fff" 7 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const Discord = require("discord.js"); //load the Discord.js Library 2 | const client = new Discord.Client(); //make a new Client 3 | const config = require("./config.json"); //load the config.json file 4 | const Enmap = require("enmap") //load the enmap library 5 | const canvacord = require("canvacord") //load the canvacord library 6 | client.points = new Enmap({ name: "points" }); //For ranking system 7 | client.on("ready", ()=>console.log("READY")); //log when the bot gets ready 8 | const ranking = require("./ranking"); //load the ranking file 9 | ranking(client); //call the ranking file with the client 10 | client.login(config.TOKEN); //start the bot with the bot token 11 | //Bot coded by Tomato#6966 -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "better_discord_ranking_system", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/Tomato6966/better-discord-ranking-system.git" 12 | }, 13 | "keywords": [ 14 | "tomato", 15 | "ranking", 16 | "discord", 17 | "discord-js", 18 | "discord.js", 19 | "discord-api", 20 | "discord-music-bot", 21 | "discord-bot", 22 | "discordbot", 23 | "leveling", 24 | "rank", 25 | "level", 26 | "nsfw", 27 | "hentai-bot", 28 | "hentai-sites", 29 | "card", 30 | "cards", 31 | "music-bot", 32 | "nodejs", 33 | "npm", 34 | "node-js", 35 | "porn", 36 | "multipurpose", 37 | "gaming", 38 | "utility" 39 | ], 40 | "author": "Tomato#6966", 41 | "license": "GNU", 42 | "dependencies": { 43 | "canvacord": "^5.0.8", 44 | "discord.js": "^12.5.1", 45 | "enmap": "^5.8.4" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ranking.js: -------------------------------------------------------------------------------- 1 | const config = require("./config.json"); 2 | const canvacord = require("canvacord"); 3 | const Discord = require("discord.js"); 4 | const prefix = config.PREFIX; 5 | const embedcolor = config.embedcolor; 6 | const maximum_leaderboard = config.maximum_leaderboard; //maximum 50 users for the leaderboard! 7 | 8 | module.exports = function (client) { 9 | const description = { 10 | name: "RANKING", 11 | filename: "ranking.js", 12 | version: "2.0" 13 | } 14 | //log that the module is loaded 15 | console.log(` :: Module: ${description.name} | Loaded version ${description.version} from ("${description.filename}")`) 16 | //voice state update event to check joining/leaving channels 17 | client.on("message", async (message) => { 18 | 19 | if (message.author.bot || !message.guild) return; 20 | //get the key of the user for this guild 21 | const key = `${message.guild.id}-${message.author.id}`; 22 | /** 23 | * databasing 24 | * @info General databasing, which sets the userinto the database if he types something 25 | */ 26 | function databasing(rankuser) { 27 | //if(rankuser && rankuser.bot) return console.log("GOTTA IGNORE BOT") 28 | client.points.ensure(rankuser ? `${message.guild.id}-${rankuser.id}` : `${message.guild.id}-${message.author.id}`, { 29 | user: rankuser ? rankuser.id : message.author.id, 30 | usertag: rankuser ? rankuser.tag : message.author.tag, 31 | xpcounter: 1, 32 | guild: message.guild.id, 33 | points: 0, 34 | neededpoints: 400, 35 | level: 1, 36 | oldmessage: "", 37 | }); 38 | client.points.set(rankuser ? `${message.guild.id}-${rankuser.id}` : `${message.guild.id}-${message.author.id}`, rankuser ? rankuser.tag : message.author.tag, `usertag`); //set the usertag with EVERY message, if he has nitro his tag might change ;) 39 | client.points.set(message.guild.id, 1, `setglobalxpcounter`); //set points to 0 40 | } 41 | databasing(); 42 | 43 | /** 44 | * ARGUMENTS 45 | * @info General arguments for the Whole message Event 46 | */ 47 | const args = message.content.slice(prefix.length).trim().split(/ +/g); 48 | const command = args.shift().toLowerCase(); 49 | 50 | 51 | /** 52 | * COMMANDS 53 | * @info if a message starts with the prefix, then run it 54 | */ 55 | if (message.content.startsWith(prefix)) { 56 | 57 | switch (command) { 58 | case `rank`: 59 | rank(message.mentions.users.first()||message.author); 60 | break; 61 | ///////////////////////////////// 62 | case `leaderboard`: 63 | case `lb`: 64 | leaderboard(); 65 | break; 66 | ///////////////////////////////// 67 | case `setxpcounter`: 68 | if (!message.member.hasPermission("ADMINISTRATOR") || !message.member.hasPermission("MANAGE_GUILD")) return message.reply("You are not allowed to run this cmd!") 69 | setxpcounter(); 70 | break; 71 | ///////////////////////////////// 72 | case `setglobalxpcounter`: 73 | if (!message.member.hasPermission("ADMINISTRATOR") || !message.member.hasPermission("MANAGE_GUILD")) return message.reply("You are not allowed to run this cmd!") 74 | setglobalxpcounter(); 75 | break; 76 | ///////////////////////////////// 77 | case `addpoints`: 78 | if (!message.member.hasPermission("ADMINISTRATOR") || !message.member.hasPermission("MANAGE_GUILD")) return message.reply("You are not allowed to run this cmd!") 79 | addpoints(); 80 | break; 81 | ///////////////////////////////// 82 | case `setpoints`: 83 | if (!message.member.hasPermission("ADMINISTRATOR") || !message.member.hasPermission("MANAGE_GUILD")) return message.reply("You are not allowed to run this cmd!") 84 | 85 | setpoints(); 86 | break; 87 | ///////////////////////////////// 88 | case `removepoints`: 89 | if (!message.member.hasPermission("ADMINISTRATOR") || !message.member.hasPermission("MANAGE_GUILD")) return message.reply("You are not allowed to run this cmd!") 90 | 91 | removepoints(); 92 | break; 93 | ///////////////////////////////// 94 | case `addlevel`: 95 | if (!message.member.hasPermission("ADMINISTRATOR") || !message.member.hasPermission("MANAGE_GUILD")) return message.reply("You are not allowed to run this cmd!") 96 | 97 | addlevel(); 98 | break; 99 | ///////////////////////////////// 100 | case `setlevel`: 101 | if (!message.member.hasPermission("ADMINISTRATOR") || !message.member.hasPermission("MANAGE_GUILD")) return message.reply("You are not allowed to run this cmd!") 102 | 103 | setlevel(); 104 | break; 105 | ///////////////////////////////// 106 | case `removelevel`: 107 | if (!message.member.hasPermission("ADMINISTRATOR") || !message.member.hasPermission("MANAGE_GUILD")) return message.reply("You are not allowed to run this cmd!") 108 | 109 | removelevel(); 110 | break; 111 | ///////////////////////////////// 112 | case `resetranking`: 113 | if (!message.member.hasPermission("ADMINISTRATOR") || !message.member.hasPermission("MANAGE_GUILD")) return message.reply("You are not allowed to run this cmd!") 114 | 115 | resetranking(); 116 | break; 117 | ///////////////////////////////// 118 | case `registerall`: 119 | if (!message.member.hasPermission("ADMINISTRATOR") || !message.member.hasPermission("MANAGE_GUILD")) return message.reply("You are not allowed to run this cmd!") 120 | 121 | registerall(); 122 | break; 123 | ///////////////////////////////// 124 | case `addrandomall`: 125 | if (!message.member.hasPermission("ADMINISTRATOR") || !message.member.hasPermission("MANAGE_GUILD")) return message.reply("You are not allowed to run this cmd!") 126 | 127 | addrandomall(); 128 | break; 129 | ///////////////////////////////// 130 | case `resetrankingall`: 131 | if (!message.member.hasPermission("ADMINISTRATOR") || !message.member.hasPermission("MANAGE_GUILD")) return message.reply("You are not allowed to run this cmd!") 132 | 133 | resetrankingall() 134 | break; 135 | ///////////////////////////////// 136 | case `levelhelp`: 137 | case `rankinghelp`: 138 | case `levelinghelp`: 139 | case `rankhelp`: 140 | levelinghelp(); 141 | break; 142 | ///////////////////////////////// 143 | default: 144 | message.reply(`UNKNOWN COMMAND! Try: \`${prefix}levelinghelp\``) 145 | break; 146 | } 147 | return; 148 | } 149 | 150 | 151 | /** 152 | * Anti double messages 153 | * @info if the old message is the same as the message before: SKIP 154 | */ 155 | function anti_double_messages() { 156 | const oldmessage = client.points.get(key, `oldmessage`); 157 | if (oldmessage.toLowerCase() === message.content.toLowerCase().replace(/\s+/g, '')) { 158 | return console.log("DOUPLICATED MESSAGE, no ranking points sorry!"); 159 | } 160 | client.points.set(key, message.content.toLowerCase().replace(/\s+/g, ''), `oldmessage`); //setting the new old message 161 | } 162 | anti_double_messages(); 163 | 164 | 165 | 166 | /** 167 | * Giving Ranking Points 168 | * @info adding a random number rounded, between 1 and 5 169 | */ 170 | function Giving_Ranking_Points(thekey, maxnumber) { 171 | let setglobalxpcounter = client.points.get(message.guild.id, "setglobalxpcounter") 172 | if (!maxnumber) maxnumber = 5; 173 | var randomnum = ( Math.floor(Math.random() * Number(maxnumber)) + 1 ) * setglobalxpcounter; 174 | randomnum *= Number(client.points.get(key, `xpcounter`)); 175 | randomnum = Number(Math.floor(randomnum)); 176 | 177 | const curPoints = client.points.get(thekey ? thekey : key, `points`); 178 | const neededPoints = client.points.get(thekey ? thekey : key, `neededpoints`); 179 | let leftpoints = neededPoints - curPoints; 180 | 181 | let toaddpoints = randomnum; 182 | addingpoints(toaddpoints, leftpoints); 183 | 184 | function addingpoints(toaddpoints, leftpoints) { 185 | if (toaddpoints >= leftpoints) { 186 | client.points.set(thekey ? thekey : key, 0, `points`); //set points to 0 187 | client.points.inc(thekey ? thekey : key, `level`); //add 1 to level 188 | //get current NEW level 189 | const newLevel = client.points.get(thekey ? thekey : key, `level`); 190 | /** 191 | * HARDEN UP THE NEXT LEVEL UP 192 | * @info The neededpoints shall raise always, when the newLevel is divideable by 4, at levels: 4,8,12,16,20,24,28,32,36,40,44,... 193 | */ 194 | if (newLevel % 4 === 0) client.points.math(thekey ? thekey : key, `+`, 100, `neededpoints`) 195 | 196 | const newneededPoints = client.points.get(thekey ? thekey : key, `neededpoints`); //get NEW needed Points 197 | const newPoints = client.points.get(thekey ? thekey : key, `points`); //get current NEW points 198 | 199 | addingpoints(toaddpoints - leftpoints, newneededPoints); //Ofc there is still points left to add so... lets do it! 200 | LEVELUP() //SEND LEVEL UP EMBED MESSAGE 201 | } else { 202 | client.points.math(thekey ? thekey : key, `+`, Number(toaddpoints), `points`) 203 | } 204 | } 205 | } 206 | Giving_Ranking_Points(); 207 | 208 | /** 209 | * CURRENT DATA 210 | * @info getting the current data for LEVEL, POINTS and NEEDEDPOINTS 211 | */ 212 | const curLevel = client.points.get(key, `level`); 213 | const curPoints = client.points.get(key, `points`); 214 | const neededPoints = client.points.get(key, `neededpoints`); 215 | 216 | 217 | /** 218 | * LEVELUP 219 | * @info curPoints >= neededPoints | => 220 | * @info if the current points are equal or more then the neededpoints the points shall reset and the level shall raise! 221 | */ 222 | function LEVELUP() { 223 | const newLevel = client.points.get(key, `level`); //get current NEW level 224 | const newPoints = client.points.get(key, `points`); //get current NEW points 225 | const newneededPoints = client.points.get(key, `neededpoints`); //get NEW needed Points 226 | 227 | //THE INFORMATION EMBED 228 | const embed = new Discord.MessageEmbed() 229 | .setAuthor(`Ranking of: ${message.author.tag}`, message.member.user.displayAvatarURL({ 230 | dynamic: true 231 | })) 232 | .setDescription(`You've leveled up to Level: **\`${newLevel}\`**! (Points: \`${newPoints}\` / \`${newneededPoints}\`) `) 233 | .setColor(embedcolor); 234 | //send ping and embed message 235 | message.reply(embed); 236 | } 237 | 238 | 239 | /** 240 | * @param { FUNCTIONS AREA } 241 | * @info FUNCTIONS 242 | * @info Every command leads into a single function, which may or may not be able to work together! 243 | */ 244 | 245 | /** 246 | * @info this function "BLOCK" is for the USER RANK and for LEADERBOARD 247 | */ 248 | function rank(the_rankuser) { 249 | /** 250 | * GET the Rank User 251 | * @info you can tag him 252 | */ 253 | try { 254 | let rankuser = the_rankuser ? the_rankuser : message.mentions.users.first() ? message.mentions.users.first() : args[0] ? args[0].length == 18 ? message.guild.members.cache.get(args[0]).user : message.guild.members.cache.find(u => u.user.username.toLowerCase().includes(String(args[0]).toLowerCase())).user : message.author 255 | if (!rankuser) return message.reply("PLEASE ADD A RANKUSER!"); 256 | // if(rankuser.bot) return message.reply("NO BOTS!"); 257 | //Call the databasing function! 258 | const key = `${message.guild.id}-${rankuser.id}`; 259 | databasing(rankuser); 260 | //do some databasing 261 | const filtered = client.points.filter(p => p.guild === message.guild.id).array(); 262 | const sorted = filtered.sort((a, b) => b.level - a.level || b.points - a.points); 263 | const top10 = sorted.splice(0, message.guild.memberCount); 264 | let i = 0; 265 | //count server rank sometimes an error comes 266 | for (const data of top10) { 267 | try { 268 | i++; 269 | if (data.user === rankuser.id) break; //if its the right one then break it ;) 270 | } catch { 271 | i = `Error counting Rank`; 272 | break; 273 | } 274 | } 275 | //math 276 | let curpoints = Number(client.points.get(key, `points`).toFixed(2)); 277 | //math 278 | let curnextlevel = Number(client.points.get(key, `neededpoints`).toFixed(2)); 279 | //if not level == no rank 280 | if (client.points.get(key, `level`) === undefined) i = `No Rank`; 281 | //define the ranking card 282 | const rank = new canvacord.Rank() 283 | .setAvatar(rankuser.displayAvatarURL({ 284 | dynamic: false, 285 | format: 'png' 286 | })) 287 | .setCurrentXP(Number(curpoints.toFixed(2)), embedcolor) 288 | .setRequiredXP(Number(curnextlevel.toFixed(2)), embedcolor) 289 | .setStatus("online", true, 5) 290 | .renderEmojis(true) 291 | .setProgressBar(embedcolor, "COLOR") 292 | .setRankColor(embedcolor, "COLOR") 293 | .setLevelColor(embedcolor, "COLOR") 294 | .setUsername(rankuser.username, embedcolor) 295 | .setRank(Number(i), "Rank", true) 296 | .setLevel(Number(client.points.get(key, `level`)), "Level", true) 297 | .setDiscriminator(rankuser.discriminator, embedcolor); 298 | rank.build() 299 | .then(data => { 300 | //add rankcard to attachment 301 | const attachment = new Discord.MessageAttachment(data, "RankCard.png"); 302 | //define embed 303 | const embed = new Discord.MessageEmbed() 304 | .setTitle(`Ranking of: ${rankuser.username}`) 305 | .setColor(embedcolor) 306 | .setImage("attachment://RankCard.png") 307 | .attachFiles(attachment) 308 | //send that embed 309 | message.channel.send(embed); 310 | return; 311 | }); 312 | } catch (error) { 313 | console.log(error.stack) 314 | message.reply("PLEASE ADD A RANKUSER!"); 315 | } 316 | } 317 | 318 | function leaderboardembed() { 319 | const filtered = client.points.filter(p => p.guild === message.guild.id).array(); 320 | let orilent; 321 | const sorted = filtered.sort((a, b) => b.level - a.level || b.points - a.points); 322 | let embeds = []; 323 | let j = 0; 324 | let maxnum = 50; 325 | orilent = sorted.length; 326 | if(isNaN(maxnum)) { 327 | console.log("maximum_leaderboard NOT A NUMBER") 328 | maxnum = 50;} 329 | if (maxnum > sorted.length) 330 | maxnum = sorted.length + (10 - Number(String(sorted.length/10).slice(2))); 331 | if(maxnum < 10) maxnum = 10; 332 | for (let i = 10; i <= maxnum; i += 10) { 333 | const top = sorted.splice(0, 10); 334 | const embed = new Discord.MessageEmbed() 335 | .setTitle(`\`${message.guild.name}\` | Leaderboard`) 336 | .setTimestamp() 337 | .setDescription(`Top ${i ["⏪", "⏹", "⏩"].includes(reaction.emoji.name) && message.author.id === user.id; 371 | const collector = lbembed.createReactionCollector(filter, { 372 | time: 60000 373 | }); 374 | 375 | collector.on("collect", async (reaction, user) => { 376 | try { 377 | if (reaction.emoji.name === "⏩") { 378 | if (currentPage < embeds.length - 1) { 379 | currentPage++; 380 | lbembed.edit(`**Current Page - ${currentPage + 1}/${embeds.length}**`, embeds[currentPage]); 381 | } 382 | } else if (reaction.emoji.name === "⏪") { 383 | if (currentPage !== 0) { 384 | --currentPage; 385 | lbembed.edit(`**Current Page - ${currentPage + 1}/${embeds.length}**`, embeds[currentPage]); 386 | } 387 | } else { 388 | collector.stop(); 389 | reaction.message.reactions.removeAll(); 390 | } 391 | await reaction.users.remove(message.author.id); 392 | } catch (error) { 393 | console.error(error); 394 | } 395 | }); 396 | } 397 | 398 | function setxpcounter(){ 399 | try { 400 | /** 401 | * GET the Rank User 402 | * @info you can tag him 403 | */ 404 | if (!args[0]) return message.reply("PLEASE ADD A RANKUSER!"); 405 | let rankuser = message.mentions.users.first(); 406 | if (!rankuser) return message.reply("PLEASE ADD A RANKUSER!"); 407 | // if(rankuser.bot) return message.reply("NO BOTS!"); 408 | //Call the databasing function! 409 | const key = `${message.guild.id}-${rankuser.id}`; 410 | databasing(rankuser); 411 | if (!args[1]) return message.reply("PLEASE ADD POINTS TO ADD! Usage: `setxpcounter @USER 2`"); 412 | client.points.set(key, Number(args[1]), `xpcounter`); //set points to 0 413 | const embed = new Discord.MessageEmbed() 414 | .setColor(embedcolor) 415 | .setDescription(`Successfully set XP COUNTER to \`${args[1]}x\` for: \`${rankuser.tag}\``) 416 | message.reply(embed); 417 | } catch (error) { 418 | console.log(error.stack) 419 | message.reply("PLEASE ADD A RANKUSER!"); 420 | } 421 | } 422 | 423 | function setglobalxpcounter(){ 424 | try { 425 | if (!args[0]) return message.reply("PLEASE ADD POINTS TO ADD! Usage: `setglobalxpcounter 2`"); 426 | client.points.set(message.guild.id, Number(args[0]), `setglobalxpcounter`); //set points to 0 427 | const embed = new Discord.MessageEmbed() 428 | .setColor(embedcolor) 429 | .setDescription(`Successfully set GLOBAL XP COUNTER to \`${args[0]}x\` for: \`${message.guild.name}\``) 430 | message.reply(embed); 431 | } catch { 432 | } 433 | } 434 | /** 435 | * @info this function "BLOCK" is for managing the POINTS, adding, setting and removing! PER USER 436 | */ 437 | function addpoints(amount) { 438 | try { 439 | /** 440 | * GET the Rank User 441 | * @info you can tag him 442 | */ 443 | if (!args[0]) return message.reply("PLEASE ADD A RANKUSER!"); 444 | let rankuser = message.mentions.users.first(); 445 | if (!rankuser) return message.reply("PLEASE ADD A RANKUSER!"); 446 | // if(rankuser.bot) return message.reply("NO BOTS!"); 447 | //Call the databasing function! 448 | const key = `${message.guild.id}-${rankuser.id}`; 449 | databasing(rankuser); 450 | 451 | const curPoints = client.points.get(key, `points`); 452 | const neededPoints = client.points.get(key, `neededpoints`); 453 | let leftpoints = neededPoints - curPoints; 454 | if (!args[1] && !amount) return message.reply("PLEASE ADD POINTS TO ADD! Usage: `addpoints @USER 100`"); 455 | if (!amount) amount = Number(args[1]); 456 | if (amount < 0) removepoints(amount); 457 | let toaddpoints = amount; 458 | addingpoints(toaddpoints, leftpoints); 459 | 460 | function addingpoints(toaddpoints, leftpoints) { 461 | if (toaddpoints >= leftpoints) { 462 | client.points.set(key, 0, `points`); //set points to 0 463 | client.points.inc(key, `level`); //add 1 to level 464 | //HARDING UP! 465 | const newLevel = client.points.get(key, `level`); //get current NEW level 466 | if (newLevel % 4 === 0) client.points.math(key, `+`, 100, `neededpoints`) 467 | 468 | const newneededPoints = client.points.get(key, `neededpoints`); //get NEW needed Points 469 | const newPoints = client.points.get(key, `points`); //get current NEW points 470 | 471 | //THE INFORMATION EMBED 472 | const embed = new Discord.MessageEmbed() 473 | .setAuthor(`Ranking of: ${rankuser.tag}`, rankuser.displayAvatarURL({ 474 | dynamic: true 475 | })) 476 | .setDescription(`You've leveled up to Level: **\`${newLevel}\`**! (Points: \`${newPoints + toaddpoints - leftpoints}\` / \`${newneededPoints}\`) `) 477 | .setColor(embedcolor); 478 | //send ping and embed message only IF the adding will be completed! 479 | if (toaddpoints - leftpoints < newneededPoints) 480 | message.channel.send(rankuser, embed); 481 | 482 | addingpoints(toaddpoints - leftpoints, newneededPoints); //Ofc there is still points left to add so... lets do it! 483 | } else { 484 | client.points.math(key, `+`, Number(toaddpoints), `points`) 485 | } 486 | } 487 | 488 | 489 | const embed = new Discord.MessageEmbed() 490 | .setColor(embedcolor) 491 | .setDescription(`Successfully added \`${toaddpoints} Points\` to: \`${rankuser.tag}\``) 492 | message.reply(embed); 493 | rank(rankuser); //also sending the rankcard 494 | } catch (error) { 495 | console.log(error.stack) 496 | message.reply("PLEASE ADD A RANKUSER!"); 497 | } 498 | } 499 | 500 | function setpoints() { 501 | try { 502 | /** 503 | * GET the Rank User 504 | * @info you can tag him 505 | */ 506 | if (!args[0]) return message.reply("PLEASE ADD A RANKUSER!"); 507 | let rankuser = message.mentions.users.first(); 508 | if (!rankuser) return message.reply("PLEASE ADD A RANKUSER!"); 509 | // if(rankuser.bot) return message.reply("NO BOTS!"); 510 | //Call the databasing function! 511 | const key = `${message.guild.id}-${rankuser.id}`; 512 | databasing(rankuser); 513 | 514 | let toaddpoints = Number(args[1]); 515 | if (!args[1]) return message.reply("PLEASE ADD POINTS TO SET! Usage: `addpoints @USER 100`"); 516 | if (Number(args[1]) < 0) args[1] = 0; 517 | const neededPoints = client.points.get(key, `neededpoints`); 518 | addingpoints(toaddpoints, neededPoints); 519 | 520 | function addingpoints(toaddpoints, neededPoints) { 521 | if (toaddpoints >= neededPoints) { 522 | client.points.set(key, 0, `points`); //set points to 0 523 | client.points.inc(key, `level`); //add 1 to level 524 | //HARDING UP! 525 | const newLevel = client.points.get(key, `level`); //get current NEW level 526 | if (newLevel % 4 === 0) client.points.math(key, `+`, 100, `neededpoints`) 527 | 528 | const newneededPoints = client.points.get(key, `neededpoints`); //get NEW needed Points 529 | const newPoints = client.points.get(key, `points`); //get current NEW points 530 | 531 | //THE INFORMATION EMBED 532 | const embed = new Discord.MessageEmbed() 533 | .setAuthor(`Ranking of: ${rankuser.tag}`, rankuser.displayAvatarURL({ 534 | dynamic: true 535 | })) 536 | .setDescription(`You've leveled up to Level: **\`${newLevel}\`**! (Points: \`${newPoints}\` / \`${newneededPoints}\`) `) 537 | .setColor(embedcolor); 538 | //send ping and embed message 539 | message.channel.send(rankuser, embed); 540 | 541 | addingpoints(toaddpoints - neededPoints, newneededPoints); //Ofc there is still points left to add so... lets do it! 542 | } else { 543 | client.points.set(key, Number(toaddpoints), `points`) 544 | } 545 | } 546 | 547 | const embed = new Discord.MessageEmbed() 548 | .setColor(embedcolor) 549 | .setDescription(`Successfully set \`${toaddpoints} Points\` to: \`${rankuser.tag}\``) 550 | message.channel.send(embed); 551 | rank(rankuser); //also sending the rankcard 552 | } catch (error) { 553 | console.log(error.stack) 554 | message.reply("PLEASE ADD A RANKUSER!"); 555 | } 556 | } 557 | 558 | function removepoints(amount) { 559 | try { 560 | /** 561 | * GET the Rank User 562 | * @info you can tag him 563 | */ 564 | if (!args[0]) return message.reply("PLEASE ADD A RANKUSER!"); 565 | let rankuser = message.mentions.users.first(); 566 | if (!rankuser) return message.reply("PLEASE ADD A RANKUSER!"); 567 | // if(rankuser.bot) return message.reply("NO BOTS!"); 568 | //Call the databasing function! 569 | const key = `${message.guild.id}-${rankuser.id}`; 570 | databasing(rankuser); 571 | 572 | const curPoints = client.points.get(key, `points`); 573 | const neededPoints = client.points.get(key, `neededpoints`); 574 | 575 | if (!args[1] && !amount) return message.reply("PLEASE ADD POINTS TO REMOVE! Usage: `addpoints @USER 100`"); 576 | if (!amount) amount = Number(args[1]); 577 | if (amount < 0) addpoints(amount); 578 | 579 | removingpoints(amount, curPoints); 580 | 581 | function removingpoints(amount, curPoints) { 582 | if (amount > curPoints) { 583 | let removedpoints = amount - curPoints - 1; 584 | client.points.set(key, neededPoints - 1, `points`); //set points to 0 585 | if (client.points.get(key, `level`) == 1) return message.reply("ALREADY AT 0 POINTS"); 586 | client.points.dec(key, `level`); //remove 1 from level 587 | //HARDING UP! 588 | const newLevel = client.points.get(key, `level`); //get current NEW level 589 | if ((newLevel + 1) % 4 === 0) { //if old level was divideable by 4 set neededpoints && points -100 590 | client.points.math(key, `-`, 100, `points`) 591 | client.points.math(key, `-`, 100, `neededpoints`) 592 | } 593 | 594 | const newneededPoints = client.points.get(key, `neededpoints`); //get NEW needed Points 595 | const newPoints = client.points.get(key, `points`); //get current NEW points 596 | 597 | //THE INFORMATION EMBED 598 | const embed = new Discord.MessageEmbed() 599 | .setAuthor(`Ranking of: ${rankuser.tag}`, rankuser.displayAvatarURL({ 600 | dynamic: true 601 | })) 602 | .setDescription(`You've leveled down to Level: **\`${newLevel}\`**! (Points: \`${newPoints - amount + removedpoints}\` / \`${newneededPoints}\`) `) 603 | .setColor(embedcolor); 604 | //send ping and embed message only IF the removing will be completed! 605 | if (amount - removedpoints < neededPoints) 606 | message.channel.send(rankuser, embed); 607 | 608 | removingpoints(amount - removedpoints, newneededPoints); //Ofc there is still points left to add so... lets do it! 609 | } else { 610 | client.points.math(key, `-`, Number(amount), `points`) 611 | } 612 | } 613 | 614 | const embed = new Discord.MessageEmbed() 615 | .setColor(embedcolor) 616 | .setDescription(`Successfully removed \`${amount} Points\` from: \`${rankuser.tag}\``) 617 | message.reply(embed); 618 | rank(rankuser); //also sending the rankcard 619 | } catch (error) { 620 | console.log(error.stack) 621 | message.reply("PLEASE ADD A RANKUSER!"); 622 | } 623 | } 624 | 625 | /** 626 | * @info this function "BLOCK" is for managing the LEVELS, adding, setting and removing! PER USER 627 | */ 628 | function addlevel() { 629 | try { 630 | /** 631 | * GET the Rank User 632 | * @info you can tag him 633 | */ 634 | if (!args[0]) return message.reply("PLEASE ADD A RANKUSER!"); 635 | let rankuser = message.mentions.users.first(); 636 | if (!rankuser) return message.reply("PLEASE ADD A RANKUSER!"); 637 | // if(rankuser.bot) return message.reply("NO BOTS!"); 638 | 639 | //Call the databasing function! 640 | const key = `${message.guild.id}-${rankuser.id}`; 641 | databasing(rankuser); 642 | let newLevel = client.points.get(key, `level`); 643 | if (!args[1]) return message.reply("Please add the amount of Levels you want to add to! Usage: addlevel @User 4"); 644 | if (Number(args[1]) < 0) args[1] = 0; 645 | for (let i = 0; i < Number(args[1]); i++) { 646 | client.points.set(key, 0, `points`); //set points to 0 647 | client.points.inc(key, `level`); //add 1 to level 648 | //HARDING UP! 649 | newLevel = client.points.get(key, `level`); //get current NEW level 650 | if (newLevel % 4 === 0) client.points.math(key, `+`, 100, `neededpoints`) 651 | } 652 | const newneededPoints = client.points.get(key, `neededpoints`); //get NEW needed Points 653 | const newPoints = client.points.get(key, `points`); //get current NEW points 654 | 655 | //THE INFORMATION EMBED 656 | const embed = new Discord.MessageEmbed() 657 | .setAuthor(`Ranking of: ${rankuser.tag}`, rankuser.displayAvatarURL({ 658 | dynamic: true 659 | })) 660 | .setDescription(`You've leveled up to Level: **\`${newLevel}\`**! (Points: \`${newPoints}\` / \`${newneededPoints}\`) `) 661 | .setColor(embedcolor); 662 | message.channel.send(rankuser, embed); 663 | rank(rankuser); //also sending the rankcard 664 | const sssembed = new Discord.MessageEmbed() 665 | .setColor(embedcolor) 666 | .setDescription(`Successfully added ${args[1]} Levels to: \`${rankuser.tag}\``) 667 | message.reply(sssembed); 668 | } catch (error) { 669 | console.log(error.stack) 670 | message.reply("PLEASE ADD A RANKUSER!"); 671 | } 672 | } 673 | 674 | function setlevel() { 675 | try { 676 | /** 677 | * GET the Rank User 678 | * @info you can tag him 679 | */ 680 | if (!args[0]) return message.reply("PLEASE ADD A RANKUSER!"); 681 | let rankuser = message.mentions.users.first(); 682 | if (!rankuser) return message.reply("PLEASE ADD A RANKUSER!"); 683 | // if(rankuser.bot) return message.reply("NO BOTS!"); 684 | 685 | //Call the databasing function! 686 | const key = `${message.guild.id}-${rankuser.id}`; 687 | databasing(rankuser); 688 | 689 | if (!args[1]) return message.reply("Please add the amount of Levels you want to set to! Usage: setlevel @User 3"); 690 | if (Number(args[1]) < 1) args[1] = 1; 691 | client.points.set(key, Number(args[1]), `level`); //set level to the wanted level 692 | client.points.set(key, 0, `points`); //set the points to 0 693 | 694 | let newLevel = client.points.get(key, `level`); //set level to the wanted level 695 | let counter = Number(newLevel) / 4; 696 | 697 | client.points.set(key, 400, `neededpoints`) //set neededpoints to 0 for beeing sure 698 | //add 100 for each divideable 4 699 | for (let i = 0; i < Math.floor(counter); i++) { 700 | client.points.math(key, `+`, 100, `neededpoints`) 701 | } 702 | const newneededPoints = client.points.get(key, `neededpoints`); //get NEW needed Points 703 | 704 | const newPoints = client.points.get(key, `points`); //get current NEW points 705 | //THE INFORMATION EMBED 706 | const embed = new Discord.MessageEmbed() 707 | .setAuthor(`Ranking of: ${rankuser.tag}`, rankuser.displayAvatarURL({ 708 | dynamic: true 709 | })) 710 | .setDescription(`You've leveled up to Level: **\`${newLevel}\`**! (Points: \`${newPoints}\` / \`${newneededPoints}\`) `) 711 | .setColor(embedcolor); 712 | message.channel.send(rankuser, embed); 713 | rank(rankuser); //also sending the rankcard 714 | const sssembed = new Discord.MessageEmbed() 715 | .setColor(embedcolor) 716 | .setDescription(`Successfully set \`${rankuser.tag}\` to Level: ${args[1]}`) 717 | message.reply(sssembed); 718 | } catch (error) { 719 | console.log(error.stack) 720 | message.reply("PLEASE ADD A RANKUSER!"); 721 | } 722 | } 723 | 724 | function removelevel() { 725 | try { 726 | /** 727 | * GET the Rank User 728 | * @info you can tag him 729 | */ 730 | if (!args[0]) return message.reply("PLEASE ADD A RANKUSER!"); 731 | let rankuser = message.mentions.users.first(); 732 | if (!rankuser) return message.reply("PLEASE ADD A RANKUSER!"); 733 | // if(rankuser.bot) return message.reply("NO BOTS!"); 734 | 735 | //Call the databasing function! 736 | const key = `${message.guild.id}-${rankuser.id}`; 737 | databasing(rankuser); 738 | let newLevel = client.points.get(key, `level`); 739 | if (!args[1]) return message.reply("Please add the amount of Levels you want to remove to! Usage: removelevel @User 4"); 740 | if (Number(args[1]) < 0) args[1] = 0; 741 | for (let i = 0; i < Number(args[1]); i++) { 742 | client.points.set(key, 0, `points`); //set points to 0 743 | client.points.dec(key, `level`); //add 1 to level 744 | //HARDING UP! 745 | newLevel = client.points.get(key, `level`); //get current NEW level 746 | if(newLevel < 1) client.points.set(key, 1 ,`level`); //if smaller then 1 set to 1 747 | } 748 | snewLevel = client.points.get(key, `level`); //get current NEW level 749 | let counter = Number(snewLevel) / 4; 750 | 751 | client.points.set(key, 400, `neededpoints`) //set neededpoints to 0 for beeing sure 752 | //add 100 for each divideable 4 753 | for (let i = 0; i < Math.floor(counter); i++) { 754 | client.points.math(key, `+`, 100, `neededpoints`) 755 | } 756 | const newneededPoints = client.points.get(key, `neededpoints`); //get NEW needed Points 757 | const newPoints = client.points.get(key, `points`); //get current NEW points 758 | 759 | //THE INFORMATION EMBED 760 | const embed = new Discord.MessageEmbed() 761 | .setAuthor(`Ranking of: ${rankuser.tag}`, rankuser.displayAvatarURL({ 762 | dynamic: true 763 | })) 764 | .setDescription(`You've leveled down to Level: **\`${newLevel}\`**! (Points: \`${newPoints}\` / \`${newneededPoints}\`) `) 765 | .setColor(embedcolor); 766 | message.channel.send(rankuser, embed); 767 | rank(rankuser); //also sending the rankcard 768 | const sssembed = new Discord.MessageEmbed() 769 | .setColor(embedcolor) 770 | .setDescription(`Successfully removed \`${args[0]}\` Levels from: \`${rankuser.tag}\``) 771 | message.reply(sssembed); 772 | } catch (error) { 773 | console.log(error.stack) 774 | message.reply("PLEASE ADD A RANKUSER!"); 775 | } 776 | } 777 | 778 | /** 779 | * @info This function is for ressetting a single USER 780 | */ 781 | function resetranking() { 782 | try { 783 | /** 784 | * GET the Rank User 785 | * @info you can tag him 786 | */ 787 | if (!args[0]) return message.reply("PLEASE ADD A RANKUSER!"); 788 | let rankuser = message.mentions.users.first(); 789 | if (!rankuser) return message.reply("PLEASE ADD A RANKUSER!"); 790 | // if(rankuser.bot) return message.reply("NO BOTS!"); 791 | 792 | //Call the databasing function! 793 | const key = `${message.guild.id}-${rankuser.id}`; 794 | databasing(rankuser); 795 | 796 | client.points.set(key, 1, `level`); //set level to 0 797 | client.points.set(key, 0, `points`); //set the points to 0 798 | client.points.set(key, 400, `neededpoints`) //set neededpoints to 0 for beeing sure 799 | client.points.set(key, "", `oldmessage`); //set old message to 0 800 | 801 | //THE INFORMATION EMBED 802 | const embed = new Discord.MessageEmbed() 803 | .setAuthor(`Ranking of: ${rankuser.tag}`, rankuser.displayAvatarURL({ 804 | dynamic: true 805 | })) 806 | .setDescription(`You've been resetted to Level: **\`1\`**! (Points: \`0\` / \`400\`) `) 807 | .setColor(embedcolor); 808 | message.channel.send(rankuser, embed); 809 | rank(rankuser); //also sending the rankcard 810 | const sssembed = new Discord.MessageEmbed() 811 | .setColor(embedcolor) 812 | .setDescription(`Successfully resetted ranking from: \`${rankuser.tag}\``) 813 | message.reply(sssembed); 814 | } catch (error) { 815 | console.log(error.stack) 816 | message.reply("PLEASE ADD A RANKUSER!"); 817 | } 818 | } 819 | 820 | 821 | /** 822 | * @info this function "BLOCK" is for managing the POINTS for EVERYONE, like randompoints to EVERYONE, and registering EVERYONE and resetting EVERYONE 823 | */ 824 | function registerall() { 825 | let allmembers = message.guild.members.cache.keyArray(); 826 | for (let i = 0; i < allmembers.length; i++) { 827 | //Call the databasing function! 828 | let rankuser = message.guild.members.cache.get(allmembers[i]).user; 829 | databasing(rankuser); 830 | } 831 | const embed = new Discord.MessageEmbed() 832 | .setColor(embedcolor) 833 | .setDescription(`Successfully registered everyone`) 834 | message.reply(embed); 835 | } 836 | 837 | function resetrankingall() { 838 | let allmembers = message.guild.members.cache.keyArray(); 839 | for (let i = 0; i < allmembers.length; i++) { 840 | let rankuser = message.guild.members.cache.get(allmembers[i]).user; 841 | const key = `${message.guild.id}-${rankuser.id}`; 842 | client.points.set(key, 1, `level`); //set level to 0 843 | client.points.set(key, 0, `points`); //set the points to 0 844 | client.points.set(key, 400, `neededpoints`) //set neededpoints to 0 for beeing sure 845 | client.points.set(key, "", `oldmessage`); //set old message to 0 846 | } 847 | const embed = new Discord.MessageEmbed() 848 | .setColor(embedcolor) 849 | .setDescription(`Successfully resetted everyone`) 850 | message.reply(embed); 851 | } 852 | 853 | function addrandomall() { 854 | let maxnum = 5; 855 | if (args[0]) maxnum = Number(args[0]); 856 | let allmembers = message.guild.members.cache.keyArray(); 857 | for (let i = 0; i < allmembers.length; i++) { 858 | //Call the databasing function! 859 | let rankuser = message.guild.members.cache.get(allmembers[i]).user; 860 | databasing(rankuser); 861 | if(rankuser.bot) continue; 862 | Giving_Ranking_Points(`${message.guild.id}-${rankuser.id}`, maxnum); 863 | Giving_Ranking_Points(`${message.guild.id}-${message.author.id}`, maxnum); 864 | } 865 | const embed = new Discord.MessageEmbed() 866 | .setColor(embedcolor) 867 | .setDescription(`Successfully added ${args[0]} Points to everyone`) 868 | message.reply(embed); 869 | } 870 | 871 | 872 | 873 | function levelinghelp() { 874 | const embed = new Discord.MessageEmbed() 875 | .setTitle(`\`${message.guild.name}\` | Ranking Commands`) 876 | .setTimestamp() 877 | .setDescription(`> **HELP:** \`${prefix}levelinghelp\``) 878 | .setColor(embedcolor) 879 | .addFields([{ 880 | name: "`rank [@User]`", 881 | value: ">>> *Shows the Rank of a User*", 882 | inline: true 883 | }, 884 | { 885 | name: "`leaderboard`", 886 | value: ">>> *Shows the Top 10 Leaderboard*", 887 | inline: true 888 | }, 889 | { 890 | name: "`setxpcounter <@USER> `", 891 | value: ">>> *Changes the amount of how much to count, x1, x2, x3, ...*", 892 | inline: true 893 | }, 894 | 895 | { 896 | name: "`addpoints <@User> >> *Add a specific amount of Points to a User*", 898 | inline: true 899 | }, 900 | { 901 | name: "`setpoints <@User> >> *Set a specific amount of Points to a User*", 903 | inline: true 904 | }, 905 | { 906 | name: "`removepoints <@User> >> *Remove a specific amount of Points to a User*", 908 | inline: true 909 | }, 910 | 911 | { 912 | name: "`addlevel <@User> >> *Add a specific amount of Levels to a User*", 914 | inline: true 915 | }, 916 | { 917 | name: "`setlevel <@User> >> *Set a specific amount of Levels to a User*", 919 | inline: true 920 | }, 921 | { 922 | name: "`removelevel <@User> >> *Remove a specific amount of Levels to a User*", 924 | inline: true 925 | }, 926 | 927 | { 928 | name: "`resetranking <@User>`", 929 | value: ">>> *Resets the ranking of a User*", 930 | inline: true 931 | }, 932 | { 933 | name: "`setglobalxpcounter `", 934 | value: ">>> *Sets the global xp counter for this guild, standard 1*", 935 | inline: true 936 | }, 937 | { 938 | name: "\u200b", 939 | value: "\u200b", 940 | inline: true 941 | }, 942 | 943 | { 944 | name: "`registerall`", 945 | value: ">>> *Register everyone in the Server to the Database*", 946 | inline: true 947 | }, 948 | { 949 | name: "`resetrankingall`", 950 | value: ">>> *Reset ranking of everyone in this Server*", 951 | inline: true 952 | }, 953 | { 954 | name: "`addrandomall`", 955 | value: ">>> *Add a random amount of Points to everyone*", 956 | inline: true 957 | } 958 | ]) 959 | message.channel.send(embed) 960 | } 961 | 962 | }) 963 | } 964 | 965 | 966 | //Coded by Tomato#6966! 967 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Better-Discord-Ranking-System 2 | 3 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) 4 | [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://GitHub.com/Tomato6966/) 5 | [![Ask Me Anything !](https://img.shields.io/badge/Ask%20me-anything-1abc9c.svg)](https://GitHub.com/Tomato6966/Ask-Me-Anything) 6 | [![Support Server](https://img.shields.io/discord/591914197219016707.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/fS6qBSm) 7 | 8 | An easy to setup and easy to use Welcome System Bot for Discord.js with the package `canvas` 9 | 10 | ## [**DISCORD SUPPORT SERVER INVITE**](https://support.milrato.eu) 11 | 12 | ## Installation | How to use the Bot 13 | 14 | **1.** Install [node.js v12+](https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode) or higher 15 | 16 | **2.** Download this repo and unzip it | or git clone it 17 | 18 | **3.** Install all of the packages with **`npm install`** | the packages are **`npm install discord.js canvacord enmap`** 19 | 20 | **3.1** Fill in everything in config.json 21 | 22 | **4.** start the bot with **`node index.js`** 23 | 24 | ### Usage - index.js 25 | 26 | ```javascript 27 | const Discord = require("discord.js"); //load the Discord.js Library 28 | const client = new Discord.Client(); //make a new Client 29 | const config = require("./config.json"); //load the config.json file 30 | const Enmap = require("enmap") //load the enmap library 31 | const canvacord = require("canvacord") //load the canvacord library 32 | client.points = new Enmap({ name: "points" }); //For ranking system 33 | client.on("ready", ()=>console.log("READY")); //log when the bot gets ready 34 | const ranking = require("./ranking"); //load the ranking file 35 | ranking(client); //call the ranking file with the client 36 | client.login(config.TOKEN); //start the bot with the bot token 37 | ``` 38 | 39 | ### Usage - config.json 40 | - "TOKEN" ... is your Bot token 41 | - "PREFIX" ... is the PREFIX for the commands 42 | - "maximum_leaderboard" ... is the maximum amount of users listed on the leaderboard cmd 43 | - "embedcolor" ... is the color of your embeds 44 | 45 | ```json 46 | { 47 | "TOKEN": "NzQ4MDk22135412OTY5.X0Yc2g.masd2pFasdasd2Urh3X0S_2yuBo", 48 | "PREFIX": "?", 49 | 50 | "maximum_leaderboard": "50", 51 | "embedcolor": "#118fff" 52 | } 53 | ``` 54 | 55 | #### **NOTE:** 56 | 57 | *If you are having errors/problems with starting delete the package.json file and do, before you install the packages `npm init`* 58 | 59 |
60 | 61 | *** 62 | 63 | ## [Discord Server 😎](https://discord.gg/milrato) | [Website](https://milrato.dev) 64 | 65 | 66 | *** 67 | 68 | ## SUPPORT ME AND MILRATO DEVELOPMENT 69 | 70 | > You can always Support me by inviting one of my **own Discord Bots** 71 | 72 | [![2021's best Music Bot | Lava Music](https://cdn.discordapp.com/attachments/748533465972080670/817088638780440579/test3.png)](https://lava.milrato.dev) 73 | [![Musicium Music Bot](https://cdn.discordapp.com/attachments/742446682381221938/770055673965707264/test1.png)](https://musicium.musicium.dev) 74 | [![Milrato Multi Bot](https://cdn.discordapp.com/attachments/742446682381221938/770056826724679680/test1.png)](https://milrato.milrato.dev) 75 | 76 | # Credits 77 | 78 | > If consider using this Bot, make sure to credit me! 79 | --------------------------------------------------------------------------------