diff --git a/datasrc/network.py b/datasrc/network.py index 893e83f2e..6b6849703 100644 --- a/datasrc/network.py +++ b/datasrc/network.py @@ -246,6 +246,7 @@ Messages = [ NetMessage("Sv_Chat", [ NetIntRange("m_Mode", 0, 'NUM_CHATS-1'), NetIntRange("m_ClientID", -1, 'MAX_CLIENTS-1'), + NetIntRange("m_TargetID", -1, 'MAX_CLIENTS-1'), NetStringStrict("m_pMessage"), ]), diff --git a/src/game/client/components/chat.cpp b/src/game/client/components/chat.cpp index e7204707a..6cf3c1b78 100644 --- a/src/game/client/components/chat.cpp +++ b/src/game/client/components/chat.cpp @@ -359,11 +359,11 @@ void CChat::OnMessage(int MsgType, void *pRawMsg) if(MsgType == NETMSGTYPE_SV_CHAT) { CNetMsg_Sv_Chat *pMsg = (CNetMsg_Sv_Chat *)pRawMsg; - AddLine(pMsg->m_ClientID, pMsg->m_Mode, pMsg->m_pMessage); + AddLine(pMsg->m_ClientID, pMsg->m_Mode, pMsg->m_pMessage, pMsg->m_TargetID); } } -void CChat::AddLine(int ClientID, int Mode, const char *pLine) +void CChat::AddLine(int ClientID, int Mode, const char *pLine, int TargetID) { if(*pLine == 0 || (ClientID != -1 && (!g_Config.m_ClShowsocial || m_pClient->m_aClients[ClientID].m_aName[0] == '\0' || // unknown client m_pClient->m_aClients[ClientID].m_ChatIgnore || @@ -419,6 +419,7 @@ void CChat::AddLine(int ClientID, int Mode, const char *pLine) m_aLines[m_CurrentLine].m_Size[0].y = -1.0f; m_aLines[m_CurrentLine].m_Size[1].y = -1.0f; m_aLines[m_CurrentLine].m_ClientID = ClientID; + m_aLines[m_CurrentLine].m_TargetID = TargetID; m_aLines[m_CurrentLine].m_Mode = Mode; m_aLines[m_CurrentLine].m_NameColor = -2; @@ -790,34 +791,27 @@ void CChat::OnRender() } char aBuf[48]; - if(Line.m_Mode == CHAT_TEAM) - { - TextColor = ColorTeamPre; - str_format(aBuf, sizeof(aBuf), "[%s] ", Localize("Team")); - TextRender()->TextShadowed(&Cursor, aBuf, -1, ShadowOffset, ShadowColor, TextColor); - } - else if(Line.m_Mode == CHAT_WHISPER) + if(Line.m_Mode == CHAT_WHISPER) { TextColor = ColorWhisper; ShadowColor = ShadowWhisper; - str_format(aBuf, sizeof(aBuf), "[%s] ", Localize("Whisper")); + const int LocalCID = m_pClient->m_LocalClientID; + if(Line.m_ClientID == LocalCID && Line.m_TargetID >= 0) + { + str_format(aBuf, sizeof(aBuf), "%s [%s] ", Localize("To"), + m_pClient->m_aClients[Line.m_TargetID].m_aName); + } + else if(Line.m_TargetID == LocalCID) + { + str_format(aBuf, sizeof(aBuf), "%s [%s] ", Localize("From"), + m_pClient->m_aClients[Line.m_ClientID].m_aName); + } + else + dbg_break(); + TextRender()->TextShadowed(&Cursor, aBuf, -1, ShadowOffset, ShadowColor, TextColor); } - - // we have to break protocol to make that work - // CNetMsg_Sv_Chat needs a TargetID, like Cl_Chat -#if 0 - if(line.m_Mode == CHAT_WHISPER) - { - TextColor = vec4(1.0f, 0.5f, 0.9f, Blend); - if(line.m_ClientID == m_pClient->m_LocalClientID) - TextRender()->TextEx(&Cursor, "To ", -1); - else - TextRender()->TextEx(&Cursor, "From ", -1); - } -#endif - // render name if(Line.m_ClientID == -1) TextColor = ColorSystem; diff --git a/src/game/client/components/chat.h b/src/game/client/components/chat.h index 8f62ca324..aac6a558c 100644 --- a/src/game/client/components/chat.h +++ b/src/game/client/components/chat.h @@ -20,6 +20,7 @@ class CChat : public CComponent int64 m_Time; vec2 m_Size[2]; int m_ClientID; + int m_TargetID; int m_Mode; int m_NameColor; char m_aName[64]; @@ -74,7 +75,7 @@ public: bool IsActive() const { return m_Mode != CHAT_NONE; } - void AddLine(int ClientID, int Team, const char *pLine); + void AddLine(int ClientID, int Team, const char *pLine, int TargetID = -1); void EnableMode(int Team); diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index 21ee3e3ed..0e4461d29 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -214,6 +214,7 @@ void CGameContext::SendChat(int ChatterClientID, int Mode, int To, const char *p Msg.m_Mode = Mode; Msg.m_ClientID = ChatterClientID; Msg.m_pMessage = pText; + Msg.m_TargetID = -1; if(Mode == CHAT_ALL) Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, -1); @@ -234,6 +235,7 @@ void CGameContext::SendChat(int ChatterClientID, int Mode, int To, const char *p else // Mode == CHAT_WHISPER { // send to the clients + Msg.m_TargetID = To; Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, ChatterClientID); Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, To); } @@ -432,7 +434,7 @@ void CGameContext::SwapTeams() { if(!m_pController->IsTeamplay()) return; - + SendGameMsg(GAMEMSG_TEAM_SWAP, -1); for(int i = 0; i < MAX_CLIENTS; ++i) @@ -601,7 +603,7 @@ void CGameContext::OnClientEnter(int ClientID) NewClientInfoMsg.m_aUseCustomColors[p] = m_apPlayers[ClientID]->m_TeeInfos.m_aUseCustomColors[p]; NewClientInfoMsg.m_aSkinPartColors[p] = m_apPlayers[ClientID]->m_TeeInfos.m_aSkinPartColors[p]; } - + for(int i = 0; i < MAX_CLIENTS; ++i) { @@ -646,7 +648,7 @@ void CGameContext::OnClientEnter(int ClientID) void CGameContext::OnClientConnected(int ClientID, bool Dummy) { m_apPlayers[ClientID] = new(ClientID) CPlayer(this, ClientID, Dummy); - + if(Dummy) return; @@ -679,7 +681,7 @@ void CGameContext::OnClientDrop(int ClientID, const char *pReason) Msg.m_pReason = pReason; Server()->SendPackMsg(&Msg, MSGFLAG_NOSEND, -1); } - + CNetMsg_Sv_ClientDrop Msg; Msg.m_ClientID = ClientID; Msg.m_pReason = pReason; @@ -719,13 +721,13 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) return; CNetMsg_Cl_Say *pMsg = (CNetMsg_Cl_Say *)pRawMsg; - + // trim right and set maximum length to 128 utf8-characters int Length = 0; const char *p = pMsg->m_pMessage; const char *pEnd = 0; while(*p) - { + { const char *pStrOld = p; int Code = str_utf8_decode(&p); @@ -744,7 +746,7 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) *(const_cast(p)) = 0; break; } - } + } if(pEnd != 0) *(const_cast(pEnd)) = 0; @@ -786,7 +788,7 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) (pPlayer->m_LastVoteCall && pPlayer->m_LastVoteCall+Server()->TickSpeed()*VOTE_COOLDOWN > Now))) || pPlayer->GetTeam() == TEAM_SPECTATORS || m_VoteCloseTime) return; - + pPlayer->m_LastVoteTry = Now; } @@ -911,7 +913,7 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) CNetMsg_Cl_SetTeam *pMsg = (CNetMsg_Cl_SetTeam *)pRawMsg; if(pPlayer->GetTeam() == pMsg->m_Team || - (g_Config.m_SvSpamprotection && pPlayer->m_LastSetTeam && pPlayer->m_LastSetTeam+Server()->TickSpeed()*3 > Server()->Tick()) || + (g_Config.m_SvSpamprotection && pPlayer->m_LastSetTeam && pPlayer->m_LastSetTeam+Server()->TickSpeed()*3 > Server()->Tick()) || (pMsg->m_Team != TEAM_SPECTATORS && m_LockTeams) || pPlayer->m_TeamChangeTick > Server()->Tick()) return; @@ -1155,7 +1157,7 @@ void CGameContext::ConShuffleTeams(IConsole::IResult *pResult, void *pUserData) rnd = PlayerTeam % 2 ? random_int() % 2 : 0; for(int i = 0; i < PlayerTeam; i++) - pSelf->m_pController->DoTeamChange(pSelf->m_apPlayers[aPlayer[i]], i < (PlayerTeam+rnd)/2 ? TEAM_RED : TEAM_BLUE, false); + pSelf->m_pController->DoTeamChange(pSelf->m_apPlayers[aPlayer[i]], i < (PlayerTeam+rnd)/2 ? TEAM_RED : TEAM_BLUE, false); } void CGameContext::ConLockTeams(IConsole::IResult *pResult, void *pUserData)