77using Newtonsoft . Json ;
88using Newtonsoft . Json . Linq ;
99using System ;
10+ using System . Collections ;
1011using System . Collections . Generic ;
1112using System . Diagnostics ;
1213using System . IO ;
1718// ReSharper disable FieldCanBeMadeReadOnly.Local
1819
1920namespace ModTek
20- {
21+ {
2122 using static Logger ;
2223
2324 public static class ModTek
2425 {
26+ public static VersionManifest cachedManifest = null ;
27+
2528 private static bool hasLoadedMods ; //defaults to false
2629
2730 // file/directory names
@@ -123,9 +126,21 @@ public static void Init()
123126 jsonMergeCache = LoadOrCreateMergeCache ( MergeCachePath ) ;
124127 typeCache = LoadOrCreateTypeCache ( TypeCachePath ) ;
125128
126- // init harmony and patch the stuff that comes with ModTek (contained in Patches.cs)
127- var harmony = HarmonyInstance . Create ( "io.github.mpstark.ModTek" ) ;
128- harmony . PatchAll ( Assembly . GetExecutingAssembly ( ) ) ;
129+ // First step in setting up the progress panel
130+ if ( ProgressPanel . Initialize ( ModDirectory , $ "ModTek v{ Assembly . GetExecutingAssembly ( ) . GetName ( ) . Version } ") )
131+ {
132+ // init harmony and patch the stuff that comes with ModTek (contained in Patches.cs)
133+ var harmony = HarmonyInstance . Create ( "io.github.mpstark.ModTek" ) ;
134+ harmony . PatchAll ( Assembly . GetExecutingAssembly ( ) ) ;
135+
136+ LoadMods ( ) ;
137+
138+ BuildCachedManifest ( ) ;
139+ }
140+ else
141+ {
142+ Log ( "Failed to load progress bar. Skipping mod loading completely." ) ;
143+ }
129144
130145 stopwatch . Stop ( ) ;
131146 }
@@ -329,13 +344,24 @@ private static void LoadMod(ModDef modDef)
329344
330345 internal static void LoadMods ( )
331346 {
347+ ProgressPanel . SubmitWork ( ModTek . LoadMoadsLoop ) ;
348+ }
349+
350+ internal static IEnumerator < ProgressReport > LoadMoadsLoop ( )
351+ {
352+ // Only want to run this function once -- it could get submitted a few times
332353 if ( hasLoadedMods )
333- return ;
354+ {
355+ yield break ;
356+ }
334357
335358 stopwatch . Start ( ) ;
336359
360+ string sliderText = "Loading Mods" ;
361+
337362 Log ( "" ) ;
338363 LogWithDate ( "Pre-loading mods..." ) ;
364+ yield return new ProgressReport ( 0 , sliderText , "Pre-loading mods..." ) ;
339365
340366 // find all sub-directories that have a mod.json file
341367 var modDirectories = Directory . GetDirectories ( ModDirectory )
@@ -345,7 +371,7 @@ internal static void LoadMods()
345371 {
346372 hasLoadedMods = true ;
347373 Log ( "No ModTek-compatable mods found." ) ;
348- return ;
374+ yield break ;
349375 }
350376
351377 // create ModDef objects for each mod.json file
@@ -384,10 +410,12 @@ internal static void LoadMods()
384410 PropagateConflictsForward ( modDefs ) ;
385411 modLoadOrder = GetLoadOrder ( modDefs , out var willNotLoad ) ;
386412
413+ int modLoaded = 0 ;
387414 // lists guarentee order
388415 foreach ( var modName in modLoadOrder )
389416 {
390417 var modDef = modDefs [ modName ] ;
418+ yield return new ProgressReport ( ( float ) modLoaded ++ / ( float ) modLoadOrder . Count , sliderText , string . Format ( "Loading Mod: {0}" , modDef . Name ) ) ;
391419
392420 try
393421 {
@@ -417,6 +445,8 @@ internal static void LoadMods()
417445 File . WriteAllText ( LoadOrderPath , JsonConvert . SerializeObject ( modLoadOrder , Formatting . Indented ) ) ;
418446
419447 hasLoadedMods = true ;
448+
449+ yield break ;
420450 }
421451
422452 private static string InferIDFromFile ( string path )
@@ -686,41 +716,47 @@ private static bool AddModEntryToDB(MetadataDatabase db, string path, string typ
686716 return false ;
687717 }
688718
689- internal static void AddModEntries ( VersionManifest manifest )
719+ internal static void BuildCachedManifest ( )
690720 {
691- if ( ! hasLoadedMods )
692- LoadMods ( ) ;
721+ // First load the default battletech manifest, then it'll get appended to
722+ VersionManifest vanillaManifest = VersionManifestUtilities . LoadDefaultManifest ( ) ;
723+
724+ // Wrapper to be able to submit a parameterless work function
725+ IEnumerator < ProgressReport > NestedFunc ( )
726+ {
727+ IEnumerator < ProgressReport > reports = BuildCachedManifestLoop ( vanillaManifest ) ;
728+ while ( reports . MoveNext ( ) )
729+ {
730+ yield return reports . Current ;
731+ }
732+ }
733+
734+ ProgressPanel . SubmitWork ( NestedFunc ) ;
735+ }
736+
737+
738+ internal static IEnumerator < ProgressReport > BuildCachedManifestLoop ( VersionManifest manifest ) {
693739
694740 stopwatch . Start ( ) ;
695741
696742 // there are no mods loaded, just return
697743 if ( modLoadOrder == null || modLoadOrder . Count == 0 )
698- return ;
744+ yield break ;
699745
700- if ( modEntries != null )
701- {
702- LogWithDate ( "Loading another manifest with already setup mod manifests." ) ;
703- foreach ( var modEntry in modEntries )
704- {
705- AddModEntry ( manifest , modEntry ) ;
706- }
707-
708- stopwatch . Stop ( ) ;
709- Log ( "" ) ;
710- LogWithDate ( $ "Done. Elapsed running time: { stopwatch . Elapsed . TotalSeconds } seconds\n ") ;
711- return ;
712- }
746+ string loadingModText = "Loading Mod Manifests" ;
747+ yield return new ProgressReport ( 0.0f , loadingModText , "Setting up mod manifests..." ) ;
713748
714749 LogWithDate ( "Setting up mod manifests..." ) ;
715750
716751 var jsonMerges = new Dictionary < string , List < string > > ( ) ;
717752 modEntries = new List < ModDef . ManifestEntry > ( ) ;
718- foreach ( var modName in modLoadOrder )
719- {
720- if ( ! modManifest . ContainsKey ( modName ) )
721- continue ;
753+ int modCount = 0 ;
722754
755+ var manifestMods = modLoadOrder . Where ( name => modManifest . ContainsKey ( name ) ) . ToList ( ) ;
756+ foreach ( var modName in manifestMods )
757+ {
723758 Log ( $ "\t { modName } :") ;
759+ yield return new ProgressReport ( ( float ) modCount ++ / ( float ) manifestMods . Count , loadingModText , string . Format ( "Loading manifest for {0}" , modName ) ) ;
724760 foreach ( var modEntry in modManifest [ modName ] )
725761 {
726762 // type being null means we have to figure out the type from the path (StreamingAssets)
@@ -840,13 +876,18 @@ internal static void AddModEntries(VersionManifest manifest)
840876 }
841877 }
842878
879+ yield return new ProgressReport ( 100.0f , "JSON" , "Writing JSON file to disk" ) ;
880+
843881 // write type cache to disk
844882 WriteJsonFile ( TypeCachePath , typeCache ) ;
845883
846884 // perform merges into cache
847885 LogWithDate ( "Doing merges..." ) ;
886+ yield return new ProgressReport ( 0.0f , "Merges" , "Doing Merges..." ) ;
887+ int mergeCount = 0 ;
848888 foreach ( var jsonMerge in jsonMerges )
849889 {
890+ yield return new ProgressReport ( ( float ) mergeCount ++ / jsonMerges . Count , "Merges" , string . Format ( "Merging {0}" , jsonMerge . Key ) ) ;
850891 var cachePath = jsonMergeCache . GetOrCreateCachedEntry ( jsonMerge . Key , jsonMerge . Value ) ;
851892
852893 // something went wrong (the parent json prob had errors)
@@ -863,6 +904,8 @@ internal static void AddModEntries(VersionManifest manifest)
863904 modEntries . Add ( cacheEntry ) ;
864905 }
865906
907+ yield return new ProgressReport ( 100.0f , "Merge Cache" , "Writing Merge Cache to disk" ) ;
908+
866909 // write merge cache to disk
867910 jsonMergeCache . WriteCacheToDisk ( Path . Combine ( CacheDirectory , MERGE_CACHE_FILE_NAME ) ) ;
868911
@@ -872,6 +915,9 @@ internal static void AddModEntries(VersionManifest manifest)
872915 var rebuildDB = false ;
873916 var replacementEntries = new List < VersionManifestEntry > ( ) ;
874917 var removeEntries = new List < string > ( ) ;
918+
919+ string dbText = "Syncing Database" ;
920+ yield return new ProgressReport ( 0.0f , dbText , "" ) ;
875921 foreach ( var kvp in dbCache )
876922 {
877923 var path = kvp . Key ;
@@ -897,6 +943,8 @@ internal static void AddModEntries(VersionManifest manifest)
897943 }
898944
899945 // add removed entries replacements to db
946+ dbText = "Cleaning Database" ;
947+ yield return new ProgressReport ( 100.0f , dbText , "" ) ;
900948 if ( ! rebuildDB )
901949 {
902950 // remove old entries
@@ -924,12 +972,19 @@ internal static void AddModEntries(VersionManifest manifest)
924972 }
925973
926974 // add needed files to db
975+ dbText = "Populating Database" ;
976+ int addCount = 0 ;
977+ yield return new ProgressReport ( 0.0f , dbText , "" ) ;
927978 using ( var metadataDatabase = new MetadataDatabase ( ) )
928979 {
929980 foreach ( var modEntry in modEntries )
930981 {
931982 if ( modEntry . AddToDB && AddModEntryToDB ( metadataDatabase , modEntry . Path , modEntry . Type ) )
983+ {
984+ yield return new ProgressReport ( ( float ) addCount / ( float ) modEntries . Count , dbText , string . Format ( "Added {0}" , modEntry . Path ) ) ;
932985 Log ( $ "\t Added/Updated { modEntry . Id } ({ modEntry . Type } )") ;
986+ }
987+ addCount ++ ;
933988 }
934989 }
935990
@@ -939,6 +994,11 @@ internal static void AddModEntries(VersionManifest manifest)
939994 stopwatch . Stop ( ) ;
940995 Log ( "" ) ;
941996 LogWithDate ( $ "Done. Elapsed running time: { stopwatch . Elapsed . TotalSeconds } seconds\n ") ;
997+
998+ // Cache the completed manifest
999+ ModTek . cachedManifest = manifest ;
1000+
1001+ yield break ;
9421002 }
9431003 }
9441004}
0 commit comments