Skip to content

Commit

Permalink
Fix modpack installation, install incompatible with confirmation
Browse files Browse the repository at this point in the history
  • Loading branch information
HebaruSan committed Nov 2, 2022
1 parent 5a73b80 commit 75b127a
Show file tree
Hide file tree
Showing 17 changed files with 256 additions and 182 deletions.
4 changes: 4 additions & 0 deletions Core/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Core/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -308,4 +308,5 @@ Free up space on that device or change your settings to use another location.
<data name="NetModuleCacheModuleResuming" xml:space="preserve"><value>{0} {1} ({2}, {3} remaining)</value></data>
<data name="ModuleInstallerUpgradeInstallingUncached" xml:space="preserve"><value> * Install: {0} {1} ({2}, {3} remaining)</value></data>
<data name="ModuleInstallerUpgradeUpgradingResuming" xml:space="preserve"><value> * Upgrade: {0} {1} to {2} ({3}, {4} remaining)</value></data>
<data name="ModpackName" xml:space="preserve"><value>installed-{0}</value></data>
</root>
80 changes: 50 additions & 30 deletions Core/Registry/RegistryManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.ComponentModel;
using System.Reflection;

using ChinhDo.Transactions.FileManager;
using log4net;
Expand Down Expand Up @@ -462,59 +464,77 @@ private string SerializeCurrentInstall(bool recommends = false, bool with_versio
public CkanModule GenerateModpack(bool recommends = false, bool with_versions = true)
{
string gameInstanceName = gameInstance.Name;
string name = $"installed-{gameInstanceName}";
string name = string.Format(Properties.Resources.ModpackName, gameInstanceName);
var crit = gameInstance.VersionCriteria();
var minAndMax = crit.MinAndMax;
var module = new CkanModule(
// v1.18 to allow Unlicense
new ModuleVersion("v1.18"),
Identifier.Sanitize(name),
name,
string.Format(Properties.Resources.RegistryManagerDefaultModpackAbstract, gameInstanceName),
null,
new List<string>() { Environment.UserName },
new List<License>() { new License("unknown") },
new List<string>() { Environment.UserName },
new List<License>() { License.UnknownLicense },
new ModuleVersion(DateTime.UtcNow.ToString("yyyy.MM.dd.hh.mm.ss")),
null,
"metapackage"
)
{
download_content_type = "application/zip",
release_date = DateTime.Now,
"metapackage")
{
ksp_version_min = minAndMax.Lower.AsInclusiveLower().WithoutBuild,
ksp_version_max = minAndMax.Upper.AsInclusiveUpper().WithoutBuild,
download_content_type = typeof(CkanModule).GetTypeInfo()
.GetDeclaredField("download_content_type")
.GetCustomAttribute<DefaultValueAttribute>()
.Value.ToString(),
release_date = DateTime.Now,
};

List<RelationshipDescriptor> mods = registry.Installed(false, false)
.Where(kvp => {
// Skip unavailable modules (custom .ckan files)
try
{
var avail = registry.LatestAvailable(kvp.Key, null, null);
return !avail.IsDLC;
}
catch
{
return false;
}
})
// Case insensitive sort by identifier
.OrderBy(kvp => kvp.Key, StringComparer.OrdinalIgnoreCase)
.Select(kvp => (RelationshipDescriptor) new ModuleRelationshipDescriptor()
{
name = kvp.Key,
version = with_versions ? kvp.Value : null
})
var rels = registry.InstalledModules
.Where(inst => !inst.Module.IsDLC && IsAvailable(inst))
.OrderBy(inst => inst.identifier, StringComparer.OrdinalIgnoreCase)
.Select(with_versions ? (Func<InstalledModule, RelationshipDescriptor>) RelationshipWithVersion
: RelationshipWithoutVersion)
.ToList();

if (recommends)
{
module.recommends = mods;
module.recommends = rels;
}
else
{
module.depends = mods;
module.depends = rels;
}

return module;
}

private bool IsAvailable(InstalledModule inst)
{
try
{
var avail = registry.LatestAvailable(inst.identifier, null, null);
return true;
}
catch
{
// Skip unavailable modules (custom .ckan files)
return false;
}
}

private RelationshipDescriptor RelationshipWithVersion(InstalledModule inst)
=> new ModuleRelationshipDescriptor()
{
name = inst.identifier,
version = inst.Module.version,
};

private RelationshipDescriptor RelationshipWithoutVersion(InstalledModule inst)
=> new ModuleRelationshipDescriptor()
{
name = inst.identifier,
};

/// <summary>
/// Look for DLC installed in GameData
/// </summary>
Expand Down
9 changes: 9 additions & 0 deletions Core/Relationships/RelationshipResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,10 @@ private void ResolveStanza(IEnumerable<RelationshipDescriptor> stanza, Selection
private void Add(CkanModule module, SelectionReason reason)
{
if (module.IsMetapackage)
{
AddReason(module, reason);
return;
}
if (module.IsDLC)
{
throw new ModuleIsDLCKraken(module);
Expand Down Expand Up @@ -698,6 +701,12 @@ public IEnumerable<CkanModule> ModList()
log.DebugFormat("Parent found: {0}, {1}", index, module);
sortedDepsFirst.Insert(index, module);
}
catch (ArgumentException)
{
// ReasonsFor throws this for mods without reasons, just add it to the end
log.DebugFormat("Reasons for parent not found: {0}", module);
sortedDepsFirst.Add(module);
}
catch (InvalidOperationException)
{
// No index, just append
Expand Down
61 changes: 27 additions & 34 deletions Core/Types/RelationshipDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ out CkanModule matched

public abstract List<CkanModule> LatestAvailableWithProvides(
IRegistryQuerier registry, GameVersionCriteria crit, IEnumerable<CkanModule> installed = null,
IEnumerable<CkanModule> toInstall = null
);
IEnumerable<CkanModule> toInstall = null);

public abstract CkanModule ExactMatch(
IRegistryQuerier registry, GameVersionCriteria crit, IEnumerable<CkanModule> installed = null,
IEnumerable<CkanModule> toInstall = null);

public abstract bool Equals(RelationshipDescriptor other);

Expand Down Expand Up @@ -167,11 +170,14 @@ out CkanModule matched

public override List<CkanModule> LatestAvailableWithProvides(
IRegistryQuerier registry, GameVersionCriteria crit, IEnumerable<CkanModule> installed = null,
IEnumerable<CkanModule> toInstall = null
)
{
return registry.LatestAvailableWithProvides(name, crit, this, installed, toInstall);
}
IEnumerable<CkanModule> toInstall = null)
=> registry.LatestAvailableWithProvides(name, crit, this, installed, toInstall);

public override CkanModule ExactMatch(
IRegistryQuerier registry, GameVersionCriteria crit, IEnumerable<CkanModule> installed = null,
IEnumerable<CkanModule> toInstall = null)
=> registry.LatestAvailableWithProvides(name, crit, this, installed, toInstall)
.FirstOrDefault(mod => mod.identifier == name);

public override bool Equals(RelationshipDescriptor other)
{
Expand All @@ -183,15 +189,10 @@ public override bool Equals(RelationshipDescriptor other)
&& max_version == modRel.max_version;
}

public override bool ContainsAny(IEnumerable<string> identifiers)
{
return identifiers.Contains(name);
}
public override bool ContainsAny(IEnumerable<string> identifiers) => identifiers.Contains(name);

public override bool StartsWith(string prefix)
{
return name.IndexOf(prefix, StringComparison.CurrentCultureIgnoreCase) == 0;
}
=> name.IndexOf(prefix, StringComparison.CurrentCultureIgnoreCase) == 0;

/// <summary>
/// Generate a user readable description of the relationship
Expand All @@ -205,16 +206,13 @@ public override bool StartsWith(string prefix)
/// name max_version or earlier
/// </returns>
public override string ToString()
{
return
version != null ? $"{name} {version}"
=> version != null ? $"{name} {version}"
: min_version != null && max_version != null ? $"{name} {min_version}{max_version}"
: min_version != null
? string.Format(Properties.Resources.RelationshipDescriptorMinVersionOnly, name, min_version)
: max_version != null
? string.Format(Properties.Resources.RelationshipDescriptorMaxVersionOnly, name, max_version)
: name;
}

}

Expand Down Expand Up @@ -262,11 +260,14 @@ out CkanModule matched

public override List<CkanModule> LatestAvailableWithProvides(
IRegistryQuerier registry, GameVersionCriteria crit, IEnumerable<CkanModule> installed = null,
IEnumerable<CkanModule> toInstall = null
)
{
return any_of?.SelectMany(r => r.LatestAvailableWithProvides(registry, crit, installed, toInstall)).Distinct().ToList();
}
IEnumerable<CkanModule> toInstall = null)
=> any_of?.SelectMany(r => r.LatestAvailableWithProvides(registry, crit, installed, toInstall)).Distinct().ToList();

// Exact match is not possible for any_of
public override CkanModule ExactMatch(
IRegistryQuerier registry, GameVersionCriteria crit, IEnumerable<CkanModule> installed = null,
IEnumerable<CkanModule> toInstall = null)
=> null;

public override bool Equals(RelationshipDescriptor other)
{
Expand All @@ -276,22 +277,14 @@ public override bool Equals(RelationshipDescriptor other)
}

public override bool ContainsAny(IEnumerable<string> identifiers)
{
return any_of?.Any(r => r.ContainsAny(identifiers))
?? false;
}
=> any_of?.Any(r => r.ContainsAny(identifiers)) ?? false;

public override bool StartsWith(string prefix)
{
return any_of?.Any(r => r.StartsWith(prefix))
?? false;
}
=> any_of?.Any(r => r.StartsWith(prefix)) ?? false;

public override string ToString()
{
return any_of?.Select(r => r.ToString())
=> any_of?.Select(r => r.ToString())
.Aggregate((a, b) =>
string.Format(Properties.Resources.RelationshipDescriptorAnyOfJoiner, a, b));
}
}
}
Loading

0 comments on commit 75b127a

Please sign in to comment.