A simple server selector for Overwatch
  • Rust 95.2%
  • Shell 4.8%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
hir0xygen a6a537e6b1
All checks were successful
Release / build (push) Successful in 2m4s
Release / release (push) Successful in 10s
ci: correct release-dir
2026-08-19 19:16:39 +02:00
.forgejo/workflows ci: correct release-dir 2026-08-19 19:16:39 +02:00
assets Hello world 2026-08-19 18:16:55 +02:00
scripts Hello world 2026-08-19 18:16:55 +02:00
src Hello world 2026-08-19 18:16:55 +02:00
.gitignore Hello world 2026-08-19 18:16:55 +02:00
build.rs Hello world 2026-08-19 18:16:55 +02:00
Cargo.lock Hello world 2026-08-19 18:16:55 +02:00
Cargo.toml Hello world 2026-08-19 18:16:55 +02:00
LICENSE Hello world 2026-08-19 18:16:55 +02:00
README.md Hello world 2026-08-19 18:16:55 +02:00

Servimari

A small Linux GUI (FLTK) for choosing which Overwatch 2 server region you play on. Check the regions you want to play in; Servimari blocks the rest with iptables so the matchmaker can only place you in an allowed region.

Building

Requires Rust (edition 2021) and the FLTK system dependencies (libx11, libxext, libxft, libxrender, libxcursor, libxfixes, libxinerama, libxi, libfontconfig1, libfreetype6, mesa).

cargo build --release
# or, for the portable AppImage:
bash scripts/build-appimage.sh

pkexec (polkit) is used to run the iptables commands, so a working polkit agent is required at runtime.

How it works

  1. On startup Servimari downloads Google's public cloud IP ranges (https://www.gstatic.com/ipranges/cloud.json) in the background; if that fails it falls back to the bundled assets/gcp_snapshot.json and retries twice more (30 s apart).
  2. Applying a block creates a user chain SERVIMARI, jumps to it from the INPUT and OUTPUT chains, and for every blocked CIDR adds:
    • 4 RETURN rules that let the Overwatch login port through, then
    • 2 DROP rules covering the whole CIDR in both directions.
  3. The selected regions are persisted to $XDG_CONFIG_HOME/servimari/state.jsononly after the firewall confirms the rules installed — together with the current boot id, so after a reboot Servimari can suggest re-applying.

Design trade-offs (read before you rely on it)

  • Cloud ranges are broad. GCP-backed regions block the whole public GCP range for that region, not just Blizzard's servers. Any unrelated service you use that happens to be hosted in a blocked region's range will also be cut off. This is what makes region blocking effective, and it is intentional.
  • IPv4 only. IPv6 prefixes are not fetched, so a blocked region may still be reachable over IPv6.
  • Firewall rules are not persistent by default. If your distro runs iptables-persistent/firewalld the rules may survive a reboot; otherwise you must re-apply after booting (Servimari will suggest it).
  • "Blocked N regions" counts regions with loaded ranges. If the live fetch failed and a region's ranges are missing, it is skipped and reported rather than silently claimed as blocked.

Refreshing the bundled GCP snapshot

assets/gcp_snapshot.json is a point-in-time copy of the GCP ranges for just the regions Servimari can block. Unlike the live fetch (which filters to the relevant scopes at runtime), the bundled file is a JSON object that maps each GCP scope directly to its list of ipv4Prefix CIDR strings, e.g. {"us-east4": ["...", ...], ...}. snapshot_gcp() loads it straight into that shape, so the file must not be wrapped in a {"prefixes": [...]} envelope.

The scope values are exactly the GoogleCloud(...) entries in src/region.rs (currently us-east4, southamerica-east1, europe-north1, me-central2, asia-northeast1, asia-southeast1); the app ignores any other scopes. Regenerate it with:

curl -s https://www.gstatic.com/ipranges/cloud.json \
  | jq 'reduce (.prefixes[] | select(.ipv4Prefix and .scope and (.scope | IN(
        "us-east4","southamerica-east1","europe-north1",
        "me-central2","asia-northeast1","asia-southeast1")))
      )) as $p ({}; .[$p.scope] += [$p.ipv4Prefix])' \
  > assets/gcp_snapshot.json

Because the live fetch succeeds in almost all cases, the snapshot only matters for offline-first launches; keeping it roughly up to date is a nice-to-have.

Development

cargo test   # unit tests for CIDR validation, ping parsing, batch building,
             # the shell marker protocol and state-file round-trips
cargo check  # fast compile check

Releases are built by the .forgejo/workflows/release.yml workflow (tag v*).

License

GPL-3.0-or-later — see LICENSE.