Catch (nearly) all exceptions thrown by OsuParser.

- Properly handle bad input and log a warning.  The game may run with some gameplay errors (ex. if no base TimingPoint is parsed), but it should not crash.

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han 2014-07-24 13:38:59 -04:00
parent 39dcdf6dee
commit 83e486054f
2 changed files with 222 additions and 171 deletions

View File

@ -133,6 +133,7 @@ public class OsuParser {
break; break;
if ((tokens = tokenize(line)) == null) if ((tokens = tokenize(line)) == null)
continue; continue;
try {
switch (tokens[0]) { switch (tokens[0]) {
case "AudioFilename": case "AudioFilename":
osu.audioFilename = new File(file.getParent() + File.separator + tokens[1]); osu.audioFilename = new File(file.getParent() + File.separator + tokens[1]);
@ -174,6 +175,10 @@ public class OsuParser {
default: default:
break; break;
} }
} catch (Exception e) {
Log.warn(String.format("Failed to read line '%s' for file '%s'.",
line, file.getAbsolutePath()), e);
}
} }
break; break;
case "[Editor]": case "[Editor]":
@ -186,6 +191,7 @@ public class OsuParser {
/* Not implemented. */ /* Not implemented. */
// if ((tokens = tokenize(line)) == null) // if ((tokens = tokenize(line)) == null)
// continue; // continue;
// try {
// switch (tokens[0]) { // switch (tokens[0]) {
// case "Bookmarks": // case "Bookmarks":
// String[] bookmarks = tokens[1].split(","); // String[] bookmarks = tokens[1].split(",");
@ -207,6 +213,10 @@ public class OsuParser {
// break; // break;
// default: // default:
// break; // break;
// }
// } catch (Exception e) {
// Log.warn(String.format("Failed to read editor line '%s' for file '%s'.",
// line, file.getAbsolutePath()), e);
// } // }
} }
break; break;
@ -219,6 +229,7 @@ public class OsuParser {
break; break;
if ((tokens = tokenize(line)) == null) if ((tokens = tokenize(line)) == null)
continue; continue;
try {
switch (tokens[0]) { switch (tokens[0]) {
case "Title": case "Title":
osu.title = tokens[1]; osu.title = tokens[1];
@ -251,6 +262,10 @@ public class OsuParser {
osu.beatmapSetID = Integer.parseInt(tokens[1]); osu.beatmapSetID = Integer.parseInt(tokens[1]);
break; break;
} }
} catch (Exception e) {
Log.warn(String.format("Failed to read metadata '%s' for file '%s'.",
line, file.getAbsolutePath()), e);
}
} }
break; break;
case "[Difficulty]": case "[Difficulty]":
@ -262,6 +277,7 @@ public class OsuParser {
break; break;
if ((tokens = tokenize(line)) == null) if ((tokens = tokenize(line)) == null)
continue; continue;
try {
switch (tokens[0]) { switch (tokens[0]) {
case "HPDrainRate": case "HPDrainRate":
osu.HPDrainRate = Float.parseFloat(tokens[1]); osu.HPDrainRate = Float.parseFloat(tokens[1]);
@ -282,6 +298,10 @@ public class OsuParser {
osu.sliderTickRate = Float.parseFloat(tokens[1]); osu.sliderTickRate = Float.parseFloat(tokens[1]);
break; break;
} }
} catch (Exception e) {
Log.warn(String.format("Failed to read difficulty '%s' for file '%s'.",
line, file.getAbsolutePath()), e);
}
} }
if (osu.approachRate == -1f) // not in old format if (osu.approachRate == -1f) // not in old format
osu.approachRate = osu.overallDifficulty; osu.approachRate = osu.overallDifficulty;
@ -302,10 +322,15 @@ public class OsuParser {
osu.bg = file.getParent() + File.separator + tokens[2]; osu.bg = file.getParent() + File.separator + tokens[2];
break; break;
case "2": // break periods case "2": // break periods
try {
if (osu.breaks == null) // optional, create if needed if (osu.breaks == null) // optional, create if needed
osu.breaks = new ArrayList<Integer>(); osu.breaks = new ArrayList<Integer>();
osu.breaks.add(Integer.parseInt(tokens[1])); osu.breaks.add(Integer.parseInt(tokens[1]));
osu.breaks.add(Integer.parseInt(tokens[2])); osu.breaks.add(Integer.parseInt(tokens[2]));
} catch (Exception e) {
Log.warn(String.format("Failed to read break period '%s' for file '%s'.",
line, file.getAbsolutePath()), e);
}
break; break;
default: default:
/* Not implemented. */ /* Not implemented. */
@ -321,6 +346,7 @@ public class OsuParser {
if (line.charAt(0) == '[') if (line.charAt(0) == '[')
break; break;
try {
// parse timing point // parse timing point
OsuTimingPoint timingPoint = new OsuTimingPoint(line); OsuTimingPoint timingPoint = new OsuTimingPoint(line);
@ -336,6 +362,10 @@ public class OsuParser {
} }
osu.timingPoints.add(timingPoint); osu.timingPoints.add(timingPoint);
} catch (Exception e) {
Log.warn(String.format("Failed to read timing point '%s' for file '%s'.",
line, file.getAbsolutePath()), e);
}
} }
break; break;
case "[Colours]": case "[Colours]":
@ -348,6 +378,7 @@ public class OsuParser {
break; break;
if ((tokens = tokenize(line)) == null) if ((tokens = tokenize(line)) == null)
continue; continue;
try {
switch (tokens[0]) { switch (tokens[0]) {
case "Combo1": case "Combo1":
case "Combo2": case "Combo2":
@ -366,6 +397,10 @@ public class OsuParser {
default: default:
break; break;
} }
} catch (Exception e) {
Log.warn(String.format("Failed to read color '%s' for file '%s'.",
line, file.getAbsolutePath()), e);
}
} }
if (!colors.isEmpty()) if (!colors.isEmpty())
osu.combo = colors.toArray(new Color[colors.size()]); osu.combo = colors.toArray(new Color[colors.size()]);
@ -380,6 +415,7 @@ public class OsuParser {
break; break;
/* Only type counts parsed at this time. */ /* Only type counts parsed at this time. */
tokens = line.split(","); tokens = line.split(",");
try {
type = Integer.parseInt(tokens[3]); type = Integer.parseInt(tokens[3]);
if ((type & OsuHitObject.TYPE_CIRCLE) > 0) if ((type & OsuHitObject.TYPE_CIRCLE) > 0)
osu.hitObjectCircle++; osu.hitObjectCircle++;
@ -387,8 +423,13 @@ public class OsuParser {
osu.hitObjectSlider++; osu.hitObjectSlider++;
else //if ((type & OsuHitObject.TYPE_SPINNER) > 0) else //if ((type & OsuHitObject.TYPE_SPINNER) > 0)
osu.hitObjectSpinner++; osu.hitObjectSpinner++;
} catch (Exception e) {
Log.warn(String.format("Failed to read hit object '%s' for file '%s'.",
line, file.getAbsolutePath()), e);
}
} }
try {
// map length = last object end time (TODO: end on slider?) // map length = last object end time (TODO: end on slider?)
if ((type & OsuHitObject.TYPE_SPINNER) > 0) { if ((type & OsuHitObject.TYPE_SPINNER) > 0) {
// some 'endTime' fields contain a ':' character (?) // some 'endTime' fields contain a ':' character (?)
@ -398,6 +439,10 @@ public class OsuParser {
osu.endTime = Integer.parseInt(tokens[5]); osu.endTime = Integer.parseInt(tokens[5]);
} else if (type != 0) } else if (type != 0)
osu.endTime = Integer.parseInt(tokens[2]); osu.endTime = Integer.parseInt(tokens[2]);
} catch (Exception e) {
Log.warn(String.format("Failed to read hit object end time '%s' for file '%s'.",
line, file.getAbsolutePath()), e);
}
break; break;
default: default:
line = in.readLine(); line = in.readLine();
@ -463,6 +508,7 @@ public class OsuParser {
if (tokenCount < 4) if (tokenCount < 4)
continue; continue;
try {
// create a new OsuHitObject for each line // create a new OsuHitObject for each line
OsuHitObject hitObject = new OsuHitObject(line); OsuHitObject hitObject = new OsuHitObject(line);
@ -477,6 +523,10 @@ public class OsuParser {
hitObject.setComboNumber(comboNumber++); hitObject.setComboNumber(comboNumber++);
osu.objects[objectIndex++] = hitObject; osu.objects[objectIndex++] = hitObject;
} catch (Exception e) {
Log.warn(String.format("Failed to read hit object '%s' for OsuFile '%s'.",
line, osu.toString()), e);
}
} }
} catch (IOException e) { } catch (IOException e) {
Log.error(String.format("Failed to read file '%s'.", osu.getFile().getAbsolutePath()), e); Log.error(String.format("Failed to read file '%s'.", osu.getFile().getAbsolutePath()), e);

View File

@ -755,6 +755,7 @@ public class Game extends BasicGameState {
breakTime = 0; breakTime = 0;
breakSound = false; breakSound = false;
timingPointIndex = 0; timingPointIndex = 0;
beatLengthBase = beatLength = 1;
pauseTime = -1; pauseTime = -1;
pausedMouseX = -1; pausedMouseX = -1;
pausedMouseY = -1; pausedMouseY = -1;