From 6f764fb06522c0faefbb50b4df801be7ef1d1639 Mon Sep 17 00:00:00 2001 From: Voyager Date: Tue, 11 Aug 2026 20:31:02 -0400 Subject: [PATCH 1/2] Prepare v0.6.7-alpha dedicated packaging --- README.md | 12 +++++++++--- scripts/install-native-release.sh | 11 ++++++++++- scripts/package-native.sh | 26 ++++++++++++++++++++++++++ scripts/stage-build.sh | 14 +++++++++++++- 4 files changed, 58 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4366614..84001ef 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,12 @@ This repository packages the headless NETfishing server produced by the main game project. Gameplay and networking code remain in the `netfishing` repository so clients and servers use the same protocol implementation. +Production tags follow the coordinated NETfishing release train. Package a +game release with the same `vX.Y.Z-alpha` tag checked out in this repository. +The package manifest records both the exact game commit and the exact dedicated +packaging commit; packaging refuses to run when its matching release tag does +not point to the current commit. + ## Stage a build Export the `Linux Dedicated Server` preset from the game project, then stage @@ -18,9 +24,9 @@ game_commit="$(git -C ../netfishing rev-parse HEAD)" ``` The staged binaries under `dist/` are release inputs and are intentionally not -tracked by Git. `dist/BUILD_INFO` records the version, full game commit, export -preset, platform, and binary hashes. Packaging refuses a version mismatch or -failed internal checksum. +tracked by Git. `dist/BUILD_INFO` records the version, full game and packaging +commits, export preset, platform, and binary hashes. Packaging refuses a +version mismatch, packaging-tag mismatch, or failed internal checksum. Create a deterministic native archive after staging: diff --git a/scripts/install-native-release.sh b/scripts/install-native-release.sh index 06fef49..96c9bc5 100755 --- a/scripts/install-native-release.sh +++ b/scripts/install-native-release.sh @@ -101,8 +101,9 @@ manifest_value() { manifest_version="$(manifest_value manifest_version)" game_version="$(manifest_value game_version)" game_commit="$(manifest_value game_commit)" +packaging_commit="$(manifest_value packaging_commit)" platform="$(manifest_value platform)" -if [[ "${manifest_version}" != "1" ]]; then +if [[ "${manifest_version}" != "1" && "${manifest_version}" != "2" ]]; then echo "Unsupported BUILD_INFO format." >&2 exit 1 fi @@ -114,6 +115,11 @@ if [[ ! "${game_commit}" =~ ^[0-9a-f]{40}$ ]]; then echo "Invalid game commit in BUILD_INFO." >&2 exit 1 fi +if [[ "${manifest_version}" == "2" \ + && ! "${packaging_commit}" =~ ^[0-9a-f]{40}$ ]]; then + echo "Invalid packaging commit in BUILD_INFO." >&2 + exit 1 +fi if [[ "${platform}" != "linux-x86_64" ]]; then echo "This installer only accepts linux-x86_64 packages." >&2 exit 1 @@ -201,6 +207,9 @@ if [[ -n "${old_current}" && "${old_current}" != "${release_dir}" ]]; then fi echo "Installed NETfishing dedicated server ${game_version} (${game_commit})." +if [[ -n "${packaging_commit}" ]]; then + echo "Dedicated packaging commit: ${packaging_commit}." +fi if ${service_exists} && ! ${service_active}; then echo "${service_name} was inactive and was not started." fi diff --git a/scripts/package-native.sh b/scripts/package-native.sh index ebd25ae..bd41e1c 100755 --- a/scripts/package-native.sh +++ b/scripts/package-native.sh @@ -18,6 +18,12 @@ package_name="netfishing-dedicated-server-${version}-linux-x86_64" staging_dir="$(mktemp -d)" trap 'rm -rf -- "${staging_dir}"' EXIT +if ! git -C "${repository_dir}" diff --quiet \ + || ! git -C "${repository_dir}" diff --cached --quiet; then + echo "Commit dedicated packaging changes before creating a release." >&2 + exit 1 +fi + for filename in NETfishingServer.x86_64 NETfishingServer.pck BUILD_INFO SHA256SUMS; do if [[ ! -f "${dist_dir}/${filename}" ]]; then echo "Run scripts/stage-build.sh before packaging." >&2 @@ -28,6 +34,26 @@ if ! grep -Fxq "game_version=${version}" "${dist_dir}/BUILD_INFO"; then echo "Staged BUILD_INFO does not match package version ${version}." >&2 exit 1 fi +packaging_commit="$( + awk -F= '$1 == "packaging_commit" {print tolower($2); exit}' \ + "${dist_dir}/BUILD_INFO" +)" +current_packaging_commit="$(git -C "${repository_dir}" rev-parse HEAD)" +if [[ "${packaging_commit}" != "${current_packaging_commit}" ]]; then + echo "Staged BUILD_INFO does not match the current packaging commit." >&2 + exit 1 +fi +release_tag="v${version}" +if ! release_commit="$( + git -C "${repository_dir}" rev-parse --verify "refs/tags/${release_tag}^{commit}" +)"; then + echo "Dedicated packaging tag ${release_tag} does not exist." >&2 + exit 1 +fi +if [[ "${release_commit}" != "${current_packaging_commit}" ]]; then + echo "Dedicated packaging tag ${release_tag} does not point to HEAD." >&2 + exit 1 +fi (cd -- "${dist_dir}" && sha256sum -c SHA256SUMS) install -d "${staging_dir}/${package_name}" diff --git a/scripts/stage-build.sh b/scripts/stage-build.sh index f007691..eaecf78 100755 --- a/scripts/stage-build.sh +++ b/scripts/stage-build.sh @@ -11,6 +11,13 @@ game_version="$2" game_commit="${3,,}" repository_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" destination_dir="${repository_dir}/dist" +packaging_commit="$(git -C "${repository_dir}" rev-parse HEAD)" + +if ! git -C "${repository_dir}" diff --quiet \ + || ! git -C "${repository_dir}" diff --cached --quiet; then + echo "Commit dedicated packaging changes before staging a release." >&2 + exit 1 +fi if [[ ! "${game_version}" =~ ^[A-Za-z0-9][A-Za-z0-9._-]*$ ]]; then echo "GAME_VERSION must contain only letters, numbers, dots, underscores, or hyphens." >&2 @@ -20,6 +27,10 @@ if [[ ! "${game_commit}" =~ ^[0-9a-f]{40}$ ]]; then echo "GAME_COMMIT must be the full 40-character Git commit." >&2 exit 2 fi +if [[ ! "${packaging_commit}" =~ ^[0-9a-f]{40}$ ]]; then + echo "Could not resolve the dedicated packaging Git commit." >&2 + exit 2 +fi for filename in NETfishingServer.x86_64 NETfishingServer.pck; do if [[ ! -f "${source_dir}/${filename}" ]]; then @@ -40,9 +51,10 @@ pck_sha256="$(sha256sum NETfishingServer.pck | awk '{print $1}')" apply_umask="$(umask)" umask 022 printf '%s\n' \ - "manifest_version=1" \ + "manifest_version=2" \ "game_version=${game_version}" \ "game_commit=${game_commit}" \ + "packaging_commit=${packaging_commit}" \ "export_preset=Linux Dedicated Server" \ "platform=linux-x86_64" \ "executable_sha256=${executable_sha256}" \ From 4965ea2c24c7f22cd883817d3b80a3d05a5b77e9 Mon Sep 17 00:00:00 2001 From: Voyager Date: Tue, 11 Aug 2026 22:58:53 -0400 Subject: [PATCH 2/2] Document dedicated server operators --- README.md | 37 ++++++++++++++++++++++++---- compose.yaml | 1 + config/netfishing-server.env.example | 1 + config/server.cfg.example | 3 +++ 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 84001ef..cd0d5df 100644 --- a/README.md +++ b/README.md @@ -67,8 +67,34 @@ to returning players. Configuration is applied in this order: config file, environment variables, then command-line overrides. Supported command-line options are `--name`, `--bind`, `--port`, `--max-players`, `--data-dir`, `--discovery-url`, -`--public`, and `--private`. Value options use `--option=value`. Keep the first -standalone `--` shown above; it separates Godot engine flags from server flags. +`--operators`, `--public`, and `--private`. Value options use `--option=value`. +Keep the first standalone `--` shown above; it separates Godot engine flags +from server flags. + +### Headless operators + +Headless moderation is granted by authenticated player identity, never by a +display name or shared password. A player can copy their complete 64-character +fingerprint from **Settings → Data & Identity → Copy Player Fingerprint**. + +Add trusted fingerprints to `/etc/netfishing-server.cfg`: + +```ini +[moderation] +operators=PackedStringArray("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef") +``` + +Alternatively, provide a comma-separated list through +`NETFISHING_SERVER_OPERATORS` or `--operators=fingerprint1,fingerprint2`. +Configuration file values are overridden by the environment, then by the +command line. Restart the server after changing the allowlist. + +The server grants operator status only after the connecting player proves +ownership of that exact identity key. Operators can kick, ban, unban, and clear +shared session artwork through the in-game Players page. They cannot grant +operator access, revoke another operator, or moderate another operator. Keep +the server data directory persistent because it owns the server identity and +stored bans. Public listing requires the discovery URL and a publicly reachable ENet UDP port. Discovery makes a server findable but does not relay gameplay traffic. @@ -103,9 +129,10 @@ docker compose up -d ``` Set values such as `NETFISHING_SERVER_NAME`, `NETFISHING_SERVER_PORT`, -`NETFISHING_SERVER_MAX_PLAYERS`, and `NETFISHING_SERVER_PUBLIC` in a local -`.env` file. The Compose service runs without Linux capabilities, uses a -read-only root filesystem, and stores persistent state in a named volume. +`NETFISHING_SERVER_MAX_PLAYERS`, `NETFISHING_SERVER_PUBLIC`, and the optional +comma-separated `NETFISHING_SERVER_OPERATORS` in a local `.env` file. The +Compose service runs without Linux capabilities, uses a read-only root +filesystem, and stores persistent state in a named volume. ## Steam distribution diff --git a/compose.yaml b/compose.yaml index 731d58a..413342c 100644 --- a/compose.yaml +++ b/compose.yaml @@ -18,6 +18,7 @@ services: NETFISHING_SERVER_PUBLIC: "${NETFISHING_SERVER_PUBLIC:-false}" NETFISHING_DISCOVERY_URL: "${NETFISHING_DISCOVERY_URL:-https://discovery.netfishing.org}" NETFISHING_DATA_DIR: /var/lib/netfishing-server + NETFISHING_SERVER_OPERATORS: "${NETFISHING_SERVER_OPERATORS:-}" volumes: - netfishing-server-data:/var/lib/netfishing-server tmpfs: diff --git a/config/netfishing-server.env.example b/config/netfishing-server.env.example index 43eac1e..78d7c16 100644 --- a/config/netfishing-server.env.example +++ b/config/netfishing-server.env.example @@ -5,3 +5,4 @@ NETFISHING_SERVER_MAX_PLAYERS=8 NETFISHING_SERVER_PUBLIC=false NETFISHING_DISCOVERY_URL=https://discovery.netfishing.org NETFISHING_DATA_DIR=/var/lib/netfishing-server +NETFISHING_SERVER_OPERATORS= diff --git a/config/server.cfg.example b/config/server.cfg.example index a807b6a..2567cf1 100644 --- a/config/server.cfg.example +++ b/config/server.cfg.example @@ -8,3 +8,6 @@ data_directory="/var/lib/netfishing-server" [discovery] url="https://discovery.netfishing.org" + +[moderation] +operators=PackedStringArray()