Repository navigation
fix: secure runtime paths and launcher setup - #745
Closed
MohamedElGhandour wants to merge 804 commits into
Closed
MohamedElGhandour wants to merge 804 commits into
MohamedElGhandour wants to merge 804 commits into
Conversation
This reverts commit 07b86bf.
Replace the connected-workbench modules with a live controller that drives the real C backend on :9274 exactly as the Electron renderer did: setup wizard (runtime/Steam installs into ~/.metalsharp, API key saves), library sync for Steam and Ubisoft, Play/Stop with external-exit detection, hero game settings, bottle route changes, launcher buttons, Settings actions, updater download/install/restart, post-update migration, streaming, and the GOG/Epic/GameJolt/emulator Sharp library. The backend now removes the previous route's DLLs before staging a new bottle route so switching e.g. DXMT -> D3DMetal leaves no stale DLLs. Add package-app.sh to build MetalSharp.app with the com.metalsharp.app identity expected by update.sh.
- First-launch intro video: MetalSharp-Startup.mp4 plays over the window with "Skip intro" (WKWebView overlay), remembered once seen. - Cmd+P Process Manager HUD with helper sampling, MetalFX toggle/factor, non-Steam Wine force kill, and the --process-manager-overlay mode. - LibraryView's one-time vkd3d default-rules repair. - Sharp installer tooling reachable from SharpView: Launch Doctor and diagnostics drawer, D3DMetal launch path with track-running, bottle badges and launch log, app/GameJolt rename, cover position. - GameJolt store embedded in the Sharp page with the draggable split, hidden under app overlays; toasts stay visible above it.
- Steam: the library hero button only starts Steam (it toggled, so it stopped a starting client). Skip redundant Wine registry imports, poll readiness every 100 ms, restart stale sessions instead of reporting a false success, stop via wineserver -k plus a kill sweep, show pending Starting/Stopping states, verify Wine is gone after setup's Steam install, and bring the Steam installer window to the front once. - Settings: draw the confirm dialog and language menu without nesting a deferred layer inside the deferred overlay (GPUI aborted the app); same for Sharp's resolution menu. Uninstall stops Wine sessions and the backend, deletes data off the UI thread and shows the result dialog on the main thread. - Shutdown: children spawned from GCD worker threads inherited a blocked signal mask, so the backend never received SIGTERM; clear the mask for spawned processes and in the backend's main(). Quit no longer blocks: SIGTERM plus a detached 3 s SIGKILL watchdog. Run the startup update check after the first library load, as Electron does. - Browser: per-provider persistent WebKit stores keep Steam, GOG, Epic and TheGamesDB sign-ins; GOG disconnect and Epic logout clear theirs. - Packaging: fail when the graphics bundle lacks the vkd3d-proton, DXVK or DXMT lanes; stop forcing MACOSX_DEPLOYMENT_TARGET for cargo, which made the macOS 27 linker emit proc-macro dylibs dyld rejects.
- Bottles: a saved "dxmt" route is honoured when saving, launching, checking readiness and diagnosing instead of falling back to the game's default route. Route DLLs are staged when an installed game is first detected (marker bottles/steam_<id>/.route-staged), not only on first launch or Bottle save. - Executables: Skyrim SE launches SkyrimSE.exe, and a "<Name>Launcher.exe" next to "<Name>.exe" no longer wins on directory order. - Steam: a cold start whose UI never initialized gets one automatic restart if htmlcache/"First Run" is not written within 10 s. The Steam client is launched through "MetalSharp Steam.app" (built by packaging from assets/metalsharp-steam.icon) so its first window carries the MetalSharp Steam icon instead of MetalSharp's; without the helper the launch is unchanged. - Audio: FAudio's Windows build ships in metalsharp-assets (assets/faudio), unpacks to runtime/faudio and is installed into the Steam prefix with a SkyrimSE.exe-only native override so xWMA NPC dialogue plays. Older installs extract it from the bundle on demand. Third-party notices in LICENSES/FAUDIO-*. - Updated the MetalSharp app icon.
Settings -> Graphics runtime logs now keeps each direct game launch's Wine stderr (errors, DLL loads, exceptions) in logs/<route>/<appid>/launch.stderr.log instead of discarding it; before, only Rain World and EVE wrote launch logs.
The GPUI app in app-gpui/ is now the application. Remove the Electron main process, Vue renderer, shared types, npm/Vite/TypeScript/Biome/Prettier tooling, electron-builder hooks and the Vue/Electron source tests. app/src-c, app/native, app/tools, app/bundles, app/updater and the two backend source-contract tests stay. Release: release.yml builds the GPUI app with package-app.sh, signs it inside-out with hardened runtime and tools/dmg/entitlements.mac.plist (Developer ID when signing is prepared, ad hoc otherwise), builds MetalSharp-<version>-arm64.dmg with tools/dmg/package-gpui-dmg.sh and reuses the notarize/verify scripts. The DMG name, bundle id and signing team stay as update.sh's recovery path requires. The app version comes from CMakeLists.txt; set-version.sh no longer needs Node. The intro video moves to app-gpui/assets/intro. CI drops the Vue, Electron and JS/Vue CodeQL jobs and runs the backend contract tests in the native job; the pre-commit hook checks rustfmt instead of TypeScript. Docs, install.sh, CODEOWNERS and third-party notices are updated.
GOG's sign-in now redirects to login.gog.com, and its Steam, Xbox, Google and Discord buttons open a popup that posts the login back to the opener. Allow *.gog.com for GOG sign-in, open window.open popups with the WebKit-provided configuration, and check popup navigations and redirects against the provider hosts. Epic's allowlist gains the hosts its PlayStation, Nintendo, Steam, Xbox, Apple, Facebook and LEGO logins redirect through, and captcha frames may load over HTTPS in both windows.
The column count ignored the workspace panel's 1px border, so a full row overflowed by 2px and its last card wrapped, leaving an empty column.
… Sharp - Sharp apps, GOG, Epic and GameJolt now stage the selected route's DLLs next to the game exe when the route is saved and before launch, using the Steam staging (previous route DLLs removed by byte comparison). GOG gains /sharp-library/gog/set-engine; installer exes are skipped. - When a Sharp app exits, programs it installed (new uninstall entries, Start Menu/Desktop shortcuts, and for launchers new game folders beside them, in Program Files or on mapped drives) are added to the library with the same route. Installers run before this are scanned once. - External volumes get drive letters (Y: down) in the Sharp prefix so launcher folder pickers can reach them. - The Sharp card's Open Folder button becomes Add Asset: pick files from the unpacked MetalSharp assets and copy them beside the app's exe, keeping a .metalsharp-backup of any replaced file. - gamejolt.c is clang-formatted so the pre-commit check passes.
The API key rows now end with clickable links that open the key pages in the mini browser, reusing the setup screen's help opener.
Collection gains Installed / Uninstalled tabs. Uninstalled lists owned Steam games that aren't installed and installs them with Valve's macOS steamcmd (Windows depots), downloaded once to ~/.metalsharp/tools. - Backend (steamcmd.c): stdin-driven sign-in with Steam Guard code and mobile-approval states (only the account name is saved), Steam library listing with free space, a sequential install queue with progress and cancel, staging into the chosen library then moving the game into steamapps/common with its appmanifest. steamcmd is stopped when the backend exits. - UI: sign-in sheet, internal/external library picker, per-card progress and cancel, library refresh when an install finishes. - Cards show compatibility badges from the repo's sources: Playable (GAMES-SUPPORTED.md), May Run (mtsp-rules.toml), or kernel anti-cheat.
AMID EVIL intermittently exits during startup when its shipping exe is launched directly, but starts reliably through Steam with the same staged route DLLs. Route DLLs are still staged; the launch is then handed to steam://rungameid like Baldur's Gate 3.
Nothing imports the hook, so it was never loaded; DXMT staging, the DXMT readiness check (which looked for it in lib/dxmt) and Launch Doctor's expected files no longer include it. Copies already in game folders are still removed by route cleanup.
metalsharp-runtime.tar.zst on the bundles release now ships an ntdll.so built from the MetalSharp Wine 11.17 tree with DXMT-only GSBASE/TEB switching (fixes Unity/Mono titles such as Rain World and Besiege), pipe2 gated to macOS 27+, the msync client matching wineserver (WINEMSYNC), and the MetalSharp 1.0 version string.
The description and its link sat in a wrapping row, so the text stopped wrapping and ran under the key inputs and status badges. Stack the link under the wrapped description instead.
The release check and CI bundle downloads still used the pre-transfer aaf2tbz/metalsharp path and only worked through GitHub's redirect. The update check's error responses also hard-coded current_version 0.76.0, which set-version.sh does not bump; use MS_BACKEND_VERSION.
set-version.sh no longer rewrites a hardcoded version in updater.c, whose fallback responses now use MS_BACKEND_VERSION; it checks for that instead.
With the repository variable METALSHARP_RELEASE_RUNNER set to local, the release jobs run on the runner labelled metalsharp-release instead of macos-14. The build job deletes its temporary signing keychain afterwards, since a self-hosted runner keeps the user's keychain search list.
Picks up the steamcmd and GOG set-engine routes added to the C backend.
Replace Electron desktop with native GPUI application
package-local-preview.sh bundles libmetalsharp_host_runtime.dylib from the CMake build directory, which the GPUI Preview workflow never produced.
… VKD3D-Proton and DXVK caches per lane, and games keep those caches in the lanes' folders
… with early access, the graphics lanes and Get Into It
… back from FEX leaves no MetalSharp Wine app behind
…tion, every prefix included, without the updater's marker
…etalSharp Wine, at the same version too
…s before clearing Metal's cache that every Mullion game shares
…er builds left in a game's folders, once, at its next launch
…unning migration, and an install lock keeps both from replacing the app at once
…and names both DMGs
…s-fex.toml is the regular rules on MetalSharp Wine's lanes plus the games verified there
… and updates, and a changelog entry crediting Deadlock's fixes
…Wine and everything it carries are covered with their license texts
…eds METALSHARP_WINE_APP instead of a maintainer's path
…11 and D3D10 (welcome guide, changelog, architecture)
…o longer migrates at its second launch, and a Steam prefix MetalSharp Wine built reads as FEX
…nloaded regular DMG instead of recovering, and so reinstalling, FEX
…, swapped in safely and then consumed, and a failed restore leaves the build unrecorded to retry
…-recover for the regular build updating itself, the downloaded DMG with its variant otherwise
MetalSharp 1.0.0: the Arm64 FEX build on MetalSharp Wine
MohamedElGhandour
marked this pull request as ready for review
October 28, 2026 11:10
12 tasks done
7 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In plain words
MetalSharp could load replacement runtime code without checking who supplied it, and some FEX paths were inserted into shell commands. Steam API keys could also be saved with permissions that exposed them to another local account. These fixes close those paths and preserve existing game prefixes, saves, and login data.
Summary
Harden runtime setup, launcher dependency installation, and credential storage in the C backend. The normal in-app updater already checks the publisher signature; these changes address separate setup and repair paths.
Changes
Why this approach
Regular app packaging already requires all six runtime archives. Removing the network fallback keeps those resources covered by the app's signature without adding another checksum publication mechanism. The FEX build already carries its runtime and skips those downloads.
The standalone GOG helper removes the Git, virtualenv, and unpinned package-install steps. Its existing command-line interface matches MetalSharp's callers. Failed verification leaves the previous helper and user data intact.
Verification
make -C app/src-c testmake -C app/src-c VARIANT=fex BUILD_DIR="$PWD/app/src-c/build-fex" testcargo fmt --manifest-path app-gpui/Cargo.toml --checkcargo test --manifest-path app-gpui/Cargo.toml --locked --offlinepython3 tools/ci/verify-dmg-workflow.pygit diff --check; shell syntaxcodesign --verify --deep --stricton both built backend binariesBackend tests used isolated temporary homes. Regression cases cover crafted paths, invalid CDHashes, old-wrapper regeneration, missing or shadowed bundles, tampered helper downloads, initialized GOG upgrades, legacy credential permissions, and symlink target preservation.
Real-game launch smoke — 28 October 2026
Tested commit
753bb86with Deadlock (1422450), D3DMetal, regular/Rosetta, using the existing Steam library on the internal drive. Both the frontend and backend were compiled from the PR; unchanged icons and runtime resources were copied from the installed 1.0.0 app into a separate, locally ad-hoc-signed test app. Full deep/strict signature verification passed. The installed application bundle was not modified.deadlock.exestarted; backend reported appid 1422450 and the same game PID. D3DMetal was loaded.This was a launch/rendering smoke test, not a multiplayer match, input/audio qualification, performance benchmark, or FEX game test. Existing Steam authentication was reused; no new store login was performed.
PR Readiness (MANDATORY)
/Users/...paths introduced.Follow-up verification — 4 November 2026
Merged current
mainwhile preserving the published branch history. Upstream rewrote earlier commits; the equivalent old/new 1.0 release trees were identical, so reconciliation used that tree as the common content base. All upstream data-location, Steam-launch and MetalFX changes are retained.Upstream and this branch had independently assigned facade version 3 to different wrapper updates. The combined facade now uses version 4, with a regression verifying that version-3 wrappers regenerate.
cargo test --locked --offline)Runtime archive simulation and integration with a real MetalSharp Wine app were skipped because those assets are absent. The earlier Deadlock launch test remains evidence for the original security commit; no new game launch or release packaging is claimed for this merge.
Risk and remaining checks
A damaged installation now needs the full official app reinstalled instead of downloading replacement runtime archives. Future GOGDL upgrades must update the pinned asset and digest together. Reverting this commit restores the previous behavior.
FEX game launching, standard full-Xcode packaging, release DMG signing/notarization, and real store login remain untested. The separate local regular app was assembled and its full code signature verified for the launch test above. Wine's broad file access and compatibility-related browser sandbox flags need separate isolation/compatibility work; this PR does not claim to make untrusted Windows executables safe.
Created by Codex (GPT-6).