all repos — simple-discord-music-bot @ 3df93a72ede8d6132fe3d3ccb0ff5f2fdaf949c8

A Discord bot making use of discord.js and play-yt.

add magazines, minor code refactor
Marco Andronaco andronacomarco@gmail.com
Sun, 21 Jan 2024 12:37:01 +0100
commit

3df93a72ede8d6132fe3d3ccb0ff5f2fdaf949c8

parent

7bceff48000d0f7b54cf9d779ec1ea4c931289c5

M config.json.exampleconfig.json.example

@@ -7,5 +7,6 @@ { "name": "TheFatRat - Xenogenesis", "value": "https://www.youtube.com/watch?v=6N8zvi1VNSc" },

{ "name": "OMFG - Hello", "value": "https://www.youtube.com/watch?v=5nYVNTX0Ib8" }, { "name": "Pegboard Nerds - Disconnected", "value": "https://www.youtube.com/watch?v=YdBtx8qG68w" }, { "name": "Gym Class Heroes - Stereo Hearts", "value": "https://www.youtube.com/watch?v=ThctmvQ3NGk" } - ] + ], + "magazineSize": 6 }
M src/commands/clear.tssrc/commands/clear.ts

@@ -1,5 +1,6 @@

import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js'; -import { getChannel, getQueue } from '../functions/music'; +import { getQueue } from '../functions/music'; +import { getChannel } from '../functions/voice'; module.exports = { data: new SlashCommandBuilder()
M src/commands/outro.tssrc/commands/outro.ts

@@ -1,5 +1,6 @@

import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js'; -import { getChannel, getQueue } from '../functions/music'; +import { getQueue } from '../functions/music'; +import { getChannel } from '../functions/voice'; import path from 'node:path'; const { outros } = require(path.join(process.cwd(), 'config.json'));
M src/commands/play.tssrc/commands/play.ts

@@ -1,6 +1,7 @@

import { ChatInputCommandInteraction, SlashCommandBuilder } from 'discord.js'; import play, { YouTubeVideo } from 'play-dl'; -import { getChannel, formatTitle, getQueue } from '../functions/music'; +import { getQueue, formatTitle } from '../functions/music'; +import { getChannel } from '../functions/voice'; async function handleUserInput(input: string): Promise<YouTubeVideo[]> { try {
M src/commands/queue.tssrc/commands/queue.ts

@@ -1,5 +1,6 @@

import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js'; -import { formatTitle, getChannel, getQueue } from '../functions/music'; +import { getQueue, formatTitle } from '../functions/music'; +import { getChannel } from '../functions/voice'; import { YouTubeVideo } from 'play-dl'; const CHARACTER_LIMIT_API = 2000;
M src/commands/shoot.tssrc/commands/shoot.ts

@@ -1,5 +1,6 @@

import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js'; -import { getChannel } from '../functions/music'; +import { getChannel } from '../functions/voice'; +import { getMagazine } from '../functions/magazines'; module.exports = { data: new SlashCommandBuilder()

@@ -14,13 +15,18 @@

const voiceChannelUsers = interaction.guild.voiceStates.cache.filter( (voiceState) => voiceState.channelId === channel.id ); + + const magazine = getMagazine(interaction.user.id); + if (!magazine.shoot()) + return await interaction.reply({ content: `💨 Too bad... You're out of bullets.` }); + const members = voiceChannelUsers.map((voiceState) => voiceState.member); - const l = members.length + const l = members.length; const randomIndex = Math.floor(Math.random() * l); const toBeKicked = members[randomIndex].user.bot ? members[(randomIndex + 1) % l] : members[randomIndex]; toBeKicked.voice.disconnect(); const victimName = toBeKicked.nickname ?? toBeKicked.user.globalName; - return await interaction.reply({ content: `💥 Bang! **${victimName}** was shot.` }); + return await interaction.reply({ content: `💥 Bang! **${victimName}** was shot. **${magazine.left}/${magazine.size} bullets** left in your magazine.` }); }, };
M src/commands/skip.tssrc/commands/skip.ts

@@ -1,5 +1,6 @@

import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js'; -import { getChannel, getQueue } from '../functions/music'; +import { getQueue } from '../functions/music'; +import { getChannel } from '../functions/voice'; module.exports = { data: new SlashCommandBuilder()
M src/commands/stop.tssrc/commands/stop.ts

@@ -1,5 +1,6 @@

import { SlashCommandBuilder, ChatInputCommandInteraction } from 'discord.js'; -import { getChannel, getQueue } from '../functions/music'; +import { getQueue } from '../functions/music'; +import { getChannel } from '../functions/voice'; module.exports = { data: new SlashCommandBuilder()
A src/functions/magazines.ts

@@ -0,0 +1,59 @@

+import path from 'node:path'; +const { magazineSize } = require(path.join(process.cwd(), 'config.json')); + +const magazines = new Map<string, Magazine>(); + +function sameDay(date1: Date, date2: Date): boolean { + return ( + date1.getFullYear() === date2.getFullYear() && + date1.getMonth() === date2.getMonth() && + date1.getDate() === date2.getDate() + ); + } + +export class Magazine { + #size: number; + #left: number; + #last: Date; + + constructor(size: number) { + this.#size = size; + this.#left = size; + this.#last = new Date(); + } + + update() { + const now = new Date(); + if (!sameDay(now, this.#last)) + this.#left = this.#size; + } + + get left() { + this.update(); + return this.#left; + } + + get size() { + return this.#size + } + + shoot() { + this.update(); + if (this.#left <= 0) { + return false; + } + + this.#last = new Date(); + this.#left--; + return true; + } +} + +export function getMagazine(user: string): Magazine { + if (magazines.has(user)) + return magazines.get(user); + + const q = new Magazine(magazineSize ?? 6); + magazines.set(user, q); + return q; +}
M src/functions/music.tssrc/functions/music.ts

@@ -1,4 +1,3 @@

-import { ChatInputCommandInteraction, VoiceBasedChannel } from 'discord.js' import { YouTubeVideo } from 'play-dl'; import MyQueue from './myqueue';

@@ -16,15 +15,3 @@

export function formatTitle(video: YouTubeVideo): string { return `**${video.title}** (\`${video.durationRaw}\`)`; } - -export async function getChannel(interaction: ChatInputCommandInteraction): Promise<string | VoiceBasedChannel>{ - const member = interaction.member; - if (!member) - return 'Please use this in your current server.'; - - const vc_error = 'You\'re not in a voice channel.'; - - if (!("voice" in member)) return vc_error; - const channel: VoiceBasedChannel = member.voice.channel; - return channel ? channel : vc_error; -}
A src/functions/voice.ts

@@ -0,0 +1,13 @@

+import { ChatInputCommandInteraction, VoiceBasedChannel } from 'discord.js' + +export async function getChannel(interaction: ChatInputCommandInteraction): Promise<string | VoiceBasedChannel>{ + const member = interaction.member; + if (!member) + return 'Please use this in your current server.'; + + const vc_error = 'You\'re not in a voice channel.'; + + if (!("voice" in member)) return vc_error; + const channel: VoiceBasedChannel = member.voice.channel; + return channel ? channel : vc_error; +}