Skip to content

Commit

Permalink
Alternate game command lines and Steam refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
HebaruSan committed Jan 31, 2024
1 parent 5d0b6cd commit f8d614c
Show file tree
Hide file tree
Showing 41 changed files with 661 additions and 429 deletions.
16 changes: 11 additions & 5 deletions Cmdline/ConsoleUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -254,11 +254,15 @@ public void RaiseError(string message, params object[] args)
/// <param name="percent">Progress in percent</param>
public void RaiseProgress(string message, int percent)
{
// The percent looks weird on non-download messages.
// The leading newline makes sure we don't end up with a mess from previous
// download messages.
GoToStartOfLine();
Console.Write("{0}", message);
if (message != lastProgressMessage)
{
// The percent looks weird on non-download messages.
// The leading newline makes sure we don't end up with a mess from previous
// download messages.
GoToStartOfLine();
Console.Write("{0}", message);
lastProgressMessage = message;
}

// This message leaves the cursor at the end of a line of text
atStartOfLine = false;
Expand Down Expand Up @@ -286,6 +290,8 @@ public void RaiseProgress(int percent, long bytesPerSecond, long bytesLeft)
/// </summary>
private int previousPercent = -1;

private string lastProgressMessage = null;

/// <summary>
/// Writes a message to the console
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions Core/CKAN-core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NJsonSchema" Version="10.9.0" />
<PackageReference Include="ValveKeyValue" Version="0.3.1.152" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net48' ">
<PackageReference Include="ChinhDo.Transactions.FileManager" Version="1.2.0" />
Expand Down
43 changes: 0 additions & 43 deletions Core/CKANPathUtils.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

using log4net;
Expand All @@ -20,48 +19,6 @@ public static class CKANPathUtils

private static readonly ILog log = LogManager.GetLogger(typeof(CKANPathUtils));

/// <summary>
/// Finds Steam on the current machine.
/// </summary>
/// <returns>The path to Steam, or null if not found</returns>
public static string SteamPath()
{
foreach (var steam in SteamPaths.Where(p => !string.IsNullOrEmpty(p)))
{
log.DebugFormat("Looking for Steam in {0}", steam);
if (Directory.Exists(steam))
{
log.InfoFormat("Found Steam at {0}", steam);
return steam;
}
}
log.Info("Steam not found on this system.");
return null;
}

private const string steamRegKey = @"HKEY_CURRENT_USER\Software\Valve\Steam";
private const string steamRegValue = @"SteamPath";

private static string[] SteamPaths
=> Platform.IsWindows ? new string[]
{
// First check the registry
(string)Microsoft.Win32.Registry.GetValue(steamRegKey, steamRegValue, null),
}
: Platform.IsUnix ? new string[]
{
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal),
".local", "share", "Steam"),
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal),
".steam", "steam"),
}
: Platform.IsMac ? new string[]
{
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal),
"Library", "Application Support", "Steam"),
}
: Array.Empty<string>();

/// <summary>
/// Normalizes the path by replacing all \ with / and removing any trailing slash.
/// </summary>
Expand Down
11 changes: 11 additions & 0 deletions Core/Extensions/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Text.RegularExpressions;

namespace CKAN.Extensions
{
Expand Down Expand Up @@ -216,6 +217,16 @@ public static void Deconstruct<T1, T2>(this KeyValuePair<T1, T2> kvp, out T1 key
val = kvp.Value;
}

/// <summary>
/// Try matching a regex against a series of strings and return the Match objects
/// </summary>
/// <param name="source">Sequence of strings to scan</param>
/// <param name="pattern">Pattern to match</param>
/// <returns>Sequence of Match objects</returns>
public static IEnumerable<Match> WithMatches(this IEnumerable<string> source, Regex pattern)
=> source.Select(val => pattern.TryMatch(val, out Match match) ? match : null)
.Where(m => m != null);

}

/// <summary>
Expand Down
39 changes: 1 addition & 38 deletions Core/GameInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public class GameInstance : IEquatable<GameInstance>
public TimeLog playTime;

public string Name { get; set; }

/// <summary>
/// Returns a file system safe version of the instance name that can be used within file names.
/// </summary>
Expand Down Expand Up @@ -240,44 +241,6 @@ public static string PortableDir(IGame game)
return null;
}

/// <summary>
/// Attempts to automatically find a KSP install on this system.
/// Returns the path to the install on success.
/// Throws a DirectoryNotFoundException on failure.
/// </summary>
public static string FindGameDir(IGame game)
{
// See if we can find KSP as part of a Steam install.
string gameSteamPath = game.SteamPath();
if (gameSteamPath != null)
{
if (game.GameInFolder(new DirectoryInfo(gameSteamPath)))
{
return gameSteamPath;
}

log.DebugFormat("Have Steam, but {0} is not at \"{1}\".",
game.ShortName, gameSteamPath);
}

// See if we can find a non-Steam Mac KSP install
string kspMacPath = game.MacPath();
if (kspMacPath != null)
{
if (game.GameInFolder(new DirectoryInfo(kspMacPath)))
{
log.InfoFormat("Found a {0} install at {1}",
game.ShortName, kspMacPath);
return kspMacPath;
}
log.DebugFormat("Default Mac {0} folder exists at \"{1}\", but {0} is not installed there.",
game.ShortName, kspMacPath);
}

// Oh noes! We can't find KSP!
throw new DirectoryNotFoundException();
}

/// <summary>
/// Detects the version of a game in a given directory.
/// </summary>
Expand Down
63 changes: 44 additions & 19 deletions Core/GameInstanceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public class GameInstanceManager : IDisposable

public NetModuleCache Cache { get; private set; }

public readonly SteamLibrary SteamLibrary = new SteamLibrary();

private static readonly ILog log = LogManager.GetLogger(typeof (GameInstanceManager));

private readonly SortedList<string, GameInstance> instances = new SortedList<string, GameInstance>();
Expand Down Expand Up @@ -135,7 +137,7 @@ internal GameInstance _GetPreferredInstance()
// If we know of no instances, try to find one.
// Otherwise, we know of too many instances!
// We don't know which one to pick, so we return null.
return !instances.Any() ? FindAndRegisterDefaultInstance() : null;
return !instances.Any() ? FindAndRegisterDefaultInstances() : null;
}

/// <summary>
Expand All @@ -145,35 +147,58 @@ internal GameInstance _GetPreferredInstance()
///
/// Returns the resulting game instance if found.
/// </summary>
public GameInstance FindAndRegisterDefaultInstance()
public GameInstance FindAndRegisterDefaultInstances()
{
if (instances.Any())
{
throw new KSPManagerKraken("Attempted to scan for defaults with instances");
}
GameInstance val = null;
foreach (IGame game in knownGames)
var found = FindDefaultInstances();
foreach (var inst in found)
{
try
log.DebugFormat("Registering {0} at {1}...",
inst.Name, inst.GameDir());
AddInstance(inst);
}
return found.FirstOrDefault();
}

public GameInstance[] FindDefaultInstances()
{
var found = knownGames.SelectMany(g =>
SteamLibrary.Games
.Select(sg => new { name = sg.Name, dir = sg.GameDir })
.Append(new
{
name = string.Format(Properties.Resources.GameInstanceManagerAuto,
g.ShortName),
dir = g.MacPath(),
})
.Where(obj => obj.dir != null && g.GameInFolder(obj.dir))
.Select(obj => new GameInstance(g, obj.dir.FullName, obj.name, User)))
.Where(inst => inst.Valid)
.ToArray();
foreach (var group in found.GroupBy(inst => inst.Name))
{
if (group.Count() > 1)
{
string gamedir = GameInstance.FindGameDir(game);
GameInstance foundInst = new GameInstance(
game, gamedir, string.Format(Properties.Resources.GameInstanceManagerAuto, game.ShortName), User);
if (foundInst.Valid)
// Make sure the names are unique
int index = 0;
foreach (var inst in group)
{
var inst = AddInstance(foundInst);
val = val ?? inst;
// Find an unused name
string name;
do
{
++index;
name = $"{group.Key} ({++index})";
}
while (found.Any(other => other.Name == name));
inst.Name = name;
}
}
catch (DirectoryNotFoundException)
{
// Thrown if no folder found for a game
}
catch (NotKSPDirKraken)
{
}
}
return val;
return found;
}

/// <summary>
Expand Down
9 changes: 4 additions & 5 deletions Core/Games/IGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@ public interface IGame
{
// Identification, used for display and saved/loaded in settings JSON
// Must be unique!
string ShortName { get; }
string ShortName { get; }
DateTime FirstReleaseDate { get; }

// Where are we?
bool GameInFolder(DirectoryInfo where);
string SteamPath();
string MacPath();
bool GameInFolder(DirectoryInfo where);
DirectoryInfo MacPath();

// What do we contain?
string PrimaryModDirectoryRelative { get; }
Expand All @@ -32,7 +31,7 @@ public interface IGame
bool IsReservedDirectory(GameInstance inst, string path);
bool AllowInstallationIn(string name, out string path);
void RebuildSubdirectories(string absGameRoot);
string DefaultCommandLine(string path);
string[] DefaultCommandLines(SteamLibrary steamLib, DirectoryInfo path);
string[] AdjustCommandLine(string[] args, GameVersion installedVersion);
IDlcDetector[] DlcDetectors { get; }

Expand Down
Loading

0 comments on commit f8d614c

Please sign in to comment.