mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-30 00:17:13 +00:00
feat(dashboard): draining (old version) badge; properties update when empty
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -229,6 +229,7 @@ namespace {
|
|||||||
info.ip = instance.ip.string;
|
info.ip = instance.ip.string;
|
||||||
info.port = instance.port;
|
info.port = instance.port;
|
||||||
info.isPrivate = instance.isPrivate != 0;
|
info.isPrivate = instance.isPrivate != 0;
|
||||||
|
info.outdated = instance.outdated != 0;
|
||||||
info.zoneName = GameText::ZoneName(info.mapID);
|
info.zoneName = GameText::ZoneName(info.mapID);
|
||||||
AddPropertyDetails(info);
|
AddPropertyDetails(info);
|
||||||
using eState = MasterPackets::ServerListResponse::eState;
|
using eState = MasterPackets::ServerListResponse::eState;
|
||||||
|
|||||||
@@ -253,13 +253,13 @@ namespace LiveWorld {
|
|||||||
for (const auto& w : ServerState::g_WorldInstances) {
|
for (const auto& w : ServerState::g_WorldInstances) {
|
||||||
worlds.push_back({ {"mapID", w.mapID}, {"zoneName", GameText::ZoneName(w.mapID)}, {"instanceID", w.instanceID}, {"cloneID", w.cloneID}, {"players", w.players},
|
worlds.push_back({ {"mapID", w.mapID}, {"zoneName", GameText::ZoneName(w.mapID)}, {"instanceID", w.instanceID}, {"cloneID", w.cloneID}, {"players", w.players},
|
||||||
{"isPrivate", w.isPrivate}, {"ip", w.ip}, {"port", w.port}, {"propertyId", w.propertyId}, {"propertyName", w.propertyName},
|
{"isPrivate", w.isPrivate}, {"ip", w.ip}, {"port", w.port}, {"propertyId", w.propertyId}, {"propertyName", w.propertyName},
|
||||||
{"ownerId", w.ownerId}, {"ownerName", w.ownerName}, {"state", w.state} });
|
{"ownerId", w.ownerId}, {"ownerName", w.ownerName}, {"state", w.state}, {"outdated", w.outdated} });
|
||||||
}
|
}
|
||||||
// Launched but not connected yet, or shutting down
|
// Launched but not connected yet, or shutting down
|
||||||
for (const auto& w : ServerState::g_PendingWorlds) {
|
for (const auto& w : ServerState::g_PendingWorlds) {
|
||||||
worlds.push_back({ {"mapID", w.mapID}, {"zoneName", GameText::ZoneName(w.mapID)}, {"instanceID", w.instanceID}, {"cloneID", w.cloneID}, {"players", 0},
|
worlds.push_back({ {"mapID", w.mapID}, {"zoneName", GameText::ZoneName(w.mapID)}, {"instanceID", w.instanceID}, {"cloneID", w.cloneID}, {"players", 0},
|
||||||
{"isPrivate", w.isPrivate}, {"ip", w.ip}, {"port", w.port}, {"propertyId", w.propertyId}, {"propertyName", w.propertyName},
|
{"isPrivate", w.isPrivate}, {"ip", w.ip}, {"port", w.port}, {"propertyId", w.propertyId}, {"propertyName", w.propertyName},
|
||||||
{"ownerId", w.ownerId}, {"ownerName", w.ownerName}, {"state", w.state} });
|
{"ownerId", w.ownerId}, {"ownerName", w.ownerName}, {"state", w.state}, {"outdated", w.outdated} });
|
||||||
}
|
}
|
||||||
JsonSuccess(reply, { {"worlds", worlds} });
|
JsonSuccess(reply, { {"worlds", worlds} });
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ struct WorldInstanceInfo {
|
|||||||
// "starting" (launched, not connected yet) or "stopping" (in g_PendingWorlds), or "draining" for a world that is up
|
// "starting" (launched, not connected yet) or "stopping" (in g_PendingWorlds), or "draining" for a world that is up
|
||||||
// but whose players are being moved to a new instance (in g_WorldInstances); empty for one that is just up
|
// but whose players are being moved to a new instance (in g_WorldInstances); empty for one that is just up
|
||||||
std::string state{};
|
std::string state{};
|
||||||
|
// On an old binary or old zone files (a live update or world reload): takes nobody new and stops once empty
|
||||||
|
bool outdated{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Where a server listens and the machine it runs on, from master's server list
|
// Where a server listens and the machine it runs on, from master's server list
|
||||||
@@ -88,7 +90,8 @@ namespace ServerState {
|
|||||||
{"players", world.players},
|
{"players", world.players},
|
||||||
{"isPrivate", world.isPrivate},
|
{"isPrivate", world.isPrivate},
|
||||||
{"zoneName", world.zoneName},
|
{"zoneName", world.zoneName},
|
||||||
{"state", world.state}
|
{"state", world.state},
|
||||||
|
{"outdated", world.outdated}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,8 +60,9 @@
|
|||||||
<p class="small text-body-secondary">Moves everything onto the server binaries on disk now, without a restart: the UGC server finishes its jobs
|
<p class="small text-body-secondary">Moves everything onto the server binaries on disk now, without a restart: the UGC server finishes its jobs
|
||||||
and restarts, auth restarts (logins pause for a few seconds), chat hands its teams over and restarts, every world instance is
|
and restarts, auth restarts (logins pause for a few seconds), chat hands its teams over and restarts, every world instance is
|
||||||
replaced by a new one and its players are moved there (the game's Mythran maintenance warning, then a short loading screen), and
|
replaced by a new one and its players are moved there (the game's Mythran maintenance warning, then a short loading screen), and
|
||||||
the dashboard restarts last. Properties are saved before their new instance loads them; races and minigames finish first.
|
the dashboard restarts last. Races and minigames finish first. <strong>Properties are not moved</strong> (building in progress
|
||||||
Master keeps running: updating master itself takes a normal restart.</p>
|
isn't saved): their players are told an update is waiting, and a property updates once everyone has left it. Instances on the old
|
||||||
|
build take nobody new. Master keeps running: updating master itself takes a normal restart.</p>
|
||||||
<div class="d-flex flex-wrap gap-2 align-items-center mb-2" id="liveUpdateForm">
|
<div class="d-flex flex-wrap gap-2 align-items-center mb-2" id="liveUpdateForm">
|
||||||
<div class="input-group input-group-sm" style="max-width: 20rem">
|
<div class="input-group input-group-sm" style="max-width: 20rem">
|
||||||
<span class="input-group-text">Warn players</span>
|
<span class="input-group-text">Warn players</span>
|
||||||
@@ -214,6 +215,9 @@ $(function () {
|
|||||||
if (row.state === 'starting') return ' ' + fmt.badge('Starting', 'info');
|
if (row.state === 'starting') return ' ' + fmt.badge('Starting', 'info');
|
||||||
if (row.state === 'stopping') return ' ' + fmt.badge('Shutting down', 'secondary');
|
if (row.state === 'stopping') return ' ' + fmt.badge('Shutting down', 'secondary');
|
||||||
if (row.state === 'draining') return ' ' + fmt.badge('Moving players', 'warning');
|
if (row.state === 'draining') return ' ' + fmt.badge('Moving players', 'warning');
|
||||||
|
// Old binary or old zone files: nobody new goes there; it stops once the players still there have left
|
||||||
|
if (row.outdated) return ' ' + fmt.badge('Draining (old version)', 'warning') + ' <span class="small text-body-secondary text-nowrap">' +
|
||||||
|
Number(row.players || 0).toLocaleString() + ' player(s) still there</span>';
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
// Zone names in the viewer's language (the live status carries the server's)
|
// Zone names in the viewer's language (the live status carries the server's)
|
||||||
|
|||||||
@@ -90,7 +90,9 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p class="small text-body-secondary">The zone files each running world loaded (<code>.luz</code>, <code>.lvl</code>, <code>.lutriggers</code>, terrain,
|
<p class="small text-body-secondary">The zone files each running world loaded (<code>.luz</code>, <code>.lvl</code>, <code>.lutriggers</code>, terrain,
|
||||||
navmesh). When one changes on disk, the master server replaces the instances that loaded the old version with new ones and moves their
|
navmesh). When one changes on disk, the master server replaces the instances that loaded the old version with new ones and moves their
|
||||||
players over. <strong>Reload</strong> does the same for every instance of a zone now. Files read from the client's packs are not watched.</p>
|
players over. <strong>Reload</strong> does the same for every instance of a zone now. <strong>Properties are not moved</strong> (building in
|
||||||
|
progress isn't saved): an instance of a property on old files takes nobody new, its players are told an update is waiting, and it updates
|
||||||
|
once everyone has left. Files read from the client's packs are not watched.</p>
|
||||||
<div id="worldFilesZones"><p class="text-body-secondary mb-0">Waiting for the master server…</p></div>
|
<div id="worldFilesZones"><p class="text-body-secondary mb-0">Waiting for the master server…</p></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -257,7 +259,8 @@
|
|||||||
(z.changed ? ' ' + fmt.badge('changed on disk', 'warning') : '') + '</h6>' +
|
(z.changed ? ' ' + fmt.badge('changed on disk', 'warning') : '') + '</h6>' +
|
||||||
'<button type="button" class="btn btn-outline-primary btn-sm" data-reload-zone="' + esc(z.zone) + '">Reload</button></div>';
|
'<button type="button" class="btn btn-outline-primary btn-sm" data-reload-zone="' + esc(z.zone) + '">Reload</button></div>';
|
||||||
var instances = '<div class="small mb-1">' + z.instances.map(function (i) {
|
var instances = '<div class="small mb-1">' + z.instances.map(function (i) {
|
||||||
var badges = (i.stale ? ' ' + fmt.badge('old files', 'warning') : '') + (i.reloading ? ' ' + fmt.badge('being replaced', 'info') : '');
|
var badges = (i.stale ? ' ' + fmt.badge('old files', 'warning') : '') + (i.reloading ? ' ' + fmt.badge('being replaced', 'info') :
|
||||||
|
i.outdated ? ' ' + fmt.badge(i.clone ? 'updates when empty' : 'draining (old version)', 'secondary') : '');
|
||||||
return '<span class="me-3 text-nowrap">Instance ' + esc(i.instance) + (i.clone ? ' (clone ' + esc(i.clone) + ')' : '') + ', ' +
|
return '<span class="me-3 text-nowrap">Instance ' + esc(i.instance) + (i.clone ? ' (clone ' + esc(i.clone) + ')' : '') + ', ' +
|
||||||
nf.format(i.players) + ' player(s)' + badges + '</span>';
|
nf.format(i.players) + ' player(s)' + badges + '</span>';
|
||||||
}).join('') + '</div>';
|
}).join('') + '</div>';
|
||||||
|
|||||||
Reference in New Issue
Block a user