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,
|
WORLD_RELOAD,
|
||||||
// Master -> dashboard: each running zone's files, whether they changed on disk, and which instances are stale
|
// Master -> dashboard: each running zone's files, whether they changed on disk, and which instances are stale
|
||||||
WORLD_FILES_STATUS,
|
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 "CDClientReloader.h"
|
||||||
#include "WorldReloader.h"
|
#include "WorldReloader.h"
|
||||||
#include "master/WorldFiles.h"
|
#include "master/WorldFiles.h"
|
||||||
|
#include "master/UpdateStatus.h"
|
||||||
#include "BuildInfo.h"
|
#include "BuildInfo.h"
|
||||||
|
|
||||||
#ifdef DARKFLAME_PLATFORM_UNIX
|
#ifdef DARKFLAME_PLATFORM_UNIX
|
||||||
@@ -1211,6 +1212,14 @@ namespace {
|
|||||||
Game::lastSignal = -1;
|
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) {
|
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
|
// Only the dashboard starts message captures; every world gets it, and the one with the player acts on it
|
||||||
if (sysAddr != dashboardServerMasterPeerSysAddr) {
|
if (sysAddr != dashboardServerMasterPeerSysAddr) {
|
||||||
@@ -1270,6 +1279,7 @@ namespace {
|
|||||||
handlers.On<ConfigReload>(Master::CONFIG_RELOAD, OnConfigReload);
|
handlers.On<ConfigReload>(Master::CONFIG_RELOAD, OnConfigReload);
|
||||||
handlers.On<InstanceShutdown>(Master::INSTANCE_SHUTDOWN, OnInstanceShutdown);
|
handlers.On<InstanceShutdown>(Master::INSTANCE_SHUTDOWN, OnInstanceShutdown);
|
||||||
handlers.On<DashboardShutdown>(Master::DASHBOARD_SHUTDOWN, OnDashboardShutdown);
|
handlers.On<DashboardShutdown>(Master::DASHBOARD_SHUTDOWN, OnDashboardShutdown);
|
||||||
|
handlers.On<UpdateStatus>(Master::UPDATE_STATUS, OnUpdateStatus);
|
||||||
// Only world servers report game writes; pass them on unchanged
|
// Only world servers report game writes; pass them on unchanged
|
||||||
handlers.On<DataChanged>(Master::DATA_CHANGED, ForwardWorldToDashboard<DataChanged>);
|
handlers.On<DataChanged>(Master::DATA_CHANGED, ForwardWorldToDashboard<DataChanged>);
|
||||||
handlers.On<MessageCaptureControl>(Master::MESSAGE_CAPTURE_CONTROL, OnMessageCaptureControl);
|
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_FILES) == 47);
|
||||||
static_assert(static_cast<int64_t>(MessageType::Master::WORLD_RELOAD) == 48);
|
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::WORLD_FILES_STATUS) == 49);
|
||||||
|
static_assert(static_cast<int64_t>(MessageType::Master::UPDATE_STATUS) == 50);
|
||||||
|
|
||||||
// MessageType::Server: 3 enumerators
|
// MessageType::Server: 3 enumerators
|
||||||
static_assert(static_cast<int64_t>(MessageType::Server::VERSION_CONFIRM) == 0);
|
static_assert(static_cast<int64_t>(MessageType::Server::VERSION_CONFIRM) == 0);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "master/WorldFiles.h"
|
#include "master/WorldFiles.h"
|
||||||
#include "master/MessageCapture.h"
|
#include "master/MessageCapture.h"
|
||||||
#include "master/PlayerAction.h"
|
#include "master/PlayerAction.h"
|
||||||
|
#include "master/UpdateStatus.h"
|
||||||
#include "PacketDispatcher.h"
|
#include "PacketDispatcher.h"
|
||||||
#include "PacketTestUtils.h"
|
#include "PacketTestUtils.h"
|
||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
@@ -672,6 +673,31 @@ TEST(MasterPacketsTests, WorldFilesStatus) {
|
|||||||
EXPECT_EQ(read.zones, status.zones);
|
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
|
// A master without the outdated flags (written after the endpoints) still reads: nothing is outdated
|
||||||
TEST(MasterPacketsTests, ServerListWithoutOutdatedFlags) {
|
TEST(MasterPacketsTests, ServerListWithoutOutdatedFlags) {
|
||||||
MasterPackets::ServerListResponse response;
|
MasterPackets::ServerListResponse response;
|
||||||
|
|||||||
Reference in New Issue
Block a user