@@ -18,7 +18,8 @@ import {
1818 randomNumber ,
1919 registerDiscordEvent ,
2020 requireActivePlayer ,
21- songToOpus
21+ songToOpus ,
22+ unix
2223} from './functions' ;
2324import {
2425 ComponentType ,
@@ -127,6 +128,7 @@ export class Player extends EventEmitter<PlayerEventMap> {
127128 private _currentSeeked : number = 0 ;
128129 private destroying : boolean = false ;
129130 private locked : boolean = false ;
131+ private lockedAt : number | null = null ;
130132 private autoplay : boolean = false ;
131133
132134 constructor (
@@ -288,7 +290,9 @@ export class Player extends EventEmitter<PlayerEventMap> {
288290 return ;
289291 }
290292
291- await this . playSong ( 'next' ) ;
293+ this . lock ( async ( ) => {
294+ await this . playSong ( 'next' ) ;
295+ } ) . catch ( ( ) => null ) ;
292296 } ) ;
293297
294298 this . on ( 'play' , ( ) => {
@@ -719,13 +723,24 @@ export class Player extends EventEmitter<PlayerEventMap> {
719723 * @param action The action to execute while the player is locked.
720724 * @param interaction Optional Discord interaction for error handling.
721725 * @throws {LockedPlayerError } if the player is already locked and no interaction is provided.
722- * @returns The result of the action or null if handled via interaction .
726+ * @returns Whether the player was successfully locked and the action executed .
723727 */
724728 async lock (
725729 action : ( ) => PossiblyAsync < void > ,
726730 interaction ?: Interaction
727731 ) : Promise < boolean > {
728- if ( this . locked ) {
732+ let isLocked = this . isLocked ;
733+ const lockedAt = this . lockedAt ;
734+ this . locked = true ;
735+ this . lockedAt = unix ( ) ;
736+
737+ if ( lockedAt !== null && isLocked && ( unix ( ) - ( lockedAt ?? 0 ) > 20 ) ) {
738+ gtaTunesLog ( 'PLAYER' , `Player lock in guild ${ p . magenta ( this . guild . name ) } (${ p . magenta ( this . guild . id ) } ) has expired, forcing unlock.` ) ;
739+ isLocked = false ;
740+ this . lockedAt = null ;
741+ }
742+
743+ if ( isLocked ) {
729744 gtaTunesLog (
730745 'PLAYER' ,
731746 `Player in guild ${ p . magenta ( this . guild . name ) } (${ p . magenta ( this . guild . id ) } ) is already locked.`
@@ -743,16 +758,16 @@ export class Player extends EventEmitter<PlayerEventMap> {
743758 'PLAYER' ,
744759 `Locking player in ${ p . magenta ( this . guild . name ) } (${ p . magenta ( this . guild . id ) } ).`
745760 ) ;
746- this . locked = true ;
747761
748762 try {
749763 await action ( ) ;
750764 } catch ( e ) {
751765 gtaTunesLog (
752766 'PLAYER' ,
753- `Unlocking player in ${ p . magenta ( this . guild . name ) } (${ p . magenta ( this . guild . id ) } ).`
767+ `Unlocking player in ${ p . magenta ( this . guild . name ) } (${ p . magenta ( this . guild . id ) } ) after failing action .`
754768 ) ;
755769 this . locked = false ;
770+ this . lockedAt = null ;
756771 throw e ;
757772 }
758773
@@ -761,6 +776,7 @@ export class Player extends EventEmitter<PlayerEventMap> {
761776 `Unlocking player in ${ p . magenta ( this . guild . name ) } (${ p . magenta ( this . guild . id ) } ).`
762777 ) ;
763778 this . locked = false ;
779+ this . lockedAt = null ;
764780
765781 return true ;
766782 }
0 commit comments