· 6 years ago · Apr 16, 2019, 05:16 AM
1require('events').EventEmitter.defaultMaxListeners = 0
2const config = require("./botconfig.json");
3const Discord = require("discord.js");
4const discord_token = process.env.TOKEN;
5const prefix = process.env.PREFIX;
6const db = require('quick.db')
7
8const bot = new Discord.Client({disableEveryone: true});
9
10const http = require('http');
11const express = require('express');
12const app = express();
13app.get("/", (request, response) => {
14 console.log(Date.now() + " I just pinged myself");
15 response.sendStatus(200);
16});
17app.listen(process.env.PORT);
18setInterval(() => {
19 http.get(`http://${process.env.PROJECT_DOMAIN}.glitch.me/`);
20}, 280000);
21
22const fs = require("fs");
23bot.commands = new Discord.Collection();
24bot.aliases = new Discord.Collection();
25
26fs.readdir('./events/', (err, files) => {
27 if (err) return console.error;
28 files.forEach(file => {
29 if (!file.endsWith('.js')) return;
30 const evt = require(`./events/${file}`);
31 let evtName = file.split('.')[0];
32 console.log(`Loaded '${evtName}'.`)
33 bot.on(evtName, evt.bind(null, bot));
34 });
35});
36
37fs.readdir("./commands/", (err, files) => {
38 if(err) console.log(err)
39
40 let jsfile = files.filter(f => f.split(".").pop() === "js")
41 if(jsfile.length <= 0) {
42 return console.log("[LOS] Couldn't find Commands!");
43 }
44
45 jsfile.forEach((f, i) => {
46 let pull = require(`./commands/${f}`);
47 bot.commands.set(pull.config.name, pull);
48 pull.config.aliases.forEach(alias => {
49 bot.aliases.set(alias, pull.config.name)
50 })
51 })
52});
53
54bot.on("message", async message => {
55 if(message.author.bot || message.channel.type === "dm") return;
56
57 let prefix = config.prefix;
58 let messageArray = message.content.split(" ")
59 let cmd = messageArray[0].toLowerCase();
60 let args = messageArray.slice(1);
61
62
63 if(!message.content.startsWith(prefix)) return;
64 let commandfile = bot.commands.get(cmd.slice(prefix.length)) || bot.commands.get(bot.aliases.get(cmd.slice(prefix.length)))
65 if(commandfile) commandfile.run(bot,message,args)
66});
67
68const Canvas = require('canvas');
69const snekfetch = require('snekfetch');
70
71const applyText = (canvas, text) => {
72 const ctx = canvas.getContext('2d');
73 let fontSize = 70;
74
75 do {
76 ctx.font = `${fontSize -= 10}px sans-serif`;
77 } while (ctx.measureText(text).width > canvas.width - 300);
78
79 return ctx.font;
80};
81
82bot.on('guildMemberAdd', async (member, message) => {
83 let chan = await db.fetch(`chanjl_${member.guild.id}`);
84
85 if (!chan) return;
86
87 const canvas = Canvas.createCanvas(700, 250);
88 const ctx = canvas.getContext('2d');
89
90
91 const { body:buf } = await snekfetch.get('https://cdn.glitch.com/8962952b-281e-45c3-957c-6d422dea1f53%2F7Vw2yjU.jpg?1555307315720');
92 const background = await Canvas.loadImage(buf);
93 ctx.drawImage(background, 0, 0, canvas.width, canvas.height);
94
95
96 // Slightly smaller text placed above the member's display name
97 ctx.font = '29px Arial';
98 ctx.fillStyle = '#ffffff';
99 ctx.fillText('Welcome to the server,', canvas.width / 2.5, canvas.height / 3.5);
100
101 // Add an exclamation point here and below
102 ctx.font = applyText(canvas, `${member.displayName}!`);
103 ctx.fillStyle = '#ffffff';
104 ctx.fillText(`${member.displayName}!`, canvas.width / 2.5, canvas.height / 1.8);
105
106
107 ctx.beginPath();
108 ctx.arc(125, 125, 100, 0, Math.PI * 2, true);
109 ctx.closePath();
110 ctx.clip();
111
112 const { body: buffer } = await snekfetch.get(member.user.displayAvatarURL)
113 const avatar = await Canvas.loadImage(buffer);
114
115 ctx.drawImage(avatar, 25, 25, 200, 200);
116 ctx.strokeStyle = "#ffffff";
117 ctx.stroke(25, 25, 200, 200);
118
119
120 const attachment = new Discord.Attachment(canvas.toBuffer(), 'welcome-image.png');
121 const embed = new Discord.RichEmbed()
122 console.log(chan)
123 bot.channels.get(chan).send(`Welcome to the server, ${member}!`, attachment)
124});
125
126bot.on('guildMemberRemove', async (member, message) => {
127let chan = await db.fetch(`chanjl_${member.guild.id}`);
128
129
130 if (!chan) return;
131
132 const canvas = Canvas.createCanvas(700, 250);
133 const ctx = canvas.getContext('2d');
134
135
136 const { body:buf } = await snekfetch.get('https://cdn.glitch.com/8962952b-281e-45c3-957c-6d422dea1f53%2Ftest.jpg?1555268441656');
137 const background = await Canvas.loadImage(buf);
138 ctx.drawImage(background, 0, 0, canvas.width, canvas.height);
139
140
141 // Slightly smaller text placed above the member's display name
142 ctx.font = '29px Arial';
143 ctx.fillStyle = '#ffffff';
144 ctx.fillText('See you soon,', canvas.width / 2.5, canvas.height / 3.5);
145
146 // Add an exclamation point here and below
147 ctx.font = applyText(canvas, `${member.displayName}!`);
148 ctx.fillStyle = '#ffffff';
149 ctx.fillText(`${member.displayName}!`, canvas.width / 2.5, canvas.height / 1.8);
150
151 ctx.beginPath();
152 ctx.arc(125, 125, 100, 0, Math.PI * 2, true);
153 ctx.closePath();
154 ctx.clip();
155
156 const { body: buffer } = await snekfetch.get(member.user.displayAvatarURL)
157 const avatar = await Canvas.loadImage(buffer);
158
159 ctx.drawImage(avatar, 25, 25, 200, 200);
160 ctx.strokeStyle = "#ffffff";
161 ctx.stroke(25, 25, 200, 200);
162
163
164 const attachment = new Discord.Attachment(canvas.toBuffer(), 'welcome-image.png');
165 console.log(chan)
166 bot.channels.get(chan).send(`See you soon, ${member}!`, attachment)
167});
168
169bot.on('message', async message => {
170 if (message.content === '^leave') {
171 bot.emit('guildMemberRemove', message.member || await message.guild.fetchMember(message.author));
172 }
173});
174
175
176const SQLite = require("better-sqlite3");
177const sql = new SQLite('./scores.sqlite');
178
179bot.on("ready", () => {
180 // Check if the table "points" exists.
181 const table = sql.prepare("SELECT count(*) FROM sqlite_master WHERE type='table' AND name = 'scores';").get();
182 if (!table['count(*)']) {
183 // If the table isn't there, create it and setup the database correctly.
184 sql.prepare("CREATE TABLE scores (id TEXT PRIMARY KEY, user TEXT, guild TEXT, points INTEGER, level INTEGER);").run();
185 // Ensure that the "id" row is always unique and indexed.
186 sql.prepare("CREATE UNIQUE INDEX idx_scores_id ON scores (id);").run();
187 sql.pragma("synchronous = 1");
188 sql.pragma("journal_mode = wal");
189 }
190
191 // And then we have two prepared statements to get and set the score data.
192 bot.getScore = sql.prepare("SELECT * FROM scores WHERE user = ? AND guild = ?");
193 bot.setScore = sql.prepare("INSERT OR REPLACE INTO scores (id, user, guild, points, level) VALUES (@id, @user, @guild, @points, @level);");
194});
195
196bot.on("message", message => {
197 if (message.author.bot) return;
198 let score;
199 if (message.guild) {
200 score = bot.getScore.get(message.author.id, message.guild.id);
201 if (!score) {
202 score = { id: `${message.guild.id}-${message.author.id}`, user: message.author.id, guild: message.guild.id, points: 0, level: 1 }
203 }
204 score.points++;
205 const curLevel = Math.floor(0.1 * Math.sqrt(score.points));
206 if(score.level < curLevel) {
207 score.level++;
208 message.reply(`You've leveled up to level **${curLevel}**! Ain't that cute?`,);
209 }
210 bot.setScore.run(score);
211 }
212 if (message.content.indexOf(config.prefix) !== 0) return;
213
214 const args = message.content.slice(config.prefix.length).trim().split(/ +/g);
215 const command = args.shift().toLowerCase();
216
217});
218
219const { Util } = require("discord.js");
220const YouTube = require('simple-youtube-api');
221const ytdl = require('ytdl-core');
222const { promisify } = require("util");
223
224const { GOOGLE_API_KEY } = require('./config');
225
226const youtube = new YouTube(GOOGLE_API_KEY);
227
228const queue = new Map();
229
230bot.on("message", async message => {
231 if(message.author.bot)return;
232 if(message.channel.type !== "text")return;
233 if(!message.content.startsWith(prefix))return;
234 //my phones really dumb
235 let messageArray = message.content.split(" ");
236 let cmd = messageArray[0];
237 let args = messageArray.slice(1);
238 const searchString = message.content.split(" ").slice(1).join(" ");
239 const url = message.content.split(" ").slice(1).join(" ");
240 const serverQueue = queue.get(message.guild.id);
241 let command = message.content.toLowerCase().split(" ")[0];
242 command = command.slice(prefix.length);
243
244
245 if (command === `play`||command === `p`) {
246 const voiceChannel = message.member.voiceChannel;
247 if (!voiceChannel) return message.channel.send('I\'m sorry but you need to be in a voice channel to play music!');
248 const permissions = voiceChannel.permissionsFor(message.client.user);
249 if (!permissions.has('CONNECT')) {
250 return message.channel.send('I cannot connect to your voice channel, make sure I have the proper permissions!');
251 }
252 if (!permissions.has('SPEAK')) {
253 return message.channel.send('I cannot speak in this voice channel, make sure I have the proper permissions!');
254 }
255
256 if (url.match(/^https?:\/\/(www.youtube.com|youtube.com)\/playlist(.*)$/)) {
257 const playlist = await youtube.getPlaylist(url);
258 const videos = await playlist.getVideos();
259 for (const video of Object.values(videos)) {
260 const video2 = await youtube.getVideoByID(video.id);
261 await handleVideo(video2, message, voiceChannel, true);
262 }
263 message.channel.send(`Playlist: **${playlist.title}** has been added to the queue!`).then(msg=>{msg.delete(30000)});
264 message.delete(30000)
265 } else {
266 try {
267 var video = await youtube.getVideo(url);
268 } catch (error) {
269 try {
270 var videos = await youtube.searchVideos(searchString, 10);
271 let index = 0;
272 let bed = new Discord.RichEmbed()
273 .setTitle(`Song selection:`)
274 .setColor(`${message.member.displayHexColor}`)
275 .setDescription(`${videos.map(video2 => `**${++index} -** ${video2.title}`).join('\n')}`)
276 .setFooter(`Please provide a value from 1-10.`, `${message.author.avatarURL}`)
277 let m = message.channel.send({embed: bed});
278 try {
279 var response = await message.channel.awaitMessages(msg2 => msg2.content > 0 && msg2.content < 11, {
280 maxMatches: 1,
281 time: 20000,
282 errors: ['time']
283 });
284 } catch (err) {
285 console.error(err);
286 return message.channel.send('No or invalid value entered, cancelling video selection.');
287 }
288 const videoIndex = parseInt(response.first().content);
289 var video = await youtube.getVideoByID(videos[videoIndex - 1].id);
290 } catch (err) {
291 console.error(err);
292 return message.channel.send('I could not obtain any search results.');
293 }
294 }
295 return handleVideo(video, message, voiceChannel);
296 }
297 } else if (command === `skip`) {
298 if (!message.member.voiceChannel) return message.channel.send('You are not in a voice channel!');
299 if (!serverQueue) return message.channel.send('There is nothing playing that I could skip for you.');
300 serverQueue.connection.dispatcher.end('skip');
301 message.channel.send('Skip command has been used');
302 return undefined;
303} else if (command === `stop`) {
304 if (!message.member.voiceChannel) return message.channel.send('You are not in a voice channel!');
305 if (!serverQueue) return message.channel.send('There is nothing playing that I could stop for you.');
306 serverQueue.songs = [];
307 serverQueue.connection.dispatcher.end('stop');
308 message.channel.send('Stop command has been used!');
309 return undefined;
310 } else if (command === `volume`) {
311 const uwu = message.content.split(" ").slice(1).join(" ");
312 if (!message.member.voiceChannel) return message.channel.send('You are not in a voice channel!');
313 if (!serverQueue)return message.channel.send('There is nothing playing.');
314 if (!uwu){
315 message.channel.send(`The current volume is: **${serverQueue.volume}**`);
316 }
317 if (uwu){
318 if(uwu > 0 && uwu < 11){
319 if (!message.member.voiceChannel) return message.channel.send('You are not in a voice channel!');
320 if (!serverQueue)return message.channel.send('There is nothing playing.');
321 serverQueue.volume = uwu;
322 serverQueue.connection.dispatcher.setVolumeLogarithmic(uwu / 5);
323 message.channel.send(`I set the volume to: **${uwu}**`);
324 } else return message.channel.send("The volume can only be a number from 1 to 10");
325 }
326 } else if (command === `np`||command === `nowplaying`) {
327 const parseTime = function(milliseconds) {
328 var seconds = Math.floor(milliseconds/1000); milliseconds %= 1000;
329 var minutes = Math.floor(seconds/60); seconds %= 60;
330 var hours = Math.floor(minutes/60); minutes %= 60;
331 var days = Math.floor(hours/24); hours %= 24;
332 var written = false;
333 return(days?(written=true,days+"d"):"")+(written?":":"")
334 +(hours?(written=true,hours+"h"):"")+(written?":":"")
335 +(minutes?(written=true,minutes+"m"):"")+(written?":":"")
336 +(seconds?(written=true,seconds+"s"):"")+(written?"":"");
337};
338let elapsd = parseTime(`${serverQueue.connection.dispatcher.totalStreamTime}`);
339 let embed = new Discord.RichEmbed()
340 .setColor(`${message.member.displayHexColor}`)
341 .setThumbnail(`https://i.ytimg.com/vi/${serverQueue.songs[0].id}/maxresdefault.jpg`)
342 .setTimestamp()
343 .setFooter(`Elapsed time: ${elapsd}`)
344 .addField("**Now Playing:**", `[${serverQueue.songs[0].title}](https://youtube.com/watch?v=${serverQueue.songs[0].id})`)
345 message.channel.send({embed});
346 } else if (command === `queue`||command === `q`) {
347 let i = 0;
348 let embed = new Discord.RichEmbed()
349 .setColor(`${message.member.displayHexColor}`)
350 .setFooter(`Total queue size: ${serverQueue.songs.length} songs`)
351 .addField("**Now Playing:**", `[${serverQueue.songs[0].title}](https://youtube.com/watch?v=${serverQueue.songs[0].id})`)
352 .addField('**Song Queue:**', `${serverQueue.songs.map(song => `**[${++i}] -** ${song.title}`).slice(1, 6).join('\n')}`)
353 message.channel.send(embed);
354 } else if (command === `pause`) {
355 if (serverQueue && serverQueue.playing) {
356 serverQueue.playing = false;
357 serverQueue.connection.dispatcher.pause();
358 message.channel.send('I Paused the music for you');
359 } else {
360 message.channel.send('There is nothing playing.');
361 }
362 } else if (command === `resume`) {
363 if (serverQueue && !serverQueue.playing) {
364 serverQueue.playing = true;
365 serverQueue.connection.dispatcher.resume();
366 message.channel.send("i've resumed the music");
367 } else {
368 message.channel.send('There is nothing playing.');
369 }
370}
371
372async function handleVideo(video, message, voiceChannel, playlist = false) {
373 const serverQueue = queue.get(message.guild.id);
374 const song = {
375 requestedby: message.author,
376 id: video.id,
377 title: Util.escapeMarkdown(video.title),
378 url: `https://www.youtube.com/watch?v=${video.id}`,
379 duration: video.duration
380 };
381 if (!serverQueue) {
382 const queueConstruct = {
383 textChannel: message.channel,
384 voiceChannel: voiceChannel,
385 connection: null,
386 songs: [],
387 volume: 5,
388 playing: true
389 };
390 queue.set(message.guild.id, queueConstruct);
391 queueConstruct.songs.push(song);
392
393 try {
394 var connection = await voiceChannel.join();
395 queueConstruct.connection = connection;
396 play(message.guild, queueConstruct.songs[0]);
397 } catch (error) {
398 queue.delete(message.guild.id);
399 return message.channel.send(`I could not join the voice channel:\nERROR:\n${error}`).then(msg => {msg.delete(15000)});
400 }
401 } else {
402 serverQueue.songs.push(song);
403 if (playlist)return;
404 else return message.channel.send(`**${song.title}** has been added to the queue!`);
405 }
406 return undefined;
407}
408
409function play(guild, song) {
410 const serverQueue = queue.get(guild.id);
411
412 if (!song) {
413 serverQueue.voiceChannel.leave();
414 queue.delete(guild.id);
415 return;
416 }
417
418 const dispatcher = serverQueue.connection.playStream(ytdl(song.url, { audioonly: true }))
419 .on('end', reason => {
420 if(reason == 'skip'||reason == 'stop'){
421 serverQueue.songs.shift();
422 play(guild, serverQueue.songs[0]);
423 } else {
424 message.channel.send('Song ended');
425 serverQueue.songs.shift();
426 play(guild, serverQueue.songs[0]);
427 }
428 })
429 .on('error', error => console.error(error));
430 dispatcher.setVolumeLogarithmic(serverQueue.volume / 5);
431
432 serverQueue.textChannel.send(`Started playing: **${song.title}**`);
433 }
434});
435
436bot.login(discord_token);