From 03070d0567d66978550098b7fc780a1233282127 Mon Sep 17 00:00:00 2001 From: Learath Date: Wed, 10 Jun 2020 19:12:10 +0300 Subject: [PATCH] Fix many issues --- CMakeLists.txt | 2 + src/engine/server/server.cpp | 58 ++++++++----- src/game/server/gamecontext.cpp | 89 ++++++++++++++------ src/game/server/gamecontext.h | 2 +- src/game/server/player.h | 15 +--- src/game/server/teeinfo.cpp | 139 ++++++++++++++++++++++++++++++++ src/game/server/teeinfo.h | 27 +++++++ 7 files changed, 272 insertions(+), 60 deletions(-) create mode 100644 src/game/server/teeinfo.cpp create mode 100644 src/game/server/teeinfo.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a38f1911a..ff0e7b174 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1186,6 +1186,8 @@ set_src(GAME_SERVER GLOB_RECURSE src/game/server teams.h teehistorian.cpp teehistorian.h + teeinfo.cpp + teeinfo.h ) set(GAME_GENERATED_SERVER "src/game/generated/server_data.cpp" diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index ee43384b9..3040174e8 100644 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -708,45 +708,59 @@ int CServer::SendMsg(CMsgPacker *pMsg, int Flags, int ClientID) if(!pMsg) return -1; - // repack message (inefficient) - CPacker Pack; - if(RepackMsg(pMsg, Pack, m_aClients[ClientID].m_Sixup)) - return 0; - mem_zero(&Packet, sizeof(CNetChunk)); - Packet.m_ClientID = ClientID; - Packet.m_pData = Pack.Data(); - Packet.m_DataSize = Pack.Size(); - if(Flags&MSGFLAG_VITAL) Packet.m_Flags |= NETSENDFLAG_VITAL; if(Flags&MSGFLAG_FLUSH) Packet.m_Flags |= NETSENDFLAG_FLUSH; - // write message to demo recorder - if(!(Flags&MSGFLAG_NORECORD)) + if(ClientID < 0) { - if(ClientID > -1) - m_aDemoRecorder[ClientID].RecordMessage(Pack.Data(), Pack.Size()); - m_aDemoRecorder[MAX_CLIENTS].RecordMessage(Pack.Data(), Pack.Size()); - } + CPacker Pack6, Pack7; + if(RepackMsg(pMsg, Pack6, false)) + return -1; + if(RepackMsg(pMsg, Pack7, true)) + return -1; - if(!(Flags&MSGFLAG_NOSEND)) - { - if(ClientID == -1) + // write message to demo recorder + if(!(Flags&MSGFLAG_NORECORD)) + m_aDemoRecorder[MAX_CLIENTS].RecordMessage(Pack6.Data(), Pack6.Size()); + + if(!(Flags&MSGFLAG_NOSEND)) { - // broadcast - int i; - for(i = 0; i < MAX_CLIENTS; i++) + for(int i = 0; i < MAX_CLIENTS; i++) + { if(m_aClients[i].m_State == CClient::STATE_INGAME) { + CPacker *Pack = m_aClients[i].m_Sixup ? &Pack7 : &Pack6; + Packet.m_pData = Pack->Data(); + Packet.m_DataSize = Pack->Size(); Packet.m_ClientID = i; m_NetServer.Send(&Packet); } + } } - else + } + else + { + CPacker Pack; + if(RepackMsg(pMsg, Pack, m_aClients[ClientID].m_Sixup)) + return -1; + + Packet.m_ClientID = ClientID; + Packet.m_pData = Pack.Data(); + Packet.m_DataSize = Pack.Size(); + + if(!(Flags&MSGFLAG_NORECORD)) + { + m_aDemoRecorder[ClientID].RecordMessage(Pack.Data(), Pack.Size()); + m_aDemoRecorder[MAX_CLIENTS].RecordMessage(Pack.Data(), Pack.Size()); + } + + if(!(Flags&MSGFLAG_NOSEND)) m_NetServer.Send(&Packet); } + return 0; } diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index 4d43e9d82..65f38d9c1 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -13,6 +13,7 @@ #include #include #include +#include "teeinfo.h" #include "gamecontext.h" #include #include @@ -1113,25 +1114,28 @@ void CGameContext::OnClientEnter(int ClientID) Server()->ExpireServerInfo(); + CPlayer *pNewPlayer = m_apPlayers[ClientID]; // update client infos (others before local) for(int i = 0; i < MAX_CLIENTS; ++i) { if(i == ClientID || !m_apPlayers[i] || !Server()->ClientIngame(i)) continue; + CPlayer *pPlayer = m_apPlayers[i]; + if(Server()->IsSixup(i)) { // new info for others CMsgPacker NewClientInfoMsg(-protocol7::NETMSGTYPE_SV_CLIENTINFO); // NETMSGTYPE_SV_CLIENTINFO NewClientInfoMsg.AddInt(ClientID); NewClientInfoMsg.AddInt(0); // m_Local - NewClientInfoMsg.AddInt(m_apPlayers[ClientID]->GetTeam()); + NewClientInfoMsg.AddInt(pNewPlayer->GetTeam()); NewClientInfoMsg.AddString(Server()->ClientName(ClientID), -1); NewClientInfoMsg.AddString(Server()->ClientClan(ClientID), -1); NewClientInfoMsg.AddInt(Server()->ClientCountry(ClientID)); - for(int p = 0; p < 6; p++) NewClientInfoMsg.AddString("", -1); - for(int p = 0; p < 6; p++) NewClientInfoMsg.AddInt(0); - for(int p = 0; p < 6; p++) NewClientInfoMsg.AddInt(0); + for(int p = 0; p < 6; p++) NewClientInfoMsg.AddString(pNewPlayer->m_TeeInfos.m_apSkinPartNames[p], -1); + for(int p = 0; p < 6; p++) NewClientInfoMsg.AddInt(pNewPlayer->m_TeeInfos.m_aUseCustomColors[p]); + for(int p = 0; p < 6; p++) NewClientInfoMsg.AddInt(pNewPlayer->m_TeeInfos.m_aSkinPartColors[p]); NewClientInfoMsg.AddInt(0); // m_Silent Server()->SendMsg(&NewClientInfoMsg, MSGFLAG_VITAL|MSGFLAG_NORECORD, i); @@ -1143,13 +1147,13 @@ void CGameContext::OnClientEnter(int ClientID) CMsgPacker ClientInfoMsg(-protocol7::NETMSGTYPE_SV_CLIENTINFO); // NETMSGTYPE_SV_CLIENTINFO ClientInfoMsg.AddInt(i); ClientInfoMsg.AddInt(0); // m_Local - ClientInfoMsg.AddInt(m_apPlayers[i]->GetTeam()); + ClientInfoMsg.AddInt(pPlayer->GetTeam()); ClientInfoMsg.AddString(Server()->ClientName(i), -1); ClientInfoMsg.AddString(Server()->ClientClan(i), -1); ClientInfoMsg.AddInt(Server()->ClientCountry(i)); - for(int p = 0; p < 6; p++) ClientInfoMsg.AddString("", -1); - for(int p = 0; p < 6; p++) ClientInfoMsg.AddInt(0); - for(int p = 0; p < 6; p++) ClientInfoMsg.AddInt(0); + for(int p = 0; p < 6; p++) ClientInfoMsg.AddString(pPlayer->m_TeeInfos.m_apSkinPartNames[p], -1); + for(int p = 0; p < 6; p++) ClientInfoMsg.AddInt(pPlayer->m_TeeInfos.m_aUseCustomColors[p]); + for(int p = 0; p < 6; p++) ClientInfoMsg.AddInt(pPlayer->m_TeeInfos.m_aSkinPartColors[p]); ClientInfoMsg.AddInt(0); // m_Silent Server()->SendMsg(&ClientInfoMsg, MSGFLAG_VITAL|MSGFLAG_NORECORD, ClientID); @@ -1162,13 +1166,13 @@ void CGameContext::OnClientEnter(int ClientID) CMsgPacker SelfClientInfoMsg(-protocol7::NETMSGTYPE_SV_CLIENTINFO); // NETMSGTYPE_SV_CLIENTINFO SelfClientInfoMsg.AddInt(ClientID); SelfClientInfoMsg.AddInt(1); // m_Local - SelfClientInfoMsg.AddInt(m_apPlayers[ClientID]->GetTeam()); + SelfClientInfoMsg.AddInt(pNewPlayer->GetTeam()); SelfClientInfoMsg.AddString(Server()->ClientName(ClientID), -1); SelfClientInfoMsg.AddString(Server()->ClientClan(ClientID), -1); SelfClientInfoMsg.AddInt(Server()->ClientCountry(ClientID)); - for(int p = 0; p < 6; p++) SelfClientInfoMsg.AddString("", -1); - for(int p = 0; p < 6; p++) SelfClientInfoMsg.AddInt(0); - for(int p = 0; p < 6; p++) SelfClientInfoMsg.AddInt(0); + for(int p = 0; p < 6; p++) SelfClientInfoMsg.AddString(pNewPlayer->m_TeeInfos.m_apSkinPartNames[p], -1); + for(int p = 0; p < 6; p++) SelfClientInfoMsg.AddInt(pNewPlayer->m_TeeInfos.m_aUseCustomColors[p]); + for(int p = 0; p < 6; p++) SelfClientInfoMsg.AddInt(pNewPlayer->m_TeeInfos.m_aSkinPartColors[p]); SelfClientInfoMsg.AddInt(0); // m_Silent Server()->SendMsg(&SelfClientInfoMsg, MSGFLAG_VITAL|MSGFLAG_NORECORD, ClientID); @@ -1314,30 +1318,64 @@ void CGameContext::OnClientDDNetVersionKnown(int ClientID) } } -void *CGameContext::SecureUnpackMsg(int *MsgID, CUnpacker *pUnpacker, bool Sixup) +void *CGameContext::PreProcessMsg(int *MsgID, CUnpacker *pUnpacker, int ClientID) { - if(Sixup) + if(Server()->IsSixup(ClientID)) { - using namespace protocol7; - void *pRawMsg = m_NetObjHandler7.SecureUnpackMsg(*MsgID, pUnpacker); if(!pRawMsg) return 0; - static char aRawMsg[1024]; - if(*MsgID == NETMSGTYPE_CL_SAY) + CPlayer *pPlayer = m_apPlayers[ClientID]; + static char s_aRawMsg[1024]; + + if(*MsgID == protocol7::NETMSGTYPE_CL_SAY) { - CNetMsg_Cl_Say *pMsg7 = (CNetMsg_Cl_Say *)pRawMsg; - ::CNetMsg_Cl_Say *pMsg = aRawMsg; + protocol7::CNetMsg_Cl_Say *pMsg7 = (protocol7::CNetMsg_Cl_Say *)pRawMsg; + // Should probably use a placement new to start the lifetime of the object to avoid future weirdness + ::CNetMsg_Cl_Say *pMsg = (::CNetMsg_Cl_Say *)s_aRawMsg; - pMsg->m_Team = pMsg7->m_Mode == CHAT_TEAM; + pMsg->m_Team = pMsg7->m_Mode == protocol7::CHAT_TEAM; pMsg->m_pMessage = pMsg7->m_pMessage; } + else if(*MsgID == protocol7::NETMSGTYPE_CL_STARTINFO) + { + protocol7::CNetMsg_Cl_StartInfo *pMsg7 = (protocol7::CNetMsg_Cl_StartInfo *)pRawMsg; + ::CNetMsg_Cl_StartInfo *pMsg = (::CNetMsg_Cl_StartInfo *)s_aRawMsg; - return pRawMsg; + pMsg->m_pName = pMsg7->m_pName; + pMsg->m_pClan = pMsg7->m_pClan; + pMsg->m_Country = pMsg7->m_Country; + + CTeeInfo Info(pMsg7->m_apSkinPartNames, pMsg7->m_aUseCustomColors, pMsg7->m_aSkinPartColors); + Info.FromSixup(); + pMsg->m_pSkin = Info.m_SkinName; + pMsg->m_UseCustomColor = Info.m_UseCustomColor; + pMsg->m_ColorBody = Info.m_ColorBody; + pMsg->m_ColorFeet = Info.m_ColorFeet; + + pPlayer->m_TeeInfos = Info; + } + else if(*MsgID == protocol7::NETMSGTYPE_CL_SKINCHANGE) + { + protocol7::CNetMsg_Cl_SkinChange *pMsg = (protocol7::CNetMsg_Cl_SkinChange *)pRawMsg; + if(g_Config.m_SvSpamprotection && pPlayer->m_LastChangeInfo && + pPlayer->m_LastChangeInfo + Server()->TickSpeed() * g_Config.m_SvInfoChangeDelay > Server()->Tick()) + return 0; + + CTeeInfo Info(pMsg->m_apSkinPartNames, pMsg->m_aUseCustomColors, pMsg->m_aSkinPartColors); + Info.FromSixup(); + pPlayer->m_TeeInfos = Info; + + return 0; + } + + *MsgID = SevenToSix(*MsgID); + + return s_aRawMsg; } -else + else return m_NetObjHandler.SecureUnpackMsg(*MsgID, pUnpacker); } @@ -1351,7 +1389,8 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) } } - void *pRawMsg = SecureUnpackMsg(&MsgID, pUnpacker, Server()->IsSixup(ClientID)); + void *pRawMsg = PreProcessMsg(&MsgID, pUnpacker, ClientID); + CPlayer *pPlayer = m_apPlayers[ClientID]; if(Server()->ClientIngame(ClientID)) @@ -1885,6 +1924,7 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) pPlayer->m_TeeInfos.m_UseCustomColor = pMsg->m_UseCustomColor; pPlayer->m_TeeInfos.m_ColorBody = pMsg->m_ColorBody; pPlayer->m_TeeInfos.m_ColorFeet = pMsg->m_ColorFeet; + pPlayer->m_TeeInfos.ToSixup(); Server()->ExpireServerInfo(); } @@ -1988,6 +2028,7 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) pPlayer->m_TeeInfos.m_UseCustomColor = pMsg->m_UseCustomColor; pPlayer->m_TeeInfos.m_ColorBody = pMsg->m_ColorBody; pPlayer->m_TeeInfos.m_ColorFeet = pMsg->m_ColorFeet; + pPlayer->m_TeeInfos.ToSixup(); // send clear vote options CNetMsg_Sv_VoteClearOptions ClearMsg; diff --git a/src/game/server/gamecontext.h b/src/game/server/gamecontext.h index d18a895f8..d87e70eb0 100644 --- a/src/game/server/gamecontext.h +++ b/src/game/server/gamecontext.h @@ -226,7 +226,7 @@ public: virtual void OnSnap(int ClientID); virtual void OnPostSnap(); - void *SecureUnpackMsg(int *MsgID, CUnpacker *pUnpacker, bool Sixup); + void *PreProcessMsg(int *MsgID, CUnpacker *pUnpacker, int ClientID); virtual void OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID); virtual void OnClientConnected(int ClientID); diff --git a/src/game/server/player.h b/src/game/server/player.h index 2d2f2e079..4765727a4 100644 --- a/src/game/server/player.h +++ b/src/game/server/player.h @@ -6,6 +6,7 @@ // this include should perhaps be removed #include "entities/character.h" #include "score.h" +#include "teeinfo.h" #include "gamecontext.h" #include @@ -89,19 +90,7 @@ public: int m_SendVoteIndex; - // TODO: clean this up - struct - { - char m_SkinName[64]; - int m_UseCustomColor; - int m_ColorBody; - int m_ColorFeet; - - // 0.7 - char m_apSkinPartNames[6][24]; - bool m_aUseCustomColors[6]; - int m_aSkinPartColors[6]; - } m_TeeInfos; + CTeeInfo m_TeeInfos; int m_DieTick; int m_PreviousDieTick; diff --git a/src/game/server/teeinfo.cpp b/src/game/server/teeinfo.cpp new file mode 100644 index 000000000..64afad514 --- /dev/null +++ b/src/game/server/teeinfo.cpp @@ -0,0 +1,139 @@ +#include + +#include "teeinfo.h" + +struct StdSkin +{ + char m_SkinName[64]; + char m_apSkinPartNames[6][24]; + bool m_aUseCustomColors[6]; + int m_aSkinPartColors[6]; +}; + +static StdSkin g_StdSkins[] = { +{"default",{"standard","","","standard","standard","standard"},{true,false,false,true,true,false},{1798004,0,0,1799582,1869630,0}}, +{"bluekitty",{"kitty","whisker","","standard","standard","standard"},{true,true,false,true,true,false},{8681144,-8229413,0,7885547,7885547,0}}, +{"bluestripe",{"standard","stripes","","standard","standard","standard"},{true,false,false,true,true,false},{10187898,0,0,750848,1944919,0}}, +{"brownbear",{"bear","bear","hair","standard","standard","standard"},{true,true,false,true,true,false},{1082745,-15634776,0,1082745,1147174,0}}, +{"cammo",{"standard","cammo2","","standard","standard","standard"},{true,true,false,true,true,false},{5334342,-11771603,0,750848,1944919,0}}, +{"cammostripes",{"standard","cammostripes","","standard","standard","standard"},{true,true,false,true,true,false},{5334342,-14840320,0,750848,1944919,0}}, +{"coala",{"koala","twinbelly","","standard","standard","standard"},{true,true,false,true,true,false},{184,-15397662,0,184,9765959,0}}, +{"limekitty",{"kitty","whisker","","standard","standard","standard"},{true,true,false,true,true,false},{4612803,-12229920,0,3827951,3827951,0}}, +{"pinky",{"standard","whisker","","standard","standard","standard"},{true,true,false,true,true,false},{15911355,-801066,0,15043034,15043034,0}}, +{"redbopp",{"standard","donny","unibop","standard","standard","standard"},{true,true,true,true,true,false},{16177260,-16590390,16177260,16177260,7624169,0}}, +{"redstripe",{"standard","stripe","","standard","standard","standard"},{true,false,false,true,true,false},{16307835,0,0,184,9765959,0}}, +{"saddo",{"standard","saddo","","standard","standard","standard"},{true,true,false,true,true,false},{7171455,-9685436,0,3640746,5792119,0}}, +{"toptri",{"standard","toptri","","standard","standard","standard"},{true,false,false,true,true,false},{6119331,0,0,3640746,5792119,0}}, +{"twinbop",{"standard","duodonny","twinbopp","standard","standard","standard"},{true,true,true,true,true,false},{15310519,-1600806,15310519,15310519,37600,0}}, +{"twintri",{"standard","twintri","","standard","standard","standard"},{true,true,false,true,true,false},{3447932,-14098717,0,185,9634888,0}}, +{"warpaint",{"standard","warpaint","","standard","standard","standard"},{true,false,false,true,true,false},{1944919,0,0,750337,1944919,0}}}; + +CTeeInfo::CTeeInfo(const char *pSkinName, int UseCustomColor, int ColorBody, int ColorFeet) +{ + str_copy(m_SkinName, pSkinName, sizeof(m_SkinName)); + m_UseCustomColor = UseCustomColor; + m_ColorBody = ColorBody; + m_ColorFeet = ColorFeet; +} + +CTeeInfo::CTeeInfo(const char *pSkinPartNames[6], int *pUseCustomColors, int *pSkinPartColors) +{ + for(int i = 0; i < 6; i++) + { + str_copy(m_apSkinPartNames[i], pSkinPartNames[i], sizeof(m_apSkinPartNames[i])); + m_aUseCustomColors[i] = pUseCustomColors[i]; + m_aSkinPartColors[i] = pSkinPartColors[i]; + } +} + +void CTeeInfo::ToSixup() +{ + // reset to default skin + for(int p = 0; p < 6; p++) + { + str_copy(m_apSkinPartNames[p], g_StdSkins[0].m_apSkinPartNames[p], 24); + m_aUseCustomColors[p] = g_StdSkins[0].m_aUseCustomColors[p]; + m_aSkinPartColors[p] = g_StdSkins[0].m_aSkinPartColors[p]; + } + + // check for std skin + for(int s = 0; s < 16; s++) + { + if(!str_comp(m_SkinName, g_StdSkins[s].m_SkinName)) + { + for(int p = 0; p < 6; p++) + { + str_copy(m_apSkinPartNames[p], g_StdSkins[s].m_apSkinPartNames[p], 24); + m_aUseCustomColors[p] = g_StdSkins[s].m_aUseCustomColors[p]; + m_aSkinPartColors[p] = g_StdSkins[s].m_aSkinPartColors[p]; + } + break; + } + } + + if(m_UseCustomColor) + { + m_aUseCustomColors[0] = true; + m_aUseCustomColors[1] = true; + m_aUseCustomColors[2] = true; + m_aUseCustomColors[3] = true; + m_aUseCustomColors[4] = true; + m_aSkinPartColors[0] = m_ColorBody; + m_aSkinPartColors[1] = 0x22FFFFFF; + m_aSkinPartColors[2] = m_ColorBody; + m_aSkinPartColors[3] = m_ColorBody; + m_aSkinPartColors[4] = m_ColorFeet; + } +} + +void CTeeInfo::FromSixup() +{ + // reset to default skin + str_copy(m_SkinName, "default", sizeof(m_SkinName)); + m_UseCustomColor = false; + m_ColorBody = 0; + m_ColorFeet = 0; + + // check for std skin + for(int s = 0; s < 16; s++) + { + bool match = true; + for(int p = 0; p < 6; p++) + { + if(str_comp(m_apSkinPartNames[p], g_StdSkins[s].m_apSkinPartNames[p]) + || m_aUseCustomColors[p] != g_StdSkins[s].m_aUseCustomColors[p] + || (m_aUseCustomColors[p] && m_aSkinPartColors[p] != g_StdSkins[s].m_aSkinPartColors[p])) + { + match = false; + break; + } + } + if(match) + { + str_copy(m_SkinName, g_StdSkins[s].m_SkinName, sizeof(m_SkinName)); + return; + } + } + + // find closest match + int best_skin; + int best_matches = -1; + for(int s = 0; s < 16; s++) + { + int matches = 0; + for(int p = 0; p < 3; p++) + if(str_comp(m_apSkinPartNames[p], g_StdSkins[s].m_apSkinPartNames[p]) == 0) + matches++; + + if(matches > best_matches) + { + best_matches = matches; + best_skin = s; + } + } + + str_copy(m_SkinName, g_StdSkins[best_skin].m_SkinName, sizeof(m_SkinName)); + m_UseCustomColor = true; + m_ColorBody = m_aUseCustomColors[0] ? m_aSkinPartColors[0] : 255; + m_ColorFeet = m_aUseCustomColors[4] ? m_aSkinPartColors[4] : 255; +} diff --git a/src/game/server/teeinfo.h b/src/game/server/teeinfo.h new file mode 100644 index 000000000..f7b8b774c --- /dev/null +++ b/src/game/server/teeinfo.h @@ -0,0 +1,27 @@ +#ifndef GAME_SERVER_TEEINFO_H +#define GAME_SERVER_TEEINFO_H + +class CTeeInfo +{ +public: + char m_SkinName[64]; + int m_UseCustomColor; + int m_ColorBody; + int m_ColorFeet; + + // 0.7 + char m_apSkinPartNames[6][24]; + bool m_aUseCustomColors[6]; + int m_aSkinPartColors[6]; + + CTeeInfo() = default; + + CTeeInfo(const char *pSkinName, int UseCustomColor, int ColorBody, int ColorFeet); + + // This constructor will assume all arrays are of length 6 + CTeeInfo(const char *pSkinPartNames[6], int *pUseCustomColors, int *pSkinPartColors); + + void FromSixup(); + void ToSixup(); +}; +#endif //GAME_SERVER_TEEINFO_H