@@ -156,7 +156,12 @@ public ActionResult<ModConfigRequest> GetConfig(string modId)
156156 if ( ! TryResolveGameFile ( $ "{ modId } .toml", out var path ) )
157157 return BadRequest ( "GamePath not set" ) ;
158158 if ( ! System . IO . File . Exists ( path ) )
159- return NotFound ( ) ;
159+ {
160+ var template = LoadDefaultConfig ( modId ) ;
161+ if ( template == null )
162+ return NotFound ( ) ;
163+ System . IO . File . WriteAllText ( path , template , new UTF8Encoding ( false ) ) ;
164+ }
160165
161166 var sections = ParseConfig ( System . IO . File . ReadAllText ( path , Encoding . UTF8 ) ) ;
162167 return Ok ( new ModConfigRequest ( sections ) ) ;
@@ -168,7 +173,10 @@ public ActionResult SaveConfig(string modId, [FromBody] ModConfigRequest request
168173 if ( ! TryResolveGameFile ( $ "{ modId } .toml", out var path ) )
169174 return BadRequest ( "GamePath not set" ) ;
170175
171- var toml = SerializeConfig ( request . Sections ) ;
176+ var template = LoadDefaultConfig ( modId ) ;
177+ var toml = template != null
178+ ? SerializeFromTemplate ( template , request . Sections )
179+ : SerializeConfig ( request . Sections ) ;
172180 System . IO . File . WriteAllText ( path , toml , new UTF8Encoding ( false ) ) ;
173181 return Ok ( ) ;
174182 }
@@ -257,6 +265,57 @@ private static string StripInlineComment(string value)
257265 }
258266 }
259267
268+ private static string ? LoadDefaultConfig ( string modId )
269+ {
270+ var source = Path . Combine ( StaticSettings . ExeDir , "Resources" , modId , "default_config.toml" ) ;
271+ return System . IO . File . Exists ( source ) ? System . IO . File . ReadAllText ( source , Encoding . UTF8 ) : null ;
272+ }
273+
274+ private static string SerializeFromTemplate ( string template , Dictionary < string , ModSectionConfig > sections )
275+ {
276+ var builder = new StringBuilder ( ) ;
277+ string ? currentSection = null ;
278+ var usedEntries = new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) ;
279+
280+ foreach ( var rawLine in template . Replace ( "\r \n " , "\n " ) . Split ( '\n ' ) )
281+ {
282+ var trimmed = rawLine . Trim ( ) ;
283+
284+ var uncommented = trimmed . StartsWith ( '#' ) ? trimmed [ 1 ..] . TrimStart ( ) : trimmed ;
285+ if ( uncommented . StartsWith ( '[' ) && uncommented . EndsWith ( ']' ) )
286+ {
287+ currentSection = uncommented [ 1 ..^ 1 ] . Trim ( ) ;
288+ usedEntries . Clear ( ) ;
289+ var enabled = sections . TryGetValue ( currentSection , out var s ) ? s . Enabled : ! trimmed . StartsWith ( '#' ) ;
290+ var prefix = enabled ? "" : "#" ;
291+ builder . Append ( prefix ) . Append ( '[' ) . Append ( currentSection ) . AppendLine ( "]" ) ;
292+ continue ;
293+ }
294+
295+ if ( currentSection != null && ! trimmed . StartsWith ( "##" ) && trimmed . Length > 0 )
296+ {
297+ var isCommented = trimmed . StartsWith ( '#' ) ;
298+ var line = isCommented ? uncommented : trimmed ;
299+ var eq = line . IndexOf ( '=' ) ;
300+ if ( eq > 0 )
301+ {
302+ var key = line [ ..eq ] . Trim ( ) ;
303+ if ( sections . TryGetValue ( currentSection , out var sec ) && sec . Entries . TryGetValue ( key , out var val ) )
304+ {
305+ var prefix = sec . Enabled ? "" : "#" ;
306+ builder . Append ( prefix ) . Append ( key ) . Append ( " = " ) . AppendLine ( FormatTomlValue ( val ) ) ;
307+ usedEntries . Add ( key ) ;
308+ continue ;
309+ }
310+ }
311+ }
312+
313+ builder . AppendLine ( rawLine ) ;
314+ }
315+
316+ return builder . ToString ( ) ;
317+ }
318+
260319 private static string SerializeConfig ( Dictionary < string , ModSectionConfig > sections )
261320 {
262321 var builder = new StringBuilder ( ) ;
@@ -266,10 +325,7 @@ private static string SerializeConfig(Dictionary<string, ModSectionConfig> secti
266325 builder . Append ( sectionPrefix ) . Append ( '[' ) . Append ( sectionName ) . AppendLine ( "]" ) ;
267326
268327 foreach ( var ( key , value ) in section . Entries )
269- {
270- // 禁用 section 内的配置项保留为注释,便于玩家手动编辑时理解默认格式。
271328 builder . Append ( sectionPrefix ) . Append ( key ) . Append ( " = " ) . AppendLine ( FormatTomlValue ( value ) ) ;
272- }
273329
274330 builder . AppendLine ( ) ;
275331 }
0 commit comments