@@ -38,6 +38,8 @@ public partial class XmlInstallerWindow : DecoratableWindow
3838 string ModConfigPath = string . Empty ;
3939 string ModUnique = string . Empty ;
4040 Version ModVersion = null ;
41+ List < string > ModDependencies = new List < string > ( ) ;
42+ List < Version > ModDependenciesVersions = new List < Version > ( ) ;
4143 XmlDocument Document = new XmlDocument ( ) ;
4244 List < ComponentInfo > Prerequisites = new List < ComponentInfo > ( ) ;
4345 List < ComponentInfo > CompatFiles = new List < ComponentInfo > ( ) ;
@@ -254,6 +256,78 @@ private void PrepareInstaller()
254256 else
255257 ModVersion = null ;
256258
259+ if ( Document . SelectSingleNode ( "/mod" ) . Attributes [ "depends" ] != null )
260+ {
261+ string dependsString = Document . SelectSingleNode ( "/mod" ) . Attributes [ "depends" ] . Value ;
262+ string dependsVersionString = null ;
263+ if ( Document . SelectSingleNode ( "/mod" ) . Attributes [ "dependsVersions" ] != null )
264+ dependsVersionString = Document . SelectSingleNode ( "/mod" ) . Attributes [ "dependsVersions" ] . Value ;
265+ string [ ] dependsUniqueNames = dependsString . Split ( '?' ) ;
266+ string [ ] dependsVersions = dependsVersionString == null ? null : dependsVersionString . Split ( '?' ) ;
267+ bool [ ] foundDepends = new bool [ dependsUniqueNames . Length ] ;
268+ // reset foundDepends
269+ for ( int i = 0 ; i < foundDepends . Length ; i ++ )
270+ foundDepends [ i ] = false ;
271+
272+ ModDependencies = dependsUniqueNames . ToList ( ) ;
273+ if ( dependsVersions != null )
274+ { // TODO: improve this logic...
275+ foreach ( string dependsVersion in dependsVersions )
276+ {
277+ if ( Version . TryParse ( dependsVersion , out Version parsedDependsVersion ) )
278+ {
279+ ModDependenciesVersions . Add ( parsedDependsVersion ) ;
280+ }
281+ }
282+ }
283+
284+ foreach ( ModConfiguration mod in configs )
285+ {
286+ for ( int i = 0 ; i < dependsUniqueNames . Length ; i ++ )
287+ {
288+ if ( mod . Unique == dependsUniqueNames [ i ] )
289+ {
290+ if ( mod . Version != null &&
291+ ( dependsVersions != null ) &&
292+ ( dependsVersions . Length > i ) &&
293+ ( Version . TryParse ( dependsVersions [ i ] , out Version dependVersion ) &&
294+ mod . Version >= dependVersion ) )
295+ { // name + version match
296+ foundDepends [ i ] = true ;
297+ break ;
298+ }
299+ else if ( dependsVersions == null || dependsVersions . Length <= i )
300+ { // name only match
301+ foundDepends [ i ] = true ;
302+ break ;
303+ }
304+ }
305+ }
306+ }
307+
308+ bool satisfiedDepends = true ;
309+ List < string > missingDepends = new List < string > ( ) ;
310+ for ( int i = 0 ; i < foundDepends . Length ; i ++ )
311+ {
312+ if ( ! foundDepends [ i ] )
313+ {
314+ satisfiedDepends = false ;
315+ string missingDependsText = dependsUniqueNames [ i ] ;
316+ if ( dependsVersions != null &&
317+ dependsVersions . Length > i )
318+ {
319+ missingDependsText += " " + dependsVersions [ i ] ;
320+ }
321+ missingDepends . Add ( missingDependsText ) ;
322+ }
323+ }
324+
325+ if ( ! satisfiedDepends )
326+ {
327+ throw new Exception ( $ "This mod has dependencies that you don't have installed: { String . Join ( ", " , missingDepends ) } ") ;
328+ }
329+ }
330+
257331 NameTextBlock . Text = displayName ;
258332 DescriptionTextBlock . Text = ModDescription ;
259333
@@ -769,6 +843,8 @@ await Dispatcher.BeginInvoke(new Action(() =>
769843 {
770844 DisplayName = ModDisplayName ,
771845 Version = ModVersion ,
846+ Dependencies = ModDependencies . ToArray ( ) ,
847+ DependenciesVersions = ModDependenciesVersions . ToArray ( ) ,
772848 ConfiguratorPath = Path . Combine ( ModConfigPath , "ModInfo.xml" )
773849 } ;
774850
@@ -794,6 +870,8 @@ await Dispatcher.BeginInvoke(new Action(() =>
794870 {
795871 DisplayName = ModDisplayName ,
796872 Version = ModVersion ,
873+ Dependencies = ModDependencies . ToArray ( ) ,
874+ DependenciesVersions = ModDependenciesVersions . ToArray ( ) ,
797875 } ;
798876
799877 foreach ( ComponentInfo c in Prerequisites )
0 commit comments