SMParser.java 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. package SMParser;
  2. import java.io.File;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.OutputStream;
  7. import java.nio.charset.Charset;
  8. import java.nio.file.Files;
  9. import java.nio.file.Paths;
  10. import java.util.ArrayList;
  11. import java.util.Arrays;
  12. import javax.json.Json;
  13. import javax.json.JsonArrayBuilder;
  14. import javax.json.JsonObject;
  15. import javax.json.JsonObjectBuilder;
  16. import javax.json.JsonWriter;
  17. public class SMParser {
  18. private static String[] metaDataHeaders = {"offset:","title:","artist:", "displaybpm:", "music","samplestart:", "banner:", "background:", "subtitle:"};
  19. private String[] metadata;
  20. private ArrayList<JsonObjectBuilder> arrays;
  21. private double lastNoteTime;
  22. public SMParser(){
  23. }
  24. public void parseSmFile(File inputfile){
  25. try {
  26. String file = readFile(inputfile.getAbsolutePath(), Charset.defaultCharset());
  27. String[] mainsplit = file.split("\\#");
  28. arrays = new ArrayList<JsonObjectBuilder>();
  29. metadata = new String[metaDataHeaders.length];
  30. for(String s:mainsplit){
  31. //searching for the metadata
  32. int i = 0;
  33. for(String header:metaDataHeaders){
  34. if(s.toLowerCase().contains(header) && metadata[i] == null){
  35. metadata[i] = getValue(s).replace(';', ' ').trim();
  36. }
  37. i++;
  38. }
  39. //parsing the notes
  40. if(s.contains("NOTES")){
  41. String[] notesplit = s.split("\n");
  42. if(notesplit[1].contains("-single:")){ //valid note (single player mode)
  43. String difficulty = notesplit[3].replace(":", "").trim();
  44. for(int k = 0; k < 6; k++){ //remove first 6 lines
  45. s = s.substring(s.indexOf('\n')+1);
  46. }
  47. s= s.replaceAll("//.*", ""); // remove some more bs
  48. s = s.replaceAll("\\;", "");
  49. notesplit = s.split("\\,"); //split everything in arrays which contains "beats" for 1 second
  50. double secondscounter = Double.parseDouble(metadata[0])*-1;
  51. int extraButtonTime = (notesplit.length / difficultyToMaxButtons(difficulty))*1000;
  52. int maxButtons = 1;
  53. JsonArrayBuilder objectsArrayBuilder = Json.createArrayBuilder();
  54. JsonArrayBuilder buttonsArrayBuilder = Json.createArrayBuilder();
  55. buttonsArrayBuilder.add(Json.createObjectBuilder().add("time", 0).add("button", 1).add("color", 0));
  56. for(String notespersecond:notesplit){
  57. notespersecond = notespersecond.trim();
  58. String[] notes = notespersecond.split("\n");
  59. double precision = (1.0/notes.length)*1000;
  60. double time = secondscounter*1000;
  61. for(String note:notes){
  62. int direction = noteToDirection(note.trim());
  63. if(direction != -1){
  64. if(time - lastNoteTime > difficultyToButtonsTiming(difficulty)){
  65. JsonObjectBuilder object = Json.createObjectBuilder();
  66. object.add("time", time);
  67. object.add("direction", direction);
  68. object.add("button", (int)(Math.random()*maxButtons+1));
  69. objectsArrayBuilder.add(object.build());
  70. lastNoteTime = time;
  71. }
  72. }
  73. if(extraButtonTime*maxButtons < time && maxButtons < difficultyToMaxButtons(difficulty)){ //add a new/extra button
  74. buttonsArrayBuilder.add(Json.createObjectBuilder().add("time", time).add("button", maxButtons+1).add("color", maxButtons));
  75. maxButtons++;
  76. }
  77. time += precision;
  78. }
  79. secondscounter++;
  80. }
  81. arrays.add(Json.createObjectBuilder());
  82. arrays.get(arrays.size()-1).add("difficulty", difficulty);
  83. arrays.get(arrays.size()-1).add("objects", objectsArrayBuilder);
  84. arrays.get(arrays.size()-1).add("buttons", buttonsArrayBuilder);
  85. }
  86. };
  87. }
  88. for(int i = 0; i < metadata.length; i++){
  89. if(metadata[i] == null){
  90. metadata[i] = "0";
  91. }
  92. }
  93. writeJsonFile(inputfile);
  94. } catch (IOException e) {
  95. e.printStackTrace();
  96. }
  97. }
  98. private void writeJsonFile(File inputfile){
  99. JsonObjectBuilder jsonfilebuilder = Json.createObjectBuilder();
  100. JsonArrayBuilder dataArrayBuilder = Json.createArrayBuilder();
  101. double bpm = 0;
  102. double samples = 0;
  103. try{
  104. Double.parseDouble(metadata[3]);
  105. }catch(java.lang.NumberFormatException e){
  106. }
  107. try{
  108. Double.parseDouble(metadata[5]);
  109. }catch(java.lang.NumberFormatException e){
  110. }
  111. jsonfilebuilder.add("meta", Json.createObjectBuilder().add("title", metadata[1]).add("subtitle", metadata[8]).add("author", metadata[2]).add("BPM", bpm).add("sample_start", samples));
  112. jsonfilebuilder.add("file", Json.createObjectBuilder().add("audio", metadata[4]).add("background", metadata[7]).add("banner", metadata[6]));
  113. for(JsonObjectBuilder ar:arrays){
  114. dataArrayBuilder.add(ar.build());
  115. }
  116. jsonfilebuilder.add("data", dataArrayBuilder);
  117. try {
  118. String name = metadata[1].trim().replaceAll("[^a-zA-Z0-9.-]", "_")+metadata[8].trim().replaceAll("[^a-zA-Z0-9.-]", "_");;
  119. String dirname = "scannedsongs/"+name+(int)(Math.random()*10);
  120. File f = new File(dirname);
  121. f.mkdir();
  122. try {
  123. Files.copy(new File(inputfile.getParent() + "/" + metadata[4]).toPath(), new File(dirname +"/"+metadata[4]).toPath());
  124. } catch (IOException e) {
  125. System.out.println("Music file not found");
  126. f.delete();
  127. return;
  128. }
  129. try {
  130. Files.copy(new File(inputfile.getParent() + "/" + metadata[6]).toPath(), new File(dirname +"/"+metadata[6]).toPath());
  131. } catch (IOException e) {
  132. }
  133. try {
  134. Files.copy(new File(inputfile.getParent() + "/" + metadata[7]).toPath(), new File(dirname +"/"+metadata[7]).toPath());
  135. } catch (IOException e) {
  136. }
  137. JsonObject file = jsonfilebuilder.build();
  138. OutputStream os;
  139. os = new FileOutputStream(dirname+"/"+name+".csf");
  140. JsonWriter jsonWriter = Json.createWriter(os);
  141. jsonWriter.writeObject(file);
  142. jsonWriter.close();
  143. os.close();
  144. } catch (IOException e) {
  145. e.printStackTrace();
  146. }
  147. }
  148. private int difficultyToButtonsTiming(String d){
  149. if(d.toLowerCase().equals("beginner")){
  150. return 500;
  151. }else if(d.equals("easy")){
  152. return 250;
  153. }else if(d.equals("medium")){
  154. return 200;
  155. }else if(d.equals("hard")){
  156. return 150;
  157. }
  158. return 150;
  159. }
  160. private int difficultyToMaxButtons(String d){
  161. if(d.toLowerCase().equals("beginner")){
  162. return 2;
  163. }else if(d.equals("easy")){
  164. return 3;
  165. }else if(d.equals("medium")){
  166. return 4;
  167. }else if(d.equals("hard")){
  168. return 6;
  169. }
  170. return 6;
  171. }
  172. private String getValue(String s){
  173. String[] split = s.split("\\:");
  174. if(split.length == 2 && split[1] != null){
  175. return split[1];
  176. }
  177. return "";
  178. }
  179. private static String readFile(String path, Charset encoding) throws IOException
  180. {
  181. byte[] encoded = Files.readAllBytes(Paths.get(path));
  182. return new String(encoded, encoding);
  183. }
  184. private int noteToDirection(String note){
  185. if(note.length() == 4){
  186. if(note.charAt(0) == '1'){
  187. if(note.charAt(1) == '1'){ //down left
  188. return 7;
  189. }else if(note.charAt(2) == '1'){ //up left
  190. return 1;
  191. }
  192. return 0; // left
  193. }else if(note.charAt(3) == '1'){
  194. if(note.charAt(1) == '1'){ //down right
  195. return 5;
  196. }else if(note.charAt(2) == '1'){ //up right
  197. return 3;
  198. }
  199. return 4;// right
  200. }else if(note.charAt(1) == '1'){ //down
  201. return 6;
  202. }else if(note.charAt(2) == '1'){ // up
  203. return 2;
  204. }
  205. return -1;
  206. }
  207. return -1;
  208. }
  209. }