diff --git a/package.json b/package.json index 768f538..ce3483e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "aicbot", - "version": "4.0.0-dev-2", + "version": "4.0.0-dev-3", "description": "Discord Bot for playing music", "main": "build/main.js", "scripts": { diff --git a/src/CommandTypes.ts b/src/CommandTypes.ts index 309f065..1e19c5c 100644 --- a/src/CommandTypes.ts +++ b/src/CommandTypes.ts @@ -1,5 +1,5 @@ import { - AutocompleteInteraction, + AutocompleteInteraction, ButtonInteraction, ChatInputCommandInteraction, CommandInteraction, Message, @@ -64,7 +64,8 @@ interface ISlashCommandData { interface IGuildData { guild_only?: boolean | false; voice_required?: boolean; - voice_with_bot_only?: boolean; // Property enabled only if voice_required is true + // This field have sense if field "voice_required" is true + voice_with_bot_only?: boolean; } export type InteractionReplyContext = ChatInputCommandInteraction | CommandInteraction; diff --git a/src/audioplayer/AudioPlayersManager.ts b/src/audioplayer/AudioPlayersManager.ts index 907c4eb..994e73b 100644 --- a/src/audioplayer/AudioPlayersManager.ts +++ b/src/audioplayer/AudioPlayersManager.ts @@ -8,6 +8,7 @@ import { generateAddedSongMessage } from './util/generateAddedSongMessage.js'; import { ButtonInteraction, Client, + EmbedBuilder, Guild, GuildMember, GuildTextBasedChannel, @@ -22,6 +23,8 @@ import { addSongToGuildSongsHistory } from '../schemas/SchemaSongsHistory.js'; import { PaginationList } from './PaginationList.js'; import { nodeResponse, Player, Queue, Riffy, Track } from 'riffy'; import { LavaNodes } from '../LavalinkNodes.js'; +import { clamp } from '../utilities/clamp.js'; +import { formatMilliseconds } from '../utilities/formatMillisecondsToTime.js'; export const loggerPrefixAudioplayer = `Audioplayer`; @@ -240,57 +243,50 @@ export class AudioPlayersManager { async jump(guild: Guild, position: number): Promise { const riffyPlayer = this.riffy.players.get(guild.id); if (!riffyPlayer) return; - loggerError('Riffy JUMP is not implemented.'); - /* + try { - const queue = riffyPlayer.queue + const queue = riffyPlayer.queue; if (queue) { - return queue. jump(guild, clamp(position, 1, queue.songs.length)); + //return riffyPlayer.seek() jump(guild, clamp(position, 1, queue.songs.length)); } } catch (e) { if (ENV.BOT_VERBOSE_LOGGING) loggerError(e); } - return undefined; - */ return undefined; } - // TODO: Implement Previous in audioplayer async previous(guild: Guild): Promise { - /* try { const riffyPlayer = this.riffy.players.get(guild.id); if (!riffyPlayer) return; - return await riffyPlayer. .previous(guild); + const previousSong = riffyPlayer.previous; + if (!previousSong) return undefined; + riffyPlayer.queue.unshift(previousSong); + riffyPlayer.stop(); + return previousSong; } catch (e) { if (ENV.BOT_VERBOSE_LOGGING) loggerError(e); } - */ + return undefined; } - // TODO: Implement Rewind in audioplayer - async rewind(guild: Guild, time: number): Promise { - return false; - /* + async seek(guild: Guild, ms: number): Promise { try { - const queue = this.distube.getQueue(guild); - if (!queue) return false; - const player = this.playersManager.get(queue.id); + const riffyPlayer = this.riffy.players.get(guild.id); + if (!riffyPlayer) return false; + const player = this.playersManager.get(guild.id); if (!player) return false; - if (time < 0) time = 0; - this.distube.seek(guild, time); + if (ms < 0) ms = 0; + riffyPlayer.seek(ms); await player.setState('playing'); return true; } catch { return false; } - - */ } - // TODO: Implement showLyrics in audioplayer async showLyrics(interaction: ButtonInteraction) { await interaction.reply({ content: 'undefined' }); /* @@ -307,49 +303,43 @@ export class AudioPlayersManager { */ } - // TODO: Implement showQueue in audioplayer - async showQueue(interaction: ButtonInteraction) { - await interaction.reply({ content: 'undefined' }); - /* + async showQueue(interaction: ButtonInteraction): Promise { if (!interaction.guild) return; - const queue = this.distube.getQueue(interaction.guild); - if (!queue) { - return; - } + const riffyPlayer = this.riffy.players.get(interaction.guildId!); + if (!riffyPlayer) return; function buildPage(queue: Queue, pageNumber: number, entriesPerPage: number) { let queueList = ''; const startingIndex = pageNumber * entriesPerPage; - for (let i = startingIndex; i < Math.min(startingIndex + entriesPerPage, queue.songs.length); i++) { - const song = queue.songs[i]; - queueList += `${i + 1}. ` + `[${song.name}](${song.url})` + ` - \`${song.formattedDuration}\`\n`; + for (let i = startingIndex; i < Math.min(startingIndex + entriesPerPage, queue.length); i++) { + const song = queue[i]; + queueList += + `${i + 1}. ` + `[${song.info.title}](${song.info.uri})` + ` - \`${formatMilliseconds(song.info.length)}\`\n`; } const page = new EmbedBuilder() .setAuthor({ name: `${i18next.t('audioplayer:show_queue_songs_in_queue')}: ` }) - .setTitle(queue.songs[0].name!) + .setTitle(riffyPlayer?.current.info.title ?? null) .setDescription(`**${i18next.t('audioplayer:show_queue_title')}: **\n${queueList}`.slice(0, 4096)); - if (queue.songs[0].url) { - page.setURL(queue.songs[0].url); - } + page.setURL(riffyPlayer?.current.info.uri ?? null); return page; } const arrayEmbeds: Array = []; const entriesPerPage = 20; - const pages = Math.ceil(queue.songs.length / entriesPerPage); + const pages = Math.ceil(riffyPlayer.queue.length / entriesPerPage); for (let i = 0; i < pages; i++) { - arrayEmbeds.push(buildPage(queue, i, entriesPerPage)); + arrayEmbeds.push(buildPage(riffyPlayer.queue, i, entriesPerPage)); } - await PaginationList(interaction as CommandInteraction, arrayEmbeds, interaction.user); - - */ + // @ts-expect-error ButtonInteraction have method reply(), + // but it have differences with reply() in MessageInteraction so we get error + await PaginationList(interaction, arrayEmbeds, interaction.user); } async setLeaveOnEmpty(guild: Guild, mode: boolean) { diff --git a/src/commands/audio/previous.command.ts b/src/commands/audio/previous.command.ts index 5705372..63b73ab 100644 --- a/src/commands/audio/previous.command.ts +++ b/src/commands/audio/previous.command.ts @@ -1,4 +1,3 @@ -// @ts-nocheck import { ICommand } from '../../CommandTypes.js'; import { EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder } from 'discord.js'; import { GroupAudio } from './AudioTypes.js'; @@ -8,6 +7,7 @@ import { } from '../../audioplayer/util/AudioCommandWrappers.js'; import i18next from 'i18next'; import { generateSimpleEmbed } from '../../utilities/generateSimpleEmbed.js'; +import { Track } from 'riffy'; export default function (): ICommand { return { @@ -55,9 +55,9 @@ export default function (): ICommand { }; } -export function generateEmbedAudioPlayerPrevious(member: GuildMember, song: Song): EmbedBuilder { +export function generateEmbedAudioPlayerPrevious(member: GuildMember, song: Track): EmbedBuilder { return generateSimpleEmbed( - `:rewind: ${member} ${i18next.t('commands:previous_success')} ${song.name} - ${song.uploader.name} :rewind:` + `:rewind: ${member} ${i18next.t('commands:previous_success')} ${song.info.title} - ${song.info.author} :rewind:` ); } diff --git a/src/commands/audio/rewind.command.ts b/src/commands/audio/seek.command.ts similarity index 93% rename from src/commands/audio/rewind.command.ts rename to src/commands/audio/seek.command.ts index 0677b07..732d15a 100644 --- a/src/commands/audio/rewind.command.ts +++ b/src/commands/audio/seek.command.ts @@ -12,7 +12,7 @@ import { formatMilliseconds } from '../../utilities/formatMillisecondsToTime.js' export default function (): ICommand { return { text_data: { - name: 'rewind', + name: 'seek', description: i18next.t('commands:rewind_desc'), arguments: [new CommandArgument(i18next.t('commands:rewind_arg_time'), true)], execute: async (message, args) => { @@ -20,7 +20,7 @@ export default function (): ICommand { await AudioCommandWrapperText(message, async () => { if (time) { - if (await message.client.audioPlayer.rewind(message.guild!, time)) { + if (await message.client.audioPlayer.seek(message.guild!, time * 1000)) { await message.reply({ embeds: [generateEmbedAudioPlayerRewind(message.member!, time)] }); @@ -33,7 +33,7 @@ export default function (): ICommand { }, slash_data: { slash_builder: new SlashCommandBuilder() - .setName('rewind') + .setName('seek') .setDescription(i18next.t('commands:rewind_desc')) .addStringOption((option) => option @@ -49,7 +49,7 @@ export default function (): ICommand { await AudioCommandWrapperInteraction(interaction, async () => { if (time) { - if (await interaction.client.audioPlayer.rewind(interaction.guild!, time)) { + if (await interaction.client.audioPlayer.seek(interaction.guild!, time * 1000)) { await interaction.reply({ embeds: [generateEmbedAudioPlayerRewind(interaction.member as GuildMember, time)] }); diff --git a/wiki/Commands.md b/wiki/Commands.md index 108ac3d..0fc0c6d 100644 --- a/wiki/Commands.md +++ b/wiki/Commands.md @@ -91,7 +91,7 @@ Example: /jump 4 Returns to previous played/skipped song in queue -### rewind +### seek Allow you to change the current playback time. Accept time in HH:MM:SS or MM:SS or SS format.