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:
parent
39dcdf6dee
commit
83e486054f
|
@ -133,46 +133,51 @@ public class OsuParser {
|
||||||
break;
|
break;
|
||||||
if ((tokens = tokenize(line)) == null)
|
if ((tokens = tokenize(line)) == null)
|
||||||
continue;
|
continue;
|
||||||
switch (tokens[0]) {
|
try {
|
||||||
case "AudioFilename":
|
switch (tokens[0]) {
|
||||||
osu.audioFilename = new File(file.getParent() + File.separator + tokens[1]);
|
case "AudioFilename":
|
||||||
break;
|
osu.audioFilename = new File(file.getParent() + File.separator + tokens[1]);
|
||||||
case "AudioLeadIn":
|
break;
|
||||||
osu.audioLeadIn = Integer.parseInt(tokens[1]);
|
case "AudioLeadIn":
|
||||||
break;
|
osu.audioLeadIn = Integer.parseInt(tokens[1]);
|
||||||
// case "AudioHash": // deprecated
|
break;
|
||||||
// osu.audioHash = tokens[1];
|
// case "AudioHash": // deprecated
|
||||||
// break;
|
// osu.audioHash = tokens[1];
|
||||||
case "PreviewTime":
|
// break;
|
||||||
osu.previewTime = Integer.parseInt(tokens[1]);
|
case "PreviewTime":
|
||||||
break;
|
osu.previewTime = Integer.parseInt(tokens[1]);
|
||||||
case "Countdown":
|
break;
|
||||||
osu.countdown = Byte.parseByte(tokens[1]);
|
case "Countdown":
|
||||||
break;
|
osu.countdown = Byte.parseByte(tokens[1]);
|
||||||
case "SampleSet":
|
break;
|
||||||
osu.sampleSet = tokens[1];
|
case "SampleSet":
|
||||||
break;
|
osu.sampleSet = tokens[1];
|
||||||
case "StackLeniency":
|
break;
|
||||||
osu.stackLeniency = Float.parseFloat(tokens[1]);
|
case "StackLeniency":
|
||||||
break;
|
osu.stackLeniency = Float.parseFloat(tokens[1]);
|
||||||
case "Mode":
|
break;
|
||||||
osu.mode = Byte.parseByte(tokens[1]);
|
case "Mode":
|
||||||
|
osu.mode = Byte.parseByte(tokens[1]);
|
||||||
|
|
||||||
/* Non-Opsu! standard files not implemented (obviously). */
|
/* Non-Opsu! standard files not implemented (obviously). */
|
||||||
if (osu.mode != 0)
|
if (osu.mode != 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "LetterboxInBreaks":
|
case "LetterboxInBreaks":
|
||||||
osu.letterboxInBreaks = (Integer.parseInt(tokens[1]) == 1);
|
osu.letterboxInBreaks = (Integer.parseInt(tokens[1]) == 1);
|
||||||
break;
|
break;
|
||||||
case "WidescreenStoryboard":
|
case "WidescreenStoryboard":
|
||||||
osu.widescreenStoryboard = (Integer.parseInt(tokens[1]) == 1);
|
osu.widescreenStoryboard = (Integer.parseInt(tokens[1]) == 1);
|
||||||
break;
|
break;
|
||||||
case "EpilepsyWarning":
|
case "EpilepsyWarning":
|
||||||
osu.epilepsyWarning = (Integer.parseInt(tokens[1]) == 1);
|
osu.epilepsyWarning = (Integer.parseInt(tokens[1]) == 1);
|
||||||
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;
|
||||||
|
@ -186,27 +191,32 @@ public class OsuParser {
|
||||||
/* Not implemented. */
|
/* Not implemented. */
|
||||||
// if ((tokens = tokenize(line)) == null)
|
// if ((tokens = tokenize(line)) == null)
|
||||||
// continue;
|
// continue;
|
||||||
// switch (tokens[0]) {
|
// try {
|
||||||
// case "Bookmarks":
|
// switch (tokens[0]) {
|
||||||
// String[] bookmarks = tokens[1].split(",");
|
// case "Bookmarks":
|
||||||
// osu.bookmarks = new int[bookmarks.length];
|
// String[] bookmarks = tokens[1].split(",");
|
||||||
// for (int i = 0; i < bookmarks.length; i++)
|
// osu.bookmarks = new int[bookmarks.length];
|
||||||
// osu.bookmarks[i] = Integer.parseInt(bookmarks[i]);
|
// for (int i = 0; i < bookmarks.length; i++)
|
||||||
// break;
|
// osu.bookmarks[i] = Integer.parseInt(bookmarks[i]);
|
||||||
// case "DistanceSpacing":
|
// break;
|
||||||
// osu.distanceSpacing = Float.parseFloat(tokens[1]);
|
// case "DistanceSpacing":
|
||||||
// break;
|
// osu.distanceSpacing = Float.parseFloat(tokens[1]);
|
||||||
// case "BeatDivisor":
|
// break;
|
||||||
// osu.beatDivisor = Byte.parseByte(tokens[1]);
|
// case "BeatDivisor":
|
||||||
// break;
|
// osu.beatDivisor = Byte.parseByte(tokens[1]);
|
||||||
// case "GridSize":
|
// break;
|
||||||
// osu.gridSize = Integer.parseInt(tokens[1]);
|
// case "GridSize":
|
||||||
// break;
|
// osu.gridSize = Integer.parseInt(tokens[1]);
|
||||||
// case "TimelineZoom":
|
// break;
|
||||||
// osu.timelineZoom = Integer.parseInt(tokens[1]);
|
// case "TimelineZoom":
|
||||||
// break;
|
// osu.timelineZoom = Integer.parseInt(tokens[1]);
|
||||||
// default:
|
// break;
|
||||||
// break;
|
// default:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// Log.warn(String.format("Failed to read editor line '%s' for file '%s'.",
|
||||||
|
// line, file.getAbsolutePath()), e);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -219,37 +229,42 @@ public class OsuParser {
|
||||||
break;
|
break;
|
||||||
if ((tokens = tokenize(line)) == null)
|
if ((tokens = tokenize(line)) == null)
|
||||||
continue;
|
continue;
|
||||||
switch (tokens[0]) {
|
try {
|
||||||
case "Title":
|
switch (tokens[0]) {
|
||||||
osu.title = tokens[1];
|
case "Title":
|
||||||
break;
|
osu.title = tokens[1];
|
||||||
case "TitleUnicode":
|
break;
|
||||||
osu.titleUnicode = tokens[1];
|
case "TitleUnicode":
|
||||||
break;
|
osu.titleUnicode = tokens[1];
|
||||||
case "Artist":
|
break;
|
||||||
osu.artist = tokens[1];
|
case "Artist":
|
||||||
break;
|
osu.artist = tokens[1];
|
||||||
case "ArtistUnicode":
|
break;
|
||||||
osu.artistUnicode = tokens[1];
|
case "ArtistUnicode":
|
||||||
break;
|
osu.artistUnicode = tokens[1];
|
||||||
case "Creator":
|
break;
|
||||||
osu.creator = tokens[1];
|
case "Creator":
|
||||||
break;
|
osu.creator = tokens[1];
|
||||||
case "Version":
|
break;
|
||||||
osu.version = tokens[1];
|
case "Version":
|
||||||
break;
|
osu.version = tokens[1];
|
||||||
case "Source":
|
break;
|
||||||
osu.source = tokens[1];
|
case "Source":
|
||||||
break;
|
osu.source = tokens[1];
|
||||||
case "Tags":
|
break;
|
||||||
osu.tags = tokens[1].toLowerCase();
|
case "Tags":
|
||||||
break;
|
osu.tags = tokens[1].toLowerCase();
|
||||||
case "BeatmapID":
|
break;
|
||||||
osu.beatmapID = Integer.parseInt(tokens[1]);
|
case "BeatmapID":
|
||||||
break;
|
osu.beatmapID = Integer.parseInt(tokens[1]);
|
||||||
case "BeatmapSetID":
|
break;
|
||||||
osu.beatmapSetID = Integer.parseInt(tokens[1]);
|
case "BeatmapSetID":
|
||||||
break;
|
osu.beatmapSetID = Integer.parseInt(tokens[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.warn(String.format("Failed to read metadata '%s' for file '%s'.",
|
||||||
|
line, file.getAbsolutePath()), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -262,25 +277,30 @@ public class OsuParser {
|
||||||
break;
|
break;
|
||||||
if ((tokens = tokenize(line)) == null)
|
if ((tokens = tokenize(line)) == null)
|
||||||
continue;
|
continue;
|
||||||
switch (tokens[0]) {
|
try {
|
||||||
case "HPDrainRate":
|
switch (tokens[0]) {
|
||||||
osu.HPDrainRate = Float.parseFloat(tokens[1]);
|
case "HPDrainRate":
|
||||||
break;
|
osu.HPDrainRate = Float.parseFloat(tokens[1]);
|
||||||
case "CircleSize":
|
break;
|
||||||
osu.circleSize = Float.parseFloat(tokens[1]);
|
case "CircleSize":
|
||||||
break;
|
osu.circleSize = Float.parseFloat(tokens[1]);
|
||||||
case "OverallDifficulty":
|
break;
|
||||||
osu.overallDifficulty = Float.parseFloat(tokens[1]);
|
case "OverallDifficulty":
|
||||||
break;
|
osu.overallDifficulty = Float.parseFloat(tokens[1]);
|
||||||
case "ApproachRate":
|
break;
|
||||||
osu.approachRate = Float.parseFloat(tokens[1]);
|
case "ApproachRate":
|
||||||
break;
|
osu.approachRate = Float.parseFloat(tokens[1]);
|
||||||
case "SliderMultiplier":
|
break;
|
||||||
osu.sliderMultiplier = Float.parseFloat(tokens[1]);
|
case "SliderMultiplier":
|
||||||
break;
|
osu.sliderMultiplier = Float.parseFloat(tokens[1]);
|
||||||
case "SliderTickRate":
|
break;
|
||||||
osu.sliderTickRate = Float.parseFloat(tokens[1]);
|
case "SliderTickRate":
|
||||||
break;
|
osu.sliderTickRate = Float.parseFloat(tokens[1]);
|
||||||
|
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
|
||||||
|
@ -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
|
||||||
if (osu.breaks == null) // optional, create if needed
|
try {
|
||||||
osu.breaks = new ArrayList<Integer>();
|
if (osu.breaks == null) // optional, create if needed
|
||||||
osu.breaks.add(Integer.parseInt(tokens[1]));
|
osu.breaks = new ArrayList<Integer>();
|
||||||
osu.breaks.add(Integer.parseInt(tokens[2]));
|
osu.breaks.add(Integer.parseInt(tokens[1]));
|
||||||
|
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,21 +346,26 @@ public class OsuParser {
|
||||||
if (line.charAt(0) == '[')
|
if (line.charAt(0) == '[')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// parse timing point
|
try {
|
||||||
OsuTimingPoint timingPoint = new OsuTimingPoint(line);
|
// parse timing point
|
||||||
|
OsuTimingPoint timingPoint = new OsuTimingPoint(line);
|
||||||
|
|
||||||
// calculate BPM
|
// calculate BPM
|
||||||
if (!timingPoint.isInherited()) {
|
if (!timingPoint.isInherited()) {
|
||||||
int bpm = Math.round(60000 / timingPoint.getBeatLength());
|
int bpm = Math.round(60000 / timingPoint.getBeatLength());
|
||||||
if (osu.bpmMin == 0)
|
if (osu.bpmMin == 0)
|
||||||
osu.bpmMin = osu.bpmMax = bpm;
|
osu.bpmMin = osu.bpmMax = bpm;
|
||||||
else if (bpm < osu.bpmMin)
|
else if (bpm < osu.bpmMin)
|
||||||
osu.bpmMin = bpm;
|
osu.bpmMin = bpm;
|
||||||
else if (bpm > osu.bpmMax)
|
else if (bpm > osu.bpmMax)
|
||||||
osu.bpmMax = bpm;
|
osu.bpmMax = bpm;
|
||||||
|
}
|
||||||
|
|
||||||
|
osu.timingPoints.add(timingPoint);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.warn(String.format("Failed to read timing point '%s' for file '%s'.",
|
||||||
|
line, file.getAbsolutePath()), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
osu.timingPoints.add(timingPoint);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "[Colours]":
|
case "[Colours]":
|
||||||
|
@ -348,23 +378,28 @@ public class OsuParser {
|
||||||
break;
|
break;
|
||||||
if ((tokens = tokenize(line)) == null)
|
if ((tokens = tokenize(line)) == null)
|
||||||
continue;
|
continue;
|
||||||
switch (tokens[0]) {
|
try {
|
||||||
case "Combo1":
|
switch (tokens[0]) {
|
||||||
case "Combo2":
|
case "Combo1":
|
||||||
case "Combo3":
|
case "Combo2":
|
||||||
case "Combo4":
|
case "Combo3":
|
||||||
case "Combo5":
|
case "Combo4":
|
||||||
case "Combo6":
|
case "Combo5":
|
||||||
case "Combo7":
|
case "Combo6":
|
||||||
case "Combo8":
|
case "Combo7":
|
||||||
String[] rgb = tokens[1].split(",");
|
case "Combo8":
|
||||||
colors.add(new Color(
|
String[] rgb = tokens[1].split(",");
|
||||||
Integer.parseInt(rgb[0]),
|
colors.add(new Color(
|
||||||
Integer.parseInt(rgb[1]),
|
Integer.parseInt(rgb[0]),
|
||||||
Integer.parseInt(rgb[2])
|
Integer.parseInt(rgb[1]),
|
||||||
));
|
Integer.parseInt(rgb[2])
|
||||||
default:
|
));
|
||||||
break;
|
default:
|
||||||
|
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())
|
||||||
|
@ -380,24 +415,34 @@ 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(",");
|
||||||
type = Integer.parseInt(tokens[3]);
|
try {
|
||||||
if ((type & OsuHitObject.TYPE_CIRCLE) > 0)
|
type = Integer.parseInt(tokens[3]);
|
||||||
osu.hitObjectCircle++;
|
if ((type & OsuHitObject.TYPE_CIRCLE) > 0)
|
||||||
else if ((type & OsuHitObject.TYPE_SLIDER) > 0)
|
osu.hitObjectCircle++;
|
||||||
osu.hitObjectSlider++;
|
else if ((type & OsuHitObject.TYPE_SLIDER) > 0)
|
||||||
else //if ((type & OsuHitObject.TYPE_SPINNER) > 0)
|
osu.hitObjectSlider++;
|
||||||
osu.hitObjectSpinner++;
|
else //if ((type & OsuHitObject.TYPE_SPINNER) > 0)
|
||||||
|
osu.hitObjectSpinner++;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.warn(String.format("Failed to read hit object '%s' for file '%s'.",
|
||||||
|
line, file.getAbsolutePath()), e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// map length = last object end time (TODO: end on slider?)
|
try {
|
||||||
if ((type & OsuHitObject.TYPE_SPINNER) > 0) {
|
// map length = last object end time (TODO: end on slider?)
|
||||||
// some 'endTime' fields contain a ':' character (?)
|
if ((type & OsuHitObject.TYPE_SPINNER) > 0) {
|
||||||
int index = tokens[5].indexOf(':');
|
// some 'endTime' fields contain a ':' character (?)
|
||||||
if (index != -1)
|
int index = tokens[5].indexOf(':');
|
||||||
tokens[5] = tokens[5].substring(0, index);
|
if (index != -1)
|
||||||
osu.endTime = Integer.parseInt(tokens[5]);
|
tokens[5] = tokens[5].substring(0, index);
|
||||||
} else if (type != 0)
|
osu.endTime = Integer.parseInt(tokens[5]);
|
||||||
osu.endTime = Integer.parseInt(tokens[2]);
|
} else if (type != 0)
|
||||||
|
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,20 +508,25 @@ public class OsuParser {
|
||||||
if (tokenCount < 4)
|
if (tokenCount < 4)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// create a new OsuHitObject for each line
|
try {
|
||||||
OsuHitObject hitObject = new OsuHitObject(line);
|
// create a new OsuHitObject for each line
|
||||||
|
OsuHitObject hitObject = new OsuHitObject(line);
|
||||||
|
|
||||||
// set combo info
|
// set combo info
|
||||||
// - new combo: get next combo index, reset combo number
|
// - new combo: get next combo index, reset combo number
|
||||||
// - else: maintain combo index, increase combo number
|
// - else: maintain combo index, increase combo number
|
||||||
if (hitObject.isNewCombo()) {
|
if (hitObject.isNewCombo()) {
|
||||||
comboIndex = (comboIndex + 1) % osu.combo.length;
|
comboIndex = (comboIndex + 1) % osu.combo.length;
|
||||||
comboNumber = 1;
|
comboNumber = 1;
|
||||||
|
}
|
||||||
|
hitObject.setComboIndex(comboIndex);
|
||||||
|
hitObject.setComboNumber(comboNumber++);
|
||||||
|
|
||||||
|
osu.objects[objectIndex++] = hitObject;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.warn(String.format("Failed to read hit object '%s' for OsuFile '%s'.",
|
||||||
|
line, osu.toString()), e);
|
||||||
}
|
}
|
||||||
hitObject.setComboIndex(comboIndex);
|
|
||||||
hitObject.setComboNumber(comboNumber++);
|
|
||||||
|
|
||||||
osu.objects[objectIndex++] = hitObject;
|
|
||||||
}
|
}
|
||||||
} 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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user