Add support for extra chunks in teehistorian

This allows to add rarely-used chunks without increasing the file format
version.
This commit is contained in:
heinrich5991 2017-11-18 03:08:16 +01:00
parent 2ebc993379
commit 6c378b972b
14 changed files with 119 additions and 11 deletions

View file

@ -636,6 +636,9 @@ set_glob(GAME_SHARED GLOB src/game
mapitems.h
teamscore.cpp
teamscore.h
teehistorian_ex.cpp
teehistorian_ex.h
teehistorian_ex_chunks.h
tuning.h
variables.h
version.h

View file

@ -107,7 +107,7 @@ if gen_network_header:
non_extended = [o for o in network.Objects if o.ex is None]
extended = [o for o in network.Objects if o.ex is not None]
for l in create_enum_table(["NETOBJTYPE_EX"]+[o.enum_name for o in non_extended], "NUM_NETOBJTYPES"): print(l)
for l in create_enum_table(["__NETOBJTYPE_UUID_HELPER=OFFSET_GAME_UUID-1"]+[o.enum_name for o in extended], "OFFSET_NETMSGTYPE_UUID"): print(l)
for l in create_enum_table(["__NETOBJTYPE_UUID_HELPER=OFFSET_TEEHISTORIAN_UUID-1"]+[o.enum_name for o in extended], "OFFSET_NETMSGTYPE_UUID"): print(l)
print("")
non_extended = [o for o in network.Messages if o.ex is None]
@ -343,6 +343,7 @@ if gen_network_source:
lines += ['void RegisterGameUuids(CUuidManager *pManager)']
lines += ['{']
lines += ['\tRegisterTeehistorianUuids(pManager);']
for item in network.Objects + network.Messages:
if item.ex is not None:

View file

@ -12,7 +12,7 @@ Powerups = ["HEALTH", "ARMOR", "WEAPON", "NINJA"]
RawHeader = '''
#include <engine/message.h>
#include <engine/shared/protocol_ex.h>
#include <game/teehistorian_ex.h>
enum
{

View file

@ -6,7 +6,7 @@
#include <new>
void RegisterUuids(class CUuidManager *pManager)
void RegisterUuids(CUuidManager *pManager)
{
#define UUID(id, name) pManager->RegisterName(id, name);
#include "protocol_ex_msgs.h"

View file

@ -21,4 +21,4 @@ UUID(NETMSG_WHATIS, "what-is@ddnet.tw")
UUID(NETMSG_ITIS, "it-is@ddnet.tw")
UUID(NETMSG_IDONTKNOW, "i-dont-know@ddnet.tw")
UUID(NETMSG_RCONTYPE, "rcon-type@ddnet.tw")
UUID(NETMSG_RCONTYPE, "rcon-type@ddnet.tw")

View file

@ -110,6 +110,11 @@ int CUuidManager::LookupUuid(CUuid Uuid) const
return UUID_UNKNOWN;
}
int CUuidManager::NumUuids() const
{
return m_aNames.size();
}
int CUuidManager::UnpackUuid(CUnpacker *pUnpacker) const
{
CUuid Temp;

View file

@ -42,6 +42,7 @@ public:
CUuid GetUuid(int ID) const;
const char *GetName(int ID) const;
int LookupUuid(CUuid Uuid) const;
int NumUuids() const;
int UnpackUuid(CUnpacker *pUnpacker) const;
int UnpackUuid(CUnpacker *pUnpacker, CUuid *pOut) const;

View file

@ -2585,6 +2585,7 @@ void CGameContext::OnInit(/*class IKernel *pKernel*/)
GameInfo.m_pConfig = &g_Config;
GameInfo.m_pTuning = Tuning();
GameInfo.m_pUuids = &g_UuidManager;
char aMapName[128];
Server()->GetMapInfo(aMapName, sizeof(aMapName), &GameInfo.m_MapSize, &GameInfo.m_MapCrc);

View file

@ -6,7 +6,11 @@
static const char TEEHISTORIAN_NAME[] = "teehistorian@ddnet.tw";
static const CUuid TEEHISTORIAN_UUID = CalculateUuid(TEEHISTORIAN_NAME);
static const char TEEHISTORIAN_VERSION[] = "1";
static const char TEEHISTORIAN_VERSION[] = "2";
#define UUID(id, name) static const CUuid UUID_ ## id = CalculateUuid(name);
#include <game/teehistorian_ex_chunks.h>
#undef UUID
enum
{
@ -21,6 +25,7 @@ enum
TEEHISTORIAN_JOIN,
TEEHISTORIAN_DROP,
TEEHISTORIAN_CONSOLE_COMMAND,
TEEHISTORIAN_EX,
};
static char EscapeJsonChar(char c)
@ -196,11 +201,35 @@ void CTeeHistorian::WriteHeader(const CGameInfo *pGameInfo)
#include <game/tuning.h>
#undef MACRO_TUNING_PARAM
str_format(aJson, sizeof(aJson), "}}");
str_format(aJson, sizeof(aJson), "},\"uuids\":[");
Write(aJson, str_length(aJson));
for(int i = 0; i < pGameInfo->m_pUuids->NumUuids(); i++)
{
str_format(aJson, sizeof(aJson), "%s\"%s\"",
i == 0 ? "" : ",",
E(aBuffer1, pGameInfo->m_pUuids->GetName(OFFSET_UUID + i)));
Write(aJson, str_length(aJson));
}
str_format(aJson, sizeof(aJson), "]}");
Write(aJson, str_length(aJson));
Write("", 1); // Null termination.
}
void CTeeHistorian::WriteExtra(CUuid Uuid, const void *pData, int DataSize)
{
EnsureTickWritten();
CPacker Ex;
Ex.Reset();
Ex.AddInt(-TEEHISTORIAN_EX);
Ex.AddRaw(&Uuid, sizeof(Uuid));
Ex.AddInt(DataSize);
Write(Ex.Data(), Ex.Size());
Write(pData, DataSize);
}
void CTeeHistorian::BeginTick(int Tick)
{
@ -484,6 +513,11 @@ void CTeeHistorian::RecordConsoleCommand(int ClientID, int FlagMask, const char
Write(Buffer.Data(), Buffer.Size());
}
void CTeeHistorian::RecordTestExtra()
{
WriteExtra(UUID_TEEHISTORIAN_TEST, "", 0);
}
void CTeeHistorian::EndInputs()
{
dbg_assert(m_State == STATE_INPUTS, "invalid teehistorian state");

View file

@ -7,6 +7,7 @@
struct CConfiguration;
class CTuningParams;
class CUuidManager;
class CTeeHistorian
{
@ -29,6 +30,7 @@ public:
CConfiguration *m_pConfig;
CTuningParams *m_pTuning;
CUuidManager *m_pUuids;
};
CTeeHistorian();
@ -51,6 +53,7 @@ public:
void RecordPlayerJoin(int ClientID);
void RecordPlayerDrop(int ClientID, const char *pReason);
void RecordConsoleCommand(int ClientID, int FlagMask, const char *pCmd, IConsole::IResult *pResult);
void RecordTestExtra();
void EndInputs();
void EndTick();
@ -59,6 +62,7 @@ public:
private:
void WriteHeader(const CGameInfo *pGameInfo);
void WriteExtra(CUuid Uuid, const void *pData, int DataSize);
void EnsureTickWrittenPlayerData(int ClientID);
void EnsureTickWritten();
void WriteTick();

View file

@ -0,0 +1,10 @@
#include "teehistorian_ex.h"
#include <engine/shared/uuid_manager.h>
void RegisterTeehistorianUuids(CUuidManager *pManager)
{
#define UUID(id, name) pManager->RegisterName(id, name);
#include "teehistorian_ex_chunks.h"
#undef UUID
}

View file

@ -0,0 +1,15 @@
#ifndef GAME_TEEHISTORIAN_EX_H
#define GAME_TEEHISTORIAN_EX_H
#include <engine/shared/protocol_ex.h>
enum
{
__TEEHISTORIAN_UUID_HELPER=OFFSET_GAME_UUID-1,
#define UUID(id, name) id,
#include "teehistorian_ex_chunks.h"
#undef UUID
OFFSET_TEEHISTORIAN_UUID
};
void RegisterTeehistorianUuids(class CUuidManager *pManager);
#endif // GAME_TEEHISTORIAN_EX_H

View file

@ -0,0 +1 @@
UUID(TEEHISTORIAN_TEST, "teehistorian-test@ddnet.tw")

View file

@ -5,12 +5,15 @@
#include <game/gamecore.h>
#include <game/server/teehistorian.h>
void RegisterGameUuids(CUuidManager *pManager);
class TeeHistorian : public ::testing::Test
{
protected:
CTeeHistorian m_TH;
CConfiguration m_Config;
CTuningParams m_Tuning;
CUuidManager m_UuidManager;
CTeeHistorian::CGameInfo m_GameInfo;
CPacker m_Buffer;
@ -35,6 +38,9 @@ protected:
#undef MACRO_CONFIG_STR
#undef MACRO_CONFIG_INT
RegisterUuids(&m_UuidManager);
RegisterGameUuids(&m_UuidManager);
mem_zero(&m_GameInfo, sizeof(m_GameInfo));
m_GameInfo.m_GameUuid = CalculateUuid("test@ddnet.tw");
@ -51,6 +57,7 @@ protected:
m_GameInfo.m_pConfig = &m_Config;
m_GameInfo.m_pTuning = &m_Tuning;
m_GameInfo.m_pUuids = &m_UuidManager;
Reset(&m_GameInfo);
}
@ -71,8 +78,9 @@ protected:
void Expect(const unsigned char *pOutput, int OutputSize)
{
static CUuid TEEHISTORIAN_UUID = CalculateUuid("teehistorian@ddnet.tw");
static const char PREFIX1[] = "{\"comment\":\"teehistorian@ddnet.tw\",\"version\":\"1\",\"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_crc\":\"eceaf25c\",\"config\":{},\"tuning\":{}}";
static const char PREFIX1[] = "{\"comment\":\"teehistorian@ddnet.tw\",\"version\":\"2\",\"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_crc\":\"eceaf25c\",\"config\":{},\"tuning\":{},\"uuids\":[";
static const char PREFIX3[] = "]}";
char aTimeBuf[64];
str_timestamp_ex(m_GameInfo.m_StartTime, aTimeBuf, sizeof(aTimeBuf), "%Y-%m-%d %H:%M:%S %z");
@ -83,6 +91,15 @@ protected:
Buffer.AddRaw(PREFIX1, str_length(PREFIX1));
Buffer.AddRaw(aTimeBuf, str_length(aTimeBuf));
Buffer.AddRaw(PREFIX2, str_length(PREFIX2));
for(int i = 0; i < m_UuidManager.NumUuids(); i++)
{
char aBuf[64];
str_format(aBuf, sizeof(aBuf), "%s\"%s\"",
i == 0 ? "" : ",",
m_UuidManager.GetName(OFFSET_UUID + i));
Buffer.AddRaw(aBuf, str_length(aBuf));
}
Buffer.AddRaw(PREFIX3, str_length(PREFIX3));
Buffer.AddRaw("", 1);
Buffer.AddRaw(pOutput, OutputSize);
@ -93,13 +110,12 @@ protected:
void ExpectFull(const unsigned char *pOutput, int OutputSize)
{
ASSERT_FALSE(m_Buffer.Error());
const ::testing::TestInfo *pTestInfo =
::testing::UnitTest::GetInstance()->current_test_info();
const char *pTestName = pTestInfo->name();
if(m_Buffer.Size() != OutputSize
if(m_Buffer.Error()
|| m_Buffer.Size() != OutputSize
|| mem_comp(m_Buffer.Data(), pOutput, OutputSize) != 0)
{
char aFilename[64];
@ -118,6 +134,7 @@ protected:
io_close(File);
}
ASSERT_FALSE(m_Buffer.Error());
ASSERT_EQ(m_Buffer.Size(), OutputSize);
ASSERT_TRUE(mem_comp(m_Buffer.Data(), pOutput, OutputSize) == 0);
}
@ -273,3 +290,19 @@ TEST_F(TeeHistorian, TickExplicitPlayerMessage)
Finish();
Expect(EXPECTED, sizeof(EXPECTED));
}
TEST_F(TeeHistorian, ExtraMessage)
{
const unsigned char EXPECTED[] = {
0x41, 0x00, // TICK_SKIP dt=0
// EX uuid=6bb8ba88-0f0b-382e-8dae-dbf4052b8b7d data=""
0x4a,
0x6b, 0xb8, 0xba, 0x88, 0x0f, 0x0b, 0x38, 0x2e,
0x8d, 0xae, 0xdb, 0xf4, 0x05, 0x2b, 0x8b, 0x7d,
0x00,
0x40, // FINISH
};
Tick(1); Inputs(); m_TH.RecordTestExtra();
Finish();
Expect(EXPECTED, sizeof(EXPECTED));
}