2022-11-16 06:41:30 -05:00
/* eslint-disable require-jsdoc */
2022-08-14 05:51:45 -04:00
/* eslint-disable max-len */
const { Midi } = require ( '@tonejs/midi' ) ;
const { convertMidi } = require ( '../util/midi_converter' ) ;
const soundNames = {
harp : 'minecraft:block.note_block.harp' ,
basedrum : 'minecraft:block.note_block.basedrum' ,
snare : 'minecraft:block.note_block.snare' ,
hat : 'minecraft:block.note_block.hat' ,
bass : 'minecraft:block.note_block.bass' ,
flute : 'minecraft:block.note_block.flute' ,
bell : 'minecraft:block.note_block.bell' ,
guitar : 'minecraft:block.note_block.guitar' ,
chime : 'minecraft:block.note_block.chime' ,
xylophone : 'minecraft:block.note_block.xylophone' ,
iron _xylophone : 'minecraft:block.note_block.iron_xylophone' ,
cow _bell : 'minecraft:block.note_block.cow_bell' ,
didgeridoo : 'minecraft:block.note_block.didgeridoo' ,
bit : 'minecraft:block.note_block.bit' ,
banjo : 'minecraft:block.note_block.banjo' ,
pling : 'minecraft:block.note_block.pling' ,
} ;
function inject ( bot ) {
bot . music = function ( ) { } ;
bot . music . song = null ;
2022-10-30 08:17:20 -04:00
bot . music . loop = 0 ;
bot . music . queue = [ ] ;
2022-11-16 21:07:29 -05:00
let time = 0 ;
let startTime = 0 ;
let noteIndex = 0 ;
2022-10-31 08:17:42 -04:00
bot . music . skip = function ( ) {
2022-11-09 07:40:48 -05:00
if ( bot . music . loop === 2 ) {
bot . music . queue . push ( bot . music . queue . shift ( ) ) ;
bot . music . play ( bot . music . queue [ 0 ] ) ;
} else {
bot . music . queue . shift ( ) ;
}
2022-10-31 08:17:42 -04:00
resetTime ( ) ;
} ;
2022-10-30 08:17:20 -04:00
const interval = setInterval ( async ( ) => {
2022-08-14 05:51:45 -04:00
try {
2022-10-30 08:17:20 -04:00
if ( ! bot . music . queue . length ) return ;
bot . music . song = bot . music . queue [ 0 ] ;
2022-08-14 05:51:45 -04:00
time = Date . now ( ) - startTime ;
while ( bot . music . song . notes [ noteIndex ] ? . time <= time ) {
const note = bot . music . song . notes [ noteIndex ] ;
const floatingPitch = 2 * * ( ( note . pitch - 12 ) / 12.0 ) ;
bot . core . run ( ` minecraft:execute as @a[tag=!nomusic] at @s run playsound ${ soundNames [ note . instrument ] } record @s ~ ~ ~ ${ note . volume } ${ floatingPitch } ` ) ;
noteIndex ++ ;
bot . core . run ( 'minecraft:title @a[tag=!nomusic] actionbar ' + JSON . stringify ( toComponent ( ) ) ) ;
if ( noteIndex >= bot . music . song . notes . length ) {
2022-10-30 08:17:20 -04:00
if ( bot . music . loop === 1 ) {
2022-08-14 05:51:45 -04:00
resetTime ( ) ;
return ;
}
2022-10-30 08:17:20 -04:00
if ( bot . music . loop === 2 ) {
resetTime ( ) ;
2022-10-31 08:17:42 -04:00
bot . music . queue . push ( bot . music . queue . shift ( ) ) ;
bot . music . play ( bot . music . queue [ 0 ] ) ;
2022-10-30 08:17:20 -04:00
return ;
}
bot . music . queue . shift ( ) ;
2022-11-01 07:10:45 -04:00
if ( ! bot . music . queue [ 0 ] ) {
2022-11-07 06:30:37 -05:00
bot . tellraw ( '@a' , { text : 'Finished playing every song in the queue' } ) ;
2022-11-01 07:10:45 -04:00
bot . music . stop ( ) ;
return ;
}
2022-10-31 05:46:23 -04:00
if ( bot . music . queue [ 0 ] . notes . length > 0 ) {
if ( bot . music . queue . length !== 1 ) resetTime ( ) ;
2022-10-30 08:17:20 -04:00
bot . music . play ( bot . music . queue [ 0 ] ) ;
return ;
}
2022-08-14 05:51:45 -04:00
}
}
2022-11-16 21:07:29 -05:00
} catch ( e ) { }
} , 50 ) ;
2022-08-14 05:51:45 -04:00
2022-11-16 21:07:29 -05:00
bot . once ( 'end' , ( ) => {
2022-08-29 06:31:43 -04:00
clearInterval ( interval ) ;
} ) ;
2022-08-14 05:51:45 -04:00
bot . music . load = function ( buffer , fallbackName = '[unknown]' ) {
// TODO: NBS Support
const midi = new Midi ( buffer ) ;
const song = convertMidi ( midi ) ;
if ( song . name === '' ) song . name = fallbackName ;
return song ;
} ;
bot . music . play = function ( song ) {
loop = song . loop ;
2022-10-30 08:17:20 -04:00
if ( bot . music . queue . length === 1 ) resetTime ( ) ;
2022-08-14 05:51:45 -04:00
} ;
bot . music . stop = function ( ) {
bot . music . song = null ;
2022-10-30 08:17:20 -04:00
bot . music . loop = 0 ;
bot . music . queue = [ ] ;
2022-08-14 05:51:45 -04:00
resetTime ( ) ;
} ;
function resetTime ( ) {
time = 0 ;
startTime = Date . now ( ) ;
noteIndex = 0 ;
}
function formatTime ( time ) {
const seconds = Math . floor ( time / 1000 ) ;
return ` ${ Math . floor ( seconds / 60 ) } : ${ ( seconds % 60 ) . toString ( ) . padStart ( 2 , '0' ) } ` ;
}
function toComponent ( ) {
const component = [
'§8[§eChomeNS Bot§8] ' ,
{ text : 'Now Playing' , color : 'gold' } ,
' §8| ' ,
{ text : bot . music . song . name , color : 'green' } ,
' §8| ' ,
{ text : formatTime ( time ) , color : 'gray' } ,
' §8/ ' ,
{ text : formatTime ( bot . music . song . length ) , color : 'gray' } ,
' §8| ' ,
{ text : noteIndex , color : 'gray' } ,
'§8 / ' ,
{ text : bot . music . song . notes . length , color : 'gray' } ,
] ;
2022-10-30 08:17:20 -04:00
if ( bot . music . loop === 1 ) {
component . push ( ' §8| ' ) ;
component . push ( '§aLooping Current' ) ;
}
if ( bot . music . loop === 2 ) {
2022-08-14 05:51:45 -04:00
component . push ( ' §8| ' ) ;
2022-10-30 08:17:20 -04:00
component . push ( '§aLooping All' ) ;
2022-08-14 05:51:45 -04:00
}
return component ;
}
}
module . exports = { inject } ;