Compare commits

19 Commits

Author SHA1 Message Date
jancoow 554d4b74de Fixed bug checking objects 2015-07-09 23:09:43 +02:00
jancoow 2e6ea1d46a Fixed bug 2015-07-09 22:19:10 +02:00
kennyboy55 888a4f4df1 Don't add difficulty if to few elements 2015-07-09 22:17:29 +02:00
kennyboy55 03018a8e1d Added timing per difficulty 2015-07-09 20:57:27 +02:00
jancoow bda356ffe4 Not working version with time limitter 2015-07-07 10:53:47 +02:00
jancoow e1160c6062 Fixed bug in SMParser--> Files will be now parsed good 2015-06-11 11:23:06 +02:00
kennyboy55 96c584742c Fixed something 2015-06-05 12:43:12 +02:00
kennyboy55 cf1bb2167a More bugfixes 2015-06-05 12:22:42 +02:00
kennyboy55 8408e0fb26 Fixed bugs and things 2015-06-05 12:10:59 +02:00
jancoow 61ffc4995f Time * 1000 2015-06-05 10:54:00 +02:00
jancoow 3e7d737808 Updated readme 2015-05-29 17:20:54 +02:00
jancoow 2cf6b38eb2 "stable" release of SMparser, a lot of bugfixes 2015-05-29 17:16:49 +02:00
jancoow 45cc1f919c SMparser basics functional 2015-05-29 00:00:09 +02:00
kennyboy55 adf5c1d70f Updated format 2015-05-28 22:47:08 +02:00
jancoow 37bdcc16bb Begin of the SMparser 2015-05-28 21:13:15 +02:00
kennyboy55 a9759e476b Updated format 2015-05-28 21:00:43 +02:00
kennyboy55 161d630d36 Added .SM File to convert 2015-05-28 17:00:27 +02:00
kennyboy55 8fbaf00a5c Updated format 2015-05-28 17:00:18 +02:00
kennyboy55 35fb4aadea CSF/JSON File format added 2015-05-28 16:55:50 +02:00
7 changed files with 4621 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
{
"meta": {
"title": "title of song",
"subtitle": "subtitle of song",
"author": "author of song",
"creator": "creator of song",
"BPM": 0
},
"file": {
"audio": "NAME_OF_SONG.mp3",
"background": "background.png",
"banner": "banner.png"
},
"data": [
{
"difficulty": "easy",
"objects": [
{
"time": 1,
"direction": 1,
"button": 0,
"hold": true,
"length": 1000
},
{
"time": 16,
"direction": 6,
"button": 1
}
],
"button": [
{
"time": 0,
"button": 0,
"color": 0
},
{
"time": 20,
"button": 6,
"color": 1
}
]
},
{
"difficulty": "medium",
"objects": [
{
"time": 4,
"direction": 3,
"button": 3
},
{
"time": 12,
"direction": 5,
"button": 2
}
],
"button": [
{
"time": 0,
"button": 0,
"color": 0
},
{
"time": 20,
"button": 6,
"color": 1
}
]
}
]
}
+2125
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -1 +1,7 @@
# SMtoJSON
SMtoJSON is a tool to convert .SM files (beatmaps for the Step Mania game) to a json format. The json format can be used for the game "Color Strike"
# Usage
Usage is quit simple. You only have to add a argument for the directory which contains .sm files. The tool wil automaticly create the json files and copy the sound andd images to a specific directory.
+14
View File
@@ -0,0 +1,14 @@
package SMParser;
public class Main {
public static void main(String[] args) {
if(args.length > 0 && args[0] != null){
new SMFileSearcher(args[0]);
}else{
new SMFileSearcher("/home/janco/Documents/SMTEST");
System.out.println("No inputdir given");
}
}
}
+40
View File
@@ -0,0 +1,40 @@
package SMParser;
import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
public class SMFileSearcher {
private ArrayList<File> files;
public SMFileSearcher(String dir){
files = new ArrayList<File>();
File f = new File("scannedsongs");
SMParser parser = new SMParser();
f.mkdir();
findFiles(dir);
System.out.println("Total files:"+files.size());
int current = 1;
for(File file:files){
System.out.println("\b\b\b\b\b("+current+"/"+files.size()+") \t"+file.getAbsolutePath());
parser.parseSmFile(file);
current++;
};
}
public void findFiles(String path){
File root = new File(path);
File[] list = root.listFiles();
if (list == null) return;
for ( File f : list ) {
if ( f.isDirectory() ) {
findFiles( f.getAbsolutePath() );
}
else {
if(f.getName().endsWith(".sm")){
files.add(f);
}
}
}
}
}
+239
View File
@@ -0,0 +1,239 @@
package SMParser;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.json.JsonWriter;
public class SMParser {
private static String[] metaDataHeaders = {"offset:","title:","artist:", "displaybpm:", "music","samplestart:", "banner:", "background:", "subtitle:"};
private String[] metadata;
private ArrayList<JsonObjectBuilder> arrays;
public SMParser(){
}
public void parseSmFile(File inputfile){
try {
String file = readFile(inputfile.getAbsolutePath(), Charset.defaultCharset());
String[] mainsplit = file.split("\\#");
arrays = new ArrayList<JsonObjectBuilder>();
metadata = new String[metaDataHeaders.length];
for(String s:mainsplit){
//searching for the metadata
int i = 0;
for(String header:metaDataHeaders){
if(s.toLowerCase().contains(header) && metadata[i] == null){
metadata[i] = getValue(s).replace(';', ' ').trim();
}
i++;
}
//parsing the notes
if(s.contains("NOTES")){
String[] notesplit = s.split("\n");
if(notesplit[1].contains("-single:")){ //valid note (single player mode)
String difficulty = notesplit[3].replace(":", "").trim().toLowerCase();
for(int k = 0; k < 6; k++){ //remove first 6 lines
s = s.substring(s.indexOf('\n')+1);
}
s= s.replaceAll("//.*", ""); // remove some more bs
s = s.replaceAll("\\;", "");
notesplit = s.split("\\,"); //split everything in arrays which contains "beats" for 1 second
double secondscounter = Double.parseDouble(metadata[0])*-1;
int extraButtonTime = (notesplit.length / difficultyToMaxButtons(difficulty))*1000;
int maxButtons = 1;
JsonArrayBuilder objectsArrayBuilder = Json.createArrayBuilder();
JsonArrayBuilder buttonsArrayBuilder = Json.createArrayBuilder();
buttonsArrayBuilder.add(Json.createObjectBuilder().add("time", 0).add("button", 1).add("color", 0));
double lastNoteTime = 0;
int objectscounter = 0;
System.out.println(difficultyToButtonsTiming(difficulty) + "-" + difficulty);
for(String notespersecond:notesplit){
notespersecond = notespersecond.trim();
String[] notes = notespersecond.split("\n");
double precision = (1.0/notes.length)*1000;
double time = secondscounter*1000;
for(String note:notes){
int direction = noteToDirection(note.trim());
if(direction != -1){
if(time - lastNoteTime >= difficultyToButtonsTiming(difficulty)){
JsonObjectBuilder object = Json.createObjectBuilder();
object.add("time", time);
object.add("direction", direction);
object.add("button", (int)(Math.random()*maxButtons+1));
objectsArrayBuilder.add(object.build());
lastNoteTime = time;
objectscounter++;
}
}
if(extraButtonTime*maxButtons < time && maxButtons < difficultyToMaxButtons(difficulty)){ //add a new/extra button
buttonsArrayBuilder.add(Json.createObjectBuilder().add("time", time).add("button", maxButtons+1).add("color", maxButtons));
maxButtons++;
}
time += precision;
}
secondscounter++;
}
if(objectscounter > 15)
{
arrays.add(Json.createObjectBuilder());
arrays.get(arrays.size()-1).add("difficulty", difficulty);
arrays.get(arrays.size()-1).add("objects", objectsArrayBuilder);
arrays.get(arrays.size()-1).add("buttons", buttonsArrayBuilder);
}
}
};
}
for(int i = 0; i < metadata.length; i++){
if(metadata[i] == null){
metadata[i] = "0";
}
}
writeJsonFile(inputfile);
} catch (IOException e) {
e.printStackTrace();
}
}
private void writeJsonFile(File inputfile){
JsonObjectBuilder jsonfilebuilder = Json.createObjectBuilder();
JsonArrayBuilder dataArrayBuilder = Json.createArrayBuilder();
double bpm = 0;
double samples = 0;
try{
Double.parseDouble(metadata[3]);
}catch(java.lang.NumberFormatException e){
}
try{
Double.parseDouble(metadata[5]);
}catch(java.lang.NumberFormatException e){
}
jsonfilebuilder.add("meta", Json.createObjectBuilder().add("title", metadata[1]).add("subtitle", metadata[8]).add("author", metadata[2]).add("BPM", bpm).add("sample_start", samples));
jsonfilebuilder.add("file", Json.createObjectBuilder().add("audio", metadata[4]).add("background", metadata[7]).add("banner", metadata[6]));
for(JsonObjectBuilder ar:arrays){
dataArrayBuilder.add(ar.build());
}
jsonfilebuilder.add("data", dataArrayBuilder);
try {
String name = metadata[1].trim().replaceAll("[^a-zA-Z0-9.-]", "_")+metadata[8].trim().replaceAll("[^a-zA-Z0-9.-]", "_");;
String dirname = "scannedsongs/"+name+(int)(Math.random()*10);
File f = new File(dirname);
f.mkdir();
try {
Files.copy(new File(inputfile.getParent() + "/" + metadata[4]).toPath(), new File(dirname +"/"+metadata[4]).toPath());
} catch (IOException e) {
System.out.println("Music file not found");
f.delete();
return;
}
try {
Files.copy(new File(inputfile.getParent() + "/" + metadata[6]).toPath(), new File(dirname +"/"+metadata[6]).toPath());
} catch (IOException e) {
}
try {
Files.copy(new File(inputfile.getParent() + "/" + metadata[7]).toPath(), new File(dirname +"/"+metadata[7]).toPath());
} catch (IOException e) {
}
JsonObject file = jsonfilebuilder.build();
OutputStream os;
os = new FileOutputStream(dirname+"/"+name+".csf");
JsonWriter jsonWriter = Json.createWriter(os);
jsonWriter.writeObject(file);
jsonWriter.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private int difficultyToButtonsTiming(String d){
if(d.equals("beginner")){
return 650;
}else if(d.equals("easy")){
return 600;
}else if(d.equals("medium")){
return 550;
}else if(d.equals("hard")){
return 500;
}else if(d.equals("challenge")){
return 450;
}
return 400;
}
private int difficultyToMaxButtons(String d){
if(d.equals("beginner")){
return 2;
}else if(d.equals("easy")){
return 3;
}else if(d.equals("medium")){
return 4;
}else if(d.equals("hard")){
return 5;
}else if(d.equals("challenge")){
return 6;
}
return 6;
}
private String getValue(String s){
String[] split = s.split("\\:");
if(split.length == 2 && split[1] != null){
return split[1];
}
return "";
}
private static String readFile(String path, Charset encoding) throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
private int noteToDirection(String note){
if(note.length() == 4){
if(note.charAt(0) == '1'){
if(note.charAt(1) == '1'){ //down left
return 7;
}else if(note.charAt(2) == '1'){ //up left
return 1;
}
return 0; // left
}else if(note.charAt(3) == '1'){
if(note.charAt(1) == '1'){ //down right
return 5;
}else if(note.charAt(2) == '1'){ //up right
return 3;
}
return 4;// right
}else if(note.charAt(1) == '1'){ //down
return 6;
}else if(note.charAt(2) == '1'){ // up
return 2;
}
return -1;
}
return -1;
}
}
+2125
View File
File diff suppressed because it is too large Load Diff