11using System . Text ;
2+ using MuConvert . utils ;
23
34namespace MuConvert . maidata ;
45
5- public record MaidataChart ( string Level , string NoteDesigner , string Inote ) ;
6+ public record MaidataChart ( string ? Level , string ? NoteDesigner , string Inote ) ;
67
78public class Maidata : Dictionary < string , string >
89{
910 /**
1011 * 便捷的获得一个maidata中的所有谱面的方法。
11- * 除了铺面之外的信息,如title、artist、first等,仍可通过一般的dict方法加以获得。
12+ * 除了谱面之外的信息,如title、artist、first等,可通过Infos获取;
13+ * 而由于,如果用一般的Dict的方法遍历/访问Maidata对象的话,拿到的是整个maidata的、包含inote等在内的所有信息。
1214 */
13- public Dictionary < int , MaidataChart > Levels
14- {
15- get
16- {
17- var result = new Dictionary < int , MaidataChart > ( ) ;
18- foreach ( var ( k , v ) in this )
19- {
20- if ( k . StartsWith ( "inote_" ) )
21- {
22- if ( ! int . TryParse ( k . Replace ( "inote_" , "" ) , out var id ) ) continue ;
23- var level = this . GetValueOrDefault ( $ "lv_{ id } ", "" ) ;
24- var noteDesigner = this . GetValueOrDefault ( $ "des_{ id } ", "" ) ;
25- result . Add ( id , new MaidataChart ( level , noteDesigner , v ) ) ;
26- }
27- }
28- return result ;
29- }
30- }
15+ public Dictionary < int , MaidataChart > Levels => _splitLevels ( ) . Item1 ;
16+
17+ /**
18+ * 便捷的获得一个maidata中,除了谱面相关的所有信息字段的方法。
19+ * 而由于Maidata类继承自Dictionary,如果用一般的Dict的方法遍历/访问Maidata对象的话,拿到的是整个maidata的、包含inote等在内的所有信息。
20+ */
21+ public Dictionary < string , string > Infos => _splitLevels ( ) . Item2 ;
3122
3223 /**
3324 * 将maidata.txt的文本传给此函数,即可构造Maidata对象。
@@ -65,6 +56,25 @@ private void _putKey(string? key, StringBuilder content)
6556 value = value . Trim ( ) ; // 对部分字段,要trim一下;但不能对所有的字段都trim,比如如果对title进行trim,如月车站就寄了。
6657 this [ key ] = value ;
6758 }
59+
60+ private ( Dictionary < int , MaidataChart > , Dictionary < string , string > ) _splitLevels ( )
61+ {
62+ var levels = new Dictionary < int , MaidataChart > ( ) ;
63+ var infos = new Dictionary < string , string > ( this ) ; // 复制一份,稍后删key
64+ foreach ( var k in this . Keys )
65+ {
66+ if ( k . StartsWith ( "inote_" ) )
67+ {
68+ if ( ! int . TryParse ( k . Replace ( "inote_" , "" ) , out var id ) ) continue ;
69+ // 一边从info中移除内容,一边加到levels里去
70+ infos . Remove ( k , out var v ) ;
71+ infos . Remove ( $ "lv_{ id } ", out var level ) ;
72+ infos . Remove ( $ "des_{ id } ", out var noteDesigner ) ;
73+ levels . Add ( id , new MaidataChart ( level , noteDesigner , v ! ) ) ;
74+ }
75+ }
76+ return ( levels , infos ) ;
77+ }
6878
6979 public string Title => this . GetValueOrDefault ( "title" , "" ) ;
7080 public string Artist => this . GetValueOrDefault ( "artist" , "" ) ;
@@ -80,5 +90,38 @@ private void _putKey(string? key, StringBuilder content)
8090 return ( demoStart , demoLen ) ;
8191 }
8292 }
83-
93+
94+ public override string ToString ( )
95+ {
96+ var result = new StringBuilder ( ) ;
97+
98+ string [ ] fixedKeys = [ "title" , "artist" , "first" , "des" , "wholebpm" ] ; // 对这些键,优先、按这里指定的顺序输出。
99+ foreach ( var k in fixedKeys )
100+ {
101+ if ( TryGetValue ( k , out var v ) ) result . AppendLine ( $ "&{ k } =v") ;
102+ }
103+
104+ var ( levels , infos ) = _splitLevels ( ) ;
105+ foreach ( var ( k , v ) in Infos )
106+ {
107+ if ( fixedKeys . Contains ( k ) ) continue ; // 刚刚已经输出过了
108+ result . AppendLine ( $ "&{ k } ={ v } ") ;
109+ }
110+ result . AppendLine ( "&ChartConvertTool=MuConvert" ) ;
111+ result . AppendLine ( $ "&ChartConvertToolVersion={ Utils . AppVersion } ") ;
112+ result . AppendLine ( ) ;
113+
114+ var levelIds = levels . Keys . ToList ( ) ;
115+ levelIds . Sort ( ) ;
116+ foreach ( var id in levelIds )
117+ {
118+ var data = levels [ id ] ;
119+ if ( data . Level != null ) result . AppendLine ( $ "&lv_{ id } ={ data . Level } ") ;
120+ if ( data . NoteDesigner != null ) result . AppendLine ( $ "&des_{ id } ={ data . NoteDesigner } ") ;
121+ result . AppendLine ( $ "&inote_{ id } ={ data . Inote } ") ;
122+ result . AppendLine ( ) ;
123+ }
124+
125+ return result . ToString ( ) ;
126+ }
84127}
0 commit comments