Skip to content

Commit

Permalink
Merge #2762 Update GUI modlist if scan detects changes
Browse files Browse the repository at this point in the history
  • Loading branch information
HebaruSan committed May 14, 2019
2 parents e5b1097 + f6afe59 commit 74b06ad
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file.
- [Core] Save registry inside of scan transaction (#2755 by: HebaruSan; reviewed: DasSkelett)
- [Core] Cache downloads individually upon completion (#2756 by: HebaruSan; reviewed: DasSkelett)
- [GUI] Hide auto-installed checkbox for auto-detected mods (#2758 by: HebaruSan; reviewed: DasSkelett)
- [GUI] Update GUI modlist if scan detects changes (#2762 by: HebaruSan; reviewed: DasSkelett)

## v1.26.2

Expand Down
35 changes: 20 additions & 15 deletions Core/KSP.cs
Original file line number Diff line number Diff line change
Expand Up @@ -404,13 +404,17 @@ public KspVersionCriteria VersionCriteria()
/// Clears the registry of DLL data, and refreshes it by scanning GameData.
/// This operates as a transaction.
/// This *saves* the registry upon completion.
/// TODO: This would likely be better in the Registry class itself.
/// </summary>
// TODO: This would likely be better in the Registry class itself.
public void ScanGameData()
/// <returns>
/// True if found anything different, false if same as before
/// </returns>
public bool ScanGameData()
{
var manager = RegistryManager.Instance(this);
using (TransactionScope tx = CkanTransaction.CreateTransactionScope())
{
var oldDlls = new HashSet<string>(manager.registry.InstalledDlls);
manager.registry.ClearDlls();

// TODO: It would be great to optimise this to skip .git directories and the like.
Expand All @@ -421,27 +425,28 @@ public void ScanGameData()
// GameData *twice*.
//
// The least evil is to walk it once, and filter it ourselves.
IEnumerable<string> files = Directory.EnumerateFiles(
GameData(),
"*",
SearchOption.AllDirectories
);
IEnumerable<string> files = Directory
.EnumerateFiles(GameData(), "*", SearchOption.AllDirectories)
.Where(file => dllRegex.IsMatch(file))
.Select(KSPPathUtils.NormalizePath)
.Where(absPath => !DllIgnoreList.Contains(ToRelativeGameDir(absPath)));

files = files.Where(file => Regex.IsMatch(file, @"\.dll$", RegexOptions.IgnoreCase));

foreach (string dll in files.Select(KSPPathUtils.NormalizePath))
foreach (string dll in files)
{
var relativePath = ToRelativeGameDir(dll);

if (!DllIgnoreList.Contains(relativePath))
manager.registry.RegisterDll(this, dll);
manager.registry.RegisterDll(this, dll);
}
var newDlls = new HashSet<string>(manager.registry.InstalledDlls);
bool dllChanged = !oldDlls.SetEquals(newDlls);

manager.ScanDlc();
bool dlcChanged = manager.ScanDlc();
manager.Save(false);
tx.Complete();

return dllChanged || dlcChanged;
}
}

private static readonly Regex dllRegex = new Regex(@"\.dll$", RegexOptions.IgnoreCase | RegexOptions.Compiled);

#endregion

Expand Down
42 changes: 39 additions & 3 deletions Core/Registry/RegistryManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -469,22 +469,58 @@ public void ExportInstalled(string path, bool recommends, bool with_versions)
file_transaction.WriteAllText(path, serialized);
}

public void ScanDlc()
/// <summary>
/// Look for DLC installed in GameData
/// </summary>
/// <returns>
/// True if not the same list as last scan, false otherwise
/// </returns>
public bool ScanDlc()
{
var testDlc = TestDlcScan();
var wellKnownDlc = WellKnownDlcScan();
var dlc = new Dictionary<string, UnmanagedModuleVersion>(registry.InstalledDlc);
UnmanagedModuleVersion foundVer;
bool changed = false;

registry.ClearDlc();

var testDlc = TestDlcScan();
foreach (var i in testDlc)
{
if (!changed
&& (!dlc.TryGetValue(i.Key, out foundVer)
|| foundVer != i.Value))
{
changed = true;
}
registry.RegisterDlc(i.Key, i.Value);
}

var wellKnownDlc = WellKnownDlcScan();
foreach (var i in wellKnownDlc)
{
if (!changed
&& (!dlc.TryGetValue(i.Key, out foundVer)
|| foundVer != i.Value))
{
changed = true;
}
registry.RegisterDlc(i.Key, i.Value);
}

// Check if anything got removed
if (!changed)
{
foreach (var i in dlc)
{
if (!registry.InstalledDlc.TryGetValue(i.Key, out foundVer)
|| foundVer != i.Value)
{
changed = true;
break;
}
}
}
return changed;
}

private Dictionary<string, UnmanagedModuleVersion> TestDlcScan()
Expand Down
9 changes: 7 additions & 2 deletions GUI/MainRepo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ public void UpdateRepo()
{
tabController.RenameTab("WaitTabPage", "Updating repositories");

CurrentInstance.ScanGameData();

try
{
m_UpdateRepoWorker.RunWorkerAsync();
Expand Down Expand Up @@ -65,6 +63,9 @@ private void UpdateRepo(object sender, DoWorkEventArgs e)
{
try
{
AddStatusMessage("Scanning GameData for DLCs and manually installed modules...");
bool scanChanged = CurrentInstance.ScanGameData();

AddStatusMessage("Updating repositories...");

// Note the current mods' compatibility for the NewlyCompatible filter
Expand All @@ -80,6 +81,10 @@ private void UpdateRepo(object sender, DoWorkEventArgs e)
RepoUpdateResult result = Repo.UpdateAllRepositories(
RegistryManager.Instance(CurrentInstance),
CurrentInstance, Manager.Cache, GUI.user);
if (result == RepoUpdateResult.NoChanges && scanChanged)
{
result = RepoUpdateResult.Updated;
}
e.Result = new KeyValuePair<RepoUpdateResult, Dictionary<string, bool>>(
result, oldModules);
}
Expand Down

0 comments on commit 74b06ad

Please sign in to comment.