/* eslint-disable max-len */ const {Midi} = require('@tonejs/midi'); const {convertMidi} = require('../util/midi_converter'); const sleep = require('sleep-promise'); 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; bot.music.loop = 0; bot.music.queue = []; time = 0; startTime = 0; noteIndex = 0; const interval = setInterval(async () => { try { if (!bot.music.queue.length) return; bot.music.song = bot.music.queue[0]; 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) { if (bot.music.loop === 1) { resetTime(); return; } if (bot.music.loop === 2) { resetTime(); await sleep(500); bot.music.play(bot.music.queue.shift()); return; } bot.music.queue.shift(); if (bot.music.queue[0]) { resetTime(); await sleep(500); bot.music.play(bot.music.queue[0]); return; } bot.core.run('minecraft:tellraw @a ' + JSON.stringify({text: 'Finished playing every song in the queue'})); bot.music.stop(); } } } catch (e) { return; } }, 20); bot.on('end', () => { clearInterval(interval); }); 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) { bot.music.queue.push(song); loop = song.loop; if (bot.music.queue.length === 1) resetTime(); }; bot.music.stop = function() { bot.music.song = null; bot.music.loop = 0; bot.music.queue = []; 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'}, ]; if (bot.music.loop === 1) { component.push(' §8| '); component.push('§aLooping Current'); } if (bot.music.loop === 2) { component.push(' §8| '); component.push('§aLooping All'); } return component; } } module.exports = {inject};