Merge remote-tracking branch 'origin/main'

# Conflicts:
#	scripts/package-native.sh
#	scripts/stage-build.sh
This commit is contained in:
Alexander Sellite 2026-08-12 11:23:46 -04:00
commit 0f1d931a7b
7 changed files with 96 additions and 10 deletions

View file

@ -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:
@ -61,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.
@ -97,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

View file

@ -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:

View file

@ -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=

View file

@ -8,3 +8,6 @@ data_directory="/var/lib/netfishing-server"
[discovery]
url="https://discovery.netfishing.org"
[moderation]
operators=PackedStringArray()

View file

@ -116,8 +116,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
@ -129,6 +130,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
@ -227,6 +233,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

View file

@ -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 \
@ -44,6 +50,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}"

View file

@ -12,6 +12,13 @@ game_commit="${3,,}"
repository_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
destination_dir="${repository_dir}/dist"
licenses_dir="${destination_dir}/licenses"
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
@ -21,6 +28,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
@ -53,9 +64,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}" \
@ -71,6 +83,7 @@ Exact game source revision: ${game_commit}
Packaging source:
https://forge.makearmy.io/woofmeow/netfishing-dedicated-server
Exact packaging source revision: ${packaging_commit}
EOF
umask "${apply_umask}"
sha256sum \