Skip to content

Commit f06f1c2

Browse files
committed
feat: 导入和导出谱面时均支持clock_count(MET),即谱面一开头咔咔咔的那几声的数量
1 parent 73959b2 commit f06f1c2

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

MaiChartManager/Controllers/Music/MusicTransferController.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,13 @@ public async Task ExportAsMaidata(int id, string assetDir, bool ignoreVideo = fa
585585
{
586586
// ignore preview time errors
587587
}
588+
589+
var ma2Contents = new Dictionary<int, string[]>();
590+
591+
// 关于clock_count功能,我决定不走MaiLib了,而是我们自己解析。因为ma2.Compose返回的是裸谱面inote中的内容,没有办法合理的把clock信息插进去。因此,我们自己解析吧。
592+
// 选用最难的一张有效谱面的MET值作为全曲的&clock_count
593+
int clockCount = 0;
594+
588595
for (var i = 0; i < music.Charts.Length; i++)
589596
{
590597
var chart = music.Charts[i];
@@ -599,6 +606,19 @@ public async Task ExportAsMaidata(int id, string assetDir, bool ignoreVideo = fa
599606
}
600607

601608
var ma2Content = await System.IO.File.ReadAllLinesAsync(chartPath);
609+
ma2Contents[i] = ma2Content;
610+
611+
// 从谱面内容中寻找MET行
612+
var metLine = ma2Content.FirstOrDefault(it => it.StartsWith("MET\t"));
613+
if (metLine is not null && int.TryParse(metLine.Split('\t')[4], out var v)) clockCount = v;
614+
}
615+
616+
if (clockCount > 0) simaiFile.AppendLine($"&clock_count={clockCount}");
617+
618+
// 根据前面读取的结果,向simaiFile中最终写入谱面信息相关字段
619+
foreach (var (i, ma2Content) in ma2Contents)
620+
{
621+
var chart = music.Charts[i];
602622
var ma2 = parser.ChartOfToken(ma2Content);
603623
var simai = ma2.Compose(ChartEnum.ChartVersion.SimaiFes);
604624
simaiFile.AppendLine($"&lv_{i + 2}={chart.Level}.{chart.LevelDecimal}");

MaiChartManager/Services/MaidataImportService.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,31 @@ public static Dictionary<ShiftMethod, float> CalcChartPadding(List<MaiChart> cha
256256
}
257257

258258
private record AllChartsEntry(string chartText, MaiChart simaiSharpChart);
259+
260+
[GeneratedRegex(@"^(CLK_DEF\t)(\d+\s*)$", RegexOptions.Multiline)]
261+
private static partial Regex ClockDefRegex();
262+
263+
[GeneratedRegex(@"^(MET\t\d+\t\d+\t\d+\t)(\d+\s*)$", RegexOptions.Multiline)]
264+
private static partial Regex FirstMetLineRegex();
265+
266+
private static string replaceGroup2ByRegex(string input, Match match, int value)
267+
{
268+
if (!match.Success) return input;
269+
return string.Concat(
270+
input.AsSpan(0, match.Index),
271+
match.Groups[1].ValueSpan,
272+
value.ToString(CultureInfo.InvariantCulture),
273+
input.AsSpan(match.Index + match.Length));
274+
}
275+
276+
private static string ApplyClockCountToFirstMetLine(string ma2Content, int clockCount)
277+
{
278+
var clockdefMatch = ClockDefRegex().Match(ma2Content);
279+
ma2Content = replaceGroup2ByRegex(ma2Content, clockdefMatch, 96 * clockCount);
280+
var metMatch = FirstMetLineRegex().Match(ma2Content);
281+
ma2Content = replaceGroup2ByRegex(ma2Content, metMatch, clockCount);
282+
return ma2Content;
283+
}
259284

260285
public ImportChartResult ImportMaidata(
261286
MusicXml music,
@@ -410,6 +435,12 @@ public ImportChartResult ImportMaidata(
410435
errors.Add(new ImportChartMessage(Locale.ChartNotesMissing, MessageLevel.Warning));
411436
logger.LogWarning("BUG! shiftedConverted: {shiftedLen}, originalConverted: {originalLen}", shiftedConverted.Split('\n').Length, originalConverted.Split('\n').Length);
412437
}
438+
439+
// 如果maidata中声明了clock_count,应用之,修改CLOCK_DEF和MET
440+
if (int.TryParse(maiData.GetValueOrDefault("clock_count"), out var clockCount))
441+
{
442+
shiftedConverted = ApplyClockCountToFirstMetLine(shiftedConverted, clockCount);
443+
}
413444

414445
// Just use T_NUM_ALL value in ma2 file
415446
targetChart.MaxNotes = ParseTNumAllFromMa2(shiftedConverted);

0 commit comments

Comments
 (0)