Skip to content

Commit 79f19ff

Browse files
authored
Merge pull request #1 from brianries/progress_panel_addition
Progress panel addition
2 parents f3d96e0 + 49a6f6a commit 79f19ff

6 files changed

Lines changed: 343 additions & 34 deletions

File tree

ModTek/ModTek.cs

Lines changed: 87 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Newtonsoft.Json;
88
using Newtonsoft.Json.Linq;
99
using System;
10+
using System.Collections;
1011
using System.Collections.Generic;
1112
using System.Diagnostics;
1213
using System.IO;
@@ -17,11 +18,13 @@
1718
// ReSharper disable FieldCanBeMadeReadOnly.Local
1819

1920
namespace 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($"\tAdded/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
}

ModTek/ModTek.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@
6666
<HintPath>$(BattleTechGame)\BattleTech_Data\Managed\UnityEngine.dll</HintPath>
6767
<Private>False</Private>
6868
</Reference>
69+
<Reference Include="UnityEngine.UI, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
70+
<HintPath>$(BattleTechGame)\BattleTech_Data\Managed\UnityEngine.UI.dll</HintPath>
71+
</Reference>
6972
</ItemGroup>
7073
<ItemGroup>
7174
<Compile Include="IManifestEntry.cs" />
@@ -75,6 +78,7 @@
7578
<Compile Include="ModDef.cs" />
7679
<Compile Include="ModTek.cs" />
7780
<Compile Include="Patches.cs" />
81+
<Compile Include="ProgressPanel.cs" />
7882
<Compile Include="Properties\AssemblyInfo.cs" />
7983
</ItemGroup>
8084
<ItemGroup>

ModTek/Patches.cs

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,18 +138,44 @@ public static void Prefix(ref string fileID)
138138
[HarmonyPatch(typeof(VersionManifestUtilities), "LoadDefaultManifest")]
139139
public static class VersionManifestUtilities_LoadDefaultManifest_Patch
140140
{
141-
public static void Postfix(VersionManifest __result)
141+
public static bool Prefix(ref VersionManifest __result)
142142
{
143-
ModTek.AddModEntries(__result);
143+
// Return the cached manifest if it exists -- otherwise call the method as normal
144+
if (ModTek.cachedManifest != null)
145+
{
146+
__result = ModTek.cachedManifest;
147+
return false;
148+
}
149+
else
150+
{
151+
return true;
152+
}
144153
}
145154
}
146155

147-
[HarmonyPatch(typeof(DataManager), new[] { typeof(MessageCenter) })]
148-
public static class DataManager_CTOR_Patch
156+
// This will disable activateAfterInit from functioning for the Start() on the "Main" game object which activates the BattleTechGame object
157+
// This stops the main game object from loading immediately -- so work can be done beforehand
158+
[HarmonyPatch(typeof(ActivateAfterInit), "Start")]
159+
public static class ActivateAfterInit_Start_Patch
149160
{
150-
public static void Prefix()
161+
public static bool Prefix(ActivateAfterInit __instance)
151162
{
152-
ModTek.LoadMods();
163+
Traverse trav = Traverse.Create(__instance);
164+
if (ActivateAfterInit.ActivateAfter.Start.Equals(trav.Field("activateAfter").GetValue<ActivateAfterInit.ActivateAfter>()))
165+
{
166+
GameObject[] gameObjects = trav.Field("activationSet").GetValue<GameObject[]>();
167+
foreach (var gameObject in gameObjects)
168+
{
169+
if ("BattleTechGame".Equals(gameObject.name))
170+
{
171+
// Don't activate through this call!
172+
return false;
173+
}
174+
}
175+
}
176+
// Call the method
177+
return true;
153178
}
154179
}
155180
}
181+

0 commit comments

Comments
 (0)