Phase 11: extract and ship block textures/registry (forge-1_12_2 leaf)

Forge doesn't split client/server jars, so a modded server's own classpath
already has every loaded mod's block textures, unused server-side.
BlockAssetExtractor reads them via the classloader (best-effort convention
match on registry name -> texture filename) plus the numeric-id -> registry-
name mapping, and ships both to the backend once per connection via two new
wire messages (block_registry, block_textures), fired through a new
BackendConnection#setReadyListener callback so the one-time send can't race
the async WS handshake. Only forge-1_12_2 wires it up so far; the other two
leaves can adopt it later with no protocol change.
This commit is contained in:
2026-08-09 23:20:53 +02:00
parent 52417a7b92
commit 47490309fe
7 changed files with 260 additions and 0 deletions
+22
View File
@@ -107,6 +107,28 @@ to web viewers is a separate, independent per-server admin setting on the backen
MCMapper-Backend's README) — a server operator can track positions server-side without exposing
them publicly, or vice versa.
### Real block textures (Phase 11)
Forge doesn't split client/server jars, so a dedicated server's own classpath already has every
loaded mod's `assets/<modid>/textures/blocks/*.png` (or `textures/block/` on newer conventions),
sitting there unused server-side. `forge-1_12_2` (this project's primary, most-modded target —
Enigmatica 2) reads them once at server-starting time via `BlockAssetExtractor`: `Block.REGISTRY`
gives every block's numeric id + registry name (same source as the existing column/section wire
encoding), and each block's texture is guessed by a best-effort *convention* match — the registry
name's path segment tried as a texture filename — not a real blockstate/model JSON resolution
(that's Phase 12's job; a block whose model doesn't follow the convention is just skipped, no
worse than before this phase). The registry mapping (`block_registry`) and extracted PNGs
(`block_textures`, batched 50/message) are sent to the backend once, right after the WS handshake
completes — via `BackendConnection#setReadyListener`, since `connect()` is async and a naive send
right after calling it would silently no-op before the handshake lands.
`forge-1_7_10` and `neoforge-26_1` don't implement extraction yet — `sendBlockRegistry`/
`sendBlockTextures`/`setReadyListener` live on the shared `BackendConnection` interface (so either
leaf can adopt them later with no protocol change) but only `forge-1_12_2` calls them so far,
matching this phase's Enigmatica-2-focused scope. See MCMapper-Backend's README for what the
backend currently does with this data (short version: stores it; per-server render-time
resolution is explicitly deferred, documented there).
## Attribution
See `THIRD_PARTY_NOTICES.md`.