Skip to content

Commit

Permalink
Merge #2773 Support BreakingGround-DLC in instance faking
Browse files Browse the repository at this point in the history
  • Loading branch information
HebaruSan committed Jun 27, 2019
2 parents 2f76dae + 688e4ca commit 67fd76d
Show file tree
Hide file tree
Showing 21 changed files with 457 additions and 184 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file.
- [Netkan] Migrate Perl validation checks into netkan.exe (#2788 by: HebaruSan; reviewed: DasSkelett)
- [Netkan] Refactor Netkan for SQS mode (#2798 by: HebaruSan; reviewed: DasSkelett, techman83)
- [GUI] Open ZIP button, instance name in status bar, description scroll bar (#2813 by: HebaruSan; reviewed: DasSkelett)
- [Multiple] Support BreakingGround-DLC in instance faking (#2773 by: DasSkelett; reviewed: HebaruSan)

### Bugfixes

Expand Down
7 changes: 6 additions & 1 deletion Cmdline/Action/Compare.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ public int RunCommand(object rawOptions)
var rightVersion = new ModuleVersion(options.Right);

int compareResult = leftVersion.CompareTo(rightVersion);
if (compareResult == 0)

if (options.machine_readable)
{
user.RaiseMessage(compareResult.ToString());
}
else if (compareResult == 0)
{
user.RaiseMessage(
"\"{0}\" and \"{1}\" are the same versions.", leftVersion, rightVersion);
Expand Down
120 changes: 88 additions & 32 deletions Cmdline/Action/KSP.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using CKAN.Versioning;
Expand Down Expand Up @@ -54,8 +55,7 @@ public string GetUsage(string verb)
{
// First the commands with three string arguments
case "fake":
ht.AddPreOptionsLine($"Usage: ckan ksp {verb} [options] name path version dlcVersion");
ht.AddPreOptionsLine($"Choose dlcVersion \"none\" if you want no simulated dlc.");
ht.AddPreOptionsLine($"Usage: ckan ksp {verb} [options] name path version [--MakingHistory <version>] [--BreakingGround <version>]");
break;

case "clone":
Expand Down Expand Up @@ -124,8 +124,14 @@ internal class FakeOptions : CommonOptions
[ValueOption(0)] public string name { get; set; }
[ValueOption(1)] public string path { get; set; }
[ValueOption(2)] public string version { get; set; }
[ValueOption(3)] public string dlcVersion { get; set; }
[Option("set-default", DefaultValue = false, HelpText = "Set the new instance to the default one.")] public bool setToDefault { get; set; }

[Option("MakingHistory", DefaultValue = "none", HelpText = "The version of the Making History DLC to be faked.")]
public string makingHistoryVersion { get; set; }
[Option("BreakingGround", DefaultValue = "none", HelpText = "The version of the Breaking Ground DLC to be faked.")]
public string breakingGroundVersion { get; set; }

[Option("set-default", DefaultValue = false, HelpText = "Set the new instance as the default one.")]
public bool setDefault { get; set; }
}

// This is required by ISubCommand
Expand Down Expand Up @@ -303,8 +309,8 @@ private int CloneInstall(CloneOptions options)

// Parse all options
string instanceNameOrPath = options.nameOrPath;
string new_name = options.new_name;
string new_path = options.new_path;
string newName = options.new_name;
string newPath = options.new_path;


log.Info("Cloning the KSP instance: " + options.nameOrPath);
Expand All @@ -320,16 +326,16 @@ private int CloneInstall(CloneOptions options)
if (instance.Name == instanceNameOrPath)
{
// Found it, now clone it.
Manager.CloneInstance(instance, new_name, new_path);
Manager.CloneInstance(instance, newName, newPath);
break;
}
}
}
// Try to use instanceNameOrPath as a path and create a new KSP object.
// If it's valid, go on.
else if (new CKAN.KSP(instanceNameOrPath, new_name, User) is CKAN.KSP instance && instance.Valid)
else if (new CKAN.KSP(instanceNameOrPath, newName, User) is CKAN.KSP instance && instance.Valid)
{
Manager.CloneInstance(instance, new_name, new_path);
Manager.CloneInstance(instance, newName, newPath);

}
// There is no instance with this name or at this path.
Expand Down Expand Up @@ -370,12 +376,16 @@ private int CloneInstall(CloneOptions options)
ListInstalls();
return Exit.ERROR;
}

catch (InstanceNameTakenKraken kraken)
{
User.RaiseError("This instance name is already taken: {0}", kraken.instName);
return Exit.BADOPT;
}

// Test if the instance was added to the registry.
// No need to test if valid, because this is done in AddInstance(),
// so if something went wrong, HasInstance is false.
if (Manager.HasInstance(new_name))
if (Manager.HasInstance(newName))
{
return Exit.OK;
}
Expand Down Expand Up @@ -506,27 +516,60 @@ private int SetDefaultInstall(DefaultOptions options)
/// </summary>
private int FakeNewKSPInstall (FakeOptions options)
{
if (options.name == null || options.path == null || options.version == null)
int error()
{
log.Debug("Instance faking failed, see console output for details.");
User.RaiseMessage("--Error--");
return Exit.ERROR;
}

int badArgument()
{
User.RaiseMessage("ksp fake <name> <path> <version> [dlcVersion] - argument(s) missing");
log.Debug("Instance faking failed: bad argument(s). See console output for details.");
User.RaiseMessage("--Error: bad argument(s)--");
return Exit.BADOPT;
}


if (options.name == null || options.path == null || options.version == null)
{
User.RaiseMessage("ksp fake <name> <path> <version> " +
"[--MakingHistory <version>] [--BreakingGround <version>] - argument(s) missing");
return badArgument();
}

log.Debug("Parsing arguments...");
// Parse all options
string installName = options.name;
string path = options.path;
KspVersion version;
bool setToDefault = options.setToDefault;
// dlcVersion is null if a user wants no simulated DLC
string dlcVersion;
if (options.dlcVersion == null || options.dlcVersion.ToLower() == "none")
bool setDefault = options.setDefault;

// options.<DLC>Version is "none" if the DLC should not be simulated.
Dictionary<DLC.IDlcDetector, KspVersion> dlcs = new Dictionary<DLC.IDlcDetector, KspVersion>();
if (options.makingHistoryVersion != null && options.makingHistoryVersion.ToLower() != "none")
{
dlcVersion = null;
if (KspVersion.TryParse(options.makingHistoryVersion, out KspVersion ver))
{
dlcs.Add(new DLC.MakingHistoryDlcDetector(), ver);
}
else
{
User.RaiseError("Please check the Making History DLC version argument - Format it like Maj.Min.Patch - e.g. 1.1.0");
return badArgument();
}
}
else
if (options.breakingGroundVersion != null && options.breakingGroundVersion.ToLower() != "none")
{
dlcVersion = options.dlcVersion;
if (KspVersion.TryParse(options.breakingGroundVersion, out KspVersion ver))
{
dlcs.Add(new DLC.BreakingGroundDlcDetector(), ver);
}
else
{
User.RaiseError("Please check the Breaking Ground DLC version argument - Format it like Maj.Min.Patch - e.g. 1.1.0");
return badArgument();
}
}

// Parse the choosen KSP version
Expand All @@ -538,49 +581,62 @@ private int FakeNewKSPInstall (FakeOptions options)
{
// Thrown if there is anything besides numbers and points in the version string or a different syntactic error.
User.RaiseError("Please check the version argument - Format it like Maj.Min.Patch[.Build] - e.g. 1.6.0 or 1.2.2.1622");
return Exit.BADOPT;
return badArgument();
}

// Get the full version including build number.
try
{
version = version.RaiseVersionSelectionDialog(User);
}
catch (IncorrectKSPVersionKraken)
catch (BadKSPVersionKraken)
{
User.RaiseError("Couldn't find a valid KSP version for your input.\n" +
"Make sure to enter the at least the version major and minor values in the form Maj.Min - e.g. 1.5");
return Exit.BADOPT;
return badArgument();
}
catch (CancelledActionKraken)
{
User.RaiseError("Selection cancelled! Please call 'ckan ksp fake' again.");
return Exit.ERROR;
return error();
}


User.RaiseMessage(String.Format("Creating new fake KSP install {0} at {1} with version {2}", installName, path, version.ToString()));
log.Debug("Faking instance...");

try
{
// Pass all arguments to CKAN.KSPManager.FakeInstance() and create a new one.
Manager.FakeInstance(installName, path, version, dlcVersion);
if (setToDefault)
Manager.FakeInstance(installName, path, version, dlcs);
if (setDefault)
{
User.RaiseMessage("Setting new instance to default...");
Manager.SetAutoStart(installName);
}
}
catch (InstanceNameTakenKraken kraken)
{
User.RaiseError("This instance name is already taken: {0}", kraken.instName);
return badArgument();
}
catch (BadInstallLocationKraken kraken)
{
// The folder exists and is not empty.
log.Error(kraken);
return Exit.ERROR;
User.RaiseError(kraken.Message);
return badArgument();
}
catch (WrongKSPVersionKraken kraken)
{
// Thrown because the specified KSP version is too old for one of the selected DLCs.
User.RaiseError(kraken.Message);
return badArgument();
}
catch (NotKSPDirKraken kraken)
{
// Something went wrong adding the new instance to the registry,
// most likely because the newly created directory is not valid.
// most likely because the newly created directory is somehow not valid.
log.Error(kraken);
return Exit.ERROR;
return error();
}
catch (InvalidKSPInstanceKraken)
{
Expand All @@ -600,7 +656,7 @@ private int FakeNewKSPInstall (FakeOptions options)
{
User.RaiseError("Something went wrong. Try to add the instance yourself with \"ckan ksp add\".",
"Also look if the new directory has been created.");
return Exit.ERROR;
return error();
}
}
#endregion
Expand Down
3 changes: 3 additions & 0 deletions Cmdline/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,9 @@ internal class SearchOptions : InstanceSpecificOptions

internal class CompareOptions : CommonOptions
{
[Option("machine-readable", HelpText = "Output in a machine readable format: -1, 0 or 1")]
public bool machine_readable { get; set;}

[ValueOption(0)] public string Left { get; set; }
[ValueOption(1)] public string Right { get; set; }
}
Expand Down
2 changes: 1 addition & 1 deletion Core/DLC/BreakingGroundDlcDetector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ namespace CKAN.DLC
public sealed class BreakingGroundDlcDetector : StandardDlcDetectorBase
{
public BreakingGroundDlcDetector()
: base("BreakingGround", "Serenity") { }
: base("BreakingGround", "Serenity", new Versioning.KspVersion(1, 7, 1)) { }
}
}
18 changes: 17 additions & 1 deletion Core/DLC/IDlcDetector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ namespace CKAN.DLC
/// </summary>
public interface IDlcDetector
{
string IdentifierBaseName { get; }
KspVersion ReleaseGameVersion { get; }

/// <summary>
/// Checks if the relevant DLC is installed in the specific KSP installation.
/// </summary>
Expand Down Expand Up @@ -34,6 +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 ();

/// <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);
}
}
2 changes: 1 addition & 1 deletion Core/DLC/MakingHistoryDlcDetector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace CKAN.DLC
public sealed class MakingHistoryDlcDetector : StandardDlcDetectorBase
{
public MakingHistoryDlcDetector()
: base("MakingHistory", new Dictionary<string, string>()
: base("MakingHistory", new Versioning.KspVersion(1, 4, 1), new Dictionary<string, string>()
{
{ "1.0", "1.0.0" }
}
Expand Down
21 changes: 17 additions & 4 deletions Core/DLC/StandardDlcDetectorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ namespace CKAN.DLC
/// </remarks>
public abstract class StandardDlcDetectorBase : IDlcDetector
{
private readonly string IdentifierBaseName;
public KspVersion ReleaseGameVersion { get; }
public string IdentifierBaseName { get; }

private readonly string DirectoryBaseName;
private readonly Dictionary<string, string> CanonicalVersions;

Expand All @@ -25,10 +27,10 @@ public abstract class StandardDlcDetectorBase : IDlcDetector
RegexOptions.Compiled | RegexOptions.IgnoreCase
);

protected StandardDlcDetectorBase(string identifierBaseName, Dictionary<string, string> canonicalVersions = null)
: this(identifierBaseName, identifierBaseName, canonicalVersions) { }
protected StandardDlcDetectorBase(string identifierBaseName, KspVersion releaseGameVersion, Dictionary<string, string> canonicalVersions = null)
: this(identifierBaseName, identifierBaseName, releaseGameVersion, canonicalVersions) { }

protected StandardDlcDetectorBase(string identifierBaseName, string directoryBaseName, Dictionary<string, string> canonicalVersions = null)
protected StandardDlcDetectorBase(string identifierBaseName, string directoryBaseName, KspVersion releaseGameVersion, Dictionary<string, string> canonicalVersions = null)
{
if (string.IsNullOrWhiteSpace(identifierBaseName))
throw new ArgumentException("Value must be provided.", nameof(identifierBaseName));
Expand All @@ -38,6 +40,7 @@ protected StandardDlcDetectorBase(string identifierBaseName, string directoryBas

IdentifierBaseName = identifierBaseName;
DirectoryBaseName = directoryBaseName;
ReleaseGameVersion = releaseGameVersion;
CanonicalVersions = canonicalVersions ?? new Dictionary<string, string>();
}

Expand Down Expand Up @@ -77,5 +80,15 @@ public virtual bool IsInstalled(KSP ksp, out string identifier, out UnmanagedMod
return false;
}
}

public virtual string InstallPath()
{
return Path.Combine("GameData", "SquadExpansion", DirectoryBaseName);
}

public bool AllowedOnBaseVersion(KspVersion baseVersion)
{
return baseVersion >= ReleaseGameVersion;
}
}
}
Loading

0 comments on commit 67fd76d

Please sign in to comment.