Skip to content

Commit

Permalink
Made music commands beautify (#81)
Browse files Browse the repository at this point in the history
* unfinished music commands

* commands: music: fix conflicts

* commands: Play: add loop

* commands: Play: fix sendMessage on null

* commands: Play: fix Uncaught Error: Cannot use object of type hiro\parts\VoiceSettings as array

* parts: Update VoiceSettings

* commands: Loop: added

* commands: Play: stop using $msg variable

* Update Loop.php

* commands: Play: Undefined variable $textChannel

* commands: Play: fix Call to undefined method Discord\Parts\Channel\Message::sendMessage()

* commands: music: made music commands better

* parts: VoiceSettings: fix setVoiceClient() function

* commands: Play: fix playMusic() usage

* commands: Play: fix sth

* commands: Play: fix syntax

* commands: Play: fix syntax error, unexpected token }, expecting ;

* commands: Play: fix Object of class hiro\parts\VoiceFile could not be converted to string

* commands: Play: ported 'textChannel' to 'text_channel'

* commands: Play: fix 'Undefined variable $author_id'

* commands: Play: delete message after play sound

* commands: Play: send information after add queue

* commands: Play: fix queue

* commands: Play: tried to fix bot is always trying to play

* commands: Play: fix 'Undefined variable $settings'

* commands: Play: fix bot is not playing next song

* parts: VoiceSettings: debugging

* commands: Play: tried to fix queue system

* commands: Play: hmm

* parts: VoiceSettings: close debug

* commands: Skip: added

* commands: Skip: add exactly skip song

* commands: Skip: skip the song if loop is enabled too

* commands: Play: tried to fix double play

* commands: Play: shift queue after song end not while playing song
  • Loading branch information
bariscodefxy authored Jul 29, 2023
1 parent b260496 commit 8dadd64
Show file tree
Hide file tree
Showing 9 changed files with 406 additions and 53 deletions.
3 changes: 2 additions & 1 deletion bot.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use hiro\CommandLoader;
use hiro\ArgumentParser;
use hiro\PresenceManager;
use hiro\parts\VoiceSettings;
use Discord\WebSockets\Intents;
use hiro\Version;

Expand All @@ -51,7 +52,7 @@
'loadAllMembers' => true,
'intents' => Intents::getDefaultIntents() | Intents::GUILD_MEMBERS | Intents::MESSAGE_CONTENT
]);
$voiceClients = [];
$voiceSettings = [];

function getPresenceState(): ?array
{
Expand Down
16 changes: 11 additions & 5 deletions src/commands/music/Join.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
namespace hiro\commands;

use Discord\Voice\VoiceClient;
use hiro\parts\VoiceSettings;

class Join extends Command
{
Expand All @@ -46,17 +47,22 @@ public function configure(): void
*/
public function handle($msg, $args): void
{
global $voiceClients;
$channel = $msg->member->getVoiceChannel();

if (!$channel) {
$msg->channel->sendMessage("You must be in a voice channel.");
return;
}

$this->discord->joinVoiceChannel($channel, false, true, null, true)->done(function (VoiceClient $vc) use ($channel) {
global $voiceClients;
$voiceClients[$channel->guild_id] = $vc;
$this->discord->joinVoiceChannel($channel, false, false, null, true)->done(function (VoiceClient $vc) use ($channel) {
global $voiceSettings;

$settings = new VoiceSettings($vc);

$voiceSettings[$channel->guild_id] = $settings;

$vc->on('exit', function() use ($voiceSettings) {
unset($voiceSettings[$channel->guild_id]);
});
}, function ($e) use ($msg) {
$msg->channel->sendMessage("There was an error joining the voice channel: {$e->getMessage()}");
});
Expand Down
8 changes: 4 additions & 4 deletions src/commands/music/Leave.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ public function configure(): void
*/
public function handle($msg, $args): void
{
global $voiceClients;
global $voiceSettings;
$channel = $msg->member->getVoiceChannel();

$voiceClient = $voiceClients[$msg->channel->guild_id];
$voiceClient = $this->discord->getVoiceClient($msg->guild_id);

if ($voiceClient && $channel->id !== $voiceClient->getChannel()->id) {
$msg->channel->sendMessage("You must be in same channel with me.");
Expand All @@ -58,9 +58,9 @@ public function handle($msg, $args): void

if ($voiceClient) {
$voiceClient->close();
if(isset($voiceClients[$msg->guild_id]))
if(isset($voiceSettings[$msg->guild_id]))
{
unset($voiceClients[$msg->guild_id]);
unset($voiceSettings[$msg->guild_id]);
}
} else {
$msg->channel->sendMessage("I'm not in a voice channel.");
Expand Down
75 changes: 75 additions & 0 deletions src/commands/music/Loop.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

/**
* Copyright 2023 bariscodefx
*
* This file is part of project Hiro 016 Discord Bot.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace hiro\commands;

use Discord\Voice\VoiceClient;
use React\ChildProcess\Process;
use Discord\Builders\MessageBuilder;

class Loop extends Command
{
public function configure(): void
{
$this->command = "loop";
$this->description = "Enables or disables looping in music.";
$this->aliases = [];
$this->category = "music";
}

public function handle($msg, $args): void
{
global $voiceSettings;
$channel = $msg->member->getVoiceChannel();
$voiceClient = $this->discord->getVoiceClient($msg->guild_id);

if (!$channel) {
$msg->channel->sendMessage("You must be in a voice channel.");
return;
}

if (!$voiceClient) {
$msg->reply("Use the join command first.\n");
return;
}

if ($voiceClient && $channel->id !== $voiceClient->getChannel()->id) {
$msg->reply("You must be in the same channel with me.");
return;
}

$settings = @$voiceSettings[$msg->channel->guild_id];

if (!$settings)
{
$msg->reply("Voice options couldn't found.");
return;
}

if ($settings->getLoopEnabled())
{
$settings->setLoopEnabled(false);
$msg->reply("Loop is **disabled** now.");
} else {
$settings->setLoopEnabled(true);
$msg->reply("Loop is **enabled** now.");
}
}
}
126 changes: 90 additions & 36 deletions src/commands/music/Play.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use Discord\Voice\VoiceClient;
use React\ChildProcess\Process;
use Discord\Builders\MessageBuilder;
use hiro\parts\VoiceFile;

class Play extends Command
{
Expand All @@ -34,10 +35,73 @@ public function configure(): void
$this->category = "music";
}

public function playMusic($text_channel, $settings)
{
$voice_client = $settings->getVoiceClient();
$current_voice_file = $settings->getQueue()[0];

if (!$current_voice_file)
{
$text_channel->sendMessage("Current voice file not found.");
return;
}
$author_id = $settings->getQueue()[0]->getAuthorId();

@unlink($author_id . ".m4a");
@unlink($author_id . ".info.json");

$command = "./yt-dlp -f bestaudio[ext=m4a] --ignore-config --ignore-errors --write-info-json --output=./{$author_id}.m4a --audio-quality=0 \"{$settings->getQueue()[0]->getUrl()}\"";
$process = new Process($command);
$process->start();

$editmsg = $text_channel->sendMessage("Downloading audio, please wait...");

$process->on('exit', function($code, $term) use ($voice_client, $author_id, $editmsg, $settings, $text_channel) {
if (is_file($author_id . ".m4a")) {
$play_file_promise = $voice_client->playFile($author_id . ".m4a");
}

$editmsg->then(function($m) use ($text_channel, $author_id, $play_file_promise, $settings) {

if (!is_file($author_id . ".m4a")) {
$m->edit(MessageBuilder::new()->setContent("Couldn't download the audio."));
return;
}

$jsondata = json_decode(file_get_contents($author_id . ".info.json"));

$m->edit(MessageBuilder::new()->setContent("Playing **{$jsondata->title}**. :musical_note: :tada:"))->then(function() use ($m, $play_file_promise, $settings, $text_channel){
$play_file_promise->then(function() use ($m, $settings, $text_channel) {
if(@$settings->getQueue()[0])
{
if (!$settings->getLoopEnabled())
{
$settings->nextSong();
}
$this->playMusic($text_channel, $settings);
} else {
$m->channel->sendMessage(MessageBuilder::new()->setContent("Music not found on queue."));
}

$m->delete();
});
});

});

$this->discord->getLoop()->addTimer(0.5, function() use ($author_id) {
@unlink($author_id . ".m4a");
@unlink($author_id . ".info.json");
});

});
}

public function handle($msg, $args): void
{
global $voiceClients;
$channel = $msg->member->getVoiceChannel();
global $voiceSettings;
$channel = $msg->member->getVoiceChannel();
$voiceClient = $this->discord->getVoiceClient($msg->guild_id);

if (!$channel) {
$msg->channel->sendMessage("You must be in a voice channel.");
Expand All @@ -51,8 +115,6 @@ public function handle($msg, $args): void
return;
}

$voiceClient = @$voiceClients[$msg->channel->guild_id];

if (!$voiceClient) {
$msg->reply("Use the join command first.\n");
return;
Expand All @@ -61,47 +123,39 @@ public function handle($msg, $args): void
if ($voiceClient && $channel->id !== $voiceClient->getChannel()->id) {
$msg->reply("You must be in the same channel with me.");
return;
}
}

@unlink($msg->author->id . ".m4a");
@unlink($msg->author->id . ".info.json");
$settings = @$voiceSettings[$msg->channel->guild_id];

if (!$settings)
{
$msg->reply("Voice options couldn't found.");
return;
}

$url = str_replace('\\', '', $url);
if (filter_var($url, FILTER_VALIDATE_URL) === false) {
$msg->reply("The URL is not valid.");
return;
}

preg_match('/https?:\/\/(www\.)?youtube\.com\/watch\?v\=([A-Za-z0-9-_]+)/', $url, $matches);
if(!@$matches[0])
{
$msg->reply("YouTube video url not found.\n");
return;
}
$url = $matches[0];

$command = "./yt-dlp -f bestaudio[ext=m4a] --ignore-config --ignore-errors --write-info-json --output=./{$msg->author->id}.m4a --audio-quality=0 \"$url\"";
$process = new Process($command);
$process->start();
preg_match('/https?:\/\/(www\.)?youtube\.com\/watch\?v\=([A-Za-z0-9-_]+)/', $url, $matches);
preg_match('/https?:\/\/(www\.)?youtu\.be\/([A-Za-z0-9-_]+)/', $url, $matches2);
preg_match('/https?:\/\/(www\.)?youtube\.com\/shorts\/([A-Za-z0-9-_]+)/', $url, $matches3);
if(!@$matches[0] && !@$matches2[0] && !@$matches3[0])
{
$msg->reply("YouTube video URL not found.\n");
return;
}
$url = $matches[0] ?? $matches2[0] ?? $matches3[0];

$editmsg = $msg->reply("Downloading audio, please wait...");
$settings->addToQueue(new VoiceFile($url, $msg->author->id));

$process->on('exit', function($code, $term) use ($msg, $voiceClient, $editmsg) {
if (is_file($msg->author->id . ".m4a")) {
$voiceClient->playFile($msg->author->id . ".m4a");
}
$editmsg->then(function($m) use ($msg) {
if (!is_file($msg->author->id . ".m4a")) {
$m->edit(MessageBuilder::new()->setContent("Couldn't download the audio."));
} else {
$jsondata = json_decode(file_get_contents($msg->author->id . ".info.json"));
$m->edit(MessageBuilder::new()->setContent("Playing **{$jsondata->title}**. :musical_note: :tada:"));
}
});
$this->discord->getLoop()->addTimer(0.5, function() use ($msg) {
@unlink($msg->author->id . ".m4a");
@unlink($msg->author->id . ".info.json");
});
});
if( @$settings->getQueue()[1] )
{
$msg->reply("Song added to queue.\n");
} else {
$this->playMusic($msg->channel, $settings);
}
}
}
77 changes: 77 additions & 0 deletions src/commands/music/Skip.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

/**
* Copyright 2023 bariscodefx
*
* This file part of project Hiro 016 Discord Bot.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

namespace hiro\commands;

use Discord\Voice\VoiceClient;

class Skip extends Command
{
/**
* configure
*
* @return void
*/
public function configure(): void
{
$this->command = "skip";
$this->description = "Skips the current song.";
$this->aliases = [];
$this->category = "music";
}

/**
* handle
*
* @param [type] $msg
* @param [type] $args
* @return void
*/
public function handle($msg, $args): void
{
global $voiceSettings;
$channel = $msg->member->getVoiceChannel();

$voiceClient = $this->discord->getVoiceClient($msg->channel->guild_id);

if ($voiceClient && $channel->id !== $voiceClient->getChannel()->id) {
$msg->channel->sendMessage("You must be in same channel with me.");
return;
}

$settings = @$voiceSettings[$msg->guild_id];
if(!$settings)
{
$msg->channel->sendMessage("Voice settings couldn't found.");
return;
}

try {
$voiceClient->stop();
if($cmd = $this->loader->getCmd("play"))
{
$settings->nextSong();
$cmd->playMusic($msg->channel, $settings);
}
} catch (\Throwable $e) {
$msg->reply($e->getMessage());
}
}
}
Loading

0 comments on commit 8dadd64

Please sign in to comment.