Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
8ced515
Add cross-platform Avalonia Mod Manager foundation
Yokimitsuro Aug 11, 2026
d937b35
Complete cross-platform Mod Manager feature set
Yokimitsuro Aug 11, 2026
88d7c46
Add Steam Input and Avalonia launcher
Yokimitsuro Aug 11, 2026
35ea730
Close launcher after opening Mod Manager
Yokimitsuro Aug 11, 2026
46068a9
Show Steam Input controller help
Yokimitsuro Aug 11, 2026
08ef6d5
Merge branch 'OpenKH:master' into feature/cross-platform-mod-manager
Yokimitsuro Aug 11, 2026
80f225d
Improve cross-platform controller navigation
Yokimitsuro Aug 11, 2026
258c21d
Use Avalonia as the only Mod Manager UI
Yokimitsuro Aug 14, 2026
b2fda10
Fix Linux game launch and Panacea support
Yokimitsuro Aug 14, 2026
06c824b
Fix Panacea removal for older installations
Yokimitsuro Aug 14, 2026
10a1ae0
Simplify complete game data extraction
Yokimitsuro Aug 14, 2026
ecd450f
Restore game data extraction warning
Yokimitsuro Aug 14, 2026
5d85a17
Restore the original extraction warning
Yokimitsuro Aug 14, 2026
29e3ea7
Restore remastered extraction controls
Yokimitsuro Aug 14, 2026
32576b3
Expand remastered extraction warning
Yokimitsuro Aug 14, 2026
5d44314
Adopt card-based online mod browser
Yokimitsuro Aug 14, 2026
916a0f2
Refine install navigation label
Yokimitsuro Aug 14, 2026
22174d2
Fix Lua setup and restore mod file details
Yokimitsuro Aug 19, 2026
fbe44c1
Merge branch 'master' of https://github.com/OpenKH/OpenKh into featur…
Yokimitsuro Aug 21, 2026
38e3df2
Add spatial controller navigation infrastructure
Yokimitsuro Aug 21, 2026
e85d5c6
Improve mod browsing and load order workflows
Yokimitsuro Aug 21, 2026
9ff55a9
Preserve existing Mod Manager settings
Yokimitsuro Aug 21, 2026
c213c40
Add AppImage packaging and cross-platform updates
Yokimitsuro Aug 21, 2026
b14e44a
Merge updated master into cross-platform Mod Manager
Yokimitsuro Aug 21, 2026
cb1e9d9
Fix Bdxio build and secure package extraction
Yokimitsuro Aug 22, 2026
eaeb43f
Restore repository and storage path compatibility
Yokimitsuro Aug 22, 2026
561128f
Address Mod Manager workflow review feedback
Yokimitsuro Aug 22, 2026
464c498
Isolate the reusable Bdxio library project
Yokimitsuro Aug 22, 2026
021341e
Keep the build script on the SLN format
Yokimitsuro Aug 22, 2026
50b8b68
Fix .NET 10 temporary solution layout
Yokimitsuro Aug 22, 2026
34dde2a
Register the Bdxio library in the main solution
Yokimitsuro Aug 22, 2026
f6dd3af
Limit temporary solutions to publishable projects
Yokimitsuro Aug 22, 2026
88f20ea
Make Panacea dependency copies deterministic
Yokimitsuro Aug 22, 2026
d0ad089
Read Panacea from its build output for Linux releases
Yokimitsuro Aug 22, 2026
be87031
Improve mod installation and action feedback
Yokimitsuro Aug 22, 2026
510d76b
Fix storage browsing and controller focus handling
Yokimitsuro Aug 22, 2026
efc3e32
Polish Mod Manager labels and setup warnings
Yokimitsuro Aug 22, 2026
61f3175
Align the repository install action
Yokimitsuro Aug 22, 2026
494558f
Verify repository install action alignment
Yokimitsuro Aug 22, 2026
bcb3046
Keep controller input with the virtual keyboard
Yokimitsuro Aug 22, 2026
e28a2d1
Fix shared controller navigation build
Yokimitsuro Aug 22, 2026
4daa64a
Add controller-friendly text input
Yokimitsuro Aug 22, 2026
11c88ef
Fix controller navigation in nested dialogs
Yokimitsuro Aug 22, 2026
77f699d
Confirm replacements before installing mods
Yokimitsuro Aug 22, 2026
c3a5fb0
Keep PC Patch mods at legacy priority
Yokimitsuro Aug 22, 2026
cc6055e
Keep controller focus on reordered mods
Yokimitsuro Aug 23, 2026
984c4dc
Add a portable Linux tarball
Yokimitsuro Aug 23, 2026
500d932
Use tarballs for portable Linux updates
Yokimitsuro Aug 23, 2026
b5f955d
Place newly installed mods at highest priority
Yokimitsuro Aug 23, 2026
3022fee
Fix cross-platform patching and report build progress
Yokimitsuro Aug 23, 2026
b6f5e3e
Normalize Panacea paths for Proton
Yokimitsuro Aug 23, 2026
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
63 changes: 63 additions & 0 deletions .github/scripts/create-release-archive.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
param (
[Parameter(Mandatory = $true)]
[string] $SourceDirectory,

[Parameter(Mandatory = $true)]
[string] $DestinationPath
)

$ErrorActionPreference = "Stop"

Add-Type -AssemblyName System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.FileSystem

$sourcePath = (Resolve-Path -LiteralPath $SourceDirectory).Path
$sourceName = Split-Path -Leaf $sourcePath
$destinationFullPath = [System.IO.Path]::GetFullPath($DestinationPath)
$destinationDirectory = Split-Path -Parent $destinationFullPath

if ($destinationDirectory) {
New-Item -ItemType Directory -Path $destinationDirectory -Force | Out-Null
}

if (Test-Path -LiteralPath $destinationFullPath) {
Remove-Item -LiteralPath $destinationFullPath -Force
}

$archive = [System.IO.Compression.ZipFile]::Open(
$destinationFullPath,
[System.IO.Compression.ZipArchiveMode]::Create)

try {
Get-ChildItem -LiteralPath $sourcePath -Directory -Recurse -Force | ForEach-Object {
$relativePath = $_.FullName.Substring($sourcePath.Length).TrimStart('\', '/')
$entryName = "$sourceName/$($relativePath.Replace('\', '/'))/"
$null = $archive.CreateEntry($entryName)
}

Get-ChildItem -LiteralPath $sourcePath -File -Recurse -Force | ForEach-Object {
$relativePath = $_.FullName.Substring($sourcePath.Length).TrimStart('\', '/')
$entryName = "$sourceName/$($relativePath.Replace('\', '/'))"
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile(
$archive,
$_.FullName,
$entryName,
[System.IO.Compression.CompressionLevel]::Optimal) | Out-Null
}
}
finally {
$archive.Dispose()
}

$archive = [System.IO.Compression.ZipFile]::OpenRead($destinationFullPath)
try {
$invalidEntry = $archive.Entries | Where-Object { $_.FullName.Contains('\') } | Select-Object -First 1
if ($invalidEntry) {
throw "Archive entry '$($invalidEntry.FullName)' contains a Windows path separator."
}
}
finally {
$archive.Dispose()
}

Write-Host "Created $destinationFullPath with portable ZIP paths."
107 changes: 107 additions & 0 deletions .github/scripts/prepare-appimage.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#!/bin/sh
set -eu

# linuxdeploy inspects every PATH entry, including inaccessible Windows paths inherited by WSL.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export PATH

if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then
echo "Usage: $0 RELEASE_DIRECTORY OUTPUT_APPIMAGE [VERSION]" >&2
exit 2
fi

SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
REPOSITORY_ROOT=$(CDPATH= cd -- "$SCRIPT_DIR/../.." && pwd)
RELEASE_DIRECTORY=$(CDPATH= cd -- "$1" && pwd)
OUTPUT_DIRECTORY=$(CDPATH= cd -- "$(dirname -- "$2")" && pwd)
OUTPUT_APPIMAGE="$OUTPUT_DIRECTORY/$(basename -- "$2")"
VERSION_NAME="${3:-continuous}"
WORK_DIRECTORY=$(mktemp -d)
APP_DIRECTORY="$WORK_DIRECTORY/OpenKH.AppDir"
TOOLS_DIRECTORY="$WORK_DIRECTORY/tools"
ICON_PATH="$WORK_DIRECTORY/openkh.png"

cleanup() {
rm -rf "$WORK_DIRECTORY"
}
trap cleanup EXIT INT TERM

require_file() {
if [ ! -f "$1" ]; then
echo "Required AppImage input is missing: $1" >&2
exit 1
fi
}

require_file "$RELEASE_DIRECTORY/OpenKh.Launcher"
require_file "$RELEASE_DIRECTORY/Apps/OpenKh.Tools.ModsManager"
require_file "$REPOSITORY_ROOT/distribution/AppImage/AppRun"
require_file "$REPOSITORY_ROOT/distribution/AppImage/openkh.desktop"
require_file "$REPOSITORY_ROOT/images/openKH_Old.ico"

mkdir -p \
"$APP_DIRECTORY/usr/bin" \
"$APP_DIRECTORY/usr/lib/openkh" \
"$APP_DIRECTORY/usr/share/applications" \
"$APP_DIRECTORY/usr/share/icons/hicolor/256x256/apps" \
"$TOOLS_DIRECTORY"
cp -a "$RELEASE_DIRECTORY/." "$APP_DIRECTORY/usr/lib/openkh/"
chmod +x \
"$APP_DIRECTORY/usr/lib/openkh/OpenKh.Launcher" \
"$APP_DIRECTORY/usr/lib/openkh/Apps/OpenKh.Tools.ModsManager"
ln -s ../lib/openkh/OpenKh.Launcher "$APP_DIRECTORY/usr/bin/openkh"
ln -s ../lib/openkh/Apps/OpenKh.Tools.ModsManager "$APP_DIRECTORY/usr/bin/openkh-mod-manager"
install -m 644 \
"$REPOSITORY_ROOT/distribution/AppImage/openkh.desktop" \
"$APP_DIRECTORY/usr/share/applications/openkh.desktop"

# The Windows icon already contains the approved OpenKH artwork at several sizes.
convert "${REPOSITORY_ROOT}/images/openKH_Old.ico[0]" \
-background none \
-gravity center \
-resize 256x256 \
-extent 256x256 \
"$ICON_PATH"
install -m 644 "$ICON_PATH" "$APP_DIRECTORY/usr/share/icons/hicolor/256x256/apps/openkh.png"

LINUXDEPLOY_VERSION="${LINUXDEPLOY_VERSION:-1-alpha-20251107-1}"
APPIMAGETOOL_VERSION="${APPIMAGETOOL_VERSION:-1.9.1}"
LINUXDEPLOY="$TOOLS_DIRECTORY/linuxdeploy-x86_64.AppImage"
APPIMAGETOOL="$TOOLS_DIRECTORY/appimagetool-x86_64.AppImage"
curl --fail --location --silent --show-error \
"https://github.com/linuxdeploy/linuxdeploy/releases/download/${LINUXDEPLOY_VERSION}/linuxdeploy-x86_64.AppImage" \

Check warning on line 72 in .github/scripts/prepare-appimage.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Not enforcing HTTPS here might allow for redirections to insecure websites. Make sure it is safe here.

See more on https://sonarcloud.io/project/issues?id=OpenKH_OpenKh&issues=AaBKYOeELA5NtWH9IN_e&open=AaBKYOeELA5NtWH9IN_e&pullRequest=1283
Comment on lines +71 to +72
--output "$LINUXDEPLOY"
curl --fail --location --silent --show-error \
"https://github.com/AppImage/appimagetool/releases/download/${APPIMAGETOOL_VERSION}/appimagetool-x86_64.AppImage" \

Check warning on line 75 in .github/scripts/prepare-appimage.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Not enforcing HTTPS here might allow for redirections to insecure websites. Make sure it is safe here.

See more on https://sonarcloud.io/project/issues?id=OpenKH_OpenKh&issues=AaBKYOeELA5NtWH9IN_f&open=AaBKYOeELA5NtWH9IN_f&pullRequest=1283
Comment on lines +74 to +75
--output "$APPIMAGETOOL"
chmod +x "$LINUXDEPLOY" "$APPIMAGETOOL"

set -- \
"$LINUXDEPLOY" \
--appdir "$APP_DIRECTORY" \
--desktop-file "$APP_DIRECTORY/usr/share/applications/openkh.desktop" \
--icon-file "$APP_DIRECTORY/usr/share/icons/hicolor/256x256/apps/openkh.png" \
--executable "$APP_DIRECTORY/usr/bin/openkh" \
--executable "$APP_DIRECTORY/usr/bin/openkh-mod-manager"

# Avalonia loads these libraries at runtime, so the .NET app host does not expose them to ldd.
for library_name in libfontconfig.so.1 libfreetype.so.6 libICE.so.6 libSM.so.6 libX11.so.6 libX11-xcb.so.1 libxcb.so.1; do
library_path=$(ldconfig -p | awk -v name="$library_name" '$1 == name { print $NF; exit }')
if [ -z "$library_path" ]; then
echo "Required Linux library was not found: $library_name" >&2
exit 1
fi
set -- "$@" --library "$library_path"
done

APPIMAGE_EXTRACT_AND_RUN=1 "$@"
rm -f "$APP_DIRECTORY/AppRun"
install -m 755 "$REPOSITORY_ROOT/distribution/AppImage/AppRun" "$APP_DIRECTORY/AppRun"

rm -f "$OUTPUT_APPIMAGE"
ARCH=x86_64 \
VERSION="$VERSION_NAME" \
APPIMAGE_EXTRACT_AND_RUN=1 \
"$APPIMAGETOOL" "$APP_DIRECTORY" "$OUTPUT_APPIMAGE"
chmod +x "$OUTPUT_APPIMAGE"
echo "Created $OUTPUT_APPIMAGE"
83 changes: 83 additions & 0 deletions .github/scripts/prepare-linux-release.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
param (
[string] $ReleaseDirectory = "openkh-linux-x64",
[string] $Configuration = "Release"
)

$ErrorActionPreference = "Stop"
$repositoryRoot = (Resolve-Path (Join-Path $PSScriptRoot "..\..")).Path
$launcherProject = Join-Path $repositoryRoot "OpenKh.Tools.Launcher\OpenKh.Tools.Launcher.csproj"
$modManagerProject = Join-Path $repositoryRoot "OpenKh.Tools.ModsManager.Avalonia\OpenKh.Tools.ModsManager.csproj"
$panaceaSourceDirectory = Join-Path $repositoryRoot "OpenKh.Research.Panacea\Release"
$panaceaFileNames = @(
"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"
)

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

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

dotnet publish `
$launcherProject `
--configuration $Configuration `
--runtime linux-x64 `
--self-contained true `
--source "https://api.nuget.org/v3/index.json" `
--output $ReleaseDirectory `
/p:PublishSingleFile=true `
/p:IncludeNativeLibrariesForSelfExtract=true `
/p:DebugType=None `
/p:DebugSymbols=false

if ($LASTEXITCODE -ne 0) {
throw "Publishing the Linux launcher failed with exit code $LASTEXITCODE."
}

dotnet publish `
$modManagerProject `
--configuration $Configuration `
--runtime linux-x64 `
--self-contained true `
--source "https://api.nuget.org/v3/index.json" `
--output $applicationsDirectory `
/p:PublishSingleFile=true `
/p:IncludeNativeLibrariesForSelfExtract=true `
/p:DebugType=None `
/p:DebugSymbols=false

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

foreach ($fileName in $panaceaFileNames) {
$sourcePath = Join-Path $panaceaSourceDirectory $fileName
if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {
throw "Required Panacea file '$sourcePath' does not exist."
}
Copy-Item -LiteralPath $sourcePath -Destination $applicationsDirectory
}

Get-ChildItem -LiteralPath $ReleaseDirectory -Filter "*.pdb" -File -Recurse |
Remove-Item -Force

Copy-Item `
-LiteralPath (Join-Path $repositoryRoot "distribution\README-LINUX.txt") `
-Destination (Join-Path $ReleaseDirectory "README-FIRST.txt")
Copy-Item -LiteralPath (Join-Path $repositoryRoot "distribution\install-openkh-linux.sh") -Destination $ReleaseDirectory
Copy-Item -LiteralPath (Join-Path $repositoryRoot "LICENSE") -Destination $ReleaseDirectory
Copy-Item -LiteralPath (Join-Path $repositoryRoot "NOTICE") -Destination $ReleaseDirectory
7 changes: 6 additions & 1 deletion .github/scripts/prepare-release.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,21 @@ dotnet publish `
"OpenKh.Tools.Launcher/OpenKh.Tools.Launcher.csproj" `
--configuration $Configuration `
--runtime win-x64 `
--self-contained false `
--self-contained true `
--source "https://api.nuget.org/v3/index.json" `
--output $ReleaseDirectory `
/p:PublishSingleFile=true `
/p:IncludeNativeLibrariesForSelfExtract=true `
/p:DebugType=None `
/p:DebugSymbols=false

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

Get-ChildItem -LiteralPath $ReleaseDirectory -Filter "*.pdb" -File |
Remove-Item -Force

$compatibilityExecutable = Join-Path $ReleaseDirectory "OpenKh.Tools.ModsManager.exe"
Copy-Item `
-LiteralPath (Join-Path $ReleaseDirectory "OpenKh.Launcher.exe") `
Expand Down
Loading
Loading