4431: Fix UUID for demo playback, add a conf var to toggle console colors r=def- a=Kaffeine

<!-- What is the motivation for the changes of this pull request -->
I added an extended kill message info (with killer assistant and mod-specific weapon id) and found a few bugs/mistakes in the current UUID implementation.

1. CUuidManager::RegisterName() mostly ignores the `ID` argument (totally ignored before https://github.com/ddnet/ddnet/pull/3053). Namely: it [add](a39af83a42/src/engine/shared/uuid_manager.cpp (L110)) the names into m_aNames. But then in order to pack them, the manager uses [GetUuid](a39af83a42/src/engine/shared/uuid_manager.cpp (L162)) which [picks](a39af83a42/src/engine/shared/uuid_manager.cpp (L120)) the uuid at [ID - OFFSET_UUID;](a39af83a42/src/engine/shared/uuid_manager.cpp (L94)). Sum up: if we have 10 registered UUIDs, then call `RegisterName(65536 + 123, "myname")` results in adding the name as m_aNames[11]. Later on, `GetUuid(123)` 'll pick `m_aNames[123]` and either cause a segfault or get invalid data. Why this does not affect the current production code? This works because the order of registration coincides with the registration ID and we have no sparse. If we'll swap `RegisterTeehistorianUuids()` and `RegisterGameUuids()` then the server 'll send corrupted packets.
2. Demo playback with UUID messages literally ignores them. This part is obvious, and the same is the patch. I can confirm that  it works and fixes the issue.

The work to fix `#1` is not justified to me; I've already spent many hours on this. Now I fixed the registration order in my code instead and I'm done for this time.

Keep in mind that this might hurt DDNet later. Or not.

I've also added an option to disable colors in the debug output because it makes the text unreadable in my IDE:
![image](https://user-images.githubusercontent.com/374839/145075621-c2b96c94-aa36-4f59-bd5c-2b1df940366e.png)

## Checklist

- [x] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test if it works standalone, system.c especially
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: Alexander Akulich <akulichalexander@gmail.com>
This commit is contained in:
bors[bot] 2021-12-09 07:48:09 +00:00 committed by GitHub
commit 9bfbad7b93
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 39 additions and 19 deletions

View file

@ -2617,14 +2617,18 @@ void CClient::OnDemoPlayerMessage(void *pData, int Size)
{
CUnpacker Unpacker;
Unpacker.Reset(pData, Size);
CMsgPacker Packer(NETMSG_EX, true);
// unpack msgid and system flag
int Msg = Unpacker.GetInt();
int Sys = Msg & 1;
Msg >>= 1;
int Msg;
bool Sys;
CUuid Uuid;
if(Unpacker.Error())
int Result = UnpackMessageID(&Msg, &Sys, &Uuid, &Unpacker, &Packer);
if(Result == UNPACKMESSAGE_ERROR)
{
return;
}
if(!Sys)
GameClient()->OnMessage(Msg, &Unpacker);

View file

@ -298,6 +298,8 @@ CServer::CServer() :
m_CurrentGameTick = 0;
m_RunServer = UNINITIALIZED;
m_aShutdownReason[0] = 0;
for(int i = 0; i < 2; i++)
{
m_apCurrentMapData[i] = 0;
@ -2693,6 +2695,9 @@ int CServer::Run()
}
}
const char *pDisconnectReason = "Server shutdown";
if(m_aShutdownReason[0])
pDisconnectReason = m_aShutdownReason;
if(ErrorShutdown())
{
dbg_msg("server", "shutdown from game server (%s)", m_aErrorShutdownReason);
@ -3082,7 +3087,13 @@ void CServer::ConNameBans(IConsole::IResult *pResult, void *pUser)
void CServer::ConShutdown(IConsole::IResult *pResult, void *pUser)
{
((CServer *)pUser)->m_RunServer = STOPPING;
CServer *pThis = static_cast<CServer *>(pUser);
pThis->m_RunServer = STOPPING;
const char *pReason = pResult->GetString(0);
if(pReason[0])
{
str_copy(pThis->m_aShutdownReason, pReason, sizeof(pThis->m_aShutdownReason));
}
}
void CServer::DemoRecorder_HandleAutoStart()
@ -3466,7 +3477,7 @@ void CServer::RegisterCommands()
// register console commands
Console()->Register("kick", "i[id] ?r[reason]", CFGFLAG_SERVER, ConKick, this, "Kick player with specified id for any reason");
Console()->Register("status", "?r[name]", CFGFLAG_SERVER, ConStatus, this, "List players containing name or all players");
Console()->Register("shutdown", "", CFGFLAG_SERVER, ConShutdown, this, "Shut down");
Console()->Register("shutdown", "?r[reason]", CFGFLAG_SERVER, ConShutdown, this, "Shut down");
Console()->Register("logout", "", CFGFLAG_SERVER, ConLogout, this, "Logout of rcon");
Console()->Register("show_ips", "?i[show]", CFGFLAG_SERVER, ConShowIps, this, "Show IP addresses in rcon commands (1 = on, 0 = off)");

View file

@ -231,6 +231,7 @@ public:
int m_RconClientID;
int m_RconAuthLevel;
int m_PrintCBIndex;
char m_aShutdownReason[128];
int64_t m_Lastheartbeat;
//static NETADDR4 master_server;

View file

@ -12,6 +12,7 @@ MACRO_CONFIG_INT(PlayerCountry, player_country, -1, -1, 1000, CFGFLAG_SAVE | CFG
MACRO_CONFIG_STR(Password, password, 32, "", CFGFLAG_CLIENT | CFGFLAG_SERVER | CFGFLAG_NONTEEHISTORIC, "Password to the server")
MACRO_CONFIG_STR(Logfile, logfile, 128, "", CFGFLAG_SAVE | CFGFLAG_CLIENT | CFGFLAG_SERVER, "Filename to log all output to")
MACRO_CONFIG_INT(ConsoleOutputLevel, console_output_level, 0, 0, 2, CFGFLAG_CLIENT | CFGFLAG_SERVER, "Adjusts the amount of information in the console")
MACRO_CONFIG_INT(ConsoleEnableColors, console_enable_colors, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SERVER, "Enable colors in console output")
MACRO_CONFIG_INT(Events, events, 1, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT | CFGFLAG_SERVER, "Enable triggering of events, (eye emotes on some holidays in server, christmas skins in client).")
MACRO_CONFIG_STR(SteamName, steam_name, 16, "", CFGFLAG_SAVE | CFGFLAG_CLIENT, "Last seen name of the Steam profile")

View file

@ -315,11 +315,14 @@ char *CConsole::Format(char *pBuf, int Size, const char *pFrom, const char *pStr
void CConsole::Print(int Level, const char *pFrom, const char *pStr, ColorRGBA PrintColor)
{
// if the color is pure white, use default terminal color
if(mem_comp(&PrintColor, &gs_ConsoleDefaultColor, sizeof(ColorRGBA)) == 0)
set_console_msg_color(NULL);
else
set_console_msg_color(&PrintColor);
if(g_Config.m_ConsoleEnableColors)
{
// if the color is pure white, use default terminal color
if(mem_comp(&PrintColor, &gs_ConsoleDefaultColor, sizeof(ColorRGBA)) == 0)
set_console_msg_color(NULL);
else
set_console_msg_color(&PrintColor);
}
dbg_msg(pFrom, "%s", pStr);
set_console_msg_color(NULL);
char aBuf[1024];

View file

@ -29,14 +29,14 @@ CEntity::~CEntity()
Server()->SnapFreeID(m_ID);
}
bool CEntity::NetworkClipped(int SnappingClient)
bool CEntity::NetworkClipped(int SnappingClient) const
{
return ::NetworkClipped(GameServer(), SnappingClient, m_Pos);
return ::NetworkClipped(m_pGameWorld->GameServer(), SnappingClient, m_Pos);
}
bool CEntity::NetworkClipped(int SnappingClient, vec2 CheckPos)
bool CEntity::NetworkClipped(int SnappingClient, vec2 CheckPos) const
{
return ::NetworkClipped(GameServer(), SnappingClient, CheckPos);
return ::NetworkClipped(m_pGameWorld->GameServer(), SnappingClient, CheckPos);
}
bool CEntity::GameLayerClipped(vec2 CheckPos)
@ -86,7 +86,7 @@ bool CEntity::GetNearestAirPosPlayer(vec2 PlayerPos, vec2 *OutPos)
return false;
}
bool NetworkClipped(CGameContext *pGameServer, int SnappingClient, vec2 CheckPos)
bool NetworkClipped(const CGameContext *pGameServer, int SnappingClient, vec2 CheckPos)
{
if(SnappingClient == -1 || pGameServer->m_apPlayers[SnappingClient]->m_ShowAll)
return false;

View file

@ -128,8 +128,8 @@ public:
Returns:
True if the entity doesn't have to be in the snapshot.
*/
bool NetworkClipped(int SnappingClient);
bool NetworkClipped(int SnappingClient, vec2 CheckPos);
bool NetworkClipped(int SnappingClient) const;
bool NetworkClipped(int SnappingClient, vec2 CheckPos) const;
bool GameLayerClipped(vec2 CheckPos);
@ -142,6 +142,6 @@ public:
int m_Layer;
};
bool NetworkClipped(CGameContext *pGameServer, int SnappingClient, vec2 CheckPos);
bool NetworkClipped(const CGameContext *pGameServer, int SnappingClient, vec2 CheckPos);
#endif