import 'dart:io'; enum Difficulty { Beginner, Easy, Medium, Hard, Challenge, Edit } // These are the standard note values: // // 0 – No note // 1 – Normal note // 2 – Hold head // 3 – Hold/Roll tail // 4 – Roll head // M – Mine (or other negative note) // // Later versions of StepMania accept other note values which may not work in older versions: // // K – Automatic keysound // L – Lift note // F – Fake note RegExp noteTypes = RegExp(r'^([012345MKLF]+)\s*([,;])?'); class Chart { String? chartType; // Description/author String? author; // Difficulty (one of Beginner, Easy, Medium, Hard, Challenge, Edit) Difficulty? difficulty; // Numerical meter int? numericalMeter; // Groove radar values, generated by the program String? radarValues; List>? measures; } class Simfile { String path; String? lines; // tags of simfile Map tags = {}; Chart? chartSimplest; Simfile(this.path); void load() { lines = File(path).readAsStringSync(); RegExp commentsRegExp = RegExp(r'//.*$'); lines = lines?.replaceAll(commentsRegExp, ''); RegExp fieldDataRegExp = RegExp(r'#([^;]+):([^;]*);'); for (final fieldData in fieldDataRegExp.allMatches(lines!)) { List keys = fieldData[1]!.split(':').map((key) => key.trim()).toList(); String value = fieldData[2]!; if (keys[0] != "NOTES") { tags[keys[0]] = value; continue; } Chart chart = Chart(); chart.chartType = keys[1]; chart.author = keys[2]; chart.difficulty = Difficulty.values.byName(keys[3]); chart.numericalMeter = int.parse(keys[4]); chart.radarValues = keys[5]; if (chartSimplest == null || (chart.difficulty!.index <= chartSimplest!.difficulty!.index && chart.numericalMeter! <= chartSimplest!.numericalMeter!)) { List> measures = []; for (final measureRaw in value.split(',')) { List measure = []; for (final noteRaw in measureRaw.split('\n')) { String note = noteRaw.trim(); if (noteTypes.hasMatch(note)) { measure.add(note); } } measures.add(measure); } chart.measures = measures; chartSimplest = chart; } } } }