"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; exports.__esModule = true; exports.playCommand = void 0; var discord_js_1 = require("discord.js"); // @ts-ignore // --esModuleInterop var ytdl = require("ytdl-core"); var node_path_1 = require("node:path"); var fs_1 = require("fs"); var voice_1 = require("@discordjs/voice"); var util_1 = require("../util"); var playCommand = { data: { name: 'play', description: 'Play music in voice chat', options: [ { name: 'link', description: 'Enter YouTube link (spotify support coming soon)', type: discord_js_1.ApplicationCommandOptionType.String, required: true } ] }, execute: function (interaction) { var _a, _b, _c; return __awaiter(this, void 0, void 0, function () { var link, videoId, botMember, currentConnection, memberChannel, perms, missingPerms_1, createConnection, videoInfo, audioResource, audioPlayer; var _this = this; return __generator(this, function (_d) { switch (_d.label) { case 0: link = interaction.options.getString('link', true); videoId = (_a = link.match(/^(?:https?:\/\/)?(?:(?:www\.|m\.)?youtu\.?be(?:-nocookie)?(?:\.com)?)\/(?:(?:watch\?v=|embed\/|v\/)?([\w\d-]+))$/)) === null || _a === void 0 ? void 0 : _a[1]; if (!!videoId) return [3 /*break*/, 2]; return [4 /*yield*/, interaction.reply({ embeds: [ new discord_js_1.EmbedBuilder() .setColor(0xff0000) .setTitle('`/play` - Invalid URL link') .setDescription("Invalid YouTube link.\nYouTube link must match the following regex:\n".concat((0, discord_js_1.inlineCode)('/^(?:https?:\/\/)?(?:(?:www\.|m\.)?youtu\.?be(?:-nocookie)?(?:\.com)?)\/(?:(?:watch\?v=|embed\/|v\/)?([\w\d-]+))$/'), "\nYour value did not match the regex above.")) .addFields({ name: 'Examples of valid URL links', value: [ 'www.youtube.com/watch?v=DFYRQ_zQ-gk', 'youtube.com/watch?v=DFYRQ_zQ-gk', 'm.youtube.com/watch?v=DFYRQ_zQ-gk', 'www.youtube.com/v/DFYRQ_zQ-gk?fs=1&hl=en_US', 'youtube.com/v/DFYRQ_zQ-gk?fs=1&hl=en_US', 'www.youtube.com/embed/DFYRQ_zQ-gk', 'youtube.com/embed/DFYRQ_zQ-gk', 'www.youtube-nocookie.com/embed/DFYRQ_zQ-gk', 'youtube-nocookie.com/embed/DFYRQ_zQ-gk', 'youtu.be/DFYRQ_zQ-gk', ].map(function (s) { return (0, discord_js_1.inlineCode)(s); }).join('\n') + '\n\n*`http://` and `https://` links are also valid.*' }) ] })]; case 1: return [2 /*return*/, _d.sent()]; case 2: botMember = interaction.guild.members.me; currentConnection = (0, voice_1.getVoiceConnection)(interaction.guild.id); if (!currentConnection) return [3 /*break*/, 4]; return [4 /*yield*/, interaction.reply({ embeds: [ new discord_js_1.EmbedBuilder() .setColor(0xff0000) .setTitle('`/play` - Existing connection') .setDescription("This bot is already playing audio in ".concat(((_b = botMember.voice.channel) === null || _b === void 0 ? void 0 : _b.toString()) || '**a channel that cannot be determined**.')) ] })]; case 3: return [2 /*return*/, _d.sent()]; case 4: memberChannel = (_c = interaction.member.voice) === null || _c === void 0 ? void 0 : _c.channel; if (!!memberChannel) return [3 /*break*/, 6]; return [4 /*yield*/, interaction.reply({ embeds: [ new discord_js_1.EmbedBuilder() .setColor(0xff0000) .setTitle('`/play` - No Voice Channel') .setDescription('You must be in a voice channel for this command to work!') ] })]; case 5: return [2 /*return*/, _d.sent()]; case 6: perms = new discord_js_1.PermissionsBitField(['Connect', 'Speak']).toArray(); if (!!perms.every(function (perm) { return botMember.permissions.has(perm); })) return [3 /*break*/, 8]; missingPerms_1 = perms.filter(function (p) { return !botMember.permissions.has(p); }); return [4 /*yield*/, interaction.reply({ embeds: [ new discord_js_1.EmbedBuilder() .setAuthor({ name: "".concat(interaction.user.tag, " (").concat(interaction.user.id, ")"), iconURL: interaction.user.displayAvatarURL({ forceStatic: false }) }) .setTitle("".concat((0, discord_js_1.inlineCode)('/ban remove'), " - Missing Permissions")) .setDescription("Bot is missing permissions.\nThis command requires the bot to have the ".concat((0, discord_js_1.bold)("".concat((0, util_1.commaList)(perms .map(function (s) { return (0, discord_js_1.inlineCode)(s.match(/[A-Z][a-z]+/g).join(' ')); })), " ").concat((0, util_1.pluralise)(perms.length, 'permissions'))), ".\nThe bot has the ").concat((0, discord_js_1.bold)("".concat((0, util_1.commaList)(perms .filter(function (p) { return !missingPerms_1.includes(p); }) .map(function (s) { return (0, discord_js_1.inlineCode)(s.match(/[A-Z][a-z]+/g).join(' ')); })), " ").concat((0, util_1.pluralise)(perms.filter(function (p) { return !missingPerms_1.includes(p); }).length, 'permissions'))), ", however is __missing__ the ").concat((0, discord_js_1.bold)("".concat((0, util_1.commaList)(missingPerms_1 .map(function (s) { return (0, discord_js_1.inlineCode)(s.match(/[A-Z][a-z]+/g).join(' ')); })), " ").concat((0, util_1.pluralise)(missingPerms_1.length, 'permissions'))), ".")) .setColor(0xff0000) ], ephemeral: true })]; case 7: return [2 /*return*/, _d.sent()]; case 8: createConnection = (0, voice_1.joinVoiceChannel)({ guildId: interaction.guild.id, channelId: interaction.member.voice.channel.id, adapterCreator: interaction.guild.voiceAdapterCreator }); botMember.voice.setDeaf(false); return [4 /*yield*/, interaction.reply({ embeds: [ new discord_js_1.EmbedBuilder() .setTitle('Connecting to VC') .setDescription("Joining ".concat(memberChannel.toString(), "...")) .setColor(0xffff00) ] })]; case 9: _d.sent(); ytdl(link) .pipe((0, fs_1.createWriteStream)("./ytfiles/".concat(videoId, ".mp3"))); return [4 /*yield*/, ytdl.getInfo(link)]; case 10: videoInfo = _d.sent(); audioResource = (0, voice_1.createAudioResource)((0, node_path_1.join)(__dirname, "C:/Users/zahid/Code Folder/Bots/ZBot-En/ZBot-En/ytfiles/".concat(videoId, ".mp3"))); audioPlayer = (0, voice_1.createAudioPlayer)(); audioPlayer.play(audioResource); createConnection.subscribe(audioPlayer); audioPlayer.on(voice_1.AudioPlayerStatus.Playing, function () { return __awaiter(_this, void 0, void 0, function () { var _a, _b, _c, _d; var _e; return __generator(this, function (_f) { switch (_f.label) { case 0: _b = (_a = interaction).editReply; _e = {}; _d = (_c = discord_js_1.EmbedBuilder).from; return [4 /*yield*/, interaction.fetchReply()]; case 1: return [4 /*yield*/, _b.apply(_a, [(_e.embeds = [ _d.apply(_c, [(_f.sent()).embeds[0]]) .setTitle('Playing Audio') .setDescription("Playing audio in ".concat(memberChannel.toString(), "!")) .setColor(0x00ffff) ], _e)])]; case 2: _f.sent(); return [2 /*return*/]; } }); }); }); audioPlayer.on(voice_1.AudioPlayerStatus.Idle, function () { return __awaiter(_this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: createConnection.destroy(); return [4 /*yield*/, ((_a = interaction.channel) === null || _a === void 0 ? void 0 : _a.send({ embeds: [ new discord_js_1.EmbedBuilder() .setColor(0xff7700) .setTitle("Audio Finished") .setDescription("The audio has finished. Disconnecting from ".concat(memberChannel.toString(), ".")) ] }))]; case 1: _b.sent(); return [2 /*return*/]; } }); }); }); createConnection.on(voice_1.VoiceConnectionStatus.Disconnected, function () { return __awaiter(_this, void 0, void 0, function () { var _a, _b, _c, _d; var _e; var _this = this; return __generator(this, function (_f) { switch (_f.label) { case 0: _b = (_a = interaction).editReply; _e = {}; _d = (_c = discord_js_1.EmbedBuilder).from; return [4 /*yield*/, interaction.fetchReply()]; case 1: return [4 /*yield*/, _b.apply(_a, [(_e.embeds = [ _d.apply(_c, [(_f.sent()).embeds[0]]) .setTitle('Re-connection attempt') .setDescription("The connection to ".concat(memberChannel.toString(), " was cut off, I am attempting to re-connect so please give me 10 seconds...")) .setColor(0xffff00) ], _e)])]; case 2: _f.sent(); Promise.race([ (0, voice_1.entersState)(createConnection, voice_1.VoiceConnectionStatus.Signalling, 10000), (0, voice_1.entersState)(createConnection, voice_1.VoiceConnectionStatus.Connecting, 10000) ]) .then(function () { return __awaiter(_this, void 0, void 0, function () { var _a, _b, _c, _d; var _e; return __generator(this, function (_f) { switch (_f.label) { case 0: _b = (_a = interaction).editReply; _e = {}; _d = (_c = discord_js_1.EmbedBuilder).from; return [4 /*yield*/, interaction.fetchReply()]; case 1: return [4 /*yield*/, _b.apply(_a, [(_e.embeds = [ _d.apply(_c, [(_f.sent()).embeds[0]]) .setTitle('Successful Re-connection') .setDescription("I have successfully re-connected to ".concat(memberChannel.toString(), "!")) .setColor(0x00ff00) ], _e)])]; case 2: _f.sent(); return [2 /*return*/]; } }); }); })["catch"](function () { return __awaiter(_this, void 0, void 0, function () { var _a, _b, _c, _d; var _e; return __generator(this, function (_f) { switch (_f.label) { case 0: createConnection.destroy(); _b = (_a = interaction).editReply; _e = {}; _d = (_c = discord_js_1.EmbedBuilder).from; return [4 /*yield*/, interaction.fetchReply()]; case 1: return [4 /*yield*/, _b.apply(_a, [(_e.embeds = [ _d.apply(_c, [(_f.sent()).embeds[0]]) .setTitle('Re-connection Attempt Failed') .setDescription("Attempt to re-connect to ".concat(memberChannel.toString(), " failed... try again.")) .setColor(0xff0000) ], _e)])]; case 2: _f.sent(); return [2 /*return*/]; } }); }); }); return [2 /*return*/]; } }); }); }); createConnection.on(voice_1.VoiceConnectionStatus.Destroyed, function () { return __awaiter(_this, void 0, void 0, function () { var _a, _b, _c, _d; var _e; return __generator(this, function (_f) { switch (_f.label) { case 0: _b = (_a = interaction).editReply; _e = {}; _d = (_c = discord_js_1.EmbedBuilder).from; return [4 /*yield*/, interaction.fetchReply()]; case 1: return [4 /*yield*/, _b.apply(_a, [(_e.embeds = [ _d.apply(_c, [(_f.sent()).embeds[0]]) .setTitle('Connection Destroyed') .setColor(0xff0000) .setDescription("Connection to ".concat(memberChannel.toString(), " has been manually destroyed, try again.")) ], _e)])]; case 2: _f.sent(); return [2 /*return*/]; } }); }); }); return [2 /*return*/]; } }); }); } }; exports.playCommand = playCommand;