· 8 years ago · Jun 13, 2018, 05:18 PM
1const Discord = require("discord.js");
2const client = new Discord.Client();
3const config = require("./config.json");
4const SQLite = require("better-sqlite3");
5const sql = new SQLite('./scores.sqlite');
6
7client.on("ready", () => {
8 // Check if the table "points" exists.
9 const table = sql.prepare("SELECT count(*) FROM sqlite_master WHERE type='table' AND name = 'scores';").get();
10 if (!table['count(*)']) {
11 // If the table isn't there, create it and setup the database correctly.
12 sql.prepare("CREATE TABLE scores (id TEXT PRIMARY KEY, user TEXT, guild TEXT, points INTEGER, level INTEGER);").run();
13 // Ensure that the "id" row is always unique and indexed.
14 sql.prepare("CREATE UNIQUE INDEX idx_scores_id ON scores (id);").run();
15 sql.pragma("synchronous = 1");
16 sql.pragma("journal_mode = wal");
17 }
18
19 // And then we have two prepared statements to get and set the score data.
20 client.getScore = sql.prepare("SELECT * FROM scores WHERE user = ? AND guild = ?");
21 client.setScore = sql.prepare("INSERT OR REPLACE INTO scores (id, user, guild, points, level) VALUES (@id, @user, @guild, @points, @level);");
22});
23
24client.on("message", message => {
25 if (message.author.bot) return;
26 let score;
27 if (message.guild) {
28 score = client.getScore.get(message.author.id, message.guild.id);
29 if (!score) {
30 score = { id: `${message.guild.id}-${message.author.id}`, user: message.author.id, guild: message.guild.id, points: 0, level: 1 }
31 }
32 score.points++;
33 const curLevel = Math.floor(0.1 * Math.sqrt(score.points));
34 if(score.level < curLevel) {
35 message.reply(`You've leveled up to level **${curLevel}**! Ain't that dandy?`);
36 }
37 client.setScore.run(score);
38 }
39 if (message.content.indexOf(config.prefix) !== 0) return;
40
41 const args = message.content.slice(config.prefix.length).trim().split(/ +/g);
42 const command = args.shift().toLowerCase();
43
44if(command === "points") {
45 return message.reply(`You currently have ${score.points} points and are level ${score.level}!`);
46}
47if(command === "give") {
48 // Limited to guild owner - adjust to your own preference!
49 if(!message.author.id === message.guild.owner) return message.reply("You're not the boss of me, you can't do that!");
50
51 const user = message.mentions.users.first() || client.users.get(args[0]);
52 if(!user) return message.reply("You must mention someone or give their ID!");
53
54 const pointsToAdd = parseInt(args[1], 10);
55 if(!pointsToAdd) return message.reply("You didn't tell me how many points to give...")
56
57 // Get their current points.
58 let userscore = client.getScore.get(user.id, message.guild.id);
59 // It's possible to give points to a user we haven't seen, so we need to initiate defaults here too!
60 if (!userscore) {
61 userscore = { id: `${message.guild.id}-${user.id}`, user: user.id, guild: message.guild.id, points: 0, level: 1 }
62 }
63 userscore.points += pointsToAdd;
64
65 // We also want to update their level (but we won't notify them if it changes)
66 let userLevel = Math.floor(0.1 * Math.sqrt(score.points));
67 userscore.level = userLevel;
68
69 // And we save it!
70 client.setScore.run(userscore);
71
72 return message.channel.send(`${user.tag} has received ${pointsToAdd} points and now stands at ${userscore.points} points.`);
73}
74
75if(command === "leaderboard") {
76 const top10 = sql.prepare("SELECT * FROM scores WHERE guild = ? ORDER BY points DESC LIMIT 10;").all(message.guild.id);
77
78 // Now shake it and show it! (as a nice embed, too!)
79 const embed = new Discord.RichEmbed()
80 .setTitle("Leaderboard")
81 .setAuthor(client.user.username, client.user.avatarURL)
82 .setDescription("Our top 10 points leaders!")
83 .setColor(0x00AE86);
84
85 for(const data of top10) {
86 embed.addField(client.users.get(data.user).tag, `${data.points} points (level ${data.level})`);
87 }
88 return message.channel.send({embed});
89}
90});
91client.login(process.env.SECRET);