GitHub-hosted runners are billing-blocked for this org, so the hosted
open-gitea-pr job never started (empty logs, immediate failure on every push
to main). Retarget it to [self-hosted, Linux, X64] like the other workflows;
the runner has LAN access to the Gitea host, and this workflow only fires on
push to main, so it never runs untrusted fork PR code.
Stand up the real AuthoritativeServer behind the real TCP transport on a
loopback port and drive real SyntheticProtocolClient sockets through it, so the
matrix is exercised over an actual connection rather than in-memory fakes.
Covers the baseline-protocol, TCP-compatibility, and interest-management
sections: welcome->hello->sessionReady handshake, unique/non-spoofable
server-owned ids, malformed and oversized rejection before mutation, rate-limit
tripping, transform/playerState/worldState relay, action events not
replay-cached to late joiners, disconnect/reconnect leaving no stale session,
same-cell relay vs distant interest filtering, multi-client no cross-cell spam,
and handshake-timeout reaping.
The harness runs for real wherever loopback TCP can bind (dev machines, the
self-hosted runner) and skips cleanly otherwise. Wired into a self-hosted CI
job gated by the runtime-policy guard. 60s idle-timeout, 32/64-client load /
packet-loss / reconnect-churn, and GNS sections remain follow-ups.
Give the host a cohesive vault-terminal look: header wordmark with a live
status pill that glows green while running, sectioned configuration card with
per-field labels, a terminal-style server log, richer player rows (id, name,
address, packet counts), and a bold Start/Stop control bar. All existing
bindings are unchanged.
Add publish-host.yml to build self-contained, single-file win-x64 and
linux-x64 binaries on the self-hosted runner and upload them as artifacts,
and document the untrimmed publish commands in the host README.
Delete the Qt host (src/, cmake/, CMakeLists.txt, find-qt.bat, check-setup.bat,
build.bat, deploy.bat) now that the Avalonia host in host/ covers it on the same
dotnet toolchain. Add a self-hosted host-build CI job and a host README, and
rewrite the top-level README for the C# server + Avalonia host layout.
The job-level env used runner.tool_cache, which isn't available until a
runner is assigned, so the workflow failed to parse. Set it on the
setup-dotnet step, where the runner context is valid.
setup-dotnet defaulted to /usr/share/dotnet, which the runner user cannot
write to (Permission denied). Point DOTNET_INSTALL_DIR at runner.tool_cache
so the 8.0 SDK installs into a writable, cached location.
- GnsTransport.cs: drop the illegal fixed statement on native.Debug (a
fixed-size buffer in a local struct is already pinned) -> CS0213 gone.
- ProtocolCore.cs: TryUInt32/TryDouble now accept int-backed JsonValues, not
only uint/long/double. Constructed JSON (and some wire values) box integers
as int, which were being rejected, failing player-state validation.
- MainWindow.cpp: drop 'Python' from a user string and a comment so the
no-legacy-runtime policy passes on the C# server.
- gns-transport.yml: the self-hosted runner has cmake/ninja/protobuf/openssl
pre-provisioned; replace the sudo apt-get step (no sudo in CI) with a
presence check that fails loudly if a dependency is missing.
Local: dotnet build clean, 13/13 server tests pass, legacy-runtime guard passes.
The ubuntu-latest job cannot start while GitHub-hosted minutes are
billing-blocked. Target the self-hosted Linux x64 runner, matching the
rest of the CI (csharp-server.yml, CO-BETA/beta-ci.yml).
Adds end-to-end Linux compatibility work for the dedicated server: new CI workflow (Ubuntu + Arch), line-ending/executable safeguards, and a local venv-first startup flow with split dependency files for server vs optional host GUI tooling. Improves runtime resilience with better bind error messages, stricter config validation, writable-state checks, cleaner socket/thread shutdown behavior, and SIGTERM-aware graceful stop handling for headless/systemd use. Updates deployment/startup docs and adds portability/runtime integration tests to lock in these behaviors.