mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 02:43:44 +00:00
feat(master): UPDATE_STATUS from the dashboard, logged when it changes
Appended message ID 50 (dashboard -> master): the update check's state and a one-line summary. Master logs it whenever the summary changes, so the first one after master starts says when an update is out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -102,5 +102,8 @@ namespace MessageType {
|
||||
WORLD_RELOAD,
|
||||
// Master -> dashboard: each running zone's files, whether they changed on disk, and which instances are stale
|
||||
WORLD_FILES_STATUS,
|
||||
|
||||
// Dashboard -> master: what the update check found about this build (see UpdateStatus.h), for master's log
|
||||
UPDATE_STATUS,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
#include "CDClientReloader.h"
|
||||
#include "WorldReloader.h"
|
||||
#include "master/WorldFiles.h"
|
||||
#include "master/UpdateStatus.h"
|
||||
#include "BuildInfo.h"
|
||||
|
||||
#ifdef DARKFLAME_PLATFORM_UNIX
|
||||
@@ -1211,6 +1212,14 @@ namespace {
|
||||
Game::lastSignal = -1;
|
||||
}
|
||||
|
||||
// The dashboard's update check: logged when what it says changes (so the first one after master starts, and news)
|
||||
void OnUpdateStatus(const UpdateStatus& status, const SystemAddress& sysAddr) {
|
||||
static std::string lastSummary;
|
||||
if (sysAddr != dashboardServerMasterPeerSysAddr || status.summary.empty() || status.summary == lastSummary) return;
|
||||
lastSummary = status.summary;
|
||||
LOG("%s", status.summary.c_str());
|
||||
}
|
||||
|
||||
void OnMessageCaptureControl(const MessageCaptureControl& control, const SystemAddress& sysAddr) {
|
||||
// Only the dashboard starts message captures; every world gets it, and the one with the player acts on it
|
||||
if (sysAddr != dashboardServerMasterPeerSysAddr) {
|
||||
@@ -1270,6 +1279,7 @@ namespace {
|
||||
handlers.On<ConfigReload>(Master::CONFIG_RELOAD, OnConfigReload);
|
||||
handlers.On<InstanceShutdown>(Master::INSTANCE_SHUTDOWN, OnInstanceShutdown);
|
||||
handlers.On<DashboardShutdown>(Master::DASHBOARD_SHUTDOWN, OnDashboardShutdown);
|
||||
handlers.On<UpdateStatus>(Master::UPDATE_STATUS, OnUpdateStatus);
|
||||
// Only world servers report game writes; pass them on unchanged
|
||||
handlers.On<DataChanged>(Master::DATA_CHANGED, ForwardWorldToDashboard<DataChanged>);
|
||||
handlers.On<MessageCaptureControl>(Master::MESSAGE_CAPTURE_CONTROL, OnMessageCaptureControl);
|
||||
|
||||
35
dNet/master/UpdateStatus.h
Normal file
35
dNet/master/UpdateStatus.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef __UPDATESTATUS__H__
|
||||
#define __UPDATESTATUS__H__
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "BitStream.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "DashboardMessages.h"
|
||||
#include "MessageType/Master.h"
|
||||
|
||||
/**
|
||||
* UPDATE_STATUS (dashboard -> master): what the dashboard's update check found, sent after each check and when the
|
||||
* link to master comes up, so master's log says when a newer release or newer commits are out. Nothing is updated.
|
||||
*/
|
||||
struct UpdateStatus : public LUBitStream {
|
||||
UpdateStatus() : LUBitStream(ServiceType::MASTER, MessageType::Master::UPDATE_STATUS) {}
|
||||
|
||||
static constexpr uint16_t MAX_SUMMARY = 1024;
|
||||
|
||||
// UpdateCheck::eState: 0 not checked, 1 up to date, 2 update available, 3 the check failed
|
||||
uint8_t state{};
|
||||
std::string summary; // one line for the log
|
||||
|
||||
void Serialize(RakNet::BitStream& stream) const override {
|
||||
stream.Write(state);
|
||||
DashboardMessages::WriteText(stream, summary, MAX_SUMMARY);
|
||||
}
|
||||
|
||||
bool Deserialize(RakNet::BitStream& stream) override {
|
||||
return stream.Read(state) && DashboardMessages::ReadText(stream, summary, MAX_SUMMARY);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //!__UPDATESTATUS__H__
|
||||
@@ -1816,6 +1816,7 @@ static_assert(static_cast<int64_t>(MessageType::Master::CDCLIENT_RELOAD) == 46);
|
||||
static_assert(static_cast<int64_t>(MessageType::Master::WORLD_FILES) == 47);
|
||||
static_assert(static_cast<int64_t>(MessageType::Master::WORLD_RELOAD) == 48);
|
||||
static_assert(static_cast<int64_t>(MessageType::Master::WORLD_FILES_STATUS) == 49);
|
||||
static_assert(static_cast<int64_t>(MessageType::Master::UPDATE_STATUS) == 50);
|
||||
|
||||
// MessageType::Server: 3 enumerators
|
||||
static_assert(static_cast<int64_t>(MessageType::Server::VERSION_CONFIRM) == 0);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "master/WorldFiles.h"
|
||||
#include "master/MessageCapture.h"
|
||||
#include "master/PlayerAction.h"
|
||||
#include "master/UpdateStatus.h"
|
||||
#include "PacketDispatcher.h"
|
||||
#include "PacketTestUtils.h"
|
||||
#include "Game.h"
|
||||
@@ -672,6 +673,31 @@ TEST(MasterPacketsTests, WorldFilesStatus) {
|
||||
EXPECT_EQ(read.zones, status.zones);
|
||||
}
|
||||
|
||||
TEST(MasterPacketsTests, UpdateStatus) {
|
||||
UpdateStatus status;
|
||||
status.state = 2;
|
||||
status.summary = "Update available: release v3.1.0 (this server is running release v3.0.0)";
|
||||
ExpectHeaderThenSerialize(status, MessageType::Master::UPDATE_STATUS);
|
||||
|
||||
RakNet::BitStream stream;
|
||||
status.Serialize(stream);
|
||||
UpdateStatus read;
|
||||
ASSERT_TRUE(read.Deserialize(stream));
|
||||
EXPECT_EQ(read.state, 2);
|
||||
EXPECT_EQ(read.summary, status.summary);
|
||||
|
||||
// Longer than the cap: cut on the way out, refused on the way in
|
||||
status.summary.assign(UpdateStatus::MAX_SUMMARY + 10, 'x');
|
||||
RakNet::BitStream cut;
|
||||
status.Serialize(cut);
|
||||
ASSERT_TRUE(read.Deserialize(cut));
|
||||
EXPECT_EQ(read.summary.size(), UpdateStatus::MAX_SUMMARY);
|
||||
RakNet::BitStream tooLong;
|
||||
tooLong.Write<uint8_t>(1);
|
||||
tooLong.Write<uint16_t>(UpdateStatus::MAX_SUMMARY + 1);
|
||||
EXPECT_FALSE(read.Deserialize(tooLong));
|
||||
}
|
||||
|
||||
// A master without the outdated flags (written after the endpoints) still reads: nothing is outdated
|
||||
TEST(MasterPacketsTests, ServerListWithoutOutdatedFlags) {
|
||||
MasterPackets::ServerListResponse response;
|
||||
|
||||
Reference in New Issue
Block a user