diff --git a/package.json b/package.json index 6bc4fc0..f644ddb 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,9 @@ { "scripts": { "watch": "nodemon --quiet --watch src/** --exec sucrase-node src/index.ts", - "start": "sucrase-node src/index.ts", - "lavalink": "java -jar ./lavalink.jar", - "deploy": "sucrase-node src/Helpers/DeployCommands.ts" + "start": "sucrase-node src/index.ts" }, - "version": "2.3.1", + "version": "2.3.2", "dependencies": { "axios": "^1.6.0", "discord.js": "^14.13.0", diff --git a/src/Classes/Bot.ts b/src/Classes/Bot.ts index daa524f..130bd8b 100644 --- a/src/Classes/Bot.ts +++ b/src/Classes/Bot.ts @@ -162,23 +162,20 @@ class Bot extends Client<true> { } this.createIcons() + if (process.env.REGISTER_COMMANDS_ON_START) await this.registerCommands(token) } public async registerCommands(token: string) { logger.info('Registering (/) commands...') - await this.login(token) - const commandModFiles = this.loadModFiles<Command>(COMMANDS_PATH, true) const jsonData: RESTPostAPIChatInputApplicationCommandsJSONBody[] = commandModFiles.map(m => m.data.setDMPermission(false).toJSON()) await new REST() .setToken(token) .put(Routes.applicationCommands(this.user.id), { body: jsonData }) - .then(_ => logger.info('Success!')) + .then(_ => logger.info('(/) commands registered successfully!')) .catch(error => logger.error(`Failed to register (/) commands: ${error.stack}`)) - - process.exit() } } diff --git a/src/Events/Bot/InteractionCreate.ts b/src/Events/Bot/InteractionCreate.ts index cd328f0..bf17c74 100644 --- a/src/Events/Bot/InteractionCreate.ts +++ b/src/Events/Bot/InteractionCreate.ts @@ -25,11 +25,8 @@ const InteractionCreate: Event = { defaults: { guildId: interaction.guildId, lastActive: new Date() } }) - console.log(`last active: ${record.getDataValue('lastActive')}`) - record.update({ lastActive: new Date() }, { where: { guildId: interaction.guild.id }}) - const handler = InteractionMap[interaction.type] if (!handler) { diff --git a/src/Events/Bot/VoiceStateUpdate.ts b/src/Events/Bot/VoiceStateUpdate.ts index 42c73fa..e94926d 100644 --- a/src/Events/Bot/VoiceStateUpdate.ts +++ b/src/Events/Bot/VoiceStateUpdate.ts @@ -7,6 +7,7 @@ const UpdateVoiceState: Event = { name: Events.VoiceStateUpdate, once: false, execute: (oldState: VoiceState, newState: VoiceState) => { + console.time() const guildId = oldState?.guild?.id ?? newState?.guild?.id const player = client.poru.players.get(guildId) as ExtPlayer | undefined @@ -22,14 +23,16 @@ const UpdateVoiceState: Event = { // Bot disconnect if (!newChannel) return player.destroy() - + const membersWithoutBots = newChannel.members.filter(m => !m.user.bot) // Everyone left voice if (membersWithoutBots.size === 0) { + player.pause(true) + player.messageManger.updatePlayerMessage() player.controller.setupPlayerTimeout(60000) // 1 minute for someone to join } else { - player.controller.cancelPlayerTimeout() + player.controller.cancelPlayerTimeout() } } } diff --git a/src/index.ts b/src/index.ts index f0317cb..307cfca 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,6 +4,8 @@ import { Bot } from './Classes/Bot' import cron from 'node-cron' import { serverStats, ServerStatsI } from './Models' import sequelize from './Models/Connection' +import { Track } from 'poru' +import { clipString } from './Funcs/ClipString' require('dotenv').config() export const client = new Bot({ @@ -43,6 +45,8 @@ client.initialize(process.env.BOT_TOKEN) // 100 guilds limit set for unverified bots. // You can disable this through the .env file cron.schedule('0 0 * * *', async () => { + if (!process.env.LEAVE_INACTIVE_GUILDS) return + const guilds = await client.guilds.fetch() for (const [_, guild] of guilds) { @@ -72,18 +76,32 @@ cron.schedule('0 0 * * *', async () => { // Update the bot's status every minute. This will only // fire when the new presence to be set is different to the // current presence to not send unneeded requests. -cron.schedule('* * * * *', () => { - const activePlayers = client.poru.players.size +cron.schedule('*/1 * * * *', () => { + const activePlayers = client.poru.players const currentActivity = client.user?.presence?.activities[0] let activityName = 'with YouTube\'s API' - if (client.poru.players.size) { - activityName = `music in ${activePlayers} server${activePlayers > 1 ? 's' : ''}` + console.log('updating') + + const currentlyPlayedSongs: string[] = [] + + activePlayers.forEach(player => { + if (player.currentTrack && player.isPlaying) { + currentlyPlayedSongs.push(`${player.currentTrack.info.title} - ${player.currentTrack.info.author}`) + } + }) + + console.log(currentlyPlayedSongs) + + if (currentlyPlayedSongs.length) { + const randomSong = currentlyPlayedSongs[Math.floor(Math.random() * currentlyPlayedSongs.length)] + + activityName = clipString({ string: randomSong, maxLength: 100, sliceEnd: '...' }) } if (currentActivity?.name === activityName) return client.user.setPresence({ - activities: [{ name: activityName, type: ActivityType.Playing }] + activities: [{ name: activityName, type: ActivityType.Listening }] }) }) diff --git a/src/types/Command.ts b/src/types/Command.ts index d6bc31f..e2fbe85 100644 --- a/src/types/Command.ts +++ b/src/types/Command.ts @@ -3,7 +3,6 @@ import { ExtPlayer } from '../Helpers/ExtendedPlayer' import { Bot } from '../Classes/Bot' export interface Command<T = true> { - // Command data data: Omit<SlashCommandBuilder, 'addSubcommandGroup' | 'addSubcommand'> | SlashCommandSubcommandsOnlyBuilder disabled?: boolean @@ -26,11 +25,8 @@ export interface Command<T = true> { } musicOptions?: { - /** Must be in a voice channel to be used */ requiresVc?: boolean - /** Must be playing music to use */ requiresPlaying?: boolean - /** Must have the DJ role to use */ requiresDjRole?: boolean } diff --git a/src/types/process-env.d.ts b/src/types/process-env.d.ts index 2094957..df8c7f6 100644 --- a/src/types/process-env.d.ts +++ b/src/types/process-env.d.ts @@ -6,6 +6,8 @@ declare global { TENOR_API_KEY: string CUSTOM_EMOJIS_GUILD_ID: string + REGISTER_COMMANDS_ON_START: boolean + LEAVE_INACTIVE_GUILDS: boolean DATABASE_DIALECT: 'sqlite' | 'postgres' DATABASE_HOST: string