diff --git a/Config/Configs.py b/Config/Configs.py index 682d251..8512613 100644 --- a/Config/Configs.py +++ b/Config/Configs.py @@ -12,7 +12,7 @@ class VConfigs(Singleton): # Recommended to be True, except in cases when your Bot is present in thousands servers, in that case # the delay to start a new Python process for the playback is too much, and to avoid that you set as False # This feature is for now in testing period, for a more stable version, keep this boolean = True - self.SONG_PLAYBACK_IN_SEPARATE_PROCESS = True + self.SONG_PLAYBACK_IN_SEPARATE_PROCESS = False # Maximum of songs that will be downloaded at once, the higher this number is, the faster the songs will be all available # but the slower will be the others commands of the Bot during the downloading time, for example, the playback quality self.MAX_DOWNLOAD_SONGS_AT_A_TIME = 5 diff --git a/Handlers/JumpMusicHandler.py b/Handlers/JumpMusicHandler.py index 2210eee..7a37570 100644 --- a/Handlers/JumpMusicHandler.py +++ b/Handlers/JumpMusicHandler.py @@ -49,7 +49,7 @@ class JumpMusicHandler(AbstractHandler): # Send a command to the player to skip the music command = VCommands(VCommandsType.SKIP, None) - await playersManager.sendCommandToPlayer(command, self.guild) + await playersManager.sendCommandToPlayer(command, self.guild, self.ctx) return HandlerResponse(self.ctx) except: diff --git a/Handlers/PauseHandler.py b/Handlers/PauseHandler.py index 681a48e..206108e 100644 --- a/Handlers/PauseHandler.py +++ b/Handlers/PauseHandler.py @@ -16,7 +16,7 @@ class PauseHandler(AbstractHandler): playersManager: AbstractPlayersManager = self.config.getPlayersManager() if playersManager.verifyIfPlayerExists(self.guild): command = VCommands(VCommandsType.PAUSE, None) - await playersManager.sendCommandToPlayer(command, self.guild) + await playersManager.sendCommandToPlayer(command, self.guild, self.ctx) embed = self.embeds.PLAYER_PAUSED() return HandlerResponse(self.ctx, embed) diff --git a/Handlers/PlayHandler.py b/Handlers/PlayHandler.py index 1ee3d77..82b329b 100644 --- a/Handlers/PlayHandler.py +++ b/Handlers/PlayHandler.py @@ -71,7 +71,7 @@ class PlayHandler(AbstractHandler): # Release the acquired Lock playerLock.release() playCommand = VCommands(VCommandsType.PLAY, None) - await playersManager.sendCommandToPlayer(playCommand, self.guild) + await playersManager.sendCommandToPlayer(playCommand, self.guild, self.ctx) else: playersManager.resetPlayer(self.guild, self.ctx) embed = self.embeds.PLAYER_RESTARTED() @@ -128,7 +128,7 @@ class PlayHandler(AbstractHandler): acquired = playerLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT) if acquired: playlist.add_song(song) - await playersManager.sendCommandToPlayer(playCommand, self.guild) + await playersManager.sendCommandToPlayer(playCommand, self.guild, self.ctx) playerLock.release() else: playersManager.resetPlayer(self.guild, self.ctx) diff --git a/Handlers/PrevHandler.py b/Handlers/PrevHandler.py index 09c5b14..09344c4 100644 --- a/Handlers/PrevHandler.py +++ b/Handlers/PrevHandler.py @@ -38,7 +38,7 @@ class PrevHandler(AbstractHandler): # Send a prev command, together with the user voice channel prevCommand = VCommands(VCommandsType.PREV, self.author.voice.channel.id) - await playersManager.sendCommandToPlayer(prevCommand, self.guild) + await playersManager.sendCommandToPlayer(prevCommand, self.guild, self.ctx) embed = self.embeds.RETURNING_SONG() return HandlerResponse(self.ctx, embed) diff --git a/Handlers/ResetHandler.py b/Handlers/ResetHandler.py index 4cf8eb7..498e30d 100644 --- a/Handlers/ResetHandler.py +++ b/Handlers/ResetHandler.py @@ -16,7 +16,7 @@ class ResetHandler(AbstractHandler): playersManager: AbstractPlayersManager = self.config.getPlayersManager() if playersManager.verifyIfPlayerExists(self.guild): command = VCommands(VCommandsType.RESET, None) - await playersManager.sendCommandToPlayer(command, self.guild) + await playersManager.sendCommandToPlayer(command, self.guild, self.ctx) return HandlerResponse(self.ctx) else: embed = self.embeds.NOT_PLAYING() diff --git a/Handlers/ResumeHandler.py b/Handlers/ResumeHandler.py index 5a187e9..9d5d575 100644 --- a/Handlers/ResumeHandler.py +++ b/Handlers/ResumeHandler.py @@ -16,7 +16,7 @@ class ResumeHandler(AbstractHandler): playersManager: AbstractPlayersManager = self.config.getPlayersManager() if playersManager.verifyIfPlayerExists(self.guild): command = VCommands(VCommandsType.RESUME, None) - await playersManager.sendCommandToPlayer(command, self.guild) + await playersManager.sendCommandToPlayer(command, self.guild, self.ctx) embed = self.embeds.PLAYER_RESUMED() return HandlerResponse(self.ctx, embed) else: diff --git a/Handlers/SkipHandler.py b/Handlers/SkipHandler.py index 6400fc3..b5909dc 100644 --- a/Handlers/SkipHandler.py +++ b/Handlers/SkipHandler.py @@ -16,7 +16,7 @@ class SkipHandler(AbstractHandler): playersManager: AbstractPlayersManager = self.config.getPlayersManager() if playersManager.verifyIfPlayerExists(self.guild): command = VCommands(VCommandsType.SKIP, None) - await playersManager.sendCommandToPlayer(command, self.guild) + await playersManager.sendCommandToPlayer(command, self.guild, self.ctx) embed = self.embeds.SKIPPING_SONG() return HandlerResponse(self.ctx, embed) else: diff --git a/Handlers/StopHandler.py b/Handlers/StopHandler.py index 07972dc..3cfe179 100644 --- a/Handlers/StopHandler.py +++ b/Handlers/StopHandler.py @@ -16,7 +16,7 @@ class StopHandler(AbstractHandler): playersManager: AbstractPlayersManager = self.config.getPlayersManager() if playersManager.verifyIfPlayerExists(self.guild): command = VCommands(VCommandsType.STOP, None) - await playersManager.sendCommandToPlayer(command, self.guild) + await playersManager.sendCommandToPlayer(command, self.guild, self.ctx) embed = self.embeds.STOPPING_PLAYER() return HandlerResponse(self.ctx, embed) else: diff --git a/Parallelism/AbstractProcessManager.py b/Parallelism/AbstractProcessManager.py index edcd432..34c4832 100644 --- a/Parallelism/AbstractProcessManager.py +++ b/Parallelism/AbstractProcessManager.py @@ -13,7 +13,7 @@ class AbstractPlayersManager(ABC): pass @abstractmethod - async def sendCommandToPlayer(self, command: VCommands, guild: Guild, forceCreation: bool = False, context: Union[Context, Interaction] = None): + async def sendCommandToPlayer(self, command: VCommands, guild: Guild, context: Union[Context, Interaction], forceCreation: bool = False): """If the forceCreation boolean is True, then the context must be provided for the Player to be created""" pass diff --git a/Parallelism/ProcessPlayerManager.py b/Parallelism/ProcessPlayerManager.py index 50bcaa0..a2354f2 100644 --- a/Parallelism/ProcessPlayerManager.py +++ b/Parallelism/ProcessPlayerManager.py @@ -81,7 +81,7 @@ class ProcessPlayerManager(Singleton, AbstractPlayersManager): self.__playersListeners: Dict[int, Tuple[Thread, bool]] = {} self.__playersCommandsExecutor: Dict[int, ProcessCommandsExecutor] = {} - async def sendCommandToPlayer(self, command: VCommands, guild: Guild, forceCreation: bool = False, context: Union[Context, Interaction] = None): + async def sendCommandToPlayer(self, command: VCommands, guild: Guild, context: Union[Context, Interaction], forceCreation: bool = False): if forceCreation: processInfo = self.createPlayerForGuild(guild, context) else: @@ -89,6 +89,10 @@ class ProcessPlayerManager(Singleton, AbstractPlayersManager): if processInfo == None: return + if processInfo.getStatus() == ProcessStatus.SLEEPING: + self.resetPlayer(guild, context) + processInfo = self.__getRunningPlayerInfo(guild) + queue = processInfo.getQueueToPlayer() self.__putCommandInQueue(queue, command) @@ -172,24 +176,19 @@ class ProcessPlayerManager(Singleton, AbstractPlayersManager): process = playerProcess.getProcess() process.close() process.kill() - playerProcess.getQueueToMain().close() - playerProcess.getQueueToMain().join_thread() - playerProcess.getQueueToPlayer().close() - playerProcess.getQueueToPlayer().join_thread() + except ValueError: + pass except Exception as e: - print(f'[ERROR STOPPING PROCESS] -> {e}') + print(f'[WARNINGS] -> {e}') def __recreateProcess(self, guild: Guild, context: Union[Context, Interaction]) -> PlayerProcessInfo: """Create a new process info using previous playlist""" self.__stopPossiblyRunningProcess(guild) guildID: int = context.guild.id - textID: int = context.channel.id if isinstance(context, Interaction): - authorID: int = context.user.id voiceID: int = context.user.voice.channel.id else: - authorID: int = context.author.id voiceID: int = context.author.voice.channel.id playlist: Playlist = self.__playersProcess[guildID].getPlaylist() @@ -197,7 +196,7 @@ class ProcessPlayerManager(Singleton, AbstractPlayersManager): queueToListen = Queue() queueToSend = Queue() process = ProcessPlayer(context.guild.name, playlist, lock, queueToSend, - queueToListen, guildID, textID, voiceID, authorID) + queueToListen, guildID, voiceID) processInfo = PlayerProcessInfo(process, queueToSend, queueToListen, playlist, lock, context.channel) diff --git a/Parallelism/ThreadPlayer.py b/Parallelism/ThreadPlayer.py index a80d6e8..0ae2367 100644 --- a/Parallelism/ThreadPlayer.py +++ b/Parallelism/ThreadPlayer.py @@ -342,11 +342,13 @@ class ThreadPlayer(Thread): else: break - if self.__voiceClient is not None: - try: - await self.__voiceClient.disconnect(force=True) - except Exception as e: - print(f'[THREAD PLAYER -> ERROR FORCING DISCONNECT] -> {e}') + try: + voiceClient = self.__guild.voice_client + if voiceClient is not None: + await voiceClient.disconnect(force=True) + except Exception as e: + print(f'[THREAD PLAYER -> ERROR FORCING DISCONNECT] -> {e}') + self.__voiceClient = await self.__voiceChannel.connect(reconnect=True, timeout=None) return True except Exception as e: diff --git a/Parallelism/ThreadPlayerManager.py b/Parallelism/ThreadPlayerManager.py index a6c068a..1c11e84 100644 --- a/Parallelism/ThreadPlayerManager.py +++ b/Parallelism/ThreadPlayerManager.py @@ -46,7 +46,7 @@ class ThreadPlayerManager(Singleton, AbstractPlayersManager): self.__bot = bot self.__playersThreads: Dict[int, ThreadPlayerInfo] = {} - async def sendCommandToPlayer(self, command: VCommands, guild: Guild, forceCreation: bool = False, context: Union[Context, Interaction] = None): + async def sendCommandToPlayer(self, command: VCommands, guild: Guild, context: Union[Context, Interaction], forceCreation: bool = False): playerInfo = self.__playersThreads[guild.id] player = playerInfo.getPlayer() if player is None and forceCreation: