SMParser.java 7.4 KB

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