# Minecraft Worlds

## Quickstart: Bring a World Up

1. **Create via Web Control Plane (`https://mc.drheck.dev`) or CLI (`ipctl`):**
   - **Web UI (Recommended):** Open [https://mc.drheck.dev](https://mc.drheck.dev), click **+ New World**, style the world name/MOTD and 64×64 icon, select the **World Type (`level-type`)** (`Default Overworld`, `Amplified`, `Large Biomes`, `Superflat` with all 9 Mojang presets, or `Single Biome / Buffet`), configure **Structures / Hardcore / Spawn Protection**, preview/reroll the world seed with the live 2D biome map, and click **Create & Provision World**.
   - **CLI (`ipctl`):**
     ```bash
     sudo /data/minecraft/ipctl create <name> --dns
     ```
     *(Allocates backend IPv6 `fd77:7777:5010::1337:3c:d00d:<hex>/64` in `/etc/systemd/network/20-wired.network.d/minecraft.conf`, configures HAProxy SNI routing in `/etc/haproxy/conf.d/minecraft_backends.cfg` and `/etc/haproxy/minecraft_hosts.map`, adds `<name>.drheck.dev` to `/var/unbound/etc/unbound.minecraft.conf` on `danknasty` using a short-lived 5-minute `step-ca` SSH user certificate, syncs public A/AAAA records to deSEC.io, and automatically provisions the live 3D BlueMap web map via `/usr/local/bin/mc-bluemap-provision <name>` — creating `bluemap@<name>.service` on `[fd77:7777:5010::1337:3c:d00d:<hex>]:8100`, the `/etc/nginx/sites-available/<name>` vhost, and the Authentik ForwardAuth `ProxyProvider` + `Application` attached to `authentik Embedded Outpost` at `https://<name>.drheck.dev`).*

2. **Configure the backend server:**
   In your backend server's `server.properties`:
   ```properties
   server-ip=fd77:7777:5010::1337:3c:d00d:<hex>
   server-port=25565
   online-mode=true
   ```
   *(Backend servers run with `online-mode=true`, listening on standard port `25565` on their dedicated ULA IPv6 address).*

3. **Start the server:**
   Start via `https://mc.drheck.dev` (**Start** button or automatic **On-Demand** wake-on-join) or `sudo systemctl start minecraft@<slug>.service`.

4. **Connect:**
   Players connect using `<name>.drheck.dev` (standard port `25565`). Microsoft account authentication takes place directly between the client and the backend server.

---

### 5. Manage the 3D Web Map (`Provision`, `Decom`, `Enable`, `Disable`)
Every world can have its live 3D BlueMap web map (`https://<name>.drheck.dev`) independently provisioned, decommissioned, enabled, or disabled from either the Web UI (`https://mc.drheck.dev` header buttons) or the CLI (`/usr/local/bin/mc-bluemap-provision` / `/data/minecraft/ipctl bluemap`):

- **Provision (`Provision Map` / `sudo /data/minecraft/ipctl bluemap <name> provision`):**
  Creates `/etc/nginx/sites-available/<name>` + `/etc/nginx/sites-enabled/<name>`, provisions the Authentik ForwardAuth `ProxyProvider` + `Application` attached to `authentik Embedded Outpost`, initializes `/data/minecraft/<dir>/bluemap/`, and enables/starts `bluemap@<name>.service`.
- **Disable (`Disable Map` / `sudo /data/minecraft/ipctl bluemap <name> disable`):**
  Turns off `bluemap@<name>.service` while keeping the Nginx vhost and Authentik SSO active. Visitors to `https://<name>.drheck.dev` are served a styled **3D Web Map Currently Offline** status page (`proxy_intercept_errors on; error_page 502 503 504 @bluemap_offline;` routed to `mc-manager` `/bluemap-offline/<name>`) displaying the world icon, live game server status, an auto-reload poller, and a 1-click **Turn On 3D Map Now** button for admins.
- **Enable (`Enable Map` / `sudo /data/minecraft/ipctl bluemap <name> enable`):**
  Turns `bluemap@<name>.service` back on so `https://<name>.drheck.dev` immediately resumes serving the live 3D map.
- **Decommission (`Decom Map` / `sudo /data/minecraft/ipctl bluemap <name> decom`):**
  Stops `bluemap@<name>.service`, deletes `/etc/nginx/sites-enabled/<name>` and `/etc/nginx/sites-available/<name>`, reloads Nginx, and removes the Authentik `Application` and `ProxyProvider`.

---

## Quickstart: Take a World Down

1. **Stop the backend server:**
   Click **Stop** in `https://mc.drheck.dev`, send `stop` in the live web console, or run `sudo systemctl stop minecraft@<slug>.service`.

2. **What Players See When Offline or Standby (`On-Demand`):**
   HAProxy intercepts all Multiplayer Server List pings ($\text{state} = 1$) and offline/standby Login joins ($\text{state} = 2$) via `/etc/haproxy/minecraft.lua` and `mc-manager`:
   - **In the Multiplayer Server List (`state = 1`):** Returns the server's configured custom MOTD and 64×64 `server-icon.png` (`favicon`) immediately, with version status badge `Standby (Join to Wake)` (for `ondemand` servers) or `Offline` (for `manual` servers).
   - **When Clicking "Join Server" (`state = 2`):**
     - **`ondemand` Standby:** Automatically triggers `minecraft@<slug>.service` to boot and displays a gold countdown screen (`Waking up <Server>... Ready in ~20s!`).
     - **`manual` Offline:** Immediately disconnects with a clean red screen (`<Server> is currently offline. Start at mc.drheck.dev`).

3. **Disable or remove router mapping & DNS (Teardown):**
   - **Temporary takedown (disable in router only):**
     ```bash
     sudo /data/minecraft/ipctl route disable <name>
     ```
   - **Complete teardown (release IP, remove HAProxy route, purge DNS):**
     ```bash
     sudo /data/minecraft/ipctl delete <name> --dns
     ```

---

## Architecture & Design Details

### 1. Unified Endpoint Model
All public and LAN client connections resolve to the single **Minecraft Router endpoint pair**:
- **IPv4:** `10.0.0.113` *(NAT port-forwarded from WAN IPv4 `:25565` on `danknasty`)*
- **IPv6:** `fd77:7777:5010::1337:f1ac:d00d:3c` *(dynamically mapped to GUA `<gua_prefix>:1337:f1ac:d00d:3c` in public DNS)*

Whether connecting via `pokelovers.drheck.dev`, `desertworld.drheck.dev`, or any other server subdomain, players connect to this exact IP pair on standard port `25565`.

### 2. Transparent TCP SNI Handshake Routing & Live Ping Injection (HAProxy + `mc-manager`)
Rather than using an application-level proxy (which breaks vanilla Diffie-Hellman encryption and forces `online-mode=false`), **HAProxy** performs transparent pre-handshake packet inspection:
1. HAProxy listens dual-stack on `10.0.0.113:25565` and `[fd77:7777:5010::1337:f1ac:d00d:3c]:25565`.
2. When a player connects, HAProxy peeks at the initial unencrypted Minecraft handshake packet (`0x00`) via `/etc/haproxy/minecraft.lua` and extracts the requested hostname (`txn.mc_host`, e.g. `pokelovers.drheck.dev`) and handshake state (`txn.mc_state`: `1` = Status Ping, `2` = Login Join).
3. **For All Multiplayer Server List Pings ($\text{state} = 1$):**
   Each backend uses the rule:
   ```haproxy
   tcp-request content use-service lua.mc_offline if { var(txn.mc_state) -m int eq 1 } || !{ nbsrv(<slug>) gt 0 }
   ```
   `lua.mc_offline` queries `mc-manager` (`http://127.0.0.1:8095/internal/haproxy` with `STATUS <slug>`). If the backend JVM is running, `mc-manager` queries the backend's live TCP status (`0x00`) to obtain real-time online player counts and version metadata, then overlays the latest `motd` from `server.properties` and `favicon` from `/data/minecraft/<dir>/server-icon.png`. This ensures **MOTD styling and 64×64 icon changes saved in `mc.drheck.dev` appear immediately on client Refresh without restarting a running Minecraft server**.
4. **For Player Login Joins ($\text{state} = 2$):**
   - **If the backend server is UP:** HAProxy splices the raw TCP stream directly to `[fd77:7777:5010::1337:3c:d00d:<hex>]:25565`. The client and backend perform native Microsoft/Mojang `online-mode=true` authentication directly over the spliced TCP connection.
   - **If the backend server is DOWN:** `lua.mc_offline` sends `JOIN <slug>` to `mc-manager`, which wakes `ondemand` servers automatically and returns a formatted Minecraft Disconnect packet (`0x00`).

### 3. Backend IPv6 Address Scheme & Active Worlds
Each backend Minecraft server is isolated on a dedicated Unique Local Address (ULA) on interface `eth77` of `ul`:
- **Prefix:** `fd77:7777:5010::1337:3c:d00d:<hex>/64`
- **Port:** Each server binds to standard port `25565` on its assigned IPv6 address.
- **Active Managed Worlds:**

| Hex ID | Slug / Subdomain | Display Name | Backend ULA IPv6 Address | Lifecycle Mode |
| :--- | :--- | :--- | :--- | :--- |
| `1` | `pokelovers.drheck.dev` | `Poke Lovers` | `fd77:7777:5010::1337:3c:d00d:1/64` | `ondemand` (`20G` heap) |
| `2` | `desertworld.drheck.dev` | `⚔ 𝔇𝔢𝔰𝔢𝔯𝔱 𝔚𝔬𝔯𝔩𝔡 ⚔` | `fd77:7777:5010::1337:3c:d00d:2/64` | `ondemand` (`8G` heap) |

### 4. Web Map (BlueMap) & Authentik Gated HTTPS
Interactive 3D web mapping for Minecraft is powered by **BlueMap** running in standalone watch mode:
- **Service:** `bluemap-pokelovers.service` running from `/data/minecraft/poke lovers/bluemap`.
  - Automatically updates the rendered 3D map as chunks change in `/data/minecraft/poke lovers/world`.
  - Serves live map data & Server-Sent Events (SSE) updates on internal port `8100`.
- **Reverse Proxy & Authentication:** NGINX terminates SSL on port `443` at `/etc/nginx/sites-available/pokelovers` and gates access behind **Authentik ForwardAuth** (`/outpost.goauthentik.io/auth/nginx`).
  - Serves directly at **`https://pokelovers.drheck.dev`**.
  - Unauthenticated visitors are automatically redirected to `auth.drheck.dev` to log in before viewing the 3D map.

### 5. Network & DNS Automation (`ipctl`) — Externalized Configs & Short-Lived SSH CA

To prevent dynamic Minecraft world provisioning from mutating code-reviewed host and router configuration files (`/etc/systemd/network/20-wired.network`, `/etc/haproxy/haproxy.cfg`, and `/home/luke/git/router_config/unbound.conf`), `/data/minecraft/ipctl` (symlinked at `/home/luke/bin/ipctl`) operates **exclusively on dedicated external drop-in and include files**:

| Subsystem | Static Code-Reviewed Base Config (Never Modified by `ipctl`) | Dynamic External File Managed by `ipctl` | Mirror in `/data/minecraft/.network/` |
| :--- | :--- | :--- | :--- |
| **`systemd-networkd` (`ul`)** | `/etc/systemd/network/20-wired.network` | `/etc/systemd/network/20-wired.network.d/minecraft.conf` | `minecraft.network.conf` |
| **HAProxy Map (`ul`)** | `/etc/haproxy/haproxy.cfg` | `/etc/haproxy/minecraft_hosts.map` | `minecraft_hosts.map` |
| **HAProxy Backends (`ul`)** | `/etc/haproxy/haproxy.cfg` *(loads `-f /etc/haproxy/conf.d`)* | `/etc/haproxy/conf.d/minecraft_backends.cfg` | `minecraft_backends.cfg` |
| **Unbound DNS (`danknasty`)** | `/home/luke/git/router_config/unbound.conf` *(has `include: "/var/unbound/etc/unbound.minecraft.conf"`)* | `/var/unbound/etc/unbound.minecraft.conf` | `unbound.minecraft.conf` |

#### Programmatic Short-Lived SSH CA Authentication (`step-ca` $\longrightarrow$ `danknasty`)
When `/data/minecraft/ipctl` is invoked with `--dns` (either interactively or unattended by `mc-manager.service` after a reboot when no `ssh-agent` is active):
1. `ipctl` generates a fresh ephemeral Ed25519 keypair in a mode-`0700` temporary directory (`atexit`-cleaned).
2. `ipctl` requests a **5-minute (`--not-after=5m`) SSH user certificate** for principal `luke` from the local `step-ca` container using the `webshell-svc` JWK provisioner (the same short-lived CA used by `webshell.drheck.dev`).
3. `danknasty` validates the certificate against `TrustedUserCAKeys /etc/ssh/drheck_ca_user_key.pub` (configured in `/etc/sshd_config.d/10-drheck-certs.conf`), allowing `ipctl` to update `/var/unbound/etc/unbound.minecraft.conf`, run `doas unbound-checkconf` and `doas rcctl restart unbound`, and invoke `/home/luke/git/router_config/dns_danger_sync.py --force` to synchronize public `A` and `AAAA` records to deSEC.io.
4. Both `update_dns.py` and `dns_danger_sync.py` (as well as `verify_dns.sh`) on `danknasty` recursively follow `include:` directives in `unbound.conf`, ensuring all external Minecraft subdomains are automatically included during prefix rotations and deSEC.io synchronization.

---

## Backups & Disaster Recovery

Both the HAProxy router layer and the `mc-manager` control plane (including all external network, proxy, and DNS mirror files) are integrated into `/home/luke/git/backups/ul/scripts/`:

- **Control Plane & External Network Backup:** `/home/luke/git/backups/ul/scripts/backup/mc_manager`
  - Archives `/data/minecraft/.manager`, `/data/minecraft/.network`, `/data/minecraft/ipctl`, `/usr/local/bin/{mc-manager,mc-runner,mc-seed-render}`, `/etc/systemd/system/{mc-manager.service,minecraft@.service}`, `/etc/systemd/network/20-wired.network.d/minecraft.conf`, `/etc/nginx/sites-available/mc`, `/etc/haproxy/minecraft.lua`, `/etc/haproxy/minecraft_hosts.map`, and `/etc/haproxy/conf.d/minecraft_backends.cfg` with 10% `par2` parity into `/data/backups/services/current/mc_manager/`.
- **Control Plane Restore:** `/home/luke/git/backups/ul/scripts/restore/mc_manager [timestamp]`
- **Router Backup & Restore:** `/home/luke/git/backups/ul/scripts/backup/minecraft_router` and `/home/luke/git/backups/ul/scripts/restore/minecraft_router [timestamp]`

---

## 6. Minecraft Server Manager & On-Demand Architecture (Production Architecture)

<p class="callout info"><strong>Production Control Plane:</strong> The unified web control plane at <code>https://mc.drheck.dev</code> (bound to <code>[fd77:7777:5010::1337:f1ac:d00d:3c00]:8095</code> behind Nginx and Authentik ForwardAuth) manages all Minecraft worlds on <code>ul</code>, automates <code>ipctl</code> networking and <code>systemd</code> lifecycle management, wakes sleeping servers on-demand via HAProxy when players join, streams live PTY server consoles, and provides an integrated <strong>Seed Preview Studio</strong> and <strong>Text, MOTD, Color Gradient &amp; 8-Bit Pixel Icon Studio</strong>.</p>

### 6.1 Canonical Definition of a "Server"

Every managed Minecraft world on `ul` is a self-contained unit consisting of five standardized components:

$$\text{Server}(\text{slug}) = \left\lbrace\text{Directory}, \quad \text{Manifest } (\texttt{server.json}), \quad \text{Network } (\texttt{ipctl}), \quad \text{Units } (\texttt{systemd}), \quad \text{Lifecycle Policy}\right\rbrace$$

| Component | Path / Identifier | Description |
| :--- | :--- | :--- |
| **1. Dedicated Directory** | `/data/minecraft/<dir_name>/` | Holds `server.json`, server `.jar` / libraries, `mods/` or `plugins/`, `server.properties`, `server-icon.png`, `whitelist.json`, `ops.json`, `world/`, and optional `bluemap/`. Existing worlds in `/data/minecraft/*` can be adopted in-place without moving files. |
| **2. Declarative Manifest** | `/data/minecraft/<dir_name>/server.json` | Stores the human display name, DNS slug (`<slug>`), loader type (`paper`, `vanilla`, `fabric`, `neoforge`, `forge`, `custom`), Minecraft version, JVM path (`/usr/lib/jvm/default/bin/java`), heap size (`memory_min`/`memory_max`), seed, and `start_mode` (`manual`, `ondemand`, `always`). |
| **3. Network & DNS (`ipctl`)** | `fd77:7777:5010::1337:3c:d00d:<hex>/64` | Dedicated internal IPv6 address on `eth77` in `/etc/systemd/network/20-wired.network.d/minecraft.conf`, bound in `server.properties` (`server-ip=` and `server-port=25565`), mapped in `/etc/haproxy/minecraft_hosts.map` + `/etc/haproxy/conf.d/minecraft_backends.cfg`, and published as `<slug>.drheck.dev` in `/var/unbound/etc/unbound.minecraft.conf` on `danknasty` and deSEC.io. |
| **4. Dedicated `systemd` Service & PTY Wrapper** | `minecraft@<slug>.service` *(via `/usr/local/bin/mc-runner`)* | Runs the server JVM inside a managed pseudo-terminal (PTY) with a 1,000-line ring buffer and UNIX domain socket `/run/mc-manager/<slug>.sock`, enabling real-time WebSocket log streaming and console command injection (`SendRunnerCommand`) as well as graceful `save-all` + `stop` on shutdown. |
| **5. Lifecycle Policy** | `manual` \| `ondemand` \| `always` | Controls when the server consumes RAM on `ul` (see Section 6.2). |

<details>
  <summary><strong>Click to expand example <code>/data/minecraft/desertworld/server.json</code> manifest</strong></summary>

```json
{
  "slug": "desertworld",
  "display_name": "⚔ 𝔇𝔢𝔰𝔢𝔯𝔱 𝔚𝔬𝔯𝔩𝔡 ⚔",
  "dir_name": "desertworld",
  "domain": "desertworld.drheck.dev",
  "ipv6": "fd77:7777:5010::1337:3c:d00d:2",
  "hex_id": "2",
  "port": 25565,
  "start_mode": "ondemand",
  "idle_timeout_minutes": 30,
  "type": "paper",
  "mc_version": "1.21.4",
  "jar_file": "server_26.3.jar",
  "java_bin": "/usr/lib/jvm/default/bin/java",
  "memory_min": "8G",
  "memory_max": "8G",
  "seed": "4900633019313953717",
  "admins": [],
  "created_at": "2026-10-10T18:03:46-04:00"
}
```
</details>

---

### 6.2 Resource Management & Server Lifecycle Modes

Because each active Minecraft JVM allocates $8\text{--}20\text{ GiB}$ of pinned heap memory (`-Xms` = `-Xmx` with `+AlwaysPreTouch`), running all $25+$ worlds in `/data/minecraft` simultaneously is impossible. Each server is assigned one of three lifecycle modes:

1. **`manual` (Cold / Archived)**:
   * `minecraft@<slug>.service` is disabled and stopped ($0\text{ GiB}$ RAM).
   * Only starts when explicitly clicked in the Web UI.
   * When stopped, HAProxy returns `<name> is currently offline. Start at mc.drheck.dev`.
2. **`ondemand` (Wake-on-Join + Idle Auto-Stop)**:
   * Stopped by default ($0\text{ GiB}$ RAM).
   * Automatically started when a player clicks **Join Server** in Minecraft (intercepted by HAProxy Lua $\longrightarrow$ `mc-manager`).
   * Automatically stopped (`save-all` $\longrightarrow$ `stop`) once $0$ players have been online continuously for $T_{\text{idle}}$ minutes (default $30\text{ min}$).
3. **`always` (Pinned Production)**:
   * `minecraft@<slug>.service` is enabled and active across host reboots (`systemctl enable --now`).
   * Used for primary worlds that should remain online $24/7$ regardless of player count.

---

### 6.3 HAProxy On-Demand Wake-on-Join & Live Status Ping Architecture

The Minecraft protocol sends a `Handshake` packet (`0x00`) at the start of every TCP connection containing a `Next State` VarInt:
* $\text{Next State} = 1$ (**Status Ping**): Sent when a client refreshes their Multiplayer Server List.
* $\text{Next State} = 2$ (**Login Join**): Sent **only** when a player clicks **Join Server**.

`/etc/haproxy/minecraft.lua` extracts both `txn.mc_host` and `txn.mc_state` and delegates status pings and offline joins to `mc-manager` (`http://127.0.0.1:8095/internal/haproxy`):

$$\text{Client Packet } (\texttt{0x00}) \longrightarrow \begin{cases} \text{state} = 1 \text{ (Status Ping)} & \longrightarrow \text{Return live JSON MOTD + } \texttt{server-icon.png} \text{ from } \texttt{mc-manager} \text{ without waking} \\\\ \text{state} = 2 \text{ (Login Join)} & \longrightarrow \text{If } \texttt{ONLINE}\text{: TCP splice to backend; if } \texttt{ondemand}\text{: wake server + return countdown} \end{cases}$$

#### State Machine for Managed Worlds

| Server State | Multiplayer List Ping (`state = 1`) MOTD & Icon | Player Clicks "Join Server" (`state = 2`) |
| :--- | :--- | :--- |
| **`SLEEPING` (`ondemand`)** | Configured custom MOTD (or `§e<name> §7[Standby] — §aClick Join to wake server!`) + `server-icon.png` + version badge `Standby (Join to Wake)` | HAProxy Lua sends `JOIN <slug>` to `mc-manager`, starts `minecraft@<slug>.service`, and disconnects client with: **`"⚡ Waking up <name>... Server is starting on-demand. Please reconnect in ~20 seconds!"`** |
| **`STARTING`** | Configured custom MOTD + `server-icon.png` + version badge `Starting...` | Disconnects client with: **`"⏳ <name> is currently booting up! Please wait ~15 seconds and try connecting again."`** |
| **`ONLINE`** | Live player count & sample from backend JVM overlaid with latest custom MOTD (`server.properties`) and `server-icon.png` (`favicon`) | Native TCP splice to `[fd77:7777:5010::1337:3c:d00d:<hex>]:25565` with full Microsoft `online-mode=true` auth |
| **`OFFLINE` (`manual`)** | Configured custom MOTD + `server-icon.png` + version badge `Offline` | Disconnects client with: **`"<name> is currently offline. Start it from https://mc.drheck.dev"`** |

#### Idle Shutdown Timer
For any running server in `ondemand` mode, `mc-manager` tracks the time since the last player disconnected ($N_{\text{players}} = 0$). When:

$$t_{\text{empty}} \ge T_{\text{idle}} \quad (\text{default } 30\text{ min})$$

`mc-manager` issues `save-all` and `stop` via the `/run/mc-manager/<slug>.sock` PTY socket and stops `minecraft@<slug>.service`, freeing the JVM heap until the next join request.

---

### 6.4 Web Control Plane (`https://mc.drheck.dev`)

The web frontend is served over HTTPS behind **Nginx + Authentik ForwardAuth** and provides two primary workspaces designed with a clean, hardware-ops dark interface:

#### 1. Existing Servers Dashboard & Live PTY Console
* **Server Sidebar & Status Header**:
  * Displays every registered server with its 64×64 pixel icon, live state badge (`ONLINE`, `STANDBY`, `OFFLINE`), endpoint (`<slug>.drheck.dev`), IPv6 address, heap allocation, and lifecycle mode (`On-Demand`, `Always On`, `Manual`).
  * **One-Click Controls**: `Start Server`, `Restart`, `Stop`, and `+ Provision Network / DNS` (if not yet allocated).
* **Live Server Console (`mc-runner` WebSocket Stream)**:
  * Connects via WebSocket (`/api/servers/<slug>/console/ws`) to `/run/mc-manager/<slug>.sock`, streaming the 1,000-line PTY ring buffer and real-time server stdout/stderr lines.
  * Allows admins to send console commands (`say`, `op`, `whitelist`, `time set`, `gamemode`, `/give`, etc.) directly to the server's stdin (`leading /` is automatically stripped because the server console expects bare commands).
* **Configuration, Text/MOTD Studio, Icon Studio, Whitelist & Operators Panels**:
  * Edit `Display Name`, `MOTD`, `Start Mode`, `Idle Timeout`, `Min/Max Heap`, `Jar File`, `Gamemode`, `Difficulty`, `Max Players`, `View Distance`, `Level Seed`, `server-icon.png`, `whitelist.json`, and `ops.json`.

#### 2. Minecraft Text, MOTD, Color Gradient & 8-Bit Pixel Icon Studio
Built directly into both the **+ New World** screen and the **Configuration** panel of every existing server:
* **Unicode Font Converter (Copy/Paste Safe)**:
  * Converts text into Minecraft Java Edition font variants without resource packs: `Small Caps (ꜱᴍᴘ)`, `Gothic / Fraktur (𝔖𝔲𝔯𝔳𝔦𝔳𝔞𝔩)`, `Double-Struck (𝕊𝕦𝕣𝕧𝕚𝕧𝕒𝕝)`, `Full-Width (ＳＭＰ)`, and `Monospace`.
  * Includes one-click **Java-Safe Decorative Symbols & Borders**: `⚔`, `◆`, `★`, `⚡`, `👑`, `☠`, `✦`, `❖`, `»`, `«`, and `⚔ ... ⚔`.
* **§ Color Gradient & Formatting Code Builder**:
  * Interpolates any two RGB colors (`Gradient Start` $\longrightarrow$ `Gradient End`) across the input string and maps each character to the nearest native Minecraft color code (`§0`–`§f`), combined with optional `§l` (**Bold**), `§o` (*Italic*), `§n` (Underline), `§m` (Strikethrough), or `§k` (Obfuscated).
  * Can be applied with one click to either **MOTD (`server.properties`)** or **Display Name (`server.json`)**, with a real-time **Minecraft Multiplayer Server List Preview** rendering `§` codes and the 64×64 icon side-by-side.
* **8-Bit Pixel Icon & Badge Generator (`64×64 server-icon.png`)**:
  * Generates crisp 64×64 pixel-art server icons in the browser using 6 Minecraft material themes (`Stone`, `Dirt & Grass`, `Diamond`, `Glowstone`, `Nether`, `Enchanted Glint`), 7 pixel-art stamps (`Sword`, `Pickaxe`, `Creeper`, `Crown`, `Heart`, `Star`, `Pokéball`), and 1–3 character 8-bit bitmap text with 3D drop shadows, or accepts any custom uploaded PNG/JPG/WebP image (auto-cropped and resampled to `64×64`).

#### 3. Interactive Seed Preview Studio (`cubiomes` Native Renderer)
* Uses `/usr/local/bin/mc-seed-render` (compiled against `cubiomes`) on `ul` to render a 2D biome map ($\pm 2048$ blocks around $(0,0)$) and locate nearest structures (`Village`, `Ancient City`, `Mansion`, `Monument`, `Outpost`, `Stronghold`, `Ruined Portal`) in $< 50\text{ ms}$ per seed.
* Supports **Roll Random Seed** and interactive biome legend inspection prior to provisioning a new world.

---

### 6.5 Authentik Gate, RBAC & Automatic `/op` (`ops.json`) Synchronization

Access to `https://mc.drheck.dev` is gated at the Nginx perimeter via **Authentik ForwardAuth** (`X-Authentik-Username`), and `mc-manager` maps authenticated identities via `/data/minecraft/.manager/users.json`:

$$\text{Authentik SSO } (\texttt{auth.drheck.dev}) \longrightarrow \text{Nginx ForwardAuth } (\texttt{X-Authentik-Username}) \longrightarrow \texttt{mc-manager} \text{ RBAC + } \texttt{ops.json} \text{ Sync}$$

* **Global Admins (`global_admin: true`, e.g., `luke`)**: Full access to create servers, provision network/DNS, manage the **Users & Operators Registry** (with live Mojang API username $\longrightarrow$ UUID lookup), and administer all worlds.
* **Per-Server Admins (`server.json` `admins`)**: Full control to start/stop/restart, access the live console, and edit configuration/whitelist/icon on their assigned worlds.
* **Automatic `ops.json` Synchronization**: Adding a user as a Global Admin or Server Admin automatically syncs their Mojang UUID and username into `ops.json` (Level 4 operator with `bypassesPlayerLimit: true`).

---

### 6.6 Server-Side Quality-of-Life (QoL) Datapack Library & Non-Agentic Modrinth Updater

All server-side Quality-of-Life (QoL), building, and world-generation datapacks (`world/datapacks/*.zip`) run 100\% on the server so players connect with a standard Vanilla Minecraft client without installing any client-side mod loader.

#### Curated Server-Side Datapack Library (`/data/minecraft/datapacks/`)
Both the **+ Create New Server** studio and every server's **QoL Mods & Datapacks** tab in `https://mc.drheck.dev` include a 16-pack verified library plus live Modrinth v2 search:

| Category | Datapack / QoL Mod | Modrinth Slug / Source | Default Bundle | Description |
| :--- | :--- | :--- | :--- | :--- |
| **Survival QoL** | **Graves (Ketket)** | `ketket-graves` | **PokeLovers Preset** | Spawns a grave on death storing inventory and XP safely until retrieved. |
| **Survival QoL** | **Fast Leaf Decay** | `fast_leaf_decay` | **PokeLovers Preset** | Leaves decay rapidly after chopping down tree logs. |
| **Survival QoL** | **Craftable Invisible Item Frames** | `invisframes` (local) | **PokeLovers Preset** | Adds crafting recipes for invisible item frames and glow invisible item frames. |
| **Survival QoL** | **Player Drops Head (Jodek)** | `player-drops-head` | **PokeLovers Preset** | Players drop their textured head item when killed. |
| **Survival QoL** | **NetherPortalFix** | *(Curated local pack)* | **Yes** | Tracks each player's Overworld entry portal and returns them to the exact portal when exiting the Nether in multiplayer. |
| **Survival QoL** | **Shulkers Drop Two Shells (Jodek)** | `two-shulker-shells-drop` | **PokeLovers Preset** | Every Shulker guarantees 2 Shulker Shells on death. |
| **Survival QoL** | **All Mob Heads (Jodek)** | `mob-heads` | Optional | Mobs have a balanced chance to drop their decorative head (including variants). |
| **Survival QoL** | **Veinminer** | `veinminer` | Optional | Mine entire connected ore veins at once while sneaking with a pickaxe. |
| **Survival QoL** | **Timber Strike** | `timber-strike` | Optional | Fells connected tree logs in one chop using an axe. |
| **Survival QoL** | **Call Your Horse** | `call-your-horse` | Optional | Whistle to summon your tamed horse, donkey, or mule from nearby chunks. |
| **Survival QoL** | **Mineable Spawners** | `mineable-spawner` | Optional | Pickaxes enchanted with Silk Touch can mine and relocate Monster Spawners. |
| **Building & Utility** | **Armor Stand Arms** | `armor-stand-arms` | Optional | Gives Armor Stands arms by default and enables pose customization. |
| **Building & Utility** | **MasterCutter (Wood Stonecutter)** | `mastercutter` | Optional | Adds Stonecutter recipes for all wood planks, stairs, slabs, and copper blocks. |
| **Building & Utility** | **Day Counter** | `daycounter` | Optional | Displays and tracks in-game world days survived on the scoreboard/actionbar. |
| **HUD & Utility** | **AFK Announcer & Display** | `afk-announcer` | **Yes** | Automatically marks idle players as AFK in the tab list and provides `/trigger afk`. |
| **Hermitcraft & Building** | **Mini Blocks (550+ Blocks)** | `mini-blocks-datapack` | **Yes** | Adds 550+ decorative Mini Blocks in survival via the Stonecutter (100% server-side custom heads, zero client mods). |
| **Hermitcraft & Building** | **Mini Blocks: Items Edition** | `mini-blocks-items` | Optional | Adds 150+ item-themed decorative Mini Blocks in survival (100% server-side, zero client mods). |
| **Hermitcraft & Building** | **Silence Mobs ('silent' Name Tag)** | `silent-mobs` | **Yes** | Name any mob or minecart `silent` with a Name Tag to silence it (Hermitcraft style). |
| **Survival QoL** | **No Enderman Grief** | `no-enderman-grief` | **Yes** | Prevents Endermen from picking up blocks and damaging player builds. |
| **Hermitcraft & Building** | **Armor Statues (Hermitcraft Pose Book)** | `armor-statues-datapack` | Optional | Hermitcraft clickable book for posing armor stands, toggling arms/baseplates/gravity, and locking stands. |
| **Hermitcraft & Building** | **Universal Dyeing** | `universal-dyeing-datapack` | Optional | Re-dye any stained glass, terracotta, concrete, wool, or bed in the crafting grid. |
| **Worldgen & Structures** | **Dungeons and Taverns** | `dungeons-and-taverns` | Optional | Overhauls vanilla structures and adds Vanilla-friendly taverns, shrines, and dungeons. |
| **Worldgen & Structures** | **Terralith** | `terralith` | Optional | Adds 95+ vanilla-block biomes, canyons, and caves with zero client mods required. |

#### Non-Agentic Deterministic Update Pipeline (Web UI, CLI & Weekly `systemd` Timer)
Datapacks are updated deterministically without any AI agent involvement by querying the Modrinth v2 REST API (`/v2/version_file/<sha1>` and `/v2/project/<slug>/version?loaders=["datapack"]`), verifying the downloaded archive against Modrinth's published SHA-1 digest, replacing the old `.zip` atomically in `world/datapacks/`, and issuing `reload` over `/tmp/mc-runner-<slug>.sock` if the server is online:

$$\text{On-Disk }\texttt{.zip}\text{ SHA-1} \longrightarrow \texttt{api.modrinth.com/v2} \longrightarrow \text{SHA-1 Verified Download} \longrightarrow \text{Atomic Swap + }\texttt{/reload}$$

1. **Web UI (`https://mc.drheck.dev`)**: Open any server $\longrightarrow$ **QoL Mods & Datapacks** tab $\longrightarrow$ click **↻ Check Modrinth Updates** or **⬆ Update All Installed Datapacks**.
2. **Manual CLI Check / Update**:
   ```bash
   # Check all servers for available Modrinth datapack updates (read-only):
   /usr/local/bin/mc-manager -check-datapacks

   # Download, SHA-1 verify, and apply all available Modrinth datapack updates across all servers:
   /usr/local/bin/mc-manager -update-datapacks
   ```
3. **Automated Weekly `systemd` Timer (`mc-datapack-update.timer`)**:
   * `/etc/systemd/system/mc-datapack-update.timer` triggers `/etc/systemd/system/mc-datapack-update.service` every Sunday at `04:15 EDT`, keeping all server datapacks and `/data/minecraft/datapacks/` up to date automatically.

---

### 6.7 Server Binary Repository (`/data/minecraft/jars/`) & Non-Agentic Upstream Version Catalog

`mc-manager` maintains a centralized, metadata-indexed **Server Binary Repository** in `/data/minecraft/jars/` backed by two JSON manifests:
1. **`/data/minecraft/jars/index.json` (Local Binary Inventory & Introspected JAR Metadata)**:
   * Every `.jar` in `/data/minecraft/jars/` (and every managed server's active `jar_file`) is automatically inspected by reading the embedded `version.json` and `META-INF/MANIFEST.MF` inside the ZIP archive:
     * `flavor`: `paper`, `vanilla`, `folia`, `fabric`, or `forge`
     * `mc_version`: Exact Minecraft release version (e.g., `26.3`, `26.2`, `1.21.11`, `1.20.1`)
     * `build`: PaperMC / Folia build number (e.g., `170` for `paper-26.3-170.jar`)
     * `protocol_version`: Wire protocol version (e.g., `777` for `26.3`, `776` for `26.2`)
     * `data_pack_format`: Datapack major format (e.g., `121` for `26.3`)
     * `java_version`: Required Java major version (e.g., `25` for `26.2`/`26.3`, `21` for `1.21.x`, `17` for `1.18`–`1.20`)
     * `sha256`: Full SHA-256 digest of the `.jar` file
2. **`/data/minecraft/jars/upstream_catalog.json` (Upstream Supported Versions & Latest Builds)**:
   * Synchronized deterministically (without any AI agent) against the four official upstream REST APIs:
     * **PaperMC Fill v3 API** (`https://fill.papermc.io/v3/projects/paper` and `/versions/<ver>/builds` with SHA-256 verification)
     * **Folia Fill v3 API** (`https://fill.papermc.io/v3/projects/folia` and `/versions/<ver>/builds` with SHA-256 verification)
     * **Mojang Official Piston Meta v2** (`https://piston-meta.mojang.com/mc/game/version_manifest_v2.json` with SHA-1 verification)
     * **FabricMC Meta v2** (`https://meta.fabricmc.net/v2/versions` for game versions, loader `0.19.5`, and installer `1.1.2`)

#### Non-Agentic Binary & Version Sync Workflow (Web UI, CLI & Weekly `systemd` Timer)
1. **Web UI (`https://mc.drheck.dev`)**:
   * Click **Binary Repo & Versions** in the left sidebar to view all indexed binaries in `/data/minecraft/jars/`, sync upstream version lists (`26.3` first), download & verify any `PaperMC`, `Vanilla`, `Fabric`, or `Folia` release into `/data/minecraft/jars/`, or click **⬆ Update All Cached & Server Binaries**.
   * In any server's **Config, Seed & Text Studio** tab, select any binary from the **Repository Binary** dropdown or click **⬆ Upgrade JAR** to switch or upgrade the server in one click.
2. **Standalone CLI Commands**:
   ```bash
   # Sync upstream version catalog and check all repository & server binaries:
   /usr/local/bin/mc-manager -check-binaries

   # Fetch & SHA-256/SHA-1 verify a specific upstream server binary into /data/minecraft/jars/:
   /usr/local/bin/mc-manager -fetch-jar paper:26.3
   /usr/local/bin/mc-manager -fetch-jar vanilla:26.3

   # Automatically download newer Paper/Folia builds and update servers in-place:
   /usr/local/bin/mc-manager -update-binaries
   ```
3. **Automated Weekly `systemd` Timer (`mc-datapack-update.timer`)**:
   * Runs `/usr/local/bin/mc-manager -update-binaries -update-datapacks` every Sunday at `04:15 EDT`.
