Merge pull request #7080 from heinrich5991/pr_ddnet_teehistorian_prev_game_uuid

Record previous game ID in teehistorian
This commit is contained in:
Dennis Felsing 2023-08-28 11:28:00 +00:00 committed by GitHub
commit baffa8d817
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 88 additions and 12 deletions

View file

@ -277,10 +277,14 @@ class IGameServer : public IInterface
MACRO_INTERFACE("gameserver", 0)
protected:
public:
virtual void OnInit() = 0;
// `pPersistentData` may be null if this is the first time `IGameServer`
// is instantiated.
virtual void OnInit(const void *pPersistentData) = 0;
virtual void OnConsoleInit() = 0;
virtual void OnMapChange(char *pNewMapName, int MapNameSize) = 0;
virtual void OnShutdown() = 0;
// `pPersistentData` may be null if this is the last time `IGameServer`
// is destroyed.
virtual void OnShutdown(void *pPersistentData) = 0;
virtual void OnTick() = 0;
virtual void OnPreSnap() = 0;
@ -315,6 +319,7 @@ public:
virtual bool IsClientReady(int ClientID) const = 0;
virtual bool IsClientPlayer(int ClientID) const = 0;
virtual int PersistentDataSize() const = 0;
virtual int PersistentClientDataSize() const = 0;
virtual CUuid GameUuid() const = 0;

View file

@ -368,6 +368,7 @@ CServer::~CServer()
free(Client.m_pPersistentData);
}
}
free(m_pPersistentData);
delete m_pRegister;
delete m_pConnectionPool;
@ -2636,6 +2637,7 @@ int CServer::Run()
Client.m_pPersistentData = malloc(Size);
}
}
m_pPersistentData = malloc(GameServer()->PersistentDataSize());
// load map
if(!LoadMap(Config()->m_SvMap))
@ -2704,7 +2706,7 @@ int CServer::Run()
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
Antibot()->Init();
GameServer()->OnInit();
GameServer()->OnInit(nullptr);
if(ErrorShutdown())
{
m_RunServer = STOPPING;
@ -2762,7 +2764,7 @@ int CServer::Run()
}
}
GameServer()->OnShutdown();
GameServer()->OnShutdown(m_pPersistentData);
for(int ClientID = 0; ClientID < MAX_CLIENTS; ClientID++)
{
@ -2780,7 +2782,7 @@ int CServer::Run()
m_CurrentGameTick = MIN_TICK;
m_ServerInfoFirstRequest = 0;
Kernel()->ReregisterInterface(GameServer());
GameServer()->OnInit();
GameServer()->OnInit(m_pPersistentData);
if(ErrorShutdown())
{
break;
@ -2989,7 +2991,7 @@ int CServer::Run()
m_Fifo.Shutdown();
GameServer()->OnShutdown();
GameServer()->OnShutdown(nullptr);
m_pMap->Unload();
DbPool()->OnShutdown();

View file

@ -248,6 +248,7 @@ public:
int m_RconAuthLevel;
int m_PrintCBIndex;
char m_aShutdownReason[128];
void *m_pPersistentData;
enum
{

View file

@ -3369,8 +3369,10 @@ void CGameContext::OnConsoleInit()
#include <game/ddracechat.h>
}
void CGameContext::OnInit()
void CGameContext::OnInit(const void *pPersistentData)
{
const CPersistentData *pPersistent = (const CPersistentData *)pPersistentData;
m_pServer = Kernel()->RequestInterface<IServer>();
m_pConfig = Kernel()->RequestInterface<IConfigManager>()->Values();
m_pConsole = Kernel()->RequestInterface<IConsole>();
@ -3542,6 +3544,17 @@ void CGameContext::OnInit()
GameInfo.m_MapSha256 = MapSha256;
GameInfo.m_MapCrc = MapCrc;
if(pPersistent)
{
GameInfo.m_HavePrevGameUuid = true;
GameInfo.m_PrevGameUuid = pPersistent->m_PrevGameUuid;
}
else
{
GameInfo.m_HavePrevGameUuid = false;
mem_zero(&GameInfo.m_PrevGameUuid, sizeof(GameInfo.m_PrevGameUuid));
}
m_TeeHistorian.Reset(&GameInfo, TeeHistorianWrite, this);
for(int i = 0; i < MAX_CLIENTS; i++)
@ -3814,8 +3827,15 @@ void CGameContext::OnMapChange(char *pNewMapName, int MapNameSize)
str_copy(m_aDeleteTempfile, aTemp, sizeof(m_aDeleteTempfile));
}
void CGameContext::OnShutdown()
void CGameContext::OnShutdown(void *pPersistentData)
{
CPersistentData *pPersistent = (CPersistentData *)pPersistentData;
if(pPersistent)
{
pPersistent->m_PrevGameUuid = m_GameUuid;
}
Antibot()->RoundEnd();
if(m_TeeHistorianActive)

View file

@ -139,6 +139,11 @@ class CGameContext : public IGameServer
void AddVote(const char *pDescription, const char *pCommand);
static int MapScan(const char *pName, int IsDir, int DirType, void *pUserData);
struct CPersistentData
{
CUuid m_PrevGameUuid;
};
struct CPersistentClientData
{
bool m_IsSpectator;
@ -269,10 +274,10 @@ public:
void LoadMapSettings();
// engine events
void OnInit() override;
void OnInit(const void *pPersistentData) override;
void OnConsoleInit() override;
void OnMapChange(char *pNewMapName, int MapNameSize) override;
void OnShutdown() override;
void OnShutdown(void *pPersistentData) override;
void OnTick() override;
void OnPreSnap() override;
@ -299,6 +304,7 @@ public:
bool IsClientReady(int ClientID) const override;
bool IsClientPlayer(int ClientID) const override;
int PersistentDataSize() const override { return sizeof(CPersistentData); }
int PersistentClientDataSize() const override { return sizeof(CPersistentClientData); }
CUuid GameUuid() const override;

View file

@ -1,5 +1,6 @@
#include "teehistorian.h"
#include <engine/external/json-parser/json.h>
#include <engine/shared/config.h>
#include <engine/shared/json.h>
#include <engine/shared/snapshot.h>
@ -8,7 +9,7 @@
static const char TEEHISTORIAN_NAME[] = "teehistorian@ddnet.tw";
static const CUuid TEEHISTORIAN_UUID = CalculateUuid(TEEHISTORIAN_NAME);
static const char TEEHISTORIAN_VERSION[] = "2";
static const char TEEHISTORIAN_VERSION_MINOR[] = "5";
static const char TEEHISTORIAN_VERSION_MINOR[] = "6";
#define UUID(id, name) static const CUuid UUID_##id = CalculateUuid(name);
#include <engine/shared/teehistorian_ex_chunks.h>
@ -81,6 +82,18 @@ void CTeeHistorian::WriteHeader(const CGameInfo *pGameInfo)
str_timestamp_ex(pGameInfo->m_StartTime, aStartTime, sizeof(aStartTime), "%Y-%m-%dT%H:%M:%S%z");
sha256_str(pGameInfo->m_MapSha256, aMapSha256, sizeof(aMapSha256));
char aPrevGameUuid[UUID_MAXSTRSIZE];
char aPrevGameUuidJson[64];
if(pGameInfo->m_HavePrevGameUuid)
{
FormatUuid(pGameInfo->m_PrevGameUuid, aPrevGameUuid, sizeof(aPrevGameUuid));
str_format(aPrevGameUuidJson, sizeof(aPrevGameUuidJson), "\"prev_game_uuid\":\"%s\",", aPrevGameUuid);
}
else
{
aPrevGameUuidJson[0] = 0;
}
char aCommentBuffer[128];
char aServerVersionBuffer[128];
char aStartTimeBuffer[128];
@ -100,6 +113,7 @@ void CTeeHistorian::WriteHeader(const CGameInfo *pGameInfo)
"\"version\":\"%s\","
"\"version_minor\":\"%s\","
"\"game_uuid\":\"%s\","
"%s"
"\"server_version\":\"%s\","
"\"start_time\":\"%s\","
"\"server_name\":\"%s\","
@ -115,6 +129,7 @@ void CTeeHistorian::WriteHeader(const CGameInfo *pGameInfo)
TEEHISTORIAN_VERSION,
TEEHISTORIAN_VERSION_MINOR,
aGameUuid,
aPrevGameUuidJson,
E(aServerVersionBuffer, pGameInfo->m_pServerVersion),
E(aStartTimeBuffer, aStartTime),
E(aServerNameBuffer, pGameInfo->m_pServerName),

View file

@ -33,6 +33,9 @@ public:
SHA256_DIGEST m_MapSha256;
int m_MapCrc;
bool m_HavePrevGameUuid;
CUuid m_PrevGameUuid;
CConfig *m_pConfig;
CTuningParams *m_pTuning;
CUuidManager *m_pUuids;

View file

@ -1,6 +1,7 @@
#include <gtest/gtest.h>
#include <base/detect.h>
#include <engine/external/json-parser/json.h>
#include <engine/server.h>
#include <engine/shared/config.h>
#include <game/gamecore.h>
@ -68,6 +69,9 @@ protected:
m_GameInfo.m_MapSha256 = Sha256;
m_GameInfo.m_MapCrc = 0xeceaf25c;
m_GameInfo.m_HavePrevGameUuid = false;
mem_zero(&m_GameInfo.m_PrevGameUuid, sizeof(m_GameInfo.m_PrevGameUuid));
m_GameInfo.m_pConfig = &m_Config;
m_GameInfo.m_pTuning = &m_Tuning;
m_GameInfo.m_pUuids = &m_UuidManager;
@ -101,7 +105,7 @@ protected:
void Expect(const unsigned char *pOutput, size_t OutputSize)
{
static CUuid TEEHISTORIAN_UUID = CalculateUuid("teehistorian@ddnet.tw");
static const char PREFIX1[] = "{\"comment\":\"teehistorian@ddnet.tw\",\"version\":\"2\",\"version_minor\":\"5\",\"game_uuid\":\"a1eb7182-796e-3b3e-941d-38ca71b2a4a8\",\"server_version\":\"DDNet test\",\"start_time\":\"";
static const char PREFIX1[] = "{\"comment\":\"teehistorian@ddnet.tw\",\"version\":\"2\",\"version_minor\":\"6\",\"game_uuid\":\"a1eb7182-796e-3b3e-941d-38ca71b2a4a8\",\"server_version\":\"DDNet test\",\"start_time\":\"";
static const char PREFIX2[] = "\",\"server_name\":\"server name\",\"server_port\":\"8303\",\"game_type\":\"game type\",\"map_name\":\"Kobra 3 Solo\",\"map_size\":\"903514\",\"map_sha256\":\"0123456789012345678901234567890123456789012345678901234567890123\",\"map_crc\":\"eceaf25c\",\"prng_description\":\"test-prng:02468ace\",\"config\":{},\"tuning\":{},\"uuids\":[";
static const char PREFIX3[] = "]}";
@ -833,3 +837,23 @@ TEST_F(TeeHistorian, AntibotEmptyMessage)
m_TH.RecordAntibot("🤖", 4);
Expect(EXPECTED, sizeof(EXPECTED));
}
TEST_F(TeeHistorian, PrevGameUuid)
{
m_GameInfo.m_HavePrevGameUuid = true;
CUuid PrevGameUuid = {{
// fe19c218-f555-4002-a273-126c59ccc17a
0xfe, 0x19, 0xc2, 0x18, 0xf5, 0x55, 0x40, 0x02,
0xa2, 0x73, 0x12, 0x6c, 0x59, 0xcc, 0xc1, 0x7a,
//
}};
m_GameInfo.m_PrevGameUuid = PrevGameUuid;
Reset(&m_GameInfo);
Finish();
json_value *pJson = json_parse((const char *)m_vBuffer.data() + 16, -1);
ASSERT_TRUE(pJson);
const json_value &JsonPrevGameUuid = (*pJson)["prev_game_uuid"];
ASSERT_EQ(JsonPrevGameUuid.type, json_string);
EXPECT_STREQ(JsonPrevGameUuid, "fe19c218-f555-4002-a273-126c59ccc17a");
json_value_free(pJson);
}