Add terrain minimap to dashboard

This commit is contained in:
Tanner
2026-11-08 23:46:52 +00:00
parent 20e53537b1
commit 2d5bf2df22
7 changed files with 418 additions and 8 deletions
+79
View File
@@ -8,6 +8,7 @@ import threading
import time
import traceback
import sys
from math import floor
from pathlib import Path
import logging
@@ -158,6 +159,84 @@ def api_global():
return response
def _minimap_surface_cell(chunks, x, z):
"""Return the uppermost solid/water block in a loaded world column."""
from mosfet.info import blocks
chunk_x, chunk_z = floor(x / 16), floor(z / 16)
chunk = chunks.chunks.get((chunk_x, chunk_z))
if chunk is None:
return None
local_x, local_z = x - chunk_x * 16, z - chunk_z * 16
min_y = getattr(chunks, 'min_y', -64)
for section_y in sorted(chunk.sections, reverse=True):
if section_y * 16 + 15 < min_y:
continue
section = chunk.sections[section_y]
if section.get('non_empty_blocks') == 0:
continue
for y in range(section_y * 16 + 15, max(min_y, section_y * 16) - 1, -1):
state_id = chunk.get_block_at(local_x, y, local_z)
if state_id is None or state_id == blocks.AIR:
continue
if (state_id in blocks.NON_SOLID_IDS and
state_id not in blocks.WATER_IDS):
continue
return {'block': blocks.BLOCKS.get(state_id, 'unknown'), 'y': y}
return None
@app.route('/api/minimap')
def api_minimap():
position = g.get('pos') or g.get('player_position')
chunks = g.get('chunks')
if (not g.get('connected') or position is None or position is False or
chunks is None or not hasattr(chunks, 'chunks')):
return jsonify(ready=False, cells=[])
try:
radius = int(request.args.get('radius', 12))
except (TypeError, ValueError):
radius = 12
radius = max(4, min(32, radius))
try:
radius_x = int(request.args.get('radius_x', radius))
except (TypeError, ValueError):
radius_x = radius
try:
radius_z = int(request.args.get('radius_z', radius))
except (TypeError, ValueError):
radius_z = radius
radius_x = max(4, min(48, radius_x))
radius_z = max(4, min(32, radius_z))
center_x, center_z = floor(position.x), floor(position.z)
center_y = floor(position.y)
lock = getattr(chunks, 'lock', None)
if lock is not None:
lock.acquire()
try:
cells = [
[_minimap_surface_cell(chunks, center_x + dx, center_z + dz)
for dx in range(-radius_x, radius_x + 1)]
for dz in range(-radius_z, radius_z + 1)
]
finally:
if lock is not None:
lock.release()
ready = any(cell is not None for row in cells for cell in row)
return jsonify(
ready=ready,
center={'x': center_x, 'y': center_y, 'z': center_z},
yaw=float(g.get('yaw', 0.0) or 0.0),
radius=radius,
radius_x=radius_x,
radius_z=radius_z,
cells=cells if ready else [],
)
@app.route('/api/items')
def api_items():
from mosfet.info.items import ITEM_NAMES