initial commit: reforgermods.net launcher 0.1.0

A desktop server browser for Arma Reforger, built on the reforgermods.net v2
API. Live server list with search, sort and filters; a detail inspector with
population history and mod readiness; measured ICMP latency; favorites, recents
and settings; and direct joining through Steam.

Tauri 2 and Rust, with a Preact frontend that builds to 80 KB of JavaScript in
one chunk. Logic lives in rfm-core, which has no Tauri dependency and is tested
directly; src-tauri is the window, the command surface and the wiring.

Packaged for the public beta: a per-user NSIS installer, a portable .exe and an
Arch package, with signature-verified background updates on Windows and a
release pipeline that builds from a tag. The artifacts are not yet
Authenticode-signed — that is wired and waiting on an Azure Trusted Signing
identity, and docs/distribution.md says so plainly rather than letting anyone
discover it at the SmartScreen dialog.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
SowinskiBraedenandClaude Opus 5 committed 2026-09-24 20:29:00 -07:00
commit 377f3a31b3
91 files changed
+24994

No files matched your search

+94
View File
@@ -0,0 +1,94 @@
# Maintainer: reforgermods.net
#
# Builds the launcher from a source tarball produced by scripts/build-arch.sh.
# The tarball is the working tree minus node_modules/target/dist, so this
# packages exactly what is checked out — not a tagged release.
pkgname=reforgermods-launcher
pkgver=0.1.0
pkgrel=1
pkgdesc="Server browser and direct launcher for Arma Reforger (reforgermods.net)"
arch=('x86_64')
url="https://reforgermods.net"
license=('LicenseRef-Proprietary')
# webkit2gtk-4.1 pulls gtk3, libsoup3, glib2 and the rest of the WebKit stack.
# The binary links rustls rather than OpenSSL, so there is no openssl dependency.
depends=('webkit2gtk-4.1' 'gtk3' 'libsoup3' 'glibc' 'gcc-libs')
# cmake builds aws-lc-sys, the C crypto library behind rustls' default
# provider. Without it the crate's build script produces no library and the
# link fails late with a wall of undefined aws_lc_* symbols.
makedepends=('rust' 'nodejs' 'npm' 'cmake')
# !lto: makepkg's default OPTIONS put -flto=auto into CFLAGS/LDFLAGS. That
# makes aws-lc-sys compile its C crypto into GCC LTO bitcode, which the
# linker rustc drives cannot resolve — the build dies at the very last step
# with a page of undefined aws_lc_* symbols. Rust-level LTO is unaffected:
# that comes from [profile.release] in the workspace manifest.
# !debug: the release profile already strips, so a -debug split package would
# be empty. One artifact to hand over is the point.
options=('!lto' '!debug')
source=("$pkgname-$pkgver.tar.gz")
sha256sums=('SKIP')
build() {
cd "$srcdir/$pkgname-$pkgver"
# The frontend is embedded into the binary by tauri-build, so it has to exist
# before cargo runs.
npm ci
npm run build
# --features custom-protocol is what makes this a production build: without
# it tauri-build sets cfg(dev) and the app loads its UI from the Vite dev
# server on localhost:1420 instead of the embedded assets. See the comment on
# that feature in src-tauri/Cargo.toml.
cargo build --release --locked -p reforgermods-launcher --features custom-protocol
# Assert the result is not a dev build. You cannot tell by inspecting the
# binary — tauri embeds the whole config, devUrl included, either way, and
# brotli-compresses the assets. The signal is the cargo:rustc-cfg=dev that
# tauri-build emits, recorded in the build script's output file. A dev build
# packages and installs perfectly and then shows ERR_CONNECTION_REFUSED on
# the tester's machine, which is exactly the report you cannot debug
# remotely.
local build_out
build_out=$(ls -t target/release/build/reforgermods-launcher-*/output | head -1)
if [[ -z "$build_out" ]]; then
echo "ERROR: could not find the build script output to verify the build mode." >&2
return 1
fi
if grep -q "rustc-cfg=dev" "$build_out"; then
echo "ERROR: this is a DEV build; --features custom-protocol did not take effect." >&2
return 1
fi
echo "build mode: production (frontend embedded, no dev-server dependency)"
}
check() {
cd "$srcdir/$pkgname-$pkgver"
# The launcher crate is included for the Linux-only startup workarounds in
# main.rs, which are exactly the code a Windows-first project is least likely
# to notice breaking.
cargo test --release --locked -p rfm-core -p reforgermods-launcher
}
package() {
cd "$srcdir/$pkgname-$pkgver"
install -Dm755 target/release/reforgermods-launcher \
"$pkgdir/usr/bin/reforgermods-launcher"
install -Dm644 packaging/arch/reforgermods-launcher.desktop \
"$pkgdir/usr/share/applications/reforgermods-launcher.desktop"
for size in 32 128; do
install -Dm644 "src-tauri/icons/${size}x${size}.png" \
"$pkgdir/usr/share/icons/hicolor/${size}x${size}/apps/reforgermods-launcher.png"
done
install -Dm644 src-tauri/icons/128x128@2x.png \
"$pkgdir/usr/share/icons/hicolor/256x256/apps/reforgermods-launcher.png"
install -Dm644 src-tauri/icons/icon.png \
"$pkgdir/usr/share/icons/hicolor/512x512/apps/reforgermods-launcher.png"
}
@@ -0,0 +1,13 @@
[Desktop Entry]
Type=Application
Version=1.0
Name=reforgermods.net launcher
GenericName=Arma Reforger Server Browser
Comment=Server browser and direct launcher for Arma Reforger.
Exec=reforgermods-launcher
Icon=reforgermods-launcher
Terminal=false
Categories=Game;Network;
Keywords=Arma;Reforger;server;browser;launcher;
StartupNotify=true
StartupWMClass=reforgermods-launcher
+52
View File
@@ -0,0 +1,52 @@
@echo off
REM Authenticode signing for one artifact, called by Tauri during bundling.
REM
REM Tauri invokes this once per bundled file, with the path as %1, and it must run
REM *during* the bundle rather than after it: the updater artifact is a zip of the
REM installer plus a minisign signature over that zip. Sign the installer after
REM bundling and the zip still holds the unsigned copy, while the signature it
REM ships describes a file nobody will ever download. Wiring this through
REM bundle.windows.signCommand is what keeps those two in step.
REM
REM Configuration comes from the environment so nothing about the signing identity
REM is committed. The credentials themselves are read from the environment by the
REM Azure SDK inside trusted-signing-cli (AZURE_CLIENT_ID, AZURE_CLIENT_SECRET,
REM AZURE_TENANT_ID) and are never referenced here.
REM
REM RFM_SIGN_ENDPOINT e.g. https://eus.codesigning.azure.net
REM RFM_SIGN_ACCOUNT Trusted Signing account name
REM RFM_SIGN_PROFILE certificate profile name
REM
REM This deliberately fails the build when it is reachable but misconfigured. A
REM sign step that quietly does nothing produces an unsigned installer that looks
REM signed in the release notes, which is the one outcome worth crashing over.
setlocal
if "%~1"=="" (
echo sign.cmd: no file to sign was given 1>&2
exit /b 1
)
if "%RFM_SIGN_ENDPOINT%"=="" goto :missing
if "%RFM_SIGN_ACCOUNT%"=="" goto :missing
if "%RFM_SIGN_PROFILE%"=="" goto :missing
where trusted-signing-cli >nul 2>nul
if errorlevel 1 (
echo sign.cmd: trusted-signing-cli is not on PATH 1>&2
echo sign.cmd: install it with `cargo install trusted-signing-cli` 1>&2
exit /b 1
)
echo sign.cmd: signing %~nx1
trusted-signing-cli -e "%RFM_SIGN_ENDPOINT%" -a "%RFM_SIGN_ACCOUNT%" -c "%RFM_SIGN_PROFILE%" "%~1"
if errorlevel 1 (
echo sign.cmd: signing failed for %~nx1 1>&2
exit /b 1
)
exit /b 0
:missing
echo sign.cmd: RFM_SIGN_ENDPOINT, RFM_SIGN_ACCOUNT and RFM_SIGN_PROFILE must all be set 1>&2
exit /b 1