2022-12-30 03:40:17 -05:00
const path = require ( 'path' )
2022-11-27 02:35:28 -05:00
const { Midi } = require ( '@tonejs/midi' )
const { convertMidi } = require ( '../util/midi_converter' )
2022-12-30 03:40:17 -05:00
const convertNBS = require ( '../util/nbs_converter' )
const parseTXTSong = require ( '../util/txt_song_parser' )
2022-08-14 05:51:45 -04:00
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' ,
2022-11-27 02:35:28 -05:00
pling : 'minecraft:block.note_block.pling'
}
2022-08-14 05:51:45 -04:00
2022-11-27 02:35:28 -05:00
function inject ( bot ) {
bot . music = function ( ) { }
bot . music . song = null
bot . music . loop = 0
bot . music . queue = [ ]
let time = 0
let startTime = 0
let noteIndex = 0
bot . music . skip = function ( ) {
2022-11-09 07:40:48 -05:00
if ( bot . music . loop === 2 ) {
2022-11-27 02:35:28 -05:00
bot . music . queue . push ( bot . music . queue . shift ( ) )
bot . music . play ( bot . music . queue [ 0 ] )
2022-11-09 07:40:48 -05:00
} else {
2022-11-27 02:35:28 -05:00
bot . music . queue . shift ( )
2022-11-09 07:40:48 -05:00
}
2022-11-27 02:35:28 -05:00
resetTime ( )
}
2022-10-31 08:17:42 -04:00
2022-10-30 08:17:20 -04:00
const interval = setInterval ( async ( ) => {
2022-12-29 00:05:11 -05:00
if ( ! bot . music . queue . length ) return
bot . music . song = bot . music . queue [ 0 ]
time = Date . now ( ) - startTime
bot . core . run ( 'minecraft:title @a[tag=!nomusic] actionbar ' + JSON . stringify ( toComponent ( ) ) )
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 ++
if ( noteIndex >= bot . music . song . notes . length ) {
if ( bot . music . loop === 1 ) {
resetTime ( )
return
}
if ( bot . music . loop === 2 ) {
resetTime ( )
bot . music . queue . push ( bot . music . queue . shift ( ) )
bot . music . play ( bot . music . queue [ 0 ] )
return
}
bot . music . queue . shift ( )
if ( ! bot . music . queue [ 0 ] ) {
bot . tellraw ( '@a' , { text : 'Finished playing every song in the queue' } )
bot . music . stop ( )
return
}
if ( bot . music . queue [ 0 ] . notes . length > 0 ) {
if ( bot . music . queue . length !== 1 ) resetTime ( )
bot . music . play ( bot . music . queue [ 0 ] )
return
2022-08-14 05:51:45 -04:00
}
}
2022-12-29 00:05:11 -05:00
}
2022-11-27 02:35:28 -05:00
} , 50 )
2022-08-14 05:51:45 -04:00
2022-11-30 04:45:20 -05:00
bot . on ( 'end' , ( ) => {
2022-11-27 02:35:28 -05:00
clearInterval ( interval )
} )
2022-08-29 06:31:43 -04:00
2022-12-30 03:40:17 -05:00
bot . music . load = async function ( buffer , fallbackName = '[unknown]' ) {
let song
switch ( path . extname ( fallbackName ) ) {
case '.nbs' :
song = convertNBS ( buffer )
2022-12-31 03:49:56 -05:00
if ( song . name === '' ) song . name = fallbackName
2022-12-30 03:40:17 -05:00
break
case '.txt' :
song = parseTXTSong ( buffer . toString ( ) )
2022-12-31 03:49:56 -05:00
song . name = fallbackName
2022-12-30 03:40:17 -05:00
break
default :
// eslint-disable-next-line no-case-declarations
const midi = new Midi ( buffer )
song = convertMidi ( midi )
if ( song . name === '' ) song . name = fallbackName
break
}
2022-11-27 02:35:28 -05:00
return song
}
2022-08-14 05:51:45 -04:00
2022-11-27 02:35:28 -05:00
bot . music . play = function ( ) {
if ( bot . music . queue . length === 1 ) resetTime ( )
}
2022-08-14 05:51:45 -04:00
2022-11-27 02:35:28 -05:00
bot . music . stop = function ( ) {
bot . music . song = null
bot . music . loop = 0
bot . music . queue = [ ]
resetTime ( )
}
2022-08-14 05:51:45 -04:00
2022-11-27 02:35:28 -05:00
function resetTime ( ) {
time = 0
startTime = Date . now ( )
noteIndex = 0
2022-08-14 05:51:45 -04:00
}
2022-11-27 02:35:28 -05:00
function formatTime ( time ) {
const seconds = Math . floor ( time / 1000 )
2022-08-14 05:51:45 -04:00
2022-11-27 02:35:28 -05:00
return ` ${ Math . floor ( seconds / 60 ) } : ${ ( seconds % 60 ) . toString ( ) . padStart ( 2 , '0' ) } `
2022-08-14 05:51:45 -04:00
}
2022-11-27 02:35:28 -05:00
function toComponent ( ) {
2022-08-14 05:51:45 -04:00
const component = [
2022-12-08 06:20:10 -05:00
// { text: '[', color: 'dark_gray' },
// { text: 'ChomeNS Bot', color: 'yellow' },
// { text: '] ', color: 'dark_gray' },
2022-11-27 02:35:28 -05:00
{ text : 'Now Playing' , color : 'gold' } ,
{ text : ' | ' , color : 'dark_gray' } ,
{ text : bot . music . song . name , color : 'green' } ,
{ text : ' | ' , color : 'dark_gray' } ,
{ text : formatTime ( time ) , color : 'gray' } ,
{ text : ' / ' , color : 'dark_gray' } ,
{ text : formatTime ( bot . music . song . length ) , color : 'gray' } ,
{ text : ' | ' , color : 'dark_gray' } ,
{ text : noteIndex , color : 'gray' } ,
{ text : ' / ' , color : 'dark_gray' } ,
{ text : bot . music . song . notes . length , color : 'gray' }
]
2022-08-14 05:51:45 -04:00
2022-10-30 08:17:20 -04:00
if ( bot . music . loop === 1 ) {
2022-11-27 02:35:28 -05:00
component . push ( { text : ' | ' , color : 'dark_gray' } )
component . push ( { text : 'Looping Current' , color : 'green' } )
2022-10-30 08:17:20 -04:00
}
if ( bot . music . loop === 2 ) {
2022-11-27 02:35:28 -05:00
component . push ( { text : ' | ' , color : 'dark_gray' } )
component . push ( { text : 'Looping All' , color : 'green' } )
2022-08-14 05:51:45 -04:00
}
2022-11-27 02:35:28 -05:00
return component
2022-08-14 05:51:45 -04:00
}
}
2022-11-27 02:35:28 -05:00
module . exports = { inject }