package com.xxmicloxx.NoteBlockAPI; 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.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import com.xxmicloxx.NoteBlockAPI.utils.InstrumentUtils; /** * @deprecated {@link com.xxmicloxx.NoteBlockAPI.utils.NBSDecoder} */ @Deprecated public class NBSDecoder { /** * Parses a Song from a Note Block Studio project file (.nbs) * @see Song * @param songFile .nbs file * @return Song object representing a Note Block Studio project */ public static Song parse(File songFile) { try { return parse(new FileInputStream(songFile), songFile); } catch (FileNotFoundException e) { e.printStackTrace(); } return null; } /** * Parses a Song from an InputStream * @see Song * @param inputStream of a Note Block Studio project file (.nbs) * @return Song object from the InputStream */ public static Song parse(InputStream inputStream) { return parse(inputStream, null); // Source is unknown -> no file } /** * Parses a Song from an InputStream and a Note Block Studio project file (.nbs) * @see Song * @param inputStream of a .nbs file * @param songFile representing a .nbs file * @return Song object representing the given .nbs file */ private static Song parse(InputStream inputStream, File songFile) { HashMap<Integer, Layer> layerHashMap = new HashMap<Integer, Layer>(); byte biggestInstrumentIndex = -1; try { DataInputStream dataInputStream = new DataInputStream(inputStream); short length = readShort(dataInputStream); int firstcustominstrument = 10; //Backward compatibility - most of songs with old structure are from 1.12 int firstcustominstrumentdiff; int nbsversion = 0; if (length == 0) { nbsversion = dataInputStream.readByte(); firstcustominstrument = dataInputStream.readByte(); if (nbsversion >= 3) { length = readShort(dataInputStream); } } firstcustominstrumentdiff = InstrumentUtils.getCustomInstrumentFirstIndex() - firstcustominstrument; short songHeight = readShort(dataInputStream); String title = readString(dataInputStream); String author = readString(dataInputStream); readString(dataInputStream); // original author String description = readString(dataInputStream); float speed = readShort(dataInputStream) / 100f; dataInputStream.readBoolean(); // auto-save dataInputStream.readByte(); // auto-save duration dataInputStream.readByte(); // x/4ths, time signature readInt(dataInputStream); // minutes spent on project readInt(dataInputStream); // left clicks (why?) readInt(dataInputStream); // right clicks (why?) readInt(dataInputStream); // blocks added readInt(dataInputStream); // blocks removed readString(dataInputStream); // .mid/.schematic file name if (nbsversion >= 4) { dataInputStream.readByte(); // loop on/off dataInputStream.readByte(); // max loop count readShort(dataInputStream); // loop start tick } short tick = -1; while (true) { short jumpTicks = readShort(dataInputStream); // jumps till next tick //System.out.println("Jumps to next tick: " + jumpTicks); if (jumpTicks == 0) { break; } tick += jumpTicks; //System.out.println("Tick: " + tick); short layer = -1; while (true) { short jumpLayers = readShort(dataInputStream); // jumps till next layer if (jumpLayers == 0) { break; } layer += jumpLayers; //System.out.println("Layer: " + layer); byte instrument = dataInputStream.readByte(); if (firstcustominstrumentdiff > 0 && instrument >= firstcustominstrument){ instrument += firstcustominstrumentdiff; } byte key = dataInputStream.readByte(); if (nbsversion >= 4) { dataInputStream.readByte(); // note block velocity dataInputStream.readByte(); // note block panning readShort(dataInputStream); // note block pitch } setNote(layer, tick, instrument /* instrument */, key/* note */, layerHashMap); } } if (nbsversion > 0 && nbsversion < 3) { length = tick; } for (int i = 0; i < songHeight; i++) { Layer layer = layerHashMap.get(i); String name = readString(dataInputStream); if (nbsversion >= 4){ dataInputStream.readByte(); // layer lock } byte volume = dataInputStream.readByte(); if (nbsversion >= 2){ dataInputStream.readByte(); // layer stereo } if (layer != null) { layer.setName(name); layer.setVolume(volume); } } //count of custom instruments byte customAmnt = dataInputStream.readByte(); CustomInstrument[] customInstrumentsArray = new CustomInstrument[customAmnt]; for (int index = 0; index < customAmnt; index++) { customInstrumentsArray[index] = new CustomInstrument((byte) index, readString(dataInputStream), readString(dataInputStream)); dataInputStream.readByte();//pitch dataInputStream.readByte();//key } if (firstcustominstrumentdiff < 0){ ArrayList<CustomInstrument> customInstruments = CompatibilityUtils.getVersionCustomInstrumentsForSong(firstcustominstrument); customInstruments.addAll(Arrays.asList(customInstrumentsArray)); customInstrumentsArray = customInstruments.toArray(customInstrumentsArray); } else { firstcustominstrument += firstcustominstrumentdiff; } return new Song(speed, layerHashMap, songHeight, length, title, author, description, songFile, firstcustominstrument, customInstrumentsArray); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (EOFException e) { String file = ""; if (songFile != null) { file = songFile.getName(); } Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.RED + "Song is corrupted: " + file); } catch (IOException e) { e.printStackTrace(); } return null; } /** * Sets a note at a tick in a song * @param layerIndex * @param ticks * @param instrument * @param key * @param layerHashMap */ private static void setNote(int layerIndex, int ticks, byte instrument, byte key, HashMap<Integer, Layer> layerHashMap) { Layer layer = layerHashMap.get(layerIndex); if (layer == null) { layer = new Layer(); layerHashMap.put(layerIndex, layer); } layer.setNote(ticks, new Note(instrument, key)); } private static short readShort(DataInputStream dataInputStream) throws IOException { int byte1 = dataInputStream.readUnsignedByte(); int byte2 = dataInputStream.readUnsignedByte(); return (short) (byte1 + (byte2 << 8)); } private static int readInt(DataInputStream dataInputStream) throws IOException { int byte1 = dataInputStream.readUnsignedByte(); int byte2 = dataInputStream.readUnsignedByte(); int byte3 = dataInputStream.readUnsignedByte(); int byte4 = dataInputStream.readUnsignedByte(); return (byte1 + (byte2 << 8) + (byte3 << 16) + (byte4 << 24)); } private static String readString(DataInputStream dataInputStream) throws IOException { int length = readInt(dataInputStream); StringBuilder builder = new StringBuilder(length); for (; length > 0; --length) { char c = (char) dataInputStream.readByte(); if (c == (char) 0x0D) { c = ' '; } builder.append(c); } return builder.toString(); } }