Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update GUI modlist if scan detects changes #2762

Merged
merged 1 commit into from
May 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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