diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index a59442f7c..915663a47 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -77,6 +77,9 @@ #undef main #endif +static const ColorRGBA ClientNetworkPrintColor{0.7f, 1, 0.7f, 1.0f}; +static const ColorRGBA ClientNetworkErrPrintColor{1.0f, 0.25f, 0.25f, 1.0f}; + void CGraph::Init(float Min, float Max) { m_Min = Min; @@ -709,7 +712,7 @@ void CClient::Connect(const char *pAddress, const char *pPassword) str_copy(m_aServerAddressStr, pAddress, sizeof(m_aServerAddressStr)); str_format(aBuf, sizeof(aBuf), "connecting to '%s'", m_aServerAddressStr); - m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf, ClientNetworkPrintColor); bool is_websocket = false; if(strncmp(m_aServerAddressStr, "ws://", 5) == 0) { @@ -764,7 +767,7 @@ void CClient::DisconnectWithReason(const char *pReason) { char aBuf[512]; str_format(aBuf, sizeof(aBuf), "disconnecting. reason='%s'", pReason ? pReason : "unknown"); - m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf, ClientNetworkPrintColor); // stop demo playback and recorder m_DemoPlayer.Stop(); @@ -2564,7 +2567,7 @@ void CClient::PumpNetwork() Disconnect(); char aBuf[256]; str_format(aBuf, sizeof(aBuf), "offline error='%s'", m_NetClient[CLIENT_MAIN].ErrorString()); - m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf, ClientNetworkErrPrintColor); } if(State() != IClient::STATE_OFFLINE && State() < IClient::STATE_QUITTING && m_DummyConnected && @@ -2573,14 +2576,14 @@ void CClient::PumpNetwork() DummyDisconnect(0); char aBuf[256]; str_format(aBuf, sizeof(aBuf), "offline dummy error='%s'", m_NetClient[CLIENT_DUMMY].ErrorString()); - m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf, ClientNetworkErrPrintColor); } // if(State() == IClient::STATE_CONNECTING && m_NetClient[CLIENT_MAIN].State() == NETSTATE_ONLINE) { // we switched to online - m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", "connected, sending info"); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", "connected, sending info", ClientNetworkPrintColor); SetState(IClient::STATE_LOADING); SendInfo(); } @@ -3119,7 +3122,7 @@ void CClient::Run() char aBuf[256]; str_format(aBuf, sizeof(aBuf), "version %s", GameClient()->NetVersion()); - m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf, ColorRGBA{0.7f, 0.7f, 1, 1.0f}); // connect to the server if wanted /* @@ -4085,11 +4088,20 @@ void CClient::LoadFont() Kernel()->RequestInterface()->SetDefaultFont(pDefaultFont); } + + char aBuff[1024]; + if(!pDefaultFont) - m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "gameclient", "failed to load font. filename='%s'", pFontFile); + { + str_format(aBuff, sizeof(aBuff) / sizeof(aBuff[0]), "failed to load font. filename='%s'", pFontFile); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "gameclient", aBuff); + } if(!LoadedFallbackFont) - m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "gameclient", "failed to load the fallback font. filename='%s'", pFallbackFontFile); + { + str_format(aBuff, sizeof(aBuff) / sizeof(aBuff[0]), "failed to load the fallback font. filename='%s'", pFallbackFontFile); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "gameclient", aBuff); + } } void CClient::Notify(const char *pTitle, const char *pMessage) diff --git a/src/engine/client/friends.cpp b/src/engine/client/friends.cpp index aed61520a..41849ed4e 100644 --- a/src/engine/client/friends.cpp +++ b/src/engine/client/friends.cpp @@ -153,7 +153,8 @@ void CFriends::Friends() for(int i = 0; i < m_NumFriends; ++i) { str_format(aBuf, sizeof(aBuf), "Name: %s, Clan: %s", m_aFriends[i].m_aName, m_aFriends[i].m_aClan); - pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, m_Foes ? "foes" : "friends", aBuf, true); + + pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, m_Foes ? "foes" : "friends", aBuf, color_cast(ColorHSLA(g_Config.m_ClMessageHighlightColor))); } } } diff --git a/src/engine/client/ghost.cpp b/src/engine/client/ghost.cpp index 4ffc02e76..96b4a701f 100644 --- a/src/engine/client/ghost.cpp +++ b/src/engine/client/ghost.cpp @@ -11,6 +11,8 @@ static const unsigned char gs_aHeaderMarker[8] = {'T', 'W', 'G', 'H', 'O', 'S', static const unsigned char gs_CurVersion = 6; static const int gs_NumTicksOffset = 93; +static const ColorRGBA gs_GhostPrintColor{0.6f, 0.6f, 0.6f, 1.0f}; + CGhostRecorder::CGhostRecorder() { m_File = 0; @@ -31,7 +33,7 @@ int CGhostRecorder::Start(const char *pFilename, const char *pMap, SHA256_DIGEST { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "Unable to open '%s' for ghost recording", pFilename); - m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "ghost_recorder", aBuf); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "ghost_recorder", aBuf, gs_GhostPrintColor); return -1; } @@ -50,7 +52,7 @@ int CGhostRecorder::Start(const char *pFilename, const char *pMap, SHA256_DIGEST char aBuf[256]; str_format(aBuf, sizeof(aBuf), "ghost recording to '%s'", pFilename); - m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "ghost_recorder", aBuf); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "ghost_recorder", aBuf, gs_GhostPrintColor); return 0; } @@ -135,7 +137,7 @@ int CGhostRecorder::Stop(int Ticks, int Time) if(!m_File) return -1; - m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "ghost_recorder", "Stopped ghost recording"); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "ghost_recorder", "Stopped ghost recording", gs_GhostPrintColor); FlushChunk(); diff --git a/src/engine/client/graphics_threaded.cpp b/src/engine/client/graphics_threaded.cpp index 144c2e0fb..94686eaf0 100644 --- a/src/engine/client/graphics_threaded.cpp +++ b/src/engine/client/graphics_threaded.cpp @@ -688,7 +688,7 @@ void CGraphics_Threaded::ScreenshotDirect() // save png char aBuf[256]; str_format(aBuf, sizeof(aBuf), "saved screenshot to '%s'", aWholePath); - m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf, ColorRGBA{0.75f, 0.4f, 0.0f, 1.0f}); png_open_file_write(&Png, aWholePath); // ignore_convention png_set_data(&Png, Image.m_Width, Image.m_Height, 8, PNG_TRUECOLOR, (unsigned char *)Image.m_pData); // ignore_convention png_close_file(&Png); // ignore_convention diff --git a/src/engine/console.h b/src/engine/console.h index f19ad3737..c66a8f730 100644 --- a/src/engine/console.h +++ b/src/engine/console.h @@ -76,7 +76,7 @@ public: }; typedef void (*FTeeHistorianCommandCallback)(int ClientID, int FlagMask, const char *pCmd, IResult *pResult, void *pUser); - typedef void (*FPrintCallback)(const char *pStr, void *pUser, bool Highlighted); + typedef void (*FPrintCallback)(const char *pStr, void *pUser, ColorRGBA PrintColor); typedef void (*FPossibleCallback)(const char *pCmd, void *pUser); typedef void (*FCommandCallback)(IResult *pResult, void *pUserData); typedef void (*FChainCommandCallback)(IResult *pResult, void *pUserData, FCommandCallback pfnCallback, void *pCallbackUserData); @@ -103,7 +103,7 @@ public: virtual int RegisterPrintCallback(int OutputLevel, FPrintCallback pfnPrintCallback, void *pUserData) = 0; virtual void SetPrintOutputLevel(int Index, int OutputLevel) = 0; virtual char *Format(char *pBuf, int Size, const char *pFrom, const char *pStr) = 0; - virtual void Print(int Level, const char *pFrom, const char *pStr, bool Highlighted = false) = 0; + virtual void Print(int Level, const char *pFrom, const char *pStr, ColorRGBA PrintColor = {1, 1, 1, 1}) = 0; virtual void SetTeeHistorianCommandCallback(FTeeHistorianCommandCallback pfnCallback, void *pUser) = 0; virtual void SetAccessLevel(int AccessLevel) = 0; diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 924254d77..4e3201502 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -227,7 +227,7 @@ void CServerBan::ConBanExt(IConsole::IResult *pResult, void *pUser) CServerBan *pThis = static_cast(pUser); const char *pStr = pResult->GetString(0); - int Minutes = pResult->NumArguments() > 1 ? clamp(pResult->GetInteger(1), 0, 44640) : 30; + int Minutes = pResult->NumArguments() > 1 ? clamp(pResult->GetInteger(1), 0, 525600) : 30; const char *pReason = pResult->NumArguments() > 2 ? pResult->GetString(2) : "No reason given"; if(str_isallnum(pStr)) @@ -1219,7 +1219,7 @@ void CServer::SendRconLine(int ClientID, const char *pLine) SendMsg(&Msg, MSGFLAG_VITAL, ClientID); } -void CServer::SendRconLineAuthed(const char *pLine, void *pUser, bool Highlighted) +void CServer::SendRconLineAuthed(const char *pLine, void *pUser, ColorRGBA PrintColor) { CServer *pThis = (CServer *)pUser; static volatile int s_ReentryGuard = 0; @@ -2685,6 +2685,11 @@ int CServer::Run() m_UPnP.Shutdown(); #endif + for(auto &Client : m_aClients) + { + free(Client.m_pPersistentData); + } + return ErrorShutdown(); } diff --git a/src/engine/server/server.h b/src/engine/server/server.h index d34f22cd2..7e8c76800 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -319,7 +319,7 @@ public: void SendMapData(int ClientID, int Chunk); void SendConnectionReady(int ClientID); void SendRconLine(int ClientID, const char *pLine); - static void SendRconLineAuthed(const char *pLine, void *pUser, bool Highlighted = false); + static void SendRconLineAuthed(const char *pLine, void *pUser, ColorRGBA PrintColor = {1, 1, 1, 1}); void SendRconCmdAdd(const IConsole::CCommandInfo *pCommandInfo, int ClientID); void SendRconCmdRem(const IConsole::CCommandInfo *pCommandInfo, int ClientID); diff --git a/src/engine/shared/console.cpp b/src/engine/shared/console.cpp index 949c7923d..38174733e 100644 --- a/src/engine/shared/console.cpp +++ b/src/engine/shared/console.cpp @@ -313,7 +313,7 @@ char *CConsole::Format(char *pBuf, int Size, const char *pFrom, const char *pStr return pBuf; } -void CConsole::Print(int Level, const char *pFrom, const char *pStr, bool Highlighted) +void CConsole::Print(int Level, const char *pFrom, const char *pStr, ColorRGBA PrintColor) { dbg_msg(pFrom, "%s", pStr); char aBuf[1024]; @@ -322,7 +322,7 @@ void CConsole::Print(int Level, const char *pFrom, const char *pStr, bool Highli { if(Level <= m_aPrintCB[i].m_OutputLevel && m_aPrintCB[i].m_pfnPrintCallback) { - m_aPrintCB[i].m_pfnPrintCallback(aBuf, m_aPrintCB[i].m_pPrintCallbackUserdata, Highlighted); + m_aPrintCB[i].m_pfnPrintCallback(aBuf, m_aPrintCB[i].m_pPrintCallbackUserdata, PrintColor); } } } diff --git a/src/engine/shared/console.h b/src/engine/shared/console.h index 7cf26724c..b1888b2f4 100644 --- a/src/engine/shared/console.h +++ b/src/engine/shared/console.h @@ -218,7 +218,7 @@ public: virtual int RegisterPrintCallback(int OutputLevel, FPrintCallback pfnPrintCallback, void *pUserData); virtual void SetPrintOutputLevel(int Index, int OutputLevel); virtual char *Format(char *pBuf, int Size, const char *pFrom, const char *pStr); - virtual void Print(int Level, const char *pFrom, const char *pStr, bool Highlighted = false); + virtual void Print(int Level, const char *pFrom, const char *pStr, ColorRGBA PrintColor = {1, 1, 1, 1}); virtual void SetTeeHistorianCommandCallback(FTeeHistorianCommandCallback pfnCallback, void *pUser); void SetAccessLevel(int AccessLevel) { m_AccessLevel = clamp(AccessLevel, (int)(ACCESS_LEVEL_ADMIN), (int)(ACCESS_LEVEL_USER)); } diff --git a/src/engine/shared/demo.cpp b/src/engine/shared/demo.cpp index f9a3f0f59..b5102cd03 100644 --- a/src/engine/shared/demo.cpp +++ b/src/engine/shared/demo.cpp @@ -28,6 +28,8 @@ static const unsigned char s_VersionTickCompression = 5; // demo files with this static const int s_LengthOffset = 152; static const int s_NumMarkersOffset = 176; +static const ColorRGBA gs_DemoPrintColor{0.7f, 0.7f, 0.7f, 1.0f}; + CDemoRecorder::CDemoRecorder(class CSnapshotDelta *pSnapshotDelta, bool NoMapData) { m_File = 0; @@ -55,7 +57,7 @@ int CDemoRecorder::Start(class IStorage *pStorage, class IConsole *pConsole, con { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "Unable to open '%s' for recording", pFilename); - m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", aBuf); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", aBuf, gs_DemoPrintColor); } return -1; } @@ -111,7 +113,7 @@ int CDemoRecorder::Start(class IStorage *pStorage, class IConsole *pConsole, con { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "Unable to open mapfile '%s'", pMap); - m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", aBuf); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", aBuf, gs_DemoPrintColor); } return -1; } @@ -179,7 +181,7 @@ int CDemoRecorder::Start(class IStorage *pStorage, class IConsole *pConsole, con { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "Recording to '%s'", pFilename); - m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", aBuf); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", aBuf, gs_DemoPrintColor); } m_File = DemoFile; str_copy(m_aCurrentFilename, pFilename, sizeof(m_aCurrentFilename)); @@ -377,7 +379,7 @@ int CDemoRecorder::Stop() io_close(m_File); m_File = 0; if(m_pConsole) - m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", "Stopped recording"); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", "Stopped recording", gs_DemoPrintColor); return 0; } @@ -398,7 +400,7 @@ void CDemoRecorder::AddDemoMarker() m_aTimelineMarkers[m_NumTimelineMarkers++] = m_LastTickMarker; if(m_pConsole) - m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", "Added timeline marker"); + m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "demo_recorder", "Added timeline marker", gs_DemoPrintColor); } CDemoPlayer::CDemoPlayer(class CSnapshotDelta *pSnapshotDelta) diff --git a/src/engine/shared/econ.cpp b/src/engine/shared/econ.cpp index 2a7412d40..23d0748ed 100644 --- a/src/engine/shared/econ.cpp +++ b/src/engine/shared/econ.cpp @@ -36,7 +36,7 @@ int CEcon::DelClientCallback(int ClientID, const char *pReason, void *pUser) return 0; } -void CEcon::SendLineCB(const char *pLine, void *pUserData, bool Highlighted) +void CEcon::SendLineCB(const char *pLine, void *pUserData, ColorRGBA PrintColor) { static_cast(pUserData)->Send(-1, pLine); } diff --git a/src/engine/shared/econ.h b/src/engine/shared/econ.h index f45aba38a..9c7905fe5 100644 --- a/src/engine/shared/econ.h +++ b/src/engine/shared/econ.h @@ -38,7 +38,7 @@ class CEcon int m_PrintCBIndex; int m_UserClientID; - static void SendLineCB(const char *pLine, void *pUserData, bool Highlighted); + static void SendLineCB(const char *pLine, void *pUserData, ColorRGBA PrintColor = {1, 1, 1, 1}); static void ConchainEconOutputLevelUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); static void ConLogout(IConsole::IResult *pResult, void *pUserData); diff --git a/src/engine/shared/netban.cpp b/src/engine/shared/netban.cpp index f0446037f..3bff68faf 100644 --- a/src/engine/shared/netban.cpp +++ b/src/engine/shared/netban.cpp @@ -434,7 +434,7 @@ void CNetBan::ConBan(IConsole::IResult *pResult, void *pUser) CNetBan *pThis = static_cast(pUser); const char *pStr = pResult->GetString(0); - int Minutes = pResult->NumArguments() > 1 ? clamp(pResult->GetInteger(1), 0, 44640) : 30; + int Minutes = pResult->NumArguments() > 1 ? clamp(pResult->GetInteger(1), 0, 525600) : 30; const char *pReason = pResult->NumArguments() > 2 ? pResult->GetString(2) : "No reason given"; NETADDR Addr; @@ -450,7 +450,7 @@ void CNetBan::ConBanRange(IConsole::IResult *pResult, void *pUser) const char *pStr1 = pResult->GetString(0); const char *pStr2 = pResult->GetString(1); - int Minutes = pResult->NumArguments() > 2 ? clamp(pResult->GetInteger(2), 0, 44640) : 30; + int Minutes = pResult->NumArguments() > 2 ? clamp(pResult->GetInteger(2), 0, 525600) : 30; const char *pReason = pResult->NumArguments() > 3 ? pResult->GetString(3) : "No reason given"; CNetRange Range; diff --git a/src/game/client/components/binds.cpp b/src/game/client/components/binds.cpp index 3e3cedb5b..1ac6d5920 100644 --- a/src/game/client/components/binds.cpp +++ b/src/game/client/components/binds.cpp @@ -4,6 +4,8 @@ #include #include +static const ColorRGBA gs_BindPrintColor{1.0f, 1.0f, 0.8f, 1.0f}; + bool CBinds::CBindsSpecial::OnInput(IInput::CEvent Event) { // only handle F and composed F binds @@ -68,7 +70,7 @@ void CBinds::Bind(int KeyID, const char *pStr, bool FreeOnly, int Modifier) str_copy(m_aapKeyBindings[Modifier][KeyID], pStr, Size); str_format(aBuf, sizeof(aBuf), "bound %s%s (%d) = %s", GetKeyBindModifiersName(Modifier), Input()->KeyName(KeyID), KeyID, m_aapKeyBindings[Modifier][KeyID]); } - Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf); + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf, gs_BindPrintColor); } int CBinds::GetModifierMask(IInput *i) @@ -274,7 +276,7 @@ void CBinds::ConBind(IConsole::IResult *pResult, void *pUserData) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "key %s not found", pBindStr); - pBinds->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf); + pBinds->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf, gs_BindPrintColor); return; } @@ -294,7 +296,7 @@ void CBinds::ConDumpBinds(IConsole::IResult *pResult, void *pUserData) if(!id) { str_format(aBuf, sizeof(aBuf), "key '%s' not found", pKeyName); - pBinds->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf); + pBinds->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf, gs_BindPrintColor); } else { @@ -303,7 +305,7 @@ void CBinds::ConDumpBinds(IConsole::IResult *pResult, void *pUserData) else str_format(aBuf, sizeof(aBuf), "%s (%d) = %s", pKeyName, id, pBinds->m_aapKeyBindings[Modifier][id]); - pBinds->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf); + pBinds->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf, gs_BindPrintColor); } } else if(pResult->NumArguments() == 0) @@ -317,7 +319,7 @@ void CBinds::ConDumpBinds(IConsole::IResult *pResult, void *pUserData) continue; str_format(aBuf, sizeof(aBuf), "%s%s (%d) = %s", GetKeyBindModifiersName(i), pBinds->Input()->KeyName(j), j, pBinds->m_aapKeyBindings[i][j]); - pBinds->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf); + pBinds->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf, gs_BindPrintColor); } } } @@ -334,7 +336,7 @@ void CBinds::ConUnbind(IConsole::IResult *pResult, void *pUserData) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "key %s not found", pKeyName); - pBinds->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf); + pBinds->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf, gs_BindPrintColor); return; } diff --git a/src/game/client/components/broadcast.cpp b/src/game/client/components/broadcast.cpp index c7258a1c9..fa7f4ca09 100644 --- a/src/game/client/components/broadcast.cpp +++ b/src/game/client/components/broadcast.cpp @@ -57,7 +57,7 @@ void CBroadcast::OnMessage(int MsgType, void *pRawMsg) aBuf[ii] = '\0'; ii = 0; if(aBuf[0]) - m_pClient->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "broadcast", aBuf, true); + m_pClient->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "broadcast", aBuf, color_cast(ColorHSLA(g_Config.m_ClMessageHighlightColor))); } else { @@ -67,7 +67,7 @@ void CBroadcast::OnMessage(int MsgType, void *pRawMsg) } aBuf[ii] = '\0'; if(aBuf[0]) - m_pClient->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "broadcast", aBuf, true); + m_pClient->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "broadcast", aBuf, color_cast(ColorHSLA(g_Config.m_ClMessageHighlightColor))); } } } diff --git a/src/game/client/components/chat.cpp b/src/game/client/components/chat.cpp index 9953812db..030ecf9ba 100644 --- a/src/game/client/components/chat.cpp +++ b/src/game/client/components/chat.cpp @@ -663,6 +663,9 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine) bool Highlighted = false; char *p = const_cast(pLine); + bool IsTeamLine = Team == 1; + bool IsWhisperLine = Team >= 2; + // Only empty string left if(*p == 0) return; @@ -676,7 +679,27 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine) char aBuf[1024]; str_format(aBuf, sizeof(aBuf), "%s%s%s", pLine->m_aName, pLine->m_ClientID >= 0 ? ": " : "", pLine->m_aText); - Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, pLine->m_Team >= 2 ? "whisper" : (pLine->m_Team ? "teamchat" : "chat"), aBuf, pLine->m_Highlighted); + + ColorRGBA ChatLogColor{1, 1, 1, 1}; + if(pLine->m_Highlighted) + { + ChatLogColor = color_cast(ColorHSLA(g_Config.m_ClMessageHighlightColor)); + } + else + { + if(pLine->m_Friend && g_Config.m_ClMessageFriend) + ChatLogColor = color_cast(ColorHSLA(g_Config.m_ClMessageFriendColor)); + else if(pLine->m_Team) + ChatLogColor = color_cast(ColorHSLA(g_Config.m_ClMessageTeamColor)); + else if(pLine->m_ClientID == -1) // system + ChatLogColor = color_cast(ColorHSLA(g_Config.m_ClMessageSystemColor)); + else if(pLine->m_ClientID == -2) // client + ChatLogColor = color_cast(ColorHSLA(g_Config.m_ClMessageClientColor)); + else // regular message + ChatLogColor = color_cast(ColorHSLA(g_Config.m_ClMessageColor)); + } + + Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, pLine->m_Whisper ? "whisper" : (pLine->m_Team ? "teamchat" : "chat"), aBuf, ChatLogColor); }; while(*p) @@ -696,7 +719,7 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine) CLine *pCurrentLine = &m_aLines[m_CurrentLine]; // If it's a client message, m_aText will have ": " prepended so we have to work around it. - if(pCurrentLine->m_Team == Team && pCurrentLine->m_ClientID == ClientID && str_comp(pCurrentLine->m_aText, pLine) == 0) + if(pCurrentLine->m_Team == IsTeamLine && pCurrentLine->m_Whisper == IsWhisperLine && pCurrentLine->m_ClientID == ClientID && str_comp(pCurrentLine->m_aText, pLine) == 0) { pCurrentLine->m_TimesRepeated++; if(pCurrentLine->m_TextContainerIndex != -1) @@ -722,7 +745,8 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine) pCurrentLine->m_YOffset[0] = -1.0f; pCurrentLine->m_YOffset[1] = -1.0f; pCurrentLine->m_ClientID = ClientID; - pCurrentLine->m_Team = Team; + pCurrentLine->m_Team = IsTeamLine; + pCurrentLine->m_Whisper = IsWhisperLine; pCurrentLine->m_NameColor = -2; if(pCurrentLine->m_TextContainerIndex != -1) @@ -779,7 +803,6 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine) str_format(pCurrentLine->m_aName, sizeof(pCurrentLine->m_aName), "→ %s", m_pClient->m_aClients[ClientID].m_aName); pCurrentLine->m_NameColor = TEAM_BLUE; pCurrentLine->m_Highlighted = false; - pCurrentLine->m_Team = 0; Highlighted = false; } else if(Team == 3) // whisper recv @@ -787,7 +810,6 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine) str_format(pCurrentLine->m_aName, sizeof(pCurrentLine->m_aName), "← %s", m_pClient->m_aClients[ClientID].m_aName); pCurrentLine->m_NameColor = TEAM_RED; pCurrentLine->m_Highlighted = true; - pCurrentLine->m_Team = 0; Highlighted = true; } else diff --git a/src/game/client/components/chat.h b/src/game/client/components/chat.h index 99011514e..f3ec5bc1f 100644 --- a/src/game/client/components/chat.h +++ b/src/game/client/components/chat.h @@ -25,7 +25,8 @@ class CChat : public CComponent int64 m_Time; float m_YOffset[2]; int m_ClientID; - int m_Team; + bool m_Team; + bool m_Whisper; int m_NameColor; char m_aName[64]; char m_aText[512]; diff --git a/src/game/client/components/console.cpp b/src/game/client/components/console.cpp index a9da593ec..1e66fabf7 100644 --- a/src/game/client/components/console.cpp +++ b/src/game/client/components/console.cpp @@ -337,7 +337,7 @@ void CGameConsole::CInstance::OnInput(IInput::CEvent Event) } } -void CGameConsole::CInstance::PrintLine(const char *pLine, bool Highlighted) +void CGameConsole::CInstance::PrintLine(const char *pLine, ColorRGBA PrintColor) { int Len = str_length(pLine); @@ -346,7 +346,7 @@ void CGameConsole::CInstance::PrintLine(const char *pLine, bool Highlighted) CBacklogEntry *pEntry = m_Backlog.Allocate(sizeof(CBacklogEntry) + Len); pEntry->m_YOffset = -1.0f; - pEntry->m_Highlighted = Highlighted; + pEntry->m_PrintColor = PrintColor; mem_copy(pEntry->m_aText, pLine, Len); pEntry->m_aText[Len] = 0; } @@ -639,8 +639,6 @@ void CGameConsole::OnRender() } } - ColorRGBA rgb = color_cast(ColorHSLA(g_Config.m_ClMessageHighlightColor)); - // render log (actual page, wrap lines) CInstance::CBacklogEntry *pEntry = pConsole->m_Backlog.Last(); float OffsetY = 0.0f; @@ -650,10 +648,7 @@ void CGameConsole::OnRender() { while(pEntry) { - if(pEntry->m_Highlighted) - TextRender()->TextColor(rgb); - else - TextRender()->TextColor(1, 1, 1, 1); + TextRender()->TextColor(pEntry->m_PrintColor); // get y offset (calculate it if we haven't yet) if(pEntry->m_YOffset < 0.0f) @@ -826,9 +821,9 @@ void CGameConsole::ConDumpRemoteConsole(IConsole::IResult *pResult, void *pUserD ((CGameConsole *)pUserData)->Dump(CONSOLETYPE_REMOTE); } -void CGameConsole::ClientConsolePrintCallback(const char *pStr, void *pUserData, bool Highlighted) +void CGameConsole::ClientConsolePrintCallback(const char *pStr, void *pUserData, ColorRGBA PrintColor) { - ((CGameConsole *)pUserData)->m_LocalConsole.PrintLine(pStr, Highlighted); + ((CGameConsole *)pUserData)->m_LocalConsole.PrintLine(pStr, PrintColor); } void CGameConsole::ConConsolePageUp(IConsole::IResult *pResult, void *pUserData) diff --git a/src/game/client/components/console.h b/src/game/client/components/console.h index a13d5887e..b02060a79 100644 --- a/src/game/client/components/console.h +++ b/src/game/client/components/console.h @@ -22,7 +22,7 @@ class CGameConsole : public CComponent struct CBacklogEntry { float m_YOffset; - bool m_Highlighted; + ColorRGBA m_PrintColor; char m_aText[1]; }; CStaticRingBuffer m_Backlog; @@ -61,7 +61,7 @@ class CGameConsole : public CComponent void ExecuteLine(const char *pLine); void OnInput(IInput::CEvent Event); - void PrintLine(const char *pLine, bool Highlighted = false); + void PrintLine(const char *pLine, ColorRGBA PrintColor = {1, 1, 1, 1}); const char *GetString() const { return m_Input.GetString(); } static void PossibleCommandsCompleteCallback(const char *pStr, void *pUser); @@ -85,7 +85,7 @@ class CGameConsole : public CComponent void Dump(int Type); static void PossibleCommandsRenderCallback(const char *pStr, void *pUser); - static void ClientConsolePrintCallback(const char *pStr, void *pUserData, bool Highlighted); + static void ClientConsolePrintCallback(const char *pStr, void *pUserData, ColorRGBA PrintColor = {1, 1, 1, 1}); static void ConToggleLocalConsole(IConsole::IResult *pResult, void *pUserData); static void ConToggleRemoteConsole(IConsole::IResult *pResult, void *pUserData); static void ConClearLocalConsole(IConsole::IResult *pResult, void *pUserData); diff --git a/src/game/client/components/motd.cpp b/src/game/client/components/motd.cpp index b5ef4ce5a..29b92a601 100644 --- a/src/game/client/components/motd.cpp +++ b/src/game/client/components/motd.cpp @@ -80,14 +80,14 @@ void CMotd::OnMessage(int MsgType, void *pRawMsg) if(g_Config.m_ClPrintMotd && m_aServerMotd[k] == '\n') { m_aServerMotd[k] = '\0'; - m_pClient->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "motd", pLast, true); + m_pClient->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "motd", pLast, color_cast(ColorHSLA(g_Config.m_ClMessageHighlightColor))); m_aServerMotd[k] = '\n'; pLast = m_aServerMotd + k + 1; } } m_aServerMotd[sizeof(m_aServerMotd) - 1] = '\0'; if(g_Config.m_ClPrintMotd && *pLast != '\0') - m_pClient->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "motd", pLast, true); + m_pClient->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "motd", pLast, color_cast(ColorHSLA(g_Config.m_ClMessageHighlightColor))); if(m_aServerMotd[0] && g_Config.m_ClMotdTime) m_ServerMotdTime = time() + time_freq() * g_Config.m_ClMotdTime; diff --git a/src/game/ddracechat.h b/src/game/ddracechat.h index 3c7a49a1f..1d9999777 100644 --- a/src/game/ddracechat.h +++ b/src/game/ddracechat.h @@ -35,8 +35,8 @@ CHAT_COMMAND("teamrank", "?r[player name]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConTe CHAT_COMMAND("rank", "?r[player name]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConRank, this, "Shows the rank of player with name r (your rank by default)") CHAT_COMMAND("top5team", "?s[player name] ?i[rank to start with]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConTeamTop5, this, "Shows five team ranks of the ladder or of a player beginning with rank i (1 by default, -1 for worst)") CHAT_COMMAND("teamtop5", "?s[player name] ?i[rank to start with]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConTeamTop5, this, "Shows five team ranks of the ladder or of a player beginning with rank i (1 by default, -1 for worst)") -CHAT_COMMAND("top", "?i[rank to start with]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConTop, this, "Shows five ranks of the global and regional ladder beginning with rank i (1 by default, -1 for worst)") -CHAT_COMMAND("top5", "?i[rank to start with]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConTop, this, "Shows five ranks of the global and regional ladder beginning with rank i (1 by default, -1 for worst)") +CHAT_COMMAND("top", "?i[rank to start with]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConTop, this, "Shows the top ranks of the global and regional ladder beginning with rank i (1 by default, -1 for worst)") +CHAT_COMMAND("top5", "?i[rank to start with]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConTop, this, "Shows the top ranks of the global and regional ladder beginning with rank i (1 by default, -1 for worst)") CHAT_COMMAND("times", "?s[player name] ?i[number of times to skip]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConTimes, this, "/times ?s?i shows last 5 times of the server or of a player beginning with name s starting with time i (i = 1 by default, -1 for first)") CHAT_COMMAND("points", "?r[player name]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConPoints, this, "Shows the global points of a player beginning with name r (your rank by default)") CHAT_COMMAND("top5points", "?i[number]", CFGFLAG_CHAT | CFGFLAG_SERVER, ConTopPoints, this, "Shows five points of the global point ladder beginning with rank i (1 by default)") diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index dc68ce22a..715377c62 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -3635,14 +3635,14 @@ void CGameContext::SendChatResponseAll(const char *pLine, void *pUser) if(*pLine == '[') do pLine++; - while((pLine - 2 < pLineOrig || *(pLine - 2) != ':') && *pLine != 0); //remove the category (e.g. [Console]: No Such Command) + while((pLine - 2 < pLineOrig || *(pLine - 2) != ':') && *pLine != 0); // remove the category (e.g. [Console]: No Such Command) pSelf->SendChat(-1, CHAT_ALL, pLine); ReentryGuard--; } -void CGameContext::SendChatResponse(const char *pLine, void *pUser, bool Highlighted) +void CGameContext::SendChatResponse(const char *pLine, void *pUser, ColorRGBA PrintColor) { CGameContext *pSelf = (CGameContext *)pUser; int ClientID = pSelf->m_ChatResponseTargetID; diff --git a/src/game/server/gamecontext.h b/src/game/server/gamecontext.h index f68a33f9d..8cc37ed1a 100644 --- a/src/game/server/gamecontext.h +++ b/src/game/server/gamecontext.h @@ -448,7 +448,7 @@ public: inline bool IsSpecVote() const { return m_VoteType == VOTE_TYPE_SPECTATE; }; void SendRecord(int ClientID); - static void SendChatResponse(const char *pLine, void *pUser, bool Highlighted = false); + static void SendChatResponse(const char *pLine, void *pUser, ColorRGBA PrintColor = {1, 1, 1, 1}); static void SendChatResponseAll(const char *pLine, void *pUser); virtual void OnSetAuthed(int ClientID, int Level); virtual bool PlayerCollision(); diff --git a/src/game/server/player.cpp b/src/game/server/player.cpp index 6571ad9bc..24f2a9855 100644 --- a/src/game/server/player.cpp +++ b/src/game/server/player.cpp @@ -933,18 +933,13 @@ void CPlayer::ProcessScoreResult(CScorePlayerResult &Result) } break; case CScorePlayerResult::ALL: - { - int MessageClientId = m_ClientID; for(auto &aMessage : Result.m_Data.m_aaMessages) { if(aMessage[0] == 0) break; - - GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aMessage, MessageClientId); - MessageClientId = -1; // Prevent multi-messages being flagged as spam. + GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aMessage, m_ClientID); } break; - } case CScorePlayerResult::BROADCAST: if(Result.m_Data.m_Broadcast[0] != 0) GameServer()->SendBroadcast(Result.m_Data.m_Broadcast, -1); diff --git a/src/game/server/score.cpp b/src/game/server/score.cpp index 3e0dff4e9..0e01c9ec0 100644 --- a/src/game/server/score.cpp +++ b/src/game/server/score.cpp @@ -975,9 +975,9 @@ bool CScore::ShowTopThread(IDbConnection *pSqlServer, const ISqlData *pGameData, // check sort method char aBuf[512]; str_format(aBuf, sizeof(aBuf), - "SELECT Name, Time, Rank " + "SELECT Name, Time, Rank, Server " "FROM (" - " SELECT RANK() OVER w AS Rank, Name, MIN(Time) AS Time " + " SELECT RANK() OVER w AS Rank, Name, MIN(Time) AS Time, Server " " FROM %s_race " " WHERE Map = ? " " AND Server LIKE ? " @@ -985,7 +985,7 @@ bool CScore::ShowTopThread(IDbConnection *pSqlServer, const ISqlData *pGameData, " WINDOW w AS (ORDER BY Time)" ") as a " "ORDER BY Rank %s " - "LIMIT %d, 3;", + "LIMIT %d, ?;", pSqlServer->GetPrefix(), pOrder, LimitStart); @@ -996,40 +996,17 @@ bool CScore::ShowTopThread(IDbConnection *pSqlServer, const ISqlData *pGameData, } pSqlServer->BindString(1, pData->m_Map); pSqlServer->BindString(2, pAny); + pSqlServer->BindInt(3, 6); // show top - str_copy(pResult->m_Data.m_aaMessages[0], "-----------< Global Top 3 >-----------", sizeof(pResult->m_Data.m_aaMessages[0])); - - char aTime[32]; - int Line = 1; - bool End = false; - while(!pSqlServer->Step(&End, pError, ErrorSize) && !End) - { - char aName[MAX_NAME_LENGTH]; - pSqlServer->GetString(1, aName, sizeof(aName)); - float Time = pSqlServer->GetFloat(2); - str_time_float(Time, TIME_HOURS_CENTISECS, aTime, sizeof(aTime)); - int Rank = pSqlServer->GetInt(3); - str_format(pResult->m_Data.m_aaMessages[Line], sizeof(pResult->m_Data.m_aaMessages[Line]), - "%d. %s Time: %s", Rank, aName, aTime); - Line++; - } - - char aServerLike[16]; - str_format(aServerLike, sizeof(aServerLike), "%%%s%%", pData->m_Server); - - if(pSqlServer->PrepareStatement(aBuf, pError, ErrorSize)) - { - return true; - } - pSqlServer->BindString(1, pData->m_Map); - pSqlServer->BindString(2, aServerLike); - - str_format(pResult->m_Data.m_aaMessages[Line], sizeof(pResult->m_Data.m_aaMessages[Line]), - "-----------< %s Top 3 >-----------", pData->m_Server); + int Line = 0; + str_copy(pResult->m_Data.m_aaMessages[Line], "------------ Global Top ------------", sizeof(pResult->m_Data.m_aaMessages[Line])); Line++; - // show top + char aTime[32]; + bool End = false; + bool HasLocal = false; + while(!pSqlServer->Step(&End, pError, ErrorSize) && !End) { char aName[MAX_NAME_LENGTH]; @@ -1039,8 +1016,56 @@ bool CScore::ShowTopThread(IDbConnection *pSqlServer, const ISqlData *pGameData, int Rank = pSqlServer->GetInt(3); str_format(pResult->m_Data.m_aaMessages[Line], sizeof(pResult->m_Data.m_aaMessages[Line]), "%d. %s Time: %s", Rank, aName, aTime); + + char aRecordServer[6]; + pSqlServer->GetString(4, aRecordServer, sizeof(aRecordServer)); + + HasLocal = HasLocal || str_comp(aRecordServer, pData->m_Server) == 0; + Line++; + + if(!HasLocal && Line == 4) + { + break; + } } + + if(!HasLocal) + { + char aServerLike[16]; + str_format(aServerLike, sizeof(aServerLike), "%%%s%%", pData->m_Server); + + if(pSqlServer->PrepareStatement(aBuf, pError, ErrorSize)) + { + return true; + } + pSqlServer->BindString(1, pData->m_Map); + pSqlServer->BindString(2, aServerLike); + pSqlServer->BindInt(3, 3); + + str_format(pResult->m_Data.m_aaMessages[Line], sizeof(pResult->m_Data.m_aaMessages[Line]), + "------------ %s Top ------------", pData->m_Server); + Line++; + + // show top + while(!pSqlServer->Step(&End, pError, ErrorSize) && !End) + { + char aName[MAX_NAME_LENGTH]; + pSqlServer->GetString(1, aName, sizeof(aName)); + float Time = pSqlServer->GetFloat(2); + str_time_float(Time, TIME_HOURS_CENTISECS, aTime, sizeof(aTime)); + int Rank = pSqlServer->GetInt(3); + str_format(pResult->m_Data.m_aaMessages[Line], sizeof(pResult->m_Data.m_aaMessages[Line]), + "%d. %s Time: %s", Rank, aName, aTime); + Line++; + } + } + else + { + str_copy(pResult->m_Data.m_aaMessages[Line], "---------------------------------------", + sizeof(pResult->m_Data.m_aaMessages[Line])); + } + if(!End) { return true;