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

Show DLC in recommendations list #3038

Merged
merged 2 commits into from
May 4, 2020
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
14 changes: 12 additions & 2 deletions CKAN.schema
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
},
"kind" : {
"description" : "Package type, defaults to package.",
"enum" : [ "package", "metapackage" ]
"enum" : [ "package", "metapackage", "dlc" ]
},
"abstract" : {
"description" : "Short description of the mod",
Expand Down Expand Up @@ -219,6 +219,16 @@
"description" : "Mod's remote hosted netkan",
"type" : "string",
"format" : "uri"
},
"store": {
"description" : "Purchase DLC here",
"type" : "string",
"format" : "uri"
},
"steamstore": {
"description" : "Purchase DLC on Steam here",
"type" : "string",
"format" : "uri"
}
}
},
Expand Down Expand Up @@ -316,7 +326,7 @@
{
"properties": {
"kind": {
"enum": [ "metapackage" ]
"enum": [ "metapackage", "dlc" ]
}
},
"not": {
Expand Down
6 changes: 5 additions & 1 deletion Cmdline/Action/Available.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Linq;
using System.Collections.Generic;

namespace CKAN.CmdLine
Expand All @@ -15,7 +16,10 @@ public int RunCommand(CKAN.KSP ksp, object raw_options)
{
AvailableOptions opts = (AvailableOptions)raw_options;
IRegistryQuerier registry = RegistryManager.Instance(ksp).registry;
var compatible = registry.CompatibleModules(ksp.VersionCriteria());

var compatible = registry
.CompatibleModules(ksp.VersionCriteria())
.Where(m => !m.IsDLC);

user.RaiseMessage("Modules compatible with KSP {0}", ksp.Version());
user.RaiseMessage("");
Expand Down
13 changes: 13 additions & 0 deletions Cmdline/Action/Install.cs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,19 @@ public int RunCommand(CKAN.KSP ksp, object raw_options)
user.RaiseMessage("\r\n{0}", kraken.Message);
return Exit.ERROR;
}
catch (ModuleIsDLCKraken kraken)
{
user.RaiseMessage($"CKAN can't install expansion '{kraken.module.name}' for you.");
var res = kraken?.module?.resources;
var storePagesMsg = new Uri[] { res?.store, res?.steamstore }
.Where(u => u != null)
.Aggregate("", (a, b) => $"{a}\r\n- {b}");
if (!string.IsNullOrEmpty(storePagesMsg))
{
user.RaiseMessage($"To install this expansion, purchase it from one of its store pages:\r\n{storePagesMsg}");
}
return Exit.ERROR;
}
}

return Exit.OK;
Expand Down
12 changes: 10 additions & 2 deletions Cmdline/Action/Mark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,16 @@ private int MarkAuto(MarkAutoOptions opts, bool value, string verb, string descr
else
{
user.RaiseMessage("Marking {0} as {1}...", id, descrip);
im.AutoInstalled = value;
needSave = true;
try
{
im.AutoInstalled = value;
needSave = true;
}
catch (ModuleIsDLCKraken kraken)
{
user.RaiseMessage($"Can't mark expansion '{kraken.module.name}' as auto-installed.");
return Exit.BADOPT;
}
}
}
if (needSave)
Expand Down
20 changes: 18 additions & 2 deletions Cmdline/Action/Remove.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using log4net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using log4net;

namespace CKAN.CmdLine
{
Expand Down Expand Up @@ -65,7 +66,9 @@ public int RunCommand(CKAN.KSP ksp, object raw_options)
log.Debug("Removing all mods");
// Add the list of installed modules to the list that should be uninstalled
options.modules.AddRange(
regMgr.registry.InstalledModules.Select(mod => mod.identifier)
regMgr.registry.InstalledModules
.Where(mod => !mod.Module.IsDLC)
.Select(mod => mod.identifier)
);
}

Expand All @@ -84,6 +87,19 @@ public int RunCommand(CKAN.KSP ksp, object raw_options)
user.RaiseMessage("Try `ckan list` for a list of installed mods.");
return Exit.BADOPT;
}
catch (ModuleIsDLCKraken kraken)
{
user.RaiseMessage($"CKAN can't remove expansion '{kraken.module.name}' for you.");
var res = kraken?.module?.resources;
var storePagesMsg = new Uri[] { res?.store, res?.steamstore }
.Where(u => u != null)
.Aggregate("", (a, b) => $"{a}\r\n- {b}");
if (!string.IsNullOrEmpty(storePagesMsg))
{
user.RaiseMessage($"To remove this expansion, follow the instructions for the store page from which you purchased it:\r\n{storePagesMsg}");
}
return Exit.BADOPT;
}
}
else
{
Expand Down
40 changes: 32 additions & 8 deletions Cmdline/Action/Show.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,13 @@ public int ShowMod(InstalledModule module)
ICollection<string> files = module.Files as ICollection<string>;
if (files == null) throw new InvalidCastException();

user.RaiseMessage("\r\nShowing {0} installed files:", files.Count);
foreach (string file in files)
if (!module.Module.IsDLC)
{
user.RaiseMessage("- {0}", file);
user.RaiseMessage("\r\nShowing {0} installed files:", files.Count);
foreach (string file in files)
{
user.RaiseMessage("- {0}", file);
}
}

return return_value;
Expand Down Expand Up @@ -192,22 +195,43 @@ public int ShowMod(CkanModule module)
if (module.resources != null)
{
if (module.resources.bugtracker != null)
{
user.RaiseMessage("- bugtracker: {0}", Uri.EscapeUriString(module.resources.bugtracker.ToString()));
}
if (module.resources.homepage != null)
{
user.RaiseMessage("- homepage: {0}", Uri.EscapeUriString(module.resources.homepage.ToString()));
}
if (module.resources.spacedock != null)
{
user.RaiseMessage("- spacedock: {0}", Uri.EscapeUriString(module.resources.spacedock.ToString()));
}
if (module.resources.repository != null)
{
user.RaiseMessage("- repository: {0}", Uri.EscapeUriString(module.resources.repository.ToString()));
}
if (module.resources.curse != null)
{
user.RaiseMessage("- curse: {0}", Uri.EscapeUriString(module.resources.curse.ToString()));
}
if (module.resources.store != null)
{
user.RaiseMessage("- store: {0}", Uri.EscapeUriString(module.resources.store.ToString()));
}
if (module.resources.steamstore != null)
{
user.RaiseMessage("- steamstore: {0}", Uri.EscapeUriString(module.resources.steamstore.ToString()));
}
}

// Compute the CKAN filename.
string file_uri_hash = NetFileCache.CreateURLHash(module.download);
string file_name = CkanModule.StandardName(module.identifier, module.version);

user.RaiseMessage("\r\nFilename: {0}", file_uri_hash + "-" + file_name);
if (!module.IsDLC)
{
// Compute the CKAN filename.
string file_uri_hash = NetFileCache.CreateURLHash(module.download);
string file_name = CkanModule.StandardName(module.identifier, module.version);

user.RaiseMessage("\r\nFilename: {0}", file_uri_hash + "-" + file_name);
}

return Exit.OK;
}
Expand Down
19 changes: 17 additions & 2 deletions Cmdline/Action/Upgrade.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Linq;
using System.Collections.Generic;
using CKAN.Versioning;
using log4net;
using CKAN.Versioning;

namespace CKAN.CmdLine
{
Expand Down Expand Up @@ -108,7 +110,7 @@ public int RunCommand(CKAN.KSP ksp, object raw_options)

// This may be an unindexed mod. If so,
// skip rather than crash. See KSP-CKAN/CKAN#841.
if (latest == null)
if (latest == null || latest.IsDLC)
{
continue;
}
Expand Down Expand Up @@ -150,6 +152,19 @@ public int RunCommand(CKAN.KSP ksp, object raw_options)
User.RaiseMessage(kraken.ToString());
return Exit.ERROR;
}
catch (ModuleIsDLCKraken kraken)
{
User.RaiseMessage($"CKAN can't upgrade expansion '{kraken.module.name}' for you.");
var res = kraken?.module?.resources;
var storePagesMsg = new Uri[] { res?.store, res?.steamstore }
.Where(u => u != null)
.Aggregate("", (a, b) => $"{a}\r\n- {b}");
if (!string.IsNullOrEmpty(storePagesMsg))
{
User.RaiseMessage($"To upgrade this expansion, download any updates from the store page from which you purchased it:\r\n{storePagesMsg}");
}
return Exit.ERROR;
}
User.RaiseMessage("\r\nDone!\r\n");

return Exit.OK;
Expand Down
6 changes: 3 additions & 3 deletions Core/DLC/IDlcDetector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,19 @@ public interface IDlcDetector
/// </item>
/// </list>
/// </returns>
bool IsInstalled (KSP ksp, out string identifier, out UnmanagedModuleVersion version);
bool IsInstalled(KSP ksp, out string identifier, out UnmanagedModuleVersion version);

/// <summary>
/// Path to the DLC directory relative to GameDir.
/// E.g. GameData/SquadExpansion/Serenity
/// </summary>
/// <returns>The relative path as string.</returns>
string InstallPath ();
string InstallPath();

/// <summary>
/// Determines whether the DLC is allowed to be installed (or faked)
/// on the specified base version (i.e. the game version of the KSP instance.)
/// </summary>
bool AllowedOnBaseVersion (KspVersion baseVersion);
bool AllowedOnBaseVersion(KspVersion baseVersion);
}
}
30 changes: 21 additions & 9 deletions Core/ModuleInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ public IEnumerable<string> GetModuleContentsList(CkanModule module)
/// </summary>
private void Install(CkanModule module, bool autoInstalled, Registry registry, string filename = null)
{
CheckMetapackageInstallationKraken(module);
CheckKindInstallationKraken(module);

ModuleVersion version = registry.InstalledVersion(module.identifier);

Expand Down Expand Up @@ -332,11 +332,15 @@ private void Install(CkanModule module, bool autoInstalled, Registry registry, s
/// Check if the given module is a metapackage:
/// if it is, throws a BadCommandKraken.
/// </summary>
private static void CheckMetapackageInstallationKraken(CkanModule module)
private static void CheckKindInstallationKraken(CkanModule module)
{
if (module.IsMetapackage)
{
throw new BadCommandKraken("Metapackages can not be installed!");
throw new BadCommandKraken("Metapackages cannot be installed!");
}
if (module.IsDLC)
{
throw new BadCommandKraken("DLC cannot be installed!");
}
}

Expand All @@ -348,7 +352,7 @@ private static void CheckMetapackageInstallationKraken(CkanModule module)
/// </summary>
private IEnumerable<string> InstallModule(CkanModule module, string zip_filename, Registry registry)
{
CheckMetapackageInstallationKraken(module);
CheckKindInstallationKraken(module);

using (ZipFile zipfile = new ZipFile(zip_filename))
{
Expand Down Expand Up @@ -740,6 +744,14 @@ public void UninstallList(
throw new ModNotInstalledKraken(mod);
}

var instDlc = mods
.Select(ident => registry_manager.registry.InstalledModule(ident))
.FirstOrDefault(m => m.Module.IsDLC);
if (instDlc != null)
{
throw new ModuleIsDLCKraken(instDlc.Module);
}

// Find all the things which need uninstalling.
IEnumerable<string> revdep = mods
.Union(registry_manager.registry.FindReverseDependencies(
Expand Down Expand Up @@ -1261,14 +1273,14 @@ out Dictionary<CkanModule, HashSet<string>> supporters
if (!registry.IsInstalled(provider.identifier)
&& !toInstall.Any(m => m.identifier == provider.identifier)
&& dependersIndex.TryGetValue(provider, out List<string> dependers)
&& CanInstall(RelationshipResolver.DependsOnlyOpts(),
toInstall.ToList().Concat(new List<CkanModule>() { provider }).ToList(), registry))
&& (provider.IsDLC || CanInstall(RelationshipResolver.DependsOnlyOpts(),
toInstall.ToList().Concat(new List<CkanModule>() { provider }).ToList(), registry)))
{
dependersIndex.Remove(provider);
recommendations.Add(
provider,
new Tuple<bool, List<string>>(
providers.Count <= 1 || provider.identifier == (rel as ModuleRelationshipDescriptor)?.name,
!provider.IsDLC && (providers.Count <= 1 || provider.identifier == (rel as ModuleRelationshipDescriptor)?.name),
dependers)
);
}
Expand All @@ -1288,8 +1300,8 @@ out Dictionary<CkanModule, HashSet<string>> supporters
if (!registry.IsInstalled(provider.identifier)
&& !toInstall.Any(m => m.identifier == provider.identifier)
&& dependersIndex.TryGetValue(provider, out List<string> dependers)
&& CanInstall(RelationshipResolver.DependsOnlyOpts(),
toInstall.ToList().Concat(new List<CkanModule>() { provider }).ToList(), registry))
&& (provider.IsDLC || CanInstall(RelationshipResolver.DependsOnlyOpts(),
toInstall.ToList().Concat(new List<CkanModule>() { provider }).ToList(), registry)))
{
dependersIndex.Remove(provider);
suggestions.Add(provider, dependers);
Expand Down
7 changes: 4 additions & 3 deletions Core/Registry/CompatibilitySorter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public CompatibilitySorter(
Dictionary<string, AvailableModule> available,
Dictionary<string, HashSet<AvailableModule>> providers,
HashSet<string> dlls,
Dictionary<string, UnmanagedModuleVersion> dlc
IDictionary<string, ModuleVersion> dlc
)
{
CompatibleVersions = crit;
Expand Down Expand Up @@ -63,7 +63,7 @@ public readonly SortedDictionary<string, AvailableModule> Incompatible
private readonly Stack<string> Investigating = new Stack<string>();

private readonly HashSet<string> dlls;
private readonly Dictionary<string, UnmanagedModuleVersion> dlc;
private readonly IDictionary<string, ModuleVersion> dlc;

/// <summary>
/// Filter the provides mapping by compatibility
Expand All @@ -78,9 +78,10 @@ private Dictionary<string, HashSet<AvailableModule>> CompatibleProviders(KspVers
var compat = new Dictionary<string, HashSet<AvailableModule>>();
foreach (var kvp in providers)
{
// Find providing modules that are compatible with crit
// Find providing non-DLC modules that are compatible with crit
var compatAvail = kvp.Value.Where(avm =>
avm.AllAvailable().Any(ckm =>
!ckm.IsDLC &&
ckm.ProvidesList.Contains(kvp.Key) && ckm.IsCompatibleKSP(crit))
).ToHashSet();
// Add compatible providers to mapping, if any
Expand Down
2 changes: 1 addition & 1 deletion Core/Registry/IRegistryQuerier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public interface IRegistryQuerier
{
IEnumerable<InstalledModule> InstalledModules { get; }
IEnumerable<string> InstalledDlls { get; }
IDictionary<string, UnmanagedModuleVersion> InstalledDlc { get; }
IDictionary<string, ModuleVersion> InstalledDlc { get; }

int? DownloadCount(string identifier);

Expand Down
8 changes: 7 additions & 1 deletion Core/Registry/InstalledModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,13 @@ public DateTime InstallTime
public bool AutoInstalled
{
get { return auto_installed; }
set { auto_installed = value; }
set {
if (Module.IsDLC)
{
throw new ModuleIsDLCKraken(Module);
}
auto_installed = value;
}
}

#endregion
Expand Down
Loading