Skip to content

Commit

Permalink
Make mods with missing files reinstallable via update checkbox
Browse files Browse the repository at this point in the history
  • Loading branch information
HebaruSan committed Mar 24, 2024
1 parent 06e38a5 commit bd76c47
Show file tree
Hide file tree
Showing 11 changed files with 35 additions and 24 deletions.
2 changes: 1 addition & 1 deletion Cmdline/Action/List.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public int RunCommand(CKAN.GameInstance instance, object raw_options)
{
var installed = new SortedDictionary<string, ModuleVersion>(registry.Installed());
var upgradeable = registry
.CheckUpgradeable(instance.VersionCriteria(), new HashSet<string>())
.CheckUpgradeable(instance, new HashSet<string>())
[true]
.Select(m => m.identifier)
.ToHashSet();
Expand Down
4 changes: 2 additions & 2 deletions Cmdline/Action/Upgrade.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public int RunCommand(CKAN.GameInstance instance, object raw_options)
if (options.upgrade_all)
{
var to_upgrade = registry
.CheckUpgradeable(instance.VersionCriteria(), new HashSet<string>())
.CheckUpgradeable(instance, new HashSet<string>())
[true];
if (to_upgrade.Count == 0)
{
Expand Down Expand Up @@ -225,7 +225,7 @@ private void UpgradeModules(GameInstanceManager manager,
.ToList();
// Modules allowed by THOSE modules' relationships
var upgradeable = registry
.CheckUpgradeable(crit, heldIdents, limiters)
.CheckUpgradeable(instance, heldIdents, limiters)
[true]
.ToDictionary(m => m.identifier,
m => m);
Expand Down
2 changes: 1 addition & 1 deletion ConsoleUI/InstallScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public override void Run(ConsoleTheme theme, Action<ConsoleTheme> process = null
}
if (plan.Upgrade.Count > 0) {
var upgGroups = registry
.CheckUpgradeable(manager.CurrentInstance.VersionCriteria(),
.CheckUpgradeable(manager.CurrentInstance,
// Hold identifiers not chosen for upgrading
registry.Installed(false)
.Keys
Expand Down
2 changes: 1 addition & 1 deletion ConsoleUI/ModInfoScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ private int addDependencies(int top = 8)
int nameW = midL - 2 - lblW - 2 - 1;
int depsH = (h - 2) * numDeps / (numDeps + numConfs);
var upgradeableGroups = registry
.CheckUpgradeable(manager.CurrentInstance.VersionCriteria(),
.CheckUpgradeable(manager.CurrentInstance,
new HashSet<string>());

AddObject(new ConsoleFrame(
Expand Down
2 changes: 1 addition & 1 deletion ConsoleUI/ModListScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ private List<CkanModule> GetAllMods(ConsoleTheme theme, bool force = false)
}
}
upgradeableGroups = registry
.CheckUpgradeable(crit, new HashSet<string>());
.CheckUpgradeable(manager.CurrentInstance, new HashSet<string>());
}
return allMods;
}
Expand Down
25 changes: 17 additions & 8 deletions Core/Registry/IRegistryQuerier.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;
Expand Down Expand Up @@ -172,7 +173,7 @@ public static bool IsAutodetected(this IRegistryQuerier querier, string identifi
/// </summary>
public static bool HasUpdate(this IRegistryQuerier querier,
string identifier,
GameVersionCriteria versionCrit,
GameInstance instance,
out CkanModule latestMod,
ICollection<CkanModule> installed = null)
{
Expand All @@ -186,7 +187,7 @@ public static bool HasUpdate(this IRegistryQuerier querier,
// Check if it's available
try
{
latestMod = querier.LatestAvailable(identifier, versionCrit, null, installed);
latestMod = querier.LatestAvailable(identifier, instance.VersionCriteria(), null, installed);
}
catch
{
Expand All @@ -199,7 +200,15 @@ public static bool HasUpdate(this IRegistryQuerier querier,
// Check if the installed module is up to date
var comp = latestMod.version.CompareTo(instVer);
if (comp == -1
|| (comp == 0 && !querier.MetadataChanged(identifier)))
|| (comp == 0 && !querier.MetadataChanged(identifier)
// Check if any of the files or directories are missing
&& (instance == null
|| (querier.InstalledModule(identifier)
?.Files
.Select(instance.ToAbsoluteGameDir)
.All(p => Directory.Exists(p) || File.Exists(p))
// Manually installed, consider up to date
?? true))))
{
latestMod = null;
return false;
Expand All @@ -212,26 +221,26 @@ public static bool HasUpdate(this IRegistryQuerier querier,
}

public static Dictionary<bool, List<CkanModule>> CheckUpgradeable(this IRegistryQuerier querier,
GameVersionCriteria versionCrit,
GameInstance instance,
HashSet<string> heldIdents)
{
// Get the absolute latest versions ignoring restrictions,
// to break out of mutual version-depending deadlocks
var unlimited = querier.Installed(false)
.Keys
.Select(ident => !heldIdents.Contains(ident)
&& querier.HasUpdate(ident, versionCrit,
&& querier.HasUpdate(ident, instance,
out CkanModule latest)
&& !latest.IsDLC
? latest
: querier.GetInstalledVersion(ident))
.Where(m => m != null)
.ToList();
return querier.CheckUpgradeable(versionCrit, heldIdents, unlimited);
return querier.CheckUpgradeable(instance, heldIdents, unlimited);
}

public static Dictionary<bool, List<CkanModule>> CheckUpgradeable(this IRegistryQuerier querier,
GameVersionCriteria versionCrit,
GameInstance instance,
HashSet<string> heldIdents,
List<CkanModule> initial)
{
Expand All @@ -241,7 +250,7 @@ public static Dictionary<bool, List<CkanModule>> CheckUpgradeable(this IRegistry
foreach (var ident in initial.Select(module => module.identifier))
{
if (!heldIdents.Contains(ident)
&& querier.HasUpdate(ident, versionCrit,
&& querier.HasUpdate(ident, instance,
out CkanModule latest, initial)
&& !latest.IsDLC)
{
Expand Down
3 changes: 2 additions & 1 deletion GUI/Controls/ManageMods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1857,6 +1857,7 @@ public HashSet<ModChange> ComputeUserChangeSet()
=> mainModList.ComputeUserChangeSet(
RegistryManager.Instance(currentInstance, repoData).registry,
currentInstance.VersionCriteria(),
currentInstance,
UpdateCol, ReplaceCol);

[ForbidGUICalls]
Expand All @@ -1872,7 +1873,7 @@ public void UpdateChangeSetAndConflicts(GameInstance inst, IRegistryQuerier regi
Dictionary<GUIMod, string> new_conflicts = null;

var gameVersion = inst.VersionCriteria();
var user_change_set = mainModList.ComputeUserChangeSet(registry, gameVersion, UpdateCol, ReplaceCol);
var user_change_set = mainModList.ComputeUserChangeSet(registry, gameVersion, inst, UpdateCol, ReplaceCol);
try
{
// Set the target versions of upgrading mods based on what's actually allowed
Expand Down
7 changes: 4 additions & 3 deletions GUI/Model/ModList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ private IEnumerable<ModChange> rowChanges(DataGridViewRow row,

public HashSet<ModChange> ComputeUserChangeSet(IRegistryQuerier registry,
GameVersionCriteria crit,
GameInstance instance,
DataGridViewColumn upgradeCol,
DataGridViewColumn replaceCol)
{
Expand All @@ -454,7 +455,7 @@ public HashSet<ModChange> ComputeUserChangeSet(IRegistryQuerier registry,
.ToArray();
if (upgrades.Length > 0)
{
var upgradeable = registry.CheckUpgradeable(crit,
var upgradeable = registry.CheckUpgradeable(instance,
// Hold identifiers not chosen for upgrading
registry.Installed(false)
.Select(kvp => kvp.Key)
Expand Down Expand Up @@ -503,7 +504,7 @@ public bool ResetHasUpdate(GameInstance inst,
List<ModChange> ChangeSet,
DataGridViewRowCollection rows)
{
var upgGroups = registry.CheckUpgradeable(inst.VersionCriteria(),
var upgGroups = registry.CheckUpgradeable(inst,
ModuleLabels.HeldIdentifiers(inst)
.ToHashSet());
var dlls = registry.InstalledDlls.ToList();
Expand Down Expand Up @@ -571,7 +572,7 @@ private IEnumerable<GUIMod> GetGUIMods(IRegistryQuerier registry,
HashSet<string> installedIdents,
bool hideEpochs,
bool hideV)
=> registry.CheckUpgradeable(versionCriteria,
=> registry.CheckUpgradeable(inst,
ModuleLabels.HeldIdentifiers(inst)
.ToHashSet())
.SelectMany(kvp => kvp.Value
Expand Down
6 changes: 3 additions & 3 deletions Tests/Core/Registry/Registry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ public void HasUpdate_WithUpgradeableManuallyInstalledMod_ReturnsTrue()
var mod = registry.GetModuleByVersion("AutoDetectedMod", "1.0");

GameInstance gameInst = gameInstWrapper.KSP;
gameInst.SetCompatibleVersions(new List<GameVersion> { mod.ksp_version });
registry.SetDlls(new Dictionary<string, string>()
{
{
Expand All @@ -264,10 +265,9 @@ public void HasUpdate_WithUpgradeableManuallyInstalledMod_ReturnsTrue()
"GameData", $"{mod.identifier}.dll"))
}
});
GameVersionCriteria crit = new GameVersionCriteria(mod.ksp_version);

// Act
bool has = registry.HasUpdate(mod.identifier, crit, out _);
bool has = registry.HasUpdate(mod.identifier, gameInst, out _);

// Assert
Assert.IsTrue(has, "Can't upgrade manually installed DLL");
Expand Down Expand Up @@ -320,7 +320,7 @@ public void HasUpdate_OtherModDependsOnCurrent_ReturnsFalse()
GameVersionCriteria crit = new GameVersionCriteria(olderDepMod.ksp_version);

// Act
bool has = registry.HasUpdate(olderDepMod.identifier, crit, out _,
bool has = registry.HasUpdate(olderDepMod.identifier, gameInst, out _,
registry.InstalledModules
.Select(im => im.Module)
.ToList());
Expand Down
2 changes: 1 addition & 1 deletion Tests/GUI/Model/GUIMod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public void HasUpdate_UpdateAvailable_ReturnsTrue()
var registry = new Registry(repoData.Manager, repo.repo);

registry.RegisterModule(old_version, new List<string>(), null, false);
var upgradeableGroups = registry.CheckUpgradeable(tidy.KSP.VersionCriteria(),
var upgradeableGroups = registry.CheckUpgradeable(tidy.KSP,
new HashSet<string>());

var mod = new GUIMod(old_version, repoData.Manager, registry, tidy.KSP.VersionCriteria(),
Expand Down
4 changes: 2 additions & 2 deletions Tests/GUI/Model/ModList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class ModListTests
public void ComputeFullChangeSetFromUserChangeSet_WithEmptyList_HasEmptyChangeSet()
{
var item = new ModList();
Assert.That(item.ComputeUserChangeSet(null, null, null, null), Is.Empty);
Assert.That(item.ComputeUserChangeSet(null, null, null, null, null), Is.Empty);
}

[Test]
Expand Down Expand Up @@ -210,7 +210,7 @@ public void InstallAndSortByCompat_WithAnyCompat_NoCrash()
{
// Install the "other" module
installer.InstallList(
modList.ComputeUserChangeSet(null, null, null, null).Select(change => change.Mod).ToList(),
modList.ComputeUserChangeSet(null, null, null, null, null).Select(change => change.Mod).ToList(),
new RelationshipResolverOptions(),
registryManager,
ref possibleConfigOnlyDirs,
Expand Down

0 comments on commit bd76c47

Please sign in to comment.