Note block player
This commit is contained in:
parent
cbafb2ba91
commit
488895ea53
131
Plugins/Mineplex.Core/src/mineplex/core/noteblock/NBSReader.java
Normal file
131
Plugins/Mineplex.Core/src/mineplex/core/noteblock/NBSReader.java
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
package mineplex.core.noteblock;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.EOFException;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about the NBS Format was taken from
|
||||||
|
* http://www.stuffbydavid.com/mcnbs/format
|
||||||
|
*/
|
||||||
|
public class NBSReader
|
||||||
|
{
|
||||||
|
public static NoteSong loadSong(String fileName) throws FileNotFoundException
|
||||||
|
{
|
||||||
|
return loadSong(new DataInputStream(new FileInputStream(new File(fileName))));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NoteSong loadSong(DataInputStream stream)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Header Information
|
||||||
|
short length = readShort(stream);
|
||||||
|
short height = readShort(stream);
|
||||||
|
String name = readString(stream);
|
||||||
|
String author = readString(stream);
|
||||||
|
String originalAuthor = readString(stream);
|
||||||
|
String description = readString(stream);
|
||||||
|
short tempo = readShort(stream); // Tempo multiplied by 1000
|
||||||
|
boolean autosave = stream.readBoolean();
|
||||||
|
byte autosaveDuration = stream.readByte();
|
||||||
|
byte timeSignature = stream.readByte();
|
||||||
|
int minutesSpent = readInt(stream);
|
||||||
|
int leftClicks = readInt(stream);
|
||||||
|
int rightClicks = readInt(stream);
|
||||||
|
int blocksAdded = readInt(stream);
|
||||||
|
int blocksRemoved = readInt(stream);
|
||||||
|
String midiFileName = readString(stream);
|
||||||
|
|
||||||
|
HashMap<Integer, NoteLayer> layerMap = new HashMap<Integer, NoteLayer>();
|
||||||
|
|
||||||
|
// Note Block Information
|
||||||
|
int tick = -1;
|
||||||
|
int jumps = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
jumps = readShort(stream);
|
||||||
|
if (jumps == 0)
|
||||||
|
break;
|
||||||
|
tick += jumps;
|
||||||
|
int layer = -1;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
jumps = readShort(stream);
|
||||||
|
if (jumps == 0)
|
||||||
|
break;
|
||||||
|
layer += jumps;
|
||||||
|
byte instrument = stream.readByte();
|
||||||
|
byte key = stream.readByte();
|
||||||
|
|
||||||
|
Note note = new Note(instrument, key);
|
||||||
|
NoteLayer noteLayer = layerMap.get(layer);
|
||||||
|
if (noteLayer == null)
|
||||||
|
{
|
||||||
|
noteLayer = new NoteLayer();
|
||||||
|
layerMap.put(layer, noteLayer);
|
||||||
|
}
|
||||||
|
noteLayer.setNote(tick, note);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layer Information
|
||||||
|
for (int i = 0; i < height; i++)
|
||||||
|
{
|
||||||
|
NoteLayer layer = layerMap.get(i);
|
||||||
|
if (layer != null)
|
||||||
|
{
|
||||||
|
layer.setName(readString(stream));
|
||||||
|
layer.setVolume(stream.readByte());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("[NBSReader] Successfully loaded song " + name + "");
|
||||||
|
System.out.println("Tempo: " + tempo);
|
||||||
|
return new NoteSong(length, height, name, tempo, timeSignature, layerMap);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int readInt(DataInputStream stream) throws IOException
|
||||||
|
{
|
||||||
|
// For some reason the bytes are in reverse order from stream.readInt()
|
||||||
|
int ch1 = stream.read();
|
||||||
|
int ch2 = stream.read();
|
||||||
|
int ch3 = stream.read();
|
||||||
|
int ch4 = stream.read();
|
||||||
|
if ((ch1 | ch2 | ch3 | ch4) < 0)
|
||||||
|
throw new EOFException();
|
||||||
|
return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + ch1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static short readShort(DataInputStream stream) throws IOException
|
||||||
|
{
|
||||||
|
// For some reason the bytes are in reverse order from stream.readShort()
|
||||||
|
int ch1 = stream.read();
|
||||||
|
int ch2 = stream.read();
|
||||||
|
if ((ch1 | ch2) < 0)
|
||||||
|
throw new EOFException();
|
||||||
|
return (short)((ch2 << 8) + ch1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String readString(DataInputStream stream) throws IOException
|
||||||
|
{
|
||||||
|
int length = readInt(stream);
|
||||||
|
char[] string = new char[length];
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
string[i] = (char) stream.readByte();
|
||||||
|
}
|
||||||
|
return new String(string);
|
||||||
|
}
|
||||||
|
}
|
26
Plugins/Mineplex.Core/src/mineplex/core/noteblock/Note.java
Normal file
26
Plugins/Mineplex.Core/src/mineplex/core/noteblock/Note.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package mineplex.core.noteblock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a single note to be played
|
||||||
|
*/
|
||||||
|
public class Note
|
||||||
|
{
|
||||||
|
private byte _instrument;
|
||||||
|
private byte _note;
|
||||||
|
|
||||||
|
public Note(byte instrument, byte note)
|
||||||
|
{
|
||||||
|
_instrument = instrument;
|
||||||
|
_note = note;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getInstrument()
|
||||||
|
{
|
||||||
|
return _instrument;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getNote()
|
||||||
|
{
|
||||||
|
return _note;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package mineplex.core.noteblock;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a layer of notes in Note Block Studio
|
||||||
|
*/
|
||||||
|
public class NoteLayer
|
||||||
|
{
|
||||||
|
private HashMap<Integer, Note> _noteMap; // Notes indexed by ticks
|
||||||
|
private int _volume; // Volume as a percentage 1-100
|
||||||
|
private String _name;
|
||||||
|
|
||||||
|
public NoteLayer()
|
||||||
|
{
|
||||||
|
_noteMap = new HashMap<Integer, Note>();
|
||||||
|
_volume = 100;
|
||||||
|
_name = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVolume()
|
||||||
|
{
|
||||||
|
return _volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVolume(int volume)
|
||||||
|
{
|
||||||
|
_volume = volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name)
|
||||||
|
{
|
||||||
|
_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNote(int ticks, Note note)
|
||||||
|
{
|
||||||
|
_noteMap.put(ticks, note);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Note getNote(int ticks)
|
||||||
|
{
|
||||||
|
return _noteMap.get(ticks);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
package mineplex.core.noteblock;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import mineplex.core.common.util.UtilServer;
|
||||||
|
|
||||||
|
public class NotePlayer
|
||||||
|
{
|
||||||
|
private final NoteSong _song;
|
||||||
|
private final long _sleepMs;
|
||||||
|
private volatile boolean _loop;
|
||||||
|
private volatile int _tick;
|
||||||
|
private volatile boolean _finished;
|
||||||
|
|
||||||
|
public NotePlayer(NoteSong song, boolean loop)
|
||||||
|
{
|
||||||
|
_song = song;
|
||||||
|
_sleepMs = (long) (1000 / (song.getTempo() / 100D));
|
||||||
|
_loop = loop;
|
||||||
|
_tick = 0;
|
||||||
|
_finished = false;
|
||||||
|
|
||||||
|
startThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startThread()
|
||||||
|
{
|
||||||
|
Thread thread = new Thread(new Runnable()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
while (!_finished)
|
||||||
|
{
|
||||||
|
_tick++;
|
||||||
|
if (_tick > _song.getLength())
|
||||||
|
{
|
||||||
|
if (_loop)
|
||||||
|
{
|
||||||
|
_tick = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_finished = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
playTick(_tick);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep(_sleepMs);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void playTick(int tick)
|
||||||
|
{
|
||||||
|
for (NoteLayer layer : _song.getLayers())
|
||||||
|
{
|
||||||
|
Note note = layer.getNote(tick);
|
||||||
|
if (note != null)
|
||||||
|
{
|
||||||
|
float volume = layer.getVolume() / 100F;
|
||||||
|
for (Player player : UtilServer.getPlayers())
|
||||||
|
{
|
||||||
|
player.playSound(player.getEyeLocation(), UtilNote.getInstrumentSound(note.getInstrument()), volume, (float) UtilNote.getPitch(note.getNote() - 33));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancel()
|
||||||
|
{
|
||||||
|
_finished = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package mineplex.core.noteblock;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class NoteSong
|
||||||
|
{
|
||||||
|
// Song Data
|
||||||
|
private short _length;
|
||||||
|
private short _height;
|
||||||
|
private String _name;
|
||||||
|
private short _tempo;
|
||||||
|
private byte _timeSignature;
|
||||||
|
|
||||||
|
// Layer Data
|
||||||
|
private HashMap<Integer, NoteLayer> _layerMap;
|
||||||
|
|
||||||
|
public NoteSong(short length, short height, String name, short tempo, byte timeSignature, HashMap<Integer, NoteLayer> layerMap)
|
||||||
|
{
|
||||||
|
_length = length;
|
||||||
|
_height = height;
|
||||||
|
_name = name;
|
||||||
|
_tempo = tempo;
|
||||||
|
_timeSignature = timeSignature;
|
||||||
|
_layerMap = layerMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getLength()
|
||||||
|
{
|
||||||
|
return _length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getHeight()
|
||||||
|
{
|
||||||
|
return _height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getTempo()
|
||||||
|
{
|
||||||
|
return _tempo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getTimeSignature()
|
||||||
|
{
|
||||||
|
return _timeSignature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<NoteLayer> getLayers()
|
||||||
|
{
|
||||||
|
return _layerMap.values();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package mineplex.core.noteblock;
|
||||||
|
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See http://minecraft.gamepedia.com/Note_Block for information about pitches
|
||||||
|
*/
|
||||||
|
public class UtilNote
|
||||||
|
{
|
||||||
|
private static final double[] PITCH = { 0.5, 0.53, 0.56, 0.6, 0.63, 0.67, 0.7, 0.76, 0.8, 0.84, 0.9, 0.94, 1.0,
|
||||||
|
1.06, 1.12, 1.18, 1.26, 1.34, 1.42, 1.5, 1.6, 1.68, 1.78, 1.88, 2.0 };
|
||||||
|
|
||||||
|
public static Sound getInstrumentSound(byte instrument)
|
||||||
|
{
|
||||||
|
switch (instrument)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return Sound.NOTE_PIANO;
|
||||||
|
case 1:
|
||||||
|
return Sound.NOTE_BASS_GUITAR;
|
||||||
|
case 2:
|
||||||
|
return Sound.NOTE_BASS_DRUM;
|
||||||
|
case 3:
|
||||||
|
return Sound.NOTE_SNARE_DRUM;
|
||||||
|
case 4:
|
||||||
|
return Sound.NOTE_STICKS;
|
||||||
|
default:
|
||||||
|
return Sound.NOTE_PIANO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double getPitch(int note)
|
||||||
|
{
|
||||||
|
if (note >= 0 && note < PITCH.length)
|
||||||
|
{
|
||||||
|
return PITCH[note];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package mineplex.hub;
|
package mineplex.hub;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
@ -34,6 +35,9 @@ import mineplex.core.hologram.HologramManager;
|
|||||||
import mineplex.core.inventory.InventoryManager;
|
import mineplex.core.inventory.InventoryManager;
|
||||||
import mineplex.core.message.PrivateMessageEvent;
|
import mineplex.core.message.PrivateMessageEvent;
|
||||||
import mineplex.core.mount.MountManager;
|
import mineplex.core.mount.MountManager;
|
||||||
|
import mineplex.core.noteblock.NBSReader;
|
||||||
|
import mineplex.core.noteblock.NotePlayer;
|
||||||
|
import mineplex.core.noteblock.NoteSong;
|
||||||
import mineplex.core.notifier.NotificationManager;
|
import mineplex.core.notifier.NotificationManager;
|
||||||
import mineplex.core.npc.NpcManager;
|
import mineplex.core.npc.NpcManager;
|
||||||
import mineplex.core.packethandler.PacketHandler;
|
import mineplex.core.packethandler.PacketHandler;
|
||||||
@ -219,7 +223,6 @@ public class HubManager extends MiniClientPlugin<HubClient>
|
|||||||
|
|
||||||
((CraftWorld)Bukkit.getWorlds().get(0)).getHandle().pvpMode = true;
|
((CraftWorld)Bukkit.getWorlds().get(0)).getHandle().pvpMode = true;
|
||||||
|
|
||||||
|
|
||||||
new BonusManager(plugin, clientManager, serverStatusManager, donationManager, pollManager , npcManager, hologramManager, statsManager, _inventoryManager, petManager, giveawayManager);
|
new BonusManager(plugin, clientManager, serverStatusManager, donationManager, pollManager , npcManager, hologramManager, statsManager, _inventoryManager, petManager, giveawayManager);
|
||||||
|
|
||||||
// _halloweenManager = new HalloweenSpookinessManager(this);
|
// _halloweenManager = new HalloweenSpookinessManager(this);
|
||||||
@ -229,6 +232,20 @@ public class HubManager extends MiniClientPlugin<HubClient>
|
|||||||
|
|
||||||
_serverName = getPlugin().getConfig().getString("serverstatus.name");
|
_serverName = getPlugin().getConfig().getString("serverstatus.name");
|
||||||
_serverName = _serverName.substring(0, Math.min(16, _serverName.length()));
|
_serverName = _serverName.substring(0, Math.min(16, _serverName.length()));
|
||||||
|
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// NoteSong song = NBSReader.loadSong("songs/LetItGo.nbs");
|
||||||
|
// if (song != null)
|
||||||
|
// {
|
||||||
|
// NotePlayer player = new NotePlayer(song, true);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (FileNotFoundException e)
|
||||||
|
// {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// System.out.println("FAILED TO LOAD SONG!!");
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user