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

KSP2 support #3797

Merged
merged 2 commits into from
Mar 11, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
17 changes: 11 additions & 6 deletions CKAN.schema
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,15 @@
"enum" : [ "stable", "testing", "development" ]
},
"ksp_version" : {
"description" : "Optional target KSP version",
"description" : "Optional target game version",
"$ref" : "#/definitions/ksp_version"
},
"ksp_version_min" : {
"description" : "Optional minimum KSP version",
"description" : "Optional minimum game version",
"$ref" : "#/definitions/ksp_version"
},
"ksp_version_max" : {
"description" : "Optional maximum KSP version",
"description" : "Optional maximum game version",
"$ref" : "#/definitions/ksp_version"
},
"ksp_version_strict" : {
Expand All @@ -123,7 +123,7 @@
}
},
"localizations" : {
"description" : "A list of KSP locale strings for which this mod includes localizations",
"description" : "A list of locale strings for which this mod includes localizations",
"type" : "array",
"items" : { "type" : "string" },
"uniqueItems" : true
Expand Down Expand Up @@ -361,9 +361,9 @@
"type" : "string"
},
"ksp_version" : {
"description" : "A version of KSP",
"description" : "A game version",
"type" : "string",
"pattern" : "^(any|[0-9]+\\.[0-9]+(\\.[0-9]+)?)$"
"pattern" : "^(any|[0-9]+(\\.[0-9]+(\\.[0-9]+)?)?)$"
},
"relationship" : {
"description" : "A relationship to a list of mods",
Expand Down Expand Up @@ -439,6 +439,11 @@
"description" : "Spec v1.25 Missions path",
"type" : "string",
"pattern" : "^Missions"
},
{
"description" : "KSP2 BepInEx plugins folder",
"type" : "string",
"pattern" : "BepInEx/plugins"
}
]
},
Expand Down
3 changes: 2 additions & 1 deletion Core/CKAN-core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="builds.json" />
<EmbeddedResource Include="builds-ksp.json" />
<EmbeddedResource Include="builds-ksp2.json" />
<EmbeddedResource Include="..\CKAN.schema">
<LogicalName>CKAN.Core.CKAN.schema</LogicalName>
</EmbeddedResource>
Expand Down
6 changes: 5 additions & 1 deletion Core/GameInstanceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public class GameInstanceManager : IDisposable
{
private static IGame[] knownGames = new IGame[]
{
new KerbalSpaceProgram()
new KerbalSpaceProgram(),
new KerbalSpaceProgram2(),
};

/// <summary>
Expand Down Expand Up @@ -646,5 +647,8 @@ public IGame DetermineGame(DirectoryInfo path, IUser user)
}
}

public static IGame GameByShortName(string shortName)
=> knownGames.FirstOrDefault(g => g.ShortName == shortName);

}
}
1 change: 1 addition & 0 deletions Core/Games/IGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public interface IGame
string[] AdjustCommandLine(string[] args, GameVersion installedVersion);

// Which versions exist and which is present?
void RefreshVersions();
List<GameVersion> KnownVersions { get; }
GameVersion DetectVersion(DirectoryInfo where);
string CompatibleVersionsFile { get; }
Expand Down
5 changes: 5 additions & 0 deletions Core/Games/KerbalSpaceProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ public string[] AdjustCommandLine(string[] args, GameVersion installedVersion)
return args;
}

public void RefreshVersions()
{
ServiceLocator.Container.Resolve<IKspBuildMap>().Refresh();
}

public List<GameVersion> KnownVersions =>
ServiceLocator.Container.Resolve<IKspBuildMap>().KnownVersions;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public sealed class KspBuildMap : IKspBuildMap
new Uri("https://raw.githubusercontent.com/KSP-CKAN/CKAN-meta/master/builds.json");
private static readonly string cachedBuildMapPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"CKAN", "builds.json");
"CKAN", "builds-ksp.json");

private static readonly ILog Log = LogManager.GetLogger(typeof(KspBuildMap));

Expand Down Expand Up @@ -154,7 +154,7 @@ private bool TrySetEmbeddedBuildMap()
{
Log.Debug("Getting embedded build map");
var resourceStream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream("CKAN.builds.json");
.GetManifestResourceStream("CKAN.builds-ksp.json");

if (resourceStream != null)
{
Expand Down
228 changes: 228 additions & 0 deletions Core/Games/KerbalSpaceProgram2.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.IO;
using System.Collections.Generic;
using System.Reflection;

using Autofac;
using log4net;
using Newtonsoft.Json;

using CKAN.Versioning;

namespace CKAN.Games
{
public class KerbalSpaceProgram2 : IGame
{
public string ShortName => "KSP2";

public bool GameInFolder(DirectoryInfo where)
=> where.EnumerateFiles().Any(f => f.Name == "KSP2_x64.exe")
&& where.EnumerateDirectories().Any(d => d.Name == "KSP2_x64_Data");

/// <summary>
/// Finds the Steam KSP path. Returns null if the folder cannot be located.
/// </summary>
/// <returns>The KSP path.</returns>
public string SteamPath()
{
// Attempt to get the Steam path.
string steamPath = CKANPathUtils.SteamPath();

if (steamPath == null)
{
return null;
}

// Default steam library
string installPath = GameDirectory(steamPath);
if (installPath != null)
{
return installPath;
}

// Attempt to find through config file
string configPath = Path.Combine(steamPath, "config", "config.vdf");
if (File.Exists(configPath))
{
log.InfoFormat("Found Steam config file at {0}", configPath);
StreamReader reader = new StreamReader(configPath);
string line;
while ((line = reader.ReadLine()) != null)
{
// Found Steam library
if (line.Contains("BaseInstallFolder"))
{
// This assumes config file is valid, we just skip it if it looks funny.
string[] split_line = line.Split('"');

if (split_line.Length > 3)
{
log.DebugFormat("Found a Steam Libary Location at {0}", split_line[3]);

installPath = GameDirectory(split_line[3]);
if (installPath != null)
{
log.InfoFormat("Found a KSP install at {0}", installPath);
return installPath;
}
}
}
}
}

// Could not locate the folder.
return null;
}

/// <summary>
/// Get the default non-Steam path to KSP on macOS
/// </summary>
/// <returns>
/// "/Applications/Kerbal Space Program" if it exists and we're on a Mac, else null
/// </returns>
public string MacPath()
{
if (Platform.IsMac)
{
string installPath = Path.Combine(
// This is "/Applications" in Mono on Mac
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
"Kerbal Space Program 2"
);
return Directory.Exists(installPath) ? installPath : null;
}
return null;
}

public string PrimaryModDirectoryRelative => "BepInEx/plugins";

public string PrimaryModDirectory(GameInstance inst)
=> CKANPathUtils.NormalizePath(
Path.Combine(inst.GameDir(), PrimaryModDirectoryRelative));

public string[] StockFolders => new string[]
{
"KSP2_x64_Data",
"MonoBleedingEdge",
"PDLauncher",
};

public string[] ReservedPaths => new string[]
{
};

public string[] CreateableDirs => new string[]
{
"BepInEx",
"BepInEx/plugins",
};

/// <summary>
/// Checks the path against a list of reserved game directories
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public bool IsReservedDirectory(GameInstance inst, string path)
=> path == inst.GameDir() || path == inst.CkanDir()
|| path == PrimaryModDirectory(inst);

public bool AllowInstallationIn(string name, out string path)
=> allowedFolders.TryGetValue(name, out path);

public void RebuildSubdirectories(GameInstance inst)
{
}

public string DefaultCommandLine =>
Platform.IsUnix ? "./KSP2.x86_64 -single-instance"
: Platform.IsMac ? "./KSP2.app/Contents/MacOS/KSP"
: "KSP2_x64.exe -single-instance";

public string[] AdjustCommandLine(string[] args, GameVersion installedVersion)
=> args;

private static readonly Uri BuildMapUri =
new Uri("https://raw.githubusercontent.com/KSP-CKAN/KSP2-CKAN-meta/main/builds.json");
private static readonly string cachedBuildMapPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"CKAN", "builds-ksp2.json");

private List<GameVersion> versions = JsonConvert.DeserializeObject<List<GameVersion>>(
File.Exists(cachedBuildMapPath)
? File.ReadAllText(cachedBuildMapPath)
: new StreamReader(Assembly.GetExecutingAssembly()
.GetManifestResourceStream("CKAN.builds-ksp2.json"))
.ReadToEnd());

public void RefreshVersions()
{
try
{
var json = Net.DownloadText(BuildMapUri);
versions = JsonConvert.DeserializeObject<List<GameVersion>>(json);
// Save to disk if download and parse succeeds
new FileInfo(cachedBuildMapPath).Directory.Create();
File.WriteAllText(cachedBuildMapPath, json);
}
catch (Exception e)
{
log.WarnFormat("Could not retrieve latest build map from: {0}", BuildMapUri);
log.Debug(e);
}
}

public List<GameVersion> KnownVersions => versions;

public GameVersion DetectVersion(DirectoryInfo where)
=> GameVersion.Parse(
FileVersionInfo.GetVersionInfo(
Path.Combine(where.FullName, "KSP2_x64.exe")).ProductVersion);

public string CompatibleVersionsFile => "compatible_game_versions.json";

public string[] BuildIDFiles => new string[]
{
"KSP2_x64.exe",
};

public Uri DefaultRepositoryURL => new Uri("https://github.com/KSP-CKAN/KSP2-CKAN-meta/archive/main.tar.gz");

public Uri RepositoryListURL => new Uri("https://raw.githubusercontent.com/KSP-CKAN/KSP2-CKAN-meta/main/repositories.json");

private readonly Dictionary<string, string> allowedFolders = new Dictionary<string, string>
{
{ "BepInEx", "BepInEx" },
{ "BepInEx/plugins", "BepInEx/plugins" },
};

/// <summary>
/// Finds the KSP path under a Steam Library. Returns null if the folder cannot be located.
/// </summary>
/// <param name="steamPath">Steam Library Path</param>
/// <returns>The KSP path.</returns>
private static string GameDirectory(string steamPath)
{
// There are several possibilities for the path under Linux.
// Try with the uppercase version.
string installPath = Path.Combine(steamPath, "SteamApps", "common", "Kerbal Space Program 2");

if (Directory.Exists(installPath))
{
return installPath;
}

// Try with the lowercase version.
installPath = Path.Combine(steamPath, "steamapps", "common", "Kerbal Space Program 2");

if (Directory.Exists(installPath))
{
return installPath;
}
return null;
}

private static readonly ILog log = LogManager.GetLogger(typeof(KerbalSpaceProgram2));
}
}
2 changes: 1 addition & 1 deletion Core/Net/Repo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public static RepoUpdateResult UpdateAllRepositories(RegistryManager registry_ma

// Get latest copy of the game versions data (remote build map)
user.RaiseMessage(Properties.Resources.NetRepoUpdatingBuildMap);
ServiceLocator.Container.Resolve<IKspBuildMap>().Refresh();
ksp.game.RefreshVersions();

// Check if the ETags have changed, quit if not
user.RaiseProgress(Properties.Resources.NetRepoCheckingForUpdates, 0);
Expand Down
File renamed without changes.
3 changes: 3 additions & 0 deletions Core/builds-ksp2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
"0.1.0.0"
]
2 changes: 1 addition & 1 deletion Dockerfile.netkan
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ RUN useradd -ms /bin/bash netkan
USER netkan
WORKDIR /home/netkan
ADD netkan.exe .
ENTRYPOINT /usr/bin/mono netkan.exe --queues $QUEUES \
ENTRYPOINT /usr/bin/mono netkan.exe --game $GAME --queues $QUEUES \
techman83 marked this conversation as resolved.
Show resolved Hide resolved
--net-useragent 'Mozilla/5.0 (compatible; Netkanbot/1.0; CKAN; +https://github.com/KSP-CKAN/NetKAN-Infra)' \
--github-token $GH_Token --gitlab-token "$GL_Token" --cachedir ckan_cache -v
4 changes: 3 additions & 1 deletion Netkan/CKAN-netkan.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
<Compile Include="Sources\Spacedock\SpacedockError.cs" />
<Compile Include="Sources\Spacedock\SpacedockMod.cs" />
<Compile Include="Sources\Spacedock\SpacedockUser.cs" />
<Compile Include="Sources\SpaceWarp\SpaceWarpInfo.cs" />
<Compile Include="Transformers\AvcKrefTransformer.cs" />
<Compile Include="Transformers\AvcTransformer.cs" />
<Compile Include="Transformers\CurseTransformer.cs" />
Expand All @@ -128,6 +129,7 @@
<Compile Include="Transformers\OptimusPrimeTransformer.cs" />
<Compile Include="Transformers\PropertySortTransformer.cs" />
<Compile Include="Transformers\SpacedockTransformer.cs" />
<Compile Include="Transformers\SpaceWarpInfoTransformer.cs" />
<Compile Include="Transformers\StagingTransformer.cs" />
<Compile Include="Transformers\StagingLinksTransformer.cs" />
<Compile Include="Transformers\StripNetkanMetadataTransformer.cs" />
Expand Down Expand Up @@ -180,4 +182,4 @@
<Exec Command="powershell ../build.ps1 Generate-GlobalAssemblyVersionInfo" Condition="!Exists('../_build/meta/GlobalAssemblyVersionInfo.cs') And '$(OS)' == 'Windows_NT'" />
<Exec Command="sh ../build Generate-GlobalAssemblyVersionInfo" Condition="!Exists('../_build/meta/GlobalAssemblyVersionInfo.cs') And '$(OS)' == 'Unix'" />
</Target>
</Project>
</Project>
Loading