const fs = require('fs') const convertMidi = require('../util/convert-midi.js') const convertNBS = require('../util/nbs-converter.js') function inject (bot) { bot.music = { playing: false, queue: [], nowPlaying: undefined, looping: false, _interval: null, _playNextSong, skip, stop, play } bot.music.nowPlaying = { name: '', tick: { current: null, total: null // npt: null } } setInterval(() => { if (!bot.music.playing) return const msg = [ { text: 'Now Playing', ...bot.styles.primary }, { text: ' | ', color: 'dark_gray' }, { text: bot.music.nowPlaying.name, ...bot.styles.secondary, bold: true }, { text: ' | ', color: 'dark_gray' }, format(bot.music.nowPlaying.time), { text: ' / ', color: 'gray' }, format(bot.music.nowPlaying.length) // { text: ' (', color: 'dark_gray' }, // bot.music.nowPlaying.note.npt + ' npt', // { text: ')', color: 'dark_gray' } ] if (bot.music.looping) { msg.push({ text: ' | ', color: 'dark_gray' }) msg.push({ text: 'Looping', ...bot.styles.secondary }) } bot.core.run('title @a actionbar ' + JSON.stringify(msg)) }, 500) function _playNextSong () { const song = bot.music.queue.shift() if (song != null) play(song) } function skip () { clearInterval(bot.music._interval) bot.music.playing = false if (bot.music.queue.length !== 0) _playNextSong() } function stop () { bot.music.queue = [] clearInterval(bot.music._interval) bot.music.playing = false } function play (filepath) { // set stuff up let song try { if (filepath.endsWith('.nbs')) { song = convertNBS(fs.readFileSync(filepath), filepath) } else song = convertMidi(filepath) song.time = 0 bot.music.nowPlaying = song } catch (err) { bot.tellraw({ text: err.message, ...bot.styles.error }, '@a') return } // play the music lol bot.tellraw([ { text: 'Now playing ', ...bot.styles.primary }, { text: song.name, ...bot.styles.secondary } ], '@a') bot.music.playing = true bot.music.looping = song.loop let startTime = (new Date()).valueOf() let notes = [ ...song.notes ] bot.music._interval = setInterval(async () => { const time = (new Date()).valueOf() - startTime song.time = time notes.forEach(async (note, i) => { if (time >= note.time) { const floatingpitch = Math.pow(2, (note.pitch - 12) / 12.0) bot.core.run(`minecraft:execute at @a run playsound block.note_block.${note.instrument} record @p ~ ~ ~ ${note.volume} ${floatingpitch}`) notes.splice(i, 1) } }) song.time++ if (time > song.length) { if (bot.music.looping) { notes = [ ...song.notes ] startTime = (new Date()).valueOf() + song.loopPosition return } clearInterval(bot.music._interval) bot.music.playing = false bot.tellraw([ { text: 'Finished playing ', color: 'green' }, { text: bot.music.nowPlaying.name, color: 'dark_green' } ], '@a') if (bot.music.queue.length !== 0) _playNextSong() } }, 50) } } function format (ms) { const s = ms / 1000 const seconds = Math.floor(s / 60).toString() const minutes = Math.floor(s % 60).toString() return seconds + ':' + (minutes.length <= 1 ? '0' : '') + minutes } module.exports = inject