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

Handle incompatible force-installed dependencies of recommendations #3305

Merged
merged 1 commit into from
Feb 24, 2021
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
51 changes: 36 additions & 15 deletions GUI/Controls/ChooseRecommendedMods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@ public ChooseRecommendedMods()
}

public void LoadRecommendations(
IRegistryQuerier registry, GameVersionCriteria GameVersion, NetModuleCache cache,
IRegistryQuerier registry,
HashSet<CkanModule> toInstall, HashSet<CkanModule> toUninstall,
GameVersionCriteria GameVersion, NetModuleCache cache,
Dictionary<CkanModule, Tuple<bool, List<string>>> recommendations,
Dictionary<CkanModule, List<string>> suggestions,
Dictionary<CkanModule, HashSet<string>> supporters
)
{
this.registry = registry;
this.toInstall = toInstall;
this.toUninstall = toUninstall;
this.GameVersion = GameVersion;
Util.Invoke(this, () =>
{
Expand Down Expand Up @@ -83,22 +87,36 @@ private void RecommendedModsListView_ItemChecked(object sender, ItemCheckedEvent

private void MarkConflicts()
{
var conflicts = FindConflicts();
foreach (var item in RecommendedModsListView.Items.Cast<ListViewItem>()
// Apparently ListView handes AddRange by:
// 1. Expanding the Items list to the new size by filling it with nulls
// 2. One by one, replace each null with a real item and call _ItemChecked
// ... so the Items list can contain null!!
.Where(it => it != null))
try
{
item.BackColor = conflicts.ContainsKey(item.Tag as CkanModule)
? Color.LightCoral
: Color.Empty;
var conflicts = FindConflicts();
foreach (var item in RecommendedModsListView.Items.Cast<ListViewItem>()
// Apparently ListView handes AddRange by:
// 1. Expanding the Items list to the new size by filling it with nulls
// 2. One by one, replace each null with a real item and call _ItemChecked
// ... so the Items list can contain null!!
.Where(it => it != null))
{
item.BackColor = conflicts.ContainsKey(item.Tag as CkanModule)
? Color.LightCoral
: Color.Empty;
}
RecommendedModsContinueButton.Enabled = !conflicts.Any();
if (OnConflictFound != null)
{
OnConflictFound(conflicts.Any() ? conflicts.First().Value : "");
}
}
RecommendedModsContinueButton.Enabled = !conflicts.Any();
if (OnConflictFound != null)
catch (DependencyNotSatisfiedKraken k)
{
OnConflictFound(conflicts.Any() ? conflicts.First().Value : "");
var row = RecommendedModsListView.Items.Cast<ListViewItem>()
.FirstOrDefault(it => (it?.Tag as CkanModule) == k.parent);
if (row != null)
{
row.BackColor = Color.LightCoral;
}
RecommendedModsContinueButton.Enabled = false;
OnConflictFound?.Invoke(k.Message);
}
}

Expand All @@ -115,8 +133,9 @@ private Dictionary<CkanModule, String> FindConflicts()
return new RelationshipResolver(
RecommendedModsListView.CheckedItems.Cast<ListViewItem>()
.Select(item => item.Tag as CkanModule)
.Concat(toInstall)
.Distinct(),
new CkanModule[] { },
toUninstall,
conflictOptions, registry, GameVersion
).ConflictList;
}
Expand Down Expand Up @@ -197,6 +216,8 @@ private void RecommendedModsContinueButton_Click(object sender, EventArgs e)
}

private IRegistryQuerier registry;
private HashSet<CkanModule> toInstall;
private HashSet<CkanModule> toUninstall;
private GameVersionCriteria GameVersion;

private TaskCompletionSource<HashSet<CkanModule>> task;
Expand Down
14 changes: 8 additions & 6 deletions GUI/Main/MainInstall.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ private void InstallMods(object sender, DoWorkEventArgs e)

// this will be the final list of mods we want to install
HashSet<CkanModule> toInstall = new HashSet<CkanModule>();
var toUninstall = new HashSet<string>();
var toUninstall = new HashSet<CkanModule>();
var toUpgrade = new HashSet<CkanModule>();

// First compose sets of what the user wants installed, upgraded, and removed.
Expand All @@ -88,7 +88,7 @@ private void InstallMods(object sender, DoWorkEventArgs e)
switch (change.ChangeType)
{
case GUIModChangeType.Remove:
toUninstall.Add(change.Mod.identifier);
toUninstall.Add(change.Mod);
break;
case GUIModChangeType.Update:
toUpgrade.Add(change is ModUpgrade mu
Expand All @@ -102,7 +102,7 @@ private void InstallMods(object sender, DoWorkEventArgs e)
ModuleReplacement repl = registry.GetReplacement(change.Mod, CurrentInstance.VersionCriteria());
if (repl != null)
{
toUninstall.Add(repl.ToReplace.identifier);
toUninstall.Add(repl.ToReplace);
toInstall.Add(repl.ReplaceWith);
}
break;
Expand All @@ -123,8 +123,9 @@ out Dictionary<CkanModule, HashSet<string>> supporters
{
tabController.ShowTab("ChooseRecommendedModsTabPage", 3);
ChooseRecommendedMods.LoadRecommendations(
registry, CurrentInstance.VersionCriteria(),
Manager.Cache, recommendations, suggestions, supporters);
registry, toInstall, toUninstall,
CurrentInstance.VersionCriteria(), Manager.Cache,
recommendations, suggestions, supporters);
tabController.SetTabLock(true);
var result = ChooseRecommendedMods.Wait();
if (result == null)
Expand Down Expand Up @@ -181,7 +182,8 @@ out Dictionary<CkanModule, HashSet<string>> supporters
processSuccessful = false;
if (!installCanceled)
{
installer.UninstallList(toUninstall, ref possibleConfigOnlyDirs, registry_manager, false, toInstall);
installer.UninstallList(toUninstall.Select(m => m.identifier),
ref possibleConfigOnlyDirs, registry_manager, false, toInstall);
processSuccessful = true;
}
}
Expand Down
5 changes: 3 additions & 2 deletions GUI/Main/MainRecommendations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ out Dictionary<CkanModule, HashSet<string>> supporters
{
tabController.ShowTab("ChooseRecommendedModsTabPage", 3);
ChooseRecommendedMods.LoadRecommendations(
registry, versionCriteria,
Manager.Cache, recommendations, suggestions, supporters);
registry, new HashSet<CkanModule>(), new HashSet<CkanModule>(),
versionCriteria, Manager.Cache,
recommendations, suggestions, supporters);
var result = ChooseRecommendedMods.Wait();
tabController.HideTab("ChooseRecommendedModsTabPage");
if (result != null && result.Any())
Expand Down