Skip to content

Commit

Permalink
Merge #3797 KSP2 support
Browse files Browse the repository at this point in the history
  • Loading branch information
HebaruSan committed Mar 11, 2023
2 parents 2d387d9 + 00872cf commit c2ffac2
Show file tree
Hide file tree
Showing 49 changed files with 573 additions and 106 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
- [Multiple] Italian translation and other localization fixes (#3780, #3781 by: frankieorabona, WujekFoliarz, vinix38, Kalessin1; reviewed: HebaruSan)
- [Core] Fix mkbundle executable crash (#3767 by: memchr; reviewed: HebaruSan)
- [GUI] Show conflicts in changeset (#3727 by: HebaruSan; reviewed: techman83)
- [Multiple] KSP2 support (#3797 by: HebaruSan; reviewed: techman83)

### Bugfixes

Expand Down
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 \
--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

0 comments on commit c2ffac2

Please sign in to comment.