Fixing errors when closing the player info and trying to access it again

This commit is contained in:
Rafael Vargas 2023-03-14 00:25:33 -03:00
parent db405285ac
commit 8f18ef3f2e
13 changed files with 28 additions and 27 deletions

View File

@ -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 # 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 # 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 # 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 # 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 # 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 self.MAX_DOWNLOAD_SONGS_AT_A_TIME = 5

View File

@ -49,7 +49,7 @@ class JumpMusicHandler(AbstractHandler):
# Send a command to the player to skip the music # Send a command to the player to skip the music
command = VCommands(VCommandsType.SKIP, None) command = VCommands(VCommandsType.SKIP, None)
await playersManager.sendCommandToPlayer(command, self.guild) await playersManager.sendCommandToPlayer(command, self.guild, self.ctx)
return HandlerResponse(self.ctx) return HandlerResponse(self.ctx)
except: except:

View File

@ -16,7 +16,7 @@ class PauseHandler(AbstractHandler):
playersManager: AbstractPlayersManager = self.config.getPlayersManager() playersManager: AbstractPlayersManager = self.config.getPlayersManager()
if playersManager.verifyIfPlayerExists(self.guild): if playersManager.verifyIfPlayerExists(self.guild):
command = VCommands(VCommandsType.PAUSE, None) command = VCommands(VCommandsType.PAUSE, None)
await playersManager.sendCommandToPlayer(command, self.guild) await playersManager.sendCommandToPlayer(command, self.guild, self.ctx)
embed = self.embeds.PLAYER_PAUSED() embed = self.embeds.PLAYER_PAUSED()
return HandlerResponse(self.ctx, embed) return HandlerResponse(self.ctx, embed)

View File

@ -71,7 +71,7 @@ class PlayHandler(AbstractHandler):
# Release the acquired Lock # Release the acquired Lock
playerLock.release() playerLock.release()
playCommand = VCommands(VCommandsType.PLAY, None) playCommand = VCommands(VCommandsType.PLAY, None)
await playersManager.sendCommandToPlayer(playCommand, self.guild) await playersManager.sendCommandToPlayer(playCommand, self.guild, self.ctx)
else: else:
playersManager.resetPlayer(self.guild, self.ctx) playersManager.resetPlayer(self.guild, self.ctx)
embed = self.embeds.PLAYER_RESTARTED() embed = self.embeds.PLAYER_RESTARTED()
@ -128,7 +128,7 @@ class PlayHandler(AbstractHandler):
acquired = playerLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT) acquired = playerLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
if acquired: if acquired:
playlist.add_song(song) playlist.add_song(song)
await playersManager.sendCommandToPlayer(playCommand, self.guild) await playersManager.sendCommandToPlayer(playCommand, self.guild, self.ctx)
playerLock.release() playerLock.release()
else: else:
playersManager.resetPlayer(self.guild, self.ctx) playersManager.resetPlayer(self.guild, self.ctx)

View File

@ -38,7 +38,7 @@ class PrevHandler(AbstractHandler):
# Send a prev command, together with the user voice channel # Send a prev command, together with the user voice channel
prevCommand = VCommands(VCommandsType.PREV, self.author.voice.channel.id) 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() embed = self.embeds.RETURNING_SONG()
return HandlerResponse(self.ctx, embed) return HandlerResponse(self.ctx, embed)

View File

@ -16,7 +16,7 @@ class ResetHandler(AbstractHandler):
playersManager: AbstractPlayersManager = self.config.getPlayersManager() playersManager: AbstractPlayersManager = self.config.getPlayersManager()
if playersManager.verifyIfPlayerExists(self.guild): if playersManager.verifyIfPlayerExists(self.guild):
command = VCommands(VCommandsType.RESET, None) command = VCommands(VCommandsType.RESET, None)
await playersManager.sendCommandToPlayer(command, self.guild) await playersManager.sendCommandToPlayer(command, self.guild, self.ctx)
return HandlerResponse(self.ctx) return HandlerResponse(self.ctx)
else: else:
embed = self.embeds.NOT_PLAYING() embed = self.embeds.NOT_PLAYING()

View File

@ -16,7 +16,7 @@ class ResumeHandler(AbstractHandler):
playersManager: AbstractPlayersManager = self.config.getPlayersManager() playersManager: AbstractPlayersManager = self.config.getPlayersManager()
if playersManager.verifyIfPlayerExists(self.guild): if playersManager.verifyIfPlayerExists(self.guild):
command = VCommands(VCommandsType.RESUME, None) command = VCommands(VCommandsType.RESUME, None)
await playersManager.sendCommandToPlayer(command, self.guild) await playersManager.sendCommandToPlayer(command, self.guild, self.ctx)
embed = self.embeds.PLAYER_RESUMED() embed = self.embeds.PLAYER_RESUMED()
return HandlerResponse(self.ctx, embed) return HandlerResponse(self.ctx, embed)
else: else:

View File

@ -16,7 +16,7 @@ class SkipHandler(AbstractHandler):
playersManager: AbstractPlayersManager = self.config.getPlayersManager() playersManager: AbstractPlayersManager = self.config.getPlayersManager()
if playersManager.verifyIfPlayerExists(self.guild): if playersManager.verifyIfPlayerExists(self.guild):
command = VCommands(VCommandsType.SKIP, None) command = VCommands(VCommandsType.SKIP, None)
await playersManager.sendCommandToPlayer(command, self.guild) await playersManager.sendCommandToPlayer(command, self.guild, self.ctx)
embed = self.embeds.SKIPPING_SONG() embed = self.embeds.SKIPPING_SONG()
return HandlerResponse(self.ctx, embed) return HandlerResponse(self.ctx, embed)
else: else:

View File

@ -16,7 +16,7 @@ class StopHandler(AbstractHandler):
playersManager: AbstractPlayersManager = self.config.getPlayersManager() playersManager: AbstractPlayersManager = self.config.getPlayersManager()
if playersManager.verifyIfPlayerExists(self.guild): if playersManager.verifyIfPlayerExists(self.guild):
command = VCommands(VCommandsType.STOP, None) command = VCommands(VCommandsType.STOP, None)
await playersManager.sendCommandToPlayer(command, self.guild) await playersManager.sendCommandToPlayer(command, self.guild, self.ctx)
embed = self.embeds.STOPPING_PLAYER() embed = self.embeds.STOPPING_PLAYER()
return HandlerResponse(self.ctx, embed) return HandlerResponse(self.ctx, embed)
else: else:

View File

@ -13,7 +13,7 @@ class AbstractPlayersManager(ABC):
pass pass
@abstractmethod @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""" """If the forceCreation boolean is True, then the context must be provided for the Player to be created"""
pass pass

View File

@ -81,7 +81,7 @@ class ProcessPlayerManager(Singleton, AbstractPlayersManager):
self.__playersListeners: Dict[int, Tuple[Thread, bool]] = {} self.__playersListeners: Dict[int, Tuple[Thread, bool]] = {}
self.__playersCommandsExecutor: Dict[int, ProcessCommandsExecutor] = {} 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: if forceCreation:
processInfo = self.createPlayerForGuild(guild, context) processInfo = self.createPlayerForGuild(guild, context)
else: else:
@ -89,6 +89,10 @@ class ProcessPlayerManager(Singleton, AbstractPlayersManager):
if processInfo == None: if processInfo == None:
return return
if processInfo.getStatus() == ProcessStatus.SLEEPING:
self.resetPlayer(guild, context)
processInfo = self.__getRunningPlayerInfo(guild)
queue = processInfo.getQueueToPlayer() queue = processInfo.getQueueToPlayer()
self.__putCommandInQueue(queue, command) self.__putCommandInQueue(queue, command)
@ -172,24 +176,19 @@ class ProcessPlayerManager(Singleton, AbstractPlayersManager):
process = playerProcess.getProcess() process = playerProcess.getProcess()
process.close() process.close()
process.kill() process.kill()
playerProcess.getQueueToMain().close() except ValueError:
playerProcess.getQueueToMain().join_thread() pass
playerProcess.getQueueToPlayer().close()
playerProcess.getQueueToPlayer().join_thread()
except Exception as e: except Exception as e:
print(f'[ERROR STOPPING PROCESS] -> {e}') print(f'[WARNINGS] -> {e}')
def __recreateProcess(self, guild: Guild, context: Union[Context, Interaction]) -> PlayerProcessInfo: def __recreateProcess(self, guild: Guild, context: Union[Context, Interaction]) -> PlayerProcessInfo:
"""Create a new process info using previous playlist""" """Create a new process info using previous playlist"""
self.__stopPossiblyRunningProcess(guild) self.__stopPossiblyRunningProcess(guild)
guildID: int = context.guild.id guildID: int = context.guild.id
textID: int = context.channel.id
if isinstance(context, Interaction): if isinstance(context, Interaction):
authorID: int = context.user.id
voiceID: int = context.user.voice.channel.id voiceID: int = context.user.voice.channel.id
else: else:
authorID: int = context.author.id
voiceID: int = context.author.voice.channel.id voiceID: int = context.author.voice.channel.id
playlist: Playlist = self.__playersProcess[guildID].getPlaylist() playlist: Playlist = self.__playersProcess[guildID].getPlaylist()
@ -197,7 +196,7 @@ class ProcessPlayerManager(Singleton, AbstractPlayersManager):
queueToListen = Queue() queueToListen = Queue()
queueToSend = Queue() queueToSend = Queue()
process = ProcessPlayer(context.guild.name, playlist, lock, queueToSend, process = ProcessPlayer(context.guild.name, playlist, lock, queueToSend,
queueToListen, guildID, textID, voiceID, authorID) queueToListen, guildID, voiceID)
processInfo = PlayerProcessInfo(process, queueToSend, queueToListen, processInfo = PlayerProcessInfo(process, queueToSend, queueToListen,
playlist, lock, context.channel) playlist, lock, context.channel)

View File

@ -342,11 +342,13 @@ class ThreadPlayer(Thread):
else: else:
break break
if self.__voiceClient is not None: try:
try: voiceClient = self.__guild.voice_client
await self.__voiceClient.disconnect(force=True) if voiceClient is not None:
except Exception as e: await voiceClient.disconnect(force=True)
print(f'[THREAD PLAYER -> ERROR FORCING DISCONNECT] -> {e}') except Exception as e:
print(f'[THREAD PLAYER -> ERROR FORCING DISCONNECT] -> {e}')
self.__voiceClient = await self.__voiceChannel.connect(reconnect=True, timeout=None) self.__voiceClient = await self.__voiceChannel.connect(reconnect=True, timeout=None)
return True return True
except Exception as e: except Exception as e:

View File

@ -46,7 +46,7 @@ class ThreadPlayerManager(Singleton, AbstractPlayersManager):
self.__bot = bot self.__bot = bot
self.__playersThreads: Dict[int, ThreadPlayerInfo] = {} 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] playerInfo = self.__playersThreads[guild.id]
player = playerInfo.getPlayer() player = playerInfo.getPlayer()
if player is None and forceCreation: if player is None and forceCreation: