Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
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
113 changes: 113 additions & 0 deletions .github/scripts/prepare-release.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
param (
[string] $BuildDirectory = "bin",
[string] $ReleaseDirectory = "openkh",
[string] $Configuration = "Release"
)

$ErrorActionPreference = "Stop"

if (-not (Test-Path -LiteralPath $BuildDirectory -PathType Container)) {
throw "Build directory '$BuildDirectory' does not exist."
}

if (Test-Path -LiteralPath $ReleaseDirectory) {
throw "Release directory '$ReleaseDirectory' already exists."
}

New-Item -ItemType Directory -Path $ReleaseDirectory | Out-Null

$applicationsDirectory = Join-Path $ReleaseDirectory "Apps"
$modManagerDirectory = Join-Path $applicationsDirectory "ModManager"
New-Item -ItemType Directory -Path $modManagerDirectory -Force | Out-Null

$legacyFileManifest = Join-Path $applicationsDirectory "legacy-release-files.txt"
$legacyDirectoryManifest = Join-Path $applicationsDirectory "legacy-release-directories.txt"
Get-ChildItem -LiteralPath $BuildDirectory -File |
Select-Object -ExpandProperty Name |
Sort-Object |
Set-Content -LiteralPath $legacyFileManifest -Encoding UTF8
Get-ChildItem -LiteralPath $BuildDirectory -Directory |
Select-Object -ExpandProperty Name |
Sort-Object |
Set-Content -LiteralPath $legacyDirectoryManifest -Encoding UTF8

dotnet publish `
"OpenKh.Tools.Launcher/OpenKh.Tools.Launcher.csproj" `
--configuration $Configuration `
--runtime win-x64 `
--self-contained false `
--output $ReleaseDirectory `
/p:PublishSingleFile=true `
/p:DebugType=None `
/p:DebugSymbols=false

if ($LASTEXITCODE -ne 0) {
throw "Publishing OpenKH Launcher failed with exit code $LASTEXITCODE."
}

$compatibilityExecutable = Join-Path $ReleaseDirectory "OpenKh.Tools.ModsManager.exe"
Copy-Item `
-LiteralPath (Join-Path $ReleaseDirectory "OpenKh.Launcher.exe") `
-Destination $compatibilityExecutable
(Get-Item -LiteralPath $compatibilityExecutable).Attributes += "Hidden"

dotnet publish `
"OpenKh.Tools.ModsManager/OpenKh.Tools.ModsManager.csproj" `
--configuration $Configuration `
--output $modManagerDirectory `
/p:DebugType=None `
/p:DebugSymbols=false

if ($LASTEXITCODE -ne 0) {
throw "Publishing Mods Manager failed with exit code $LASTEXITCODE."
}

$referencedCommandArtifacts = Get-ChildItem -LiteralPath $modManagerDirectory -File | Where-Object {
$_.Name -like "OpenKh.Command.*" -and $_.Extension -ne ".dll"
}

foreach ($referencedCommandArtifact in $referencedCommandArtifacts) {
Remove-Item -LiteralPath $referencedCommandArtifact.FullName
}

$panaceaFiles = @(
"OpenKH.Panacea.dll",
"avcodec-vgmstream-59.dll",
"avformat-vgmstream-59.dll",
"avutil-vgmstream-57.dll",
"bass.dll",
"bass_vgmstream.dll",
"libatrac9.dll",
"libcelt-0061.dll",
"libcelt-0110.dll",
"libg719_decode.dll",
"libmpg123-0.dll",
"libspeex-1.dll",
"libvorbis.dll",
"swresample-vgmstream-4.dll"
)

foreach ($fileName in $panaceaFiles) {
$sourcePath = Join-Path $BuildDirectory $fileName
if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {
throw "Required Panacea file '$sourcePath' does not exist."
}

Copy-Item -LiteralPath $sourcePath -Destination $modManagerDirectory
}

Copy-Item -LiteralPath "distribution/README-FIRST.txt" -Destination $ReleaseDirectory
Copy-Item -LiteralPath "LICENSE" -Destination $ReleaseDirectory
Copy-Item -LiteralPath "NOTICE" -Destination $ReleaseDirectory

$advancedToolsDirectory = Join-Path $ReleaseDirectory "AdvancedTools"
Move-Item -LiteralPath $BuildDirectory -Destination $advancedToolsDirectory

$duplicateApplicationFiles = Get-ChildItem -LiteralPath $advancedToolsDirectory -File | Where-Object {
$_.Name -like "OpenKh.Launcher.*" -or
$_.Name -like "OpenKh.Tools.ModsManager.*"
}

foreach ($duplicateFile in $duplicateApplicationFiles) {
Remove-Item -LiteralPath $duplicateFile.FullName
}
30 changes: 23 additions & 7 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,31 +27,47 @@ jobs:
- name: build.ps1
run: powershell -ExecutionPolicy Unrestricted ./build.ps1
shell: pwsh

- name: setup-msbuild
uses: microsoft/setup-msbuild@v1.1.3
- name: msbuild panacea
run: |
msbuild OpenKh.Research.Panacea\OpenKh.Research.Panacea.vcxproj /p:Configuration=Release /p:Platform=x64
xcopy "OpenKh.Research.Panacea\Release\*.dll" bin\
xcopy "OpenKh.Research.Panacea\Dependencies\*.dll" bin\


- name: Organize release for mod users
run: powershell -ExecutionPolicy Unrestricted ./.github/scripts/prepare-release.ps1
shell: pwsh

- name: create openkh-release
shell: bash
env:
RELEASE_TAG: "release2-${{github.run_number}}"
run: |
echo $RELEASE_TAG > bin/openkh-release

- name: bin → openkh
run: ren bin openkh
shell: pwsh
echo $RELEASE_TAG > openkh/openkh-release

- name: zip
uses: TheDoctor0/zip-release@0.6.2
with:
filename: openkh.zip
path: openkh

- name: validate update archive
shell: pwsh
run: |
$archiveListing = (7z l openkh.zip) -join "`n"
$requiredEntries = @(
"openkh\OpenKh.Launcher.exe",
"openkh\OpenKh.Tools.ModsManager.exe",
"openkh\Apps\ModManager\OpenKh.Tools.ModsManager.exe"
)
foreach ($entry in $requiredEntries) {
if ($archiveListing -notmatch [regex]::Escape($entry)) {
throw "Required update entry '$entry' is missing from openkh.zip."
}
}

- name: "GitHub release latest"
if: ${{ github.ref_name == 'master' }}
uses: "marvinpinto/action-automatic-releases@latest"
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

# Project specific files
.tests/
/openkh/
/openkh-*/
/OpenKh-*-release.zip

# User-specific files
*.suo
Expand Down
21 changes: 21 additions & 0 deletions OpenKh.Tests.ModsManager/OpenkhInstallationTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using OpenKh.Tools.ModsManager.Services;
using Xunit;

namespace OpenKh.Tests.ModsManager
{
public class OpenkhInstallationTest
{
[Theory]
[InlineData(@"C:\OpenKh", @"C:\OpenKh")]
[InlineData(@"C:\OpenKh\Apps\ModManager", @"C:\OpenKh")]
[InlineData(@"C:\OpenKh\apps\modmanager", @"C:\OpenKh")]
public void GetDirectoryReturnsInstallationRoot(string applicationDirectory, string expectedDirectory)
{
Assert.Equal(
Path.GetFullPath(expectedDirectory),
OpenkhInstallation.GetDirectory(applicationDirectory),
ignoreCase: true
);
}
}
}
6 changes: 6 additions & 0 deletions OpenKh.Tools.Launcher/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Application x:Class="OpenKh.Tools.Launcher.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
</Application.Resources>
</Application>
20 changes: 20 additions & 0 deletions OpenKh.Tools.Launcher/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Windows;

namespace OpenKh.Tools.Launcher;

public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);

if (LegacyInstallationMigration.TryStartModManager())
{
Shutdown();
return;
}

LegacyInstallationMigration.ScheduleCleanupIfNeeded();
new MainWindow().Show();
}
}
46 changes: 46 additions & 0 deletions OpenKh.Tools.Launcher/DesktopShortcutService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System.IO;
using System.Runtime.InteropServices;

namespace OpenKh.Tools.Launcher;

internal static class DesktopShortcutService
{
public static string CreateModManagerShortcut(string targetPath, string? shortcutDirectory = null)
{
shortcutDirectory ??= Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
var shortcutPath = Path.Combine(shortcutDirectory, "OpenKH Mod Manager.lnk");
var shellType = Type.GetTypeFromProgID("WScript.Shell")
?? throw new InvalidOperationException("Windows Script Host is not available.");
object? shell = null;
object? shortcut = null;

try
{
shell = Activator.CreateInstance(shellType)
?? throw new InvalidOperationException("Windows Script Host could not be started.");
shortcut = shellType.InvokeMember(
"CreateShortcut",
System.Reflection.BindingFlags.InvokeMethod,
null,
shell,
new object[] { shortcutPath }
) ?? throw new InvalidOperationException("The shortcut could not be created.");

var shortcutType = shortcut.GetType();
shortcutType.InvokeMember("TargetPath", System.Reflection.BindingFlags.SetProperty, null, shortcut, new object[] { targetPath });
shortcutType.InvokeMember("WorkingDirectory", System.Reflection.BindingFlags.SetProperty, null, shortcut, new object[] { Path.GetDirectoryName(targetPath)! });
shortcutType.InvokeMember("Description", System.Reflection.BindingFlags.SetProperty, null, shortcut, new object[] { "Open OpenKH Mod Manager" });
shortcutType.InvokeMember("IconLocation", System.Reflection.BindingFlags.SetProperty, null, shortcut, new object[] { $"{targetPath},0" });
shortcutType.InvokeMember("Save", System.Reflection.BindingFlags.InvokeMethod, null, shortcut, null);
}
finally
{
if (shortcut != null && Marshal.IsComObject(shortcut))
Marshal.FinalReleaseComObject(shortcut);
if (shell != null && Marshal.IsComObject(shell))
Marshal.FinalReleaseComObject(shell);
}

return shortcutPath;
}
}
Loading
Loading