Skip to content

Commit

Permalink
Show DLC in recommendations list
Browse files Browse the repository at this point in the history
  • Loading branch information
HebaruSan committed Apr 30, 2020
1 parent e47f850 commit 7bce033
Show file tree
Hide file tree
Showing 41 changed files with 657 additions and 260 deletions.
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

0 comments on commit 7bce033

Please sign in to comment.