Skip to content

Commit

Permalink
feat: Update play command with autocomplete support and response hand…
Browse files Browse the repository at this point in the history
…ling
  • Loading branch information
Fyphen1223 committed May 13, 2024
1 parent d4762d5 commit e1d56ac
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"printWidth": 80,
"printWidth": 90,
"tabWidth": 4,
"useTabs": true,
"semi": true,
Expand Down
152 changes: 144 additions & 8 deletions commands/music/play.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const config = require('../../config.json');

const { getLocale } = require('../../lang/lang.js');
const { createMessageEmbed } = require('../../util/embed.js');

const guilds = require('../../data/guilds.json');

Expand All @@ -12,6 +13,7 @@ const {
ActionRowBuilder,
EmbedBuilder,
} = require('discord.js');
const listenEvents = require('../../util/playerEvent.js');

module.exports = {
data: new SlashCommandBuilder()
Expand All @@ -29,17 +31,151 @@ module.exports = {
},
async execute(interaction) {
await interaction.deferReply();

const guildId = interaction.guild.id;

//Add guild queue to the global queue and node
if (!global.queue[interaction.guild.id]) {
global.queue.add(interaction.guild.id);
global.queue[guildId].node = global.Tsumi.getIdealNode();
}

// Check if the user is in a voice channel
if (!interaction.member.voice.channelId) {
const noValidVCEmbed = new discord.EmbedBuilder()
.setColor(config.config?.color?.info || '#000000')
.setAuthor({
name: ` | 🚫 - ${
getLocale(guilds[interaction.guild.id].locale).vc.noVC
}`,
iconURL: interaction.user.avatarURL({}),
});
const noValidVCEmbed = createMessageEmbed(
getLocale(guilds[guildId].locale).vc.noVC,
interaction
);
await interaction.editReply({ embeds: [noValidVCEmbed] });
return;
}

if (global.queue[guildId].voiceChannel) {
if (
global.queue[guildId].voiceChannel.id !==
interaction.member.voice.channelId
) {
const differentVCEmbed = createMessageEmbed(
getLocale(guilds[guildId].locale).vc.differentVC,
interaction
);
await interaction.editReply({ embeds: [differentVCEmbed] });
return;
}
}

const query = interaction.options.getString('query');

//Join channel first
if (!global.queue[guildId].voiceChannel) {
global.queue[guildId].textChannel = interaction.channel;
global.queue[guildId].voiceChannel = interaction.member.voice.channel;
global.queue[guildId].player = await global.queue[
guildId
].node.joinVoiceChannel(
{
guildId: guildId,
channelId: interaction.member.voice.channelId,
},
{
selfDeaf: true,
selfMute: false,
}
);
listenEvents(guildId);
}

//そもそもVCに未参加
if (!query && global.queue[guildId].isEmpty()) {
const noQueryEmbed = createMessageEmbed(
getLocale(guilds[guildId].locale).vc.joined,
interaction
);
await interaction.editReply({ embeds: [noQueryEmbed] });
return;
}

/*
1. そもそもVCに未参加
2. キューがないかつクエリがない
3. キューがあるかつクエリがない
4. キューがあるかつクエリがある
5. キューがないかつクエリがある
*/

// クエリが無いがキューは空ではない
if (!query && !global.queue.isEmpty()) {
// Start playing the queue
return;
}

const result = await global.queue[guildId].node.loadTracks(query);

let res = null;
switch (result.loadType) {
case 'track': {
res = result.data;
break;
}
case 'empty': {
const searchResult = await global.queue[guildId].node.loadTracks(
`ytsearch:${query}`
);
if (!searchResult?.data.length) {
await interaction.editReply('Sorry, I could not find any data.');
return;
}
res = searchResult.data.shift();
break;
}
case 'playlist': {
result.data.tracks.forEach((track) => {
global.queue[guildId].add(track, interaction.user);
});
const resultEmbed = new discord.EmbedBuilder()
.setColor(config.config.color.info)
.setAuthor({
name: ` | 🔍 Added ${result.data.info.name} to the queue.`,
iconURL: interaction.user.avatarURL({}),
});

await interaction.editReply({ embeds: [resultEmbed] });
if (global.queue[guildId].player.status === 'playing') return;
// start playing the queue
return;
}
case 'search': {
if (!result?.data.length) {
await interaction.editReply('Sorry, I could not find any data.');
return;
}
res = result.data.shift();
break;
}
case 'error': {
await interaction.editReply('Sorry, I could not find any data.');
return;
}
}
global.queue[guildId].queue.push({
data: res,
user: interaction.user,
});

const resultEmbed = new discord.EmbedBuilder()
.setColor(config.config?.color?.info || '#000000')
.setAuthor({
name: ` | 🔍 Added ${res.info.title} to the queue.`,
iconURL: interaction.user.avatarURL({}),
});

await interaction.editReply({ embeds: [resultEmbed] });

await global.queue[guildId].player.play({
track: {
encoded:
global.queue[guildId].queue[global.queue[guildId].index].data.encoded,
},
});
},
};
3 changes: 3 additions & 0 deletions events/ready.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@ module.exports = {
true,
config.config.log.saveToFile
);
config.nodes.forEach((node) => {
global.Tsumi.addNode(node);
});
},
};
8 changes: 8 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,12 @@ for (const file of eventFiles) {
}
}

global.Tsumi.on('ready', () => {
log.info('Tsumi is ready', true, config.config.log.saveToFile);
});

client.on('raw', (data) => {
global.Tsumi.handleRaw(data);
});

client.login(config.bot.token);
5 changes: 4 additions & 1 deletion lang/en.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"vc": {
"noVC": "No valid VC detected. Please join a VC and try again."
"noVC": "🚫 - No valid VC detected. Please join a VC and try again.",
"joined": "👋 - Joined your VC.",
"differentVC": "🚫 - You need to be in the same VC as me to use this command.",
"noQuery": "🚫 - Please provide a query to search for."
},
"ping": "Pong! Current Ping is"
}
14 changes: 14 additions & 0 deletions util/playerEvent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const config = require('../config.json');

const { createMusicEmbed } = require('./embed.js');

const { ButtonBuilder, ButtonStyle, ActionRowBuilder } = require('discord.js');

const listenEvents = async (guildId) => {
global.queue[guildId].player.on('start', async (data) => {
const current = global.queue[guildId].queue[global.queue[guildId].index];
global.queue[guildId].textChannel.send(`Now playing: ${current.data.info.title}`);
});
};

module.exports = listenEvents;
20 changes: 12 additions & 8 deletions util/queue.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,26 @@ class queue extends EventEmitter {
this.queue = [];
}

add = function (data) {
this.queue.push(data);
add = (data, user) => {
this.queue.push({
data: data,
user: user,
});
};

remove = function (index) {
remove = (index) => {
this.queue.splice(index, 1);
};

get = function () {
get = () => {
return this.queue;
};

isEmpty = function () {
isEmpty = () => {
return this.queue.length === 0;
};

getTitles = function () {
getTitles = () => {
let result = [];

for (let i = 0; i < this.queue.length; i++) {
Expand All @@ -43,18 +46,19 @@ class queue extends EventEmitter {
autoReplay = false;
autoPlay = false;
previous = null;
index = 0;
}

class playerQueue extends EventEmitter {
constructor() {
super();
}

add = function (guildId) {
add = (guildId) => {
this[guildId] = new queue({ guildId });
};

remove = function (guildId) {
remove = (guildId) => {
delete this[guildId];
};
}
Expand Down

0 comments on commit e1d56ac

Please sign in to comment.