Skip to content

Commit 4085f81

Browse files
committed
chore: 尽可能让 MaiLib 直接解析谱面
1 parent 557e983 commit 4085f81

File tree

1 file changed

+57
-9
lines changed

1 file changed

+57
-9
lines changed

MaiChartManager/Controllers/ImportChartController.cs

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using MaiLib;
1+
using System.Text.RegularExpressions;
2+
using MaiLib;
23
using Microsoft.AspNetCore.Mvc;
34
using SimaiSharp;
45
using SimaiSharp.Structures;
@@ -8,7 +9,7 @@ namespace MaiChartManager.Controllers;
89

910
[ApiController]
1011
[Route("MaiChartManagerServlet/[action]Api")]
11-
public class ImportChartController(StaticSettings settings, ILogger<StaticSettings> logger) : ControllerBase
12+
public partial class ImportChartController(StaticSettings settings, ILogger<StaticSettings> logger) : ControllerBase
1213
{
1314
public enum MessageLevel
1415
{
@@ -130,6 +131,11 @@ public ImportChartCheckResult ImportChartCheck(IFormFile file)
130131

131132
public record ImportChartResult(IEnumerable<ImportChartMessage> Errors, bool Fatal);
132133

134+
private record AllChartsEntry(string chartText, MaiChart simaiSharpChart);
135+
136+
[GeneratedRegex(@"\|\|.*$", RegexOptions.Multiline)]
137+
private static partial Regex SimaiCommentRegex();
138+
133139
[HttpPost]
134140
// 创建完 Music 后调用
135141
public ImportChartResult ImportChart([FromForm] int id, IFormFile file, [FromForm] bool ignoreLevelNum, [FromForm] int addVersionId, [FromForm] int genreId, [FromForm] int version,
@@ -140,26 +146,26 @@ public ImportChartResult ImportChart([FromForm] int id, IFormFile file, [FromFor
140146
var music = settings.MusicList.First(it => it.Id == id);
141147
var maiData = new Dictionary<string, string>(new SimaiFile(file.OpenReadStream()).ToKeyValuePairs());
142148

143-
var allCharts = new Dictionary<int, MaiChart>();
149+
var allCharts = new Dictionary<int, AllChartsEntry>();
144150
for (var i = 2; i < 9; i++)
145151
{
146152
if (!string.IsNullOrWhiteSpace(maiData.GetValueOrDefault($"inote_{i}")))
147153
{
148-
allCharts.Add(i, SimaiConvert.Deserialize(maiData[$"inote_{i}"]));
154+
allCharts.Add(i, new AllChartsEntry(maiData[$"inote_{i}"], SimaiConvert.Deserialize(maiData[$"inote_{i}"])));
149155
}
150156
}
151157

152158
if (!string.IsNullOrWhiteSpace(maiData.GetValueOrDefault("inote_0")))
153159
{
154-
allCharts.Add(0, SimaiConvert.Deserialize(maiData["inote_0"]));
160+
allCharts.Add(0, new AllChartsEntry(maiData["inote_0"], SimaiConvert.Deserialize(maiData["inote_0"])));
155161
}
156162

157163
float.TryParse(maiData.GetValueOrDefault("first"), out var first);
158164

159165
float chartPadding = 0;
160166
if (!noShiftChart)
161167
{
162-
var paddings = allCharts.Values.Select(chart => Converter.CalcMusicPadding(chart, first)).ToList();
168+
var paddings = allCharts.Values.Select(chart => Converter.CalcMusicPadding(chart.simaiSharpChart, first)).ToList();
163169
// 音频前面被增加了多少
164170
var audioPadding = paddings.Max();
165171
// 见下方注释
@@ -172,7 +178,7 @@ public ImportChartResult ImportChart([FromForm] int id, IFormFile file, [FromFor
172178
if (isUtage && music.Charts[0].Enable) break;
173179

174180
// var levelPadding = Converter.CalcMusicPadding(chart, first);
175-
var bpm = chart.TimingChanges[0].tempo;
181+
var bpm = chart.simaiSharpChart.TimingChanges[0].tempo;
176182
music.Bpm = (int)Math.Floor(bpm);
177183
// 一个小节多少秒
178184
var bar = 60 / bpm * 4;
@@ -242,12 +248,54 @@ public ImportChartResult ImportChart([FromForm] int id, IFormFile file, [FromFor
242248
}
243249

244250
targetChart.Designer = maiData.GetValueOrDefault($"des_{level}") ?? maiData.GetValueOrDefault("des") ?? "";
245-
var maiLibChart = simaiParser.ChartOfToken(simaiTokenizer.TokensFromText(SimaiConvert.Serialize(chart)));
251+
Chart maiLibChart = null;
252+
try
253+
{
254+
maiLibChart = simaiParser.ChartOfToken(simaiTokenizer.TokensFromText(chart.chartText));
255+
}
256+
catch (Exception e)
257+
{
258+
logger.LogWarning(e, "无法直接解析谱面");
259+
}
260+
261+
if (maiLibChart is null)
262+
{
263+
try
264+
{
265+
var normalizedText = chart.chartText
266+
// 不飞的星星
267+
.Replace("-?", "?-");
268+
// 移除注释
269+
normalizedText = SimaiCommentRegex().Replace(normalizedText, "");
270+
var tokens = simaiTokenizer.TokensFromText(normalizedText);
271+
for (var i = 0; i < tokens.Length; i++)
272+
{
273+
if (tokens[i].Contains("]b"))
274+
{
275+
tokens[i] = tokens[i].Replace("]b", "]").Replace("[", "b[");
276+
}
277+
}
278+
279+
maiLibChart = simaiParser.ChartOfToken(tokens);
280+
}
281+
catch (Exception e)
282+
{
283+
logger.LogWarning(e, "无法在手动修正错误后解析谱面");
284+
}
285+
}
286+
287+
if (maiLibChart is null)
288+
{
289+
maiLibChart = simaiParser.ChartOfToken(simaiTokenizer.TokensFromText(SimaiConvert.Serialize(chart.simaiSharpChart)));
290+
errors.Add(new ImportChartMessage("就算修正了一些已知错误,MaiLib 还是无法解析谱面,我们尝试通过 AstroDX 的 SimaiSharp 解析。" +
291+
"如果转换结果发现有什么问题的话,可以试试在 AstroDX 中有没有同样的问题并告诉我们(不试也没关系)", MessageLevel.Warning));
292+
}
293+
246294
var originalConverted = maiLibChart.Compose(ChartEnum.ChartVersion.Ma2_104);
247295

248296
if (debug)
249297
{
250-
System.IO.File.WriteAllText(Path.Combine(Path.GetDirectoryName(music.FilePath), targetChart.Path + ".afterSimaiSharp.txt"), SimaiConvert.Serialize(chart));
298+
System.IO.File.WriteAllText(Path.Combine(Path.GetDirectoryName(music.FilePath), targetChart.Path + ".afterSimaiSharp.txt"), SimaiConvert.Serialize(chart.simaiSharpChart));
251299
System.IO.File.WriteAllText(Path.Combine(Path.GetDirectoryName(music.FilePath), targetChart.Path + ".preShift.ma2"), originalConverted);
252300
System.IO.File.WriteAllText(Path.Combine(Path.GetDirectoryName(music.FilePath), targetChart.Path + ".preShift.txt"), maiLibChart.Compose(ChartEnum.ChartVersion.SimaiFes));
253301
}

0 commit comments

Comments
 (0)