Add world time to web dashboard
This commit is contained in:
@@ -32,7 +32,7 @@ class TestWebInventoryAPI(unittest.TestCase):
|
|||||||
self.g = mosfet_web.g
|
self.g = mosfet_web.g
|
||||||
self.original = {
|
self.original = {
|
||||||
key: self.g.get(key) for key in
|
key: self.g.get(key) for key in
|
||||||
('connected', 'game', 'inv', 'chest_viewers')
|
('connected', 'game', 'inv', 'chest_viewers', 'time', 'time_base')
|
||||||
}
|
}
|
||||||
self.game = FakeGame()
|
self.game = FakeGame()
|
||||||
self.g.connected = True
|
self.g.connected = True
|
||||||
@@ -54,6 +54,16 @@ class TestWebInventoryAPI(unittest.TestCase):
|
|||||||
item = response.get_json()['inv']['9']
|
item = response.get_json()['inv']['9']
|
||||||
self.assertEqual(item['components']['custom_name']['text'], 'Test Paper')
|
self.assertEqual(item['components']['custom_name']['text'], 'Test Paper')
|
||||||
|
|
||||||
|
def test_global_api_exposes_world_time_ticks(self):
|
||||||
|
self.g.time = 12345.5
|
||||||
|
self.g.time_base = 12345.5
|
||||||
|
|
||||||
|
response = self.client.get('/api/global')
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertEqual(response.get_json()['time'], 12345.5)
|
||||||
|
self.assertEqual(response.get_json()['time_base'], 12345.5)
|
||||||
|
|
||||||
def test_global_api_stringifies_tuple_keys(self):
|
def test_global_api_stringifies_tuple_keys(self):
|
||||||
self.g.chest_viewers = {(12, 64, -7): 1}
|
self.g.chest_viewers = {(12, 64, -7): 1}
|
||||||
|
|
||||||
|
|||||||
@@ -86,6 +86,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<dl class="runtime-list">
|
<dl class="runtime-list">
|
||||||
<div><dt>Game mode</dt><dd id="game-mode">—</dd></div>
|
<div><dt>Game mode</dt><dd id="game-mode">—</dd></div>
|
||||||
|
<div><dt>Time</dt><dd id="world-time">—</dd></div>
|
||||||
<div><dt>Active job</dt><dd id="job-state">IDLE</dd></div>
|
<div><dt>Active job</dt><dd id="job-state">IDLE</dd></div>
|
||||||
<div><dt>Path nodes</dt><dd id="path-length">0</dd></div>
|
<div><dt>Path nodes</dt><dd id="path-length">0</dd></div>
|
||||||
<div><dt>Entities</dt><dd id="entity-count">0 mobs · 0 drops</dd></div>
|
<div><dt>Entities</dt><dd id="entity-count">0 mobs · 0 drops</dd></div>
|
||||||
|
|||||||
@@ -86,6 +86,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<dl class="runtime-list">
|
<dl class="runtime-list">
|
||||||
<div><dt>Game mode</dt><dd id="game-mode">—</dd></div>
|
<div><dt>Game mode</dt><dd id="game-mode">—</dd></div>
|
||||||
|
<div><dt>Time</dt><dd id="world-time">—</dd></div>
|
||||||
<div><dt>Active job</dt><dd id="job-state">IDLE</dd></div>
|
<div><dt>Active job</dt><dd id="job-state">IDLE</dd></div>
|
||||||
<div><dt>Path nodes</dt><dd id="path-length">0</dd></div>
|
<div><dt>Path nodes</dt><dd id="path-length">0</dd></div>
|
||||||
<div><dt>Entities</dt><dd id="entity-count">0 mobs · 0 drops</dd></div>
|
<div><dt>Entities</dt><dd id="entity-count">0 mobs · 0 drops</dd></div>
|
||||||
|
|||||||
@@ -57,6 +57,19 @@
|
|||||||
return modes[mode] || (mode == null ? '—' : String(mode));
|
return modes[mode] || (mode == null ? '—' : String(mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatWorldClock(ticks) {
|
||||||
|
if (ticks == null) return '—';
|
||||||
|
const time = Number(ticks);
|
||||||
|
if (!Number.isFinite(time)) return '—';
|
||||||
|
const dayTicks = ((Math.floor(time) % 24000) + 24000) % 24000;
|
||||||
|
const minutes = Math.floor((((dayTicks + 6000) % 24000) / 1000) * 60);
|
||||||
|
const hour24 = Math.floor(minutes / 60);
|
||||||
|
const hour12 = hour24 % 12 || 12;
|
||||||
|
const minute = minutes % 60;
|
||||||
|
const period = hour24 < 12 ? 'AM' : 'PM';
|
||||||
|
return `${String(hour12).padStart(2, '0')}:${String(minute).padStart(2, '0')} ${period}`;
|
||||||
|
}
|
||||||
|
|
||||||
function textureCandidates(name) {
|
function textureCandidates(name) {
|
||||||
const id = String(name || '').replace(/^minecraft:/, '').toLowerCase();
|
const id = String(name || '').replace(/^minecraft:/, '').toLowerCase();
|
||||||
if (!/^[a-z0-9_]+$/.test(id) || id === 'air') return [];
|
if (!/^[a-z0-9_]+$/.test(id) || id === 'air') return [];
|
||||||
@@ -451,6 +464,11 @@
|
|||||||
const center = state.chunk_state?.center;
|
const center = state.chunk_state?.center;
|
||||||
$('chunk-detail').textContent = center ? `Center ${center[0]}, ${center[1]} · radius ${state.chunk_state.radius ?? '—'}` : 'Waiting for world data';
|
$('chunk-detail').textContent = center ? `Center ${center[0]}, ${center[1]} · radius ${state.chunk_state.radius ?? '—'}` : 'Waiting for world data';
|
||||||
$('game-mode').textContent = formatMode(state.game_mode);
|
$('game-mode').textContent = formatMode(state.game_mode);
|
||||||
|
const worldTime = online && state.time_base != null && state.time != null
|
||||||
|
? Number(state.time) : NaN;
|
||||||
|
$('world-time').textContent = Number.isFinite(worldTime)
|
||||||
|
? `${Math.floor(worldTime).toLocaleString()} t · ${formatWorldClock(worldTime)}`
|
||||||
|
: '—';
|
||||||
$('job-state').textContent = prettyName(state.job_state || 'idle').toUpperCase();
|
$('job-state').textContent = prettyName(state.job_state || 'idle').toUpperCase();
|
||||||
$('path-length').textContent = String(state.path?.length || 0);
|
$('path-length').textContent = String(state.path?.length || 0);
|
||||||
$('entity-count').textContent = `${Object.keys(state.mobs || {}).length} mobs · ${Object.keys(state.objects || {}).length} drops`;
|
$('entity-count').textContent = `${Object.keys(state.mobs || {}).length} mobs · ${Object.keys(state.objects || {}).length} drops`;
|
||||||
|
|||||||
@@ -86,6 +86,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<dl class="runtime-list">
|
<dl class="runtime-list">
|
||||||
<div><dt>Game mode</dt><dd id="game-mode">—</dd></div>
|
<div><dt>Game mode</dt><dd id="game-mode">—</dd></div>
|
||||||
|
<div><dt>Time</dt><dd id="world-time">—</dd></div>
|
||||||
<div><dt>Active job</dt><dd id="job-state">IDLE</dd></div>
|
<div><dt>Active job</dt><dd id="job-state">IDLE</dd></div>
|
||||||
<div><dt>Path nodes</dt><dd id="path-length">0</dd></div>
|
<div><dt>Path nodes</dt><dd id="path-length">0</dd></div>
|
||||||
<div><dt>Entities</dt><dd id="entity-count">0 mobs · 0 drops</dd></div>
|
<div><dt>Entities</dt><dd id="entity-count">0 mobs · 0 drops</dd></div>
|
||||||
|
|||||||
Reference in New Issue
Block a user