@@ -12,6 +12,7 @@ public class ExtractResult
1212 public int DdsCount { get ; set ; }
1313 public string OutputDir { get ; set ; } = "" ;
1414 public List < string > Files { get ; set ; } = [ ] ;
15+ public string ? Error { get ; set ; }
1516 }
1617
1718 public class ExtractDdsRequest
@@ -69,22 +70,35 @@ public ActionResult<List<ExtractResult>> ExtractDds([FromBody] ExtractDdsRequest
6970 if ( string . IsNullOrWhiteSpace ( request . Path ) )
7071 return BadRequest ( "路径不能为空" ) ;
7172
73+ if ( ! string . IsNullOrWhiteSpace ( request . OutputDir ) )
74+ {
75+ var safeOut = PathGuard . EnsureWithin ( StaticSettings . GamePath , request . OutputDir ) ;
76+ if ( safeOut == null )
77+ return BadRequest ( "输出目录不在游戏目录范围内" ) ;
78+ request . OutputDir = safeOut ;
79+ }
80+
7281 var results = new List < ExtractResult > ( ) ;
7382
7483 if ( System . IO . File . Exists ( request . Path ) )
7584 {
76- var result = ExtractFromFile ( request . Path , request . OutputDir ) ;
77- if ( result != null ) results . Add ( result ) ;
85+ var safeIn = PathGuard . EnsureWithin ( StaticSettings . GamePath , request . Path ) ;
86+ if ( safeIn == null )
87+ return BadRequest ( "源文件不在游戏目录范围内" ) ;
88+ results . Add ( ExtractFromFile ( safeIn , request . OutputDir ) ) ;
7889 }
7990 else if ( Directory . Exists ( request . Path ) )
8091 {
81- var files = Directory . GetFiles ( request . Path , "*.afb" , SearchOption . TopDirectoryOnly )
82- . Concat ( Directory . GetFiles ( request . Path , "*.svo" , SearchOption . TopDirectoryOnly ) ) ;
92+ var safeIn = PathGuard . EnsureWithin ( StaticSettings . GamePath , request . Path ) ;
93+ if ( safeIn == null )
94+ return BadRequest ( "源目录不在游戏目录范围内" ) ;
95+
96+ var files = Directory . GetFiles ( safeIn , "*.afb" , SearchOption . TopDirectoryOnly )
97+ . Concat ( Directory . GetFiles ( safeIn , "*.svo" , SearchOption . TopDirectoryOnly ) ) ;
8398
8499 foreach ( var file in files )
85100 {
86- var result = ExtractFromFile ( file , request . OutputDir ) ;
87- if ( result != null ) results . Add ( result ) ;
101+ results . Add ( ExtractFromFile ( file , request . OutputDir ) ) ;
88102 }
89103 }
90104 else
@@ -95,36 +109,45 @@ public ActionResult<List<ExtractResult>> ExtractDds([FromBody] ExtractDdsRequest
95109 return Ok ( results ) ;
96110 }
97111
98- private static ExtractResult ? ExtractFromFile ( string filePath , string ? outputDirOverride )
112+ private static ExtractResult ExtractFromFile ( string filePath , string ? outputDirOverride )
99113 {
100- var ext = System . IO . Path . GetExtension ( filePath ) . ToLowerInvariant ( ) ;
101- if ( ext != ".afb" && ext != ".svo" ) return null ;
114+ try
115+ {
116+ var ext = System . IO . Path . GetExtension ( filePath ) . ToLowerInvariant ( ) ;
117+ if ( ext != ".afb" && ext != ".svo" )
118+ return new ExtractResult { SourceFile = filePath , Error = $ "不支持的文件格式: { ext } " } ;
102119
103- var fileData = System . IO . File . ReadAllBytes ( filePath ) ;
104- var ddsList = DDSExtractor . DdsExtractor . ExtractDdsFiles ( fileData , ext == ".afb" ) ;
105- if ( ddsList . Count == 0 ) return null ;
120+ var fileData = System . IO . File . ReadAllBytes ( filePath ) ;
121+ var ddsList = DDSExtractor . DdsExtractor . ExtractDdsFiles ( fileData , ext == ".afb" ) ;
122+ if ( ddsList . Count == 0 )
123+ return new ExtractResult { SourceFile = filePath , Error = "未提取到 DDS" } ;
106124
107- var baseName = System . IO . Path . GetFileNameWithoutExtension ( filePath ) ;
108- var outputDir = ! string . IsNullOrWhiteSpace ( outputDirOverride )
109- ? System . IO . Path . Combine ( outputDirOverride , $ "{ baseName } _extracted")
110- : System . IO . Path . Combine ( System . IO . Path . GetDirectoryName ( filePath ) ! , $ "{ baseName } _extracted") ;
125+ var baseName = System . IO . Path . GetFileNameWithoutExtension ( filePath ) ;
126+ var outputDir = ! string . IsNullOrWhiteSpace ( outputDirOverride )
127+ ? System . IO . Path . Combine ( outputDirOverride , $ "{ baseName } _extracted")
128+ : System . IO . Path . Combine ( System . IO . Path . GetDirectoryName ( filePath ) ! , $ "{ baseName } _extracted") ;
111129
112- Directory . CreateDirectory ( outputDir ) ;
130+ Directory . CreateDirectory ( outputDir ) ;
113131
114- var savedFiles = new List < string > ( ) ;
115- for ( var i = 0 ; i < ddsList . Count ; i ++ )
116- {
117- var outputPath = System . IO . Path . Combine ( outputDir , $ "{ baseName } _{ i + 1 } .dds") ;
118- System . IO . File . WriteAllBytes ( outputPath , ddsList [ i ] ) ;
119- savedFiles . Add ( outputPath ) ;
120- }
132+ var savedFiles = new List < string > ( ) ;
133+ for ( var i = 0 ; i < ddsList . Count ; i ++ )
134+ {
135+ var outputPath = System . IO . Path . Combine ( outputDir , $ "{ baseName } _{ i + 1 } .dds") ;
136+ System . IO . File . WriteAllBytes ( outputPath , ddsList [ i ] ) ;
137+ savedFiles . Add ( outputPath ) ;
138+ }
121139
122- return new ExtractResult
140+ return new ExtractResult
141+ {
142+ SourceFile = filePath ,
143+ DdsCount = ddsList . Count ,
144+ OutputDir = outputDir ,
145+ Files = savedFiles ,
146+ } ;
147+ }
148+ catch ( Exception ex )
123149 {
124- SourceFile = filePath ,
125- DdsCount = ddsList . Count ,
126- OutputDir = outputDir ,
127- Files = savedFiles ,
128- } ;
150+ return new ExtractResult { SourceFile = filePath , Error = ex . Message } ;
151+ }
129152 }
130153}
0 commit comments