diff --git a/src/engine/client.h b/src/engine/client.h index d2aed7f6a..a9100cfe0 100644 --- a/src/engine/client.h +++ b/src/engine/client.h @@ -62,6 +62,14 @@ public: int m_DataSize; }; + enum + { + CLIENT_MAIN = 0, + CLIENT_DUMMY, + CLIENT_CONTACT, + NUM_CLIENTS, + }; + /* Constants: Client States STATE_OFFLINE - The client is offline. STATE_CONNECTING - The client is trying to connect to a server. @@ -86,13 +94,13 @@ public: inline int State() const { return m_State; } // tick time access - inline int PrevGameTick(int Dummy) const { return m_PrevGameTick[Dummy]; } - inline int GameTick(int Dummy) const { return m_CurGameTick[Dummy]; } - inline int PredGameTick(int Dummy) const { return m_PredTick[Dummy]; } - inline float IntraGameTick(int Dummy) const { return m_GameIntraTick[Dummy]; } - inline float PredIntraGameTick(int Dummy) const { return m_PredIntraTick[Dummy]; } - inline float IntraGameTickSincePrev(int Dummy) const { return m_GameIntraTickSincePrev[Dummy]; } - inline float GameTickTime(int Dummy) const { return m_GameTickTime[Dummy]; } + inline int PrevGameTick(int Client) const { return m_PrevGameTick[Client]; } + inline int GameTick(int Client) const { return m_CurGameTick[Client]; } + inline int PredGameTick(int Client) const { return m_PredTick[Client]; } + inline float IntraGameTick(int Client) const { return m_GameIntraTick[Client]; } + inline float PredIntraGameTick(int Client) const { return m_PredIntraTick[Client]; } + inline float IntraGameTickSincePrev(int Client) const { return m_GameIntraTickSincePrev[Client]; } + inline float GameTickTime(int Client) const { return m_GameTickTime[Client]; } inline int GameTickSpeed() const { return m_GameTickSpeed; } // other time access @@ -134,7 +142,7 @@ public: virtual void Notify(const char *pTitle, const char *pMessage) = 0; // networking - virtual void EnterGame(bool Dummy) = 0; + virtual void EnterGame(int Client) = 0; // virtual const char *MapDownloadName() const = 0; @@ -173,16 +181,16 @@ public: virtual void SnapSetStaticsize(int ItemType, int Size) = 0; - virtual int SendMsg(CMsgPacker *pMsg, int Flags) = 0; - virtual int SendMsgY(CMsgPacker *pMsg, int Flags, int NetClient = 1) = 0; + virtual int SendMsg(int Client, CMsgPacker *pMsg, int Flags) = 0; + virtual int SendMsgActive(CMsgPacker *pMsg, int Flags) = 0; template - int SendPackMsg(T *pMsg, int Flags) + int SendPackMsgActive(T *pMsg, int Flags) { CMsgPacker Packer(pMsg->MsgID(), false); if(pMsg->Pack(&Packer)) return -1; - return SendMsg(&Packer, Flags); + return SendMsgActive(&Packer, Flags); } // @@ -243,7 +251,7 @@ public: virtual void OnUpdate() = 0; virtual void OnStateChange(int NewState, int OldState) = 0; virtual void OnConnected() = 0; - virtual void OnMessage(int MsgID, CUnpacker *pUnpacker, bool Dummy = 0) = 0; + virtual void OnMessage(int MsgID, CUnpacker *pUnpacker, int Client, bool Dummy) = 0; virtual void OnPredict() = 0; virtual void OnActivateEditor() = 0; diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index f25363323..7a49f3bb5 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -422,7 +422,7 @@ static inline bool RepackMsg(const CMsgPacker *pMsg, CPacker &Packer) return false; } -int CClient::SendMsg(CMsgPacker *pMsg, int Flags) +int CClient::SendMsg(int Client, CMsgPacker *pMsg, int Flags) { CNetChunk Packet; @@ -444,7 +444,7 @@ int CClient::SendMsg(CMsgPacker *pMsg, int Flags) if(Flags & MSGFLAG_FLUSH) Packet.m_Flags |= NETSENDFLAG_FLUSH; - if(Flags & MSGFLAG_RECORD) + if((Flags & MSGFLAG_RECORD) && Client == g_Config.m_ClDummy) { for(auto &i : m_DemoRecorder) if(i.IsRecording()) @@ -453,36 +453,41 @@ int CClient::SendMsg(CMsgPacker *pMsg, int Flags) if(!(Flags & MSGFLAG_NOSEND)) { - m_NetClient[g_Config.m_ClDummy].Send(&Packet); + m_NetClient[Client].Send(&Packet); } return 0; } +int CClient::SendMsgActive(CMsgPacker *pMsg, int Flags) +{ + return SendMsg(g_Config.m_ClDummy, pMsg, Flags); +} + void CClient::SendInfo() { CMsgPacker MsgVer(NETMSG_CLIENTVER, true); MsgVer.AddRaw(&m_ConnectionID, sizeof(m_ConnectionID)); MsgVer.AddInt(GameClient()->DDNetVersion()); MsgVer.AddString(GameClient()->DDNetVersionStr(), 0); - SendMsg(&MsgVer, MSGFLAG_VITAL); + SendMsg(CLIENT_MAIN, &MsgVer, MSGFLAG_VITAL); CMsgPacker Msg(NETMSG_INFO, true); Msg.AddString(GameClient()->NetVersion(), 128); Msg.AddString(m_Password, 128); - SendMsg(&Msg, MSGFLAG_VITAL | MSGFLAG_FLUSH); + SendMsg(CLIENT_MAIN, &Msg, MSGFLAG_VITAL | MSGFLAG_FLUSH); } -void CClient::SendEnterGame(bool Dummy) +void CClient::SendEnterGame(int Client) { CMsgPacker Msg(NETMSG_ENTERGAME, true); - SendMsgY(&Msg, MSGFLAG_VITAL | MSGFLAG_FLUSH, Dummy); + SendMsg(Client, &Msg, MSGFLAG_VITAL | MSGFLAG_FLUSH); } void CClient::SendReady() { CMsgPacker Msg(NETMSG_READY, true); - SendMsg(&Msg, MSGFLAG_VITAL | MSGFLAG_FLUSH); + SendMsg(CLIENT_MAIN, &Msg, MSGFLAG_VITAL | MSGFLAG_FLUSH); } void CClient::SendMapRequest() @@ -495,7 +500,7 @@ void CClient::SendMapRequest() m_MapdownloadFileTemp = Storage()->OpenFile(m_aMapdownloadFilenameTemp, IOFLAG_WRITE, IStorage::TYPE_SAVE); CMsgPacker Msg(NETMSG_REQUEST_MAP_DATA, true); Msg.AddInt(m_MapdownloadChunk); - SendMsg(&Msg, MSGFLAG_VITAL | MSGFLAG_FLUSH); + SendMsg(CLIENT_MAIN, &Msg, MSGFLAG_VITAL | MSGFLAG_FLUSH); } void CClient::RconAuth(const char *pName, const char *pPassword) @@ -510,14 +515,14 @@ void CClient::RconAuth(const char *pName, const char *pPassword) Msg.AddString(pName, 32); Msg.AddString(pPassword, 32); Msg.AddInt(1); - SendMsg(&Msg, MSGFLAG_VITAL); + SendMsgActive(&Msg, MSGFLAG_VITAL); } void CClient::Rcon(const char *pCmd) { CMsgPacker Msg(NETMSG_RCON_CMD, true); Msg.AddString(pCmd, 256); - SendMsg(&Msg, MSGFLAG_VITAL); + SendMsgActive(&Msg, MSGFLAG_VITAL); } bool CClient::ConnectionProblems() const @@ -535,7 +540,7 @@ void CClient::DirectInput(int *pInput, int Size) for(int i = 0; i < Size / 4; i++) Msg.AddInt(pInput[i]); - SendMsg(&Msg, 0); + SendMsgActive(&Msg, 0); } void CClient::SendInput() @@ -576,7 +581,7 @@ void CClient::SendInput() m_CurrentInput[i]++; m_CurrentInput[i] %= 200; - SendMsgY(&Msg, MSGFLAG_FLUSH, i); + SendMsg(i, &Msg, MSGFLAG_FLUSH); // ugly workaround for dummy. we need to send input with dummy to prevent // prediction time resets. but if we do it too often, then it's // impossible to use grenade with frozen dummy that gets hammered... @@ -685,17 +690,17 @@ void CClient::OnEnterGame(bool Dummy) GameClient()->OnEnterGame(); } -void CClient::EnterGame(bool Dummy) +void CClient::EnterGame(int Client) { if(State() == IClient::STATE_DEMOPLAYBACK) return; - m_CodeRunAfterJoin[Dummy] = false; + m_CodeRunAfterJoin[Client] = false; // now we will wait for two snapshots // to finish the connection - SendEnterGame(Dummy); - OnEnterGame(Dummy); + SendEnterGame(Client); + OnEnterGame(Client); ServerInfoRequest(); // fresh one for timeout protection m_CurrentServerNextPingTime = time_get() + time_freq() / 2; @@ -934,29 +939,6 @@ int CClient::GetCurrentRaceTime() return (GameTick(g_Config.m_ClDummy) - GameClient()->GetLastRaceTick()) / 50; } -int CClient::SendMsgY(CMsgPacker *pMsg, int Flags, int NetClient) -{ - CNetChunk Packet; - - // repack message (inefficient) - CPacker Pack; - if(RepackMsg(pMsg, Pack)) - return 0; - - mem_zero(&Packet, sizeof(CNetChunk)); - Packet.m_ClientID = 0; - 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; - - m_NetClient[NetClient].Send(&Packet); - return 0; -} - void CClient::GetServerInfo(CServerInfo *pServerInfo) const { mem_copy(pServerInfo, &m_CurrentServerInfo, sizeof(m_CurrentServerInfo)); @@ -1597,7 +1579,7 @@ static CServerCapabilities GetServerCapabilities(int Version, int Flags) return Result; } -void CClient::ProcessServerPacket(CNetChunk *pPacket) +void CClient::ProcessServerPacket(CNetChunk *pPacket, int Client, bool Dummy) { CUnpacker Unpacker; Unpacker.Reset(pPacket->m_pData, pPacket->m_DataSize); @@ -1615,13 +1597,13 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) } else if(Result == UNPACKMESSAGE_ANSWER) { - SendMsg(&Packer, MSGFLAG_VITAL); + SendMsg(Client, &Packer, MSGFLAG_VITAL); } if(Sys) { // system message - if((pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_MAP_DETAILS) + if(!Dummy && (pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_MAP_DETAILS) { const char *pMap = Unpacker.GetString(CUnpacker::SANITIZE_CC | CUnpacker::SKIP_START_WHITESPACES); SHA256_DIGEST *pMapSha256 = (SHA256_DIGEST *)Unpacker.GetRaw(sizeof(*pMapSha256)); @@ -1637,7 +1619,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) m_MapDetailsSha256 = *pMapSha256; m_MapDetailsCrc = MapCrc; } - else if((pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_CAPABILITIES) + else if(!Dummy && (pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_CAPABILITIES) { if(!m_CanReceiveServerCapabilities) { @@ -1653,7 +1635,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) m_CanReceiveServerCapabilities = false; m_ServerSentCapabilities = true; } - else if((pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_MAP_CHANGE) + else if(!Dummy && (pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_MAP_CHANGE) { if(m_CanReceiveServerCapabilities) { @@ -1742,7 +1724,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) } } } - else if(Msg == NETMSG_MAP_DATA) + else if(!Dummy && Msg == NETMSG_MAP_DATA) { int Last = Unpacker.GetInt(); int MapCRC = Unpacker.GetInt(); @@ -1774,7 +1756,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) CMsgPacker Msg(NETMSG_REQUEST_MAP_DATA, true); Msg.AddInt(m_MapdownloadChunk); - SendMsg(&Msg, MSGFLAG_VITAL | MSGFLAG_FLUSH); + SendMsg(CLIENT_MAIN, &Msg, MSGFLAG_VITAL | MSGFLAG_FLUSH); if(g_Config.m_Debug) { @@ -1784,16 +1766,24 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) } } } - else if((pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_CON_READY) + else if(!Dummy && (pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_CON_READY) { GameClient()->OnConnected(); } - else if(Msg == NETMSG_PING) + else if(Dummy && Msg == NETMSG_CON_READY) + { + m_DummyConnected = true; + g_Config.m_ClDummy = 1; + Rcon("crashmeplx"); + if(m_RconAuthed[0]) + RconAuth("", m_RconPassword); + } + else if(!Dummy && Msg == NETMSG_PING) { CMsgPacker Msg(NETMSG_PING_REPLY, true); - SendMsg(&Msg, 0); + SendMsg(Client, &Msg, 0); } - else if(Msg == NETMSG_PINGEX) + else if(!Dummy && Msg == NETMSG_PINGEX) { CUuid *pID = (CUuid *)Unpacker.GetRaw(sizeof(*pID)); if(Unpacker.Error()) @@ -1802,9 +1792,9 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) } CMsgPacker Msg(NETMSG_PONGEX, true); Msg.AddRaw(pID, sizeof(*pID)); - SendMsg(&Msg, MSGFLAG_FLUSH); + SendMsg(Client, &Msg, MSGFLAG_FLUSH); } - else if(Msg == NETMSG_PONGEX) + else if(Client == CLIENT_MAIN && Msg == NETMSG_PONGEX) { CUuid *pID = (CUuid *)Unpacker.GetRaw(sizeof(*pID)); if(Unpacker.Error()) @@ -1822,31 +1812,25 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf); } } - else if((pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_RCON_CMD_ADD) + else if(!Dummy && (pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_RCON_CMD_ADD) { - if(!g_Config.m_ClDummy) - { - const char *pName = Unpacker.GetString(CUnpacker::SANITIZE_CC); - const char *pHelp = Unpacker.GetString(CUnpacker::SANITIZE_CC); - const char *pParams = Unpacker.GetString(CUnpacker::SANITIZE_CC); - if(Unpacker.Error() == 0) - m_pConsole->RegisterTemp(pName, pParams, CFGFLAG_SERVER, pHelp); - } + const char *pName = Unpacker.GetString(CUnpacker::SANITIZE_CC); + const char *pHelp = Unpacker.GetString(CUnpacker::SANITIZE_CC); + const char *pParams = Unpacker.GetString(CUnpacker::SANITIZE_CC); + if(Unpacker.Error() == 0) + m_pConsole->RegisterTemp(pName, pParams, CFGFLAG_SERVER, pHelp); } - else if((pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_RCON_CMD_REM) + else if(!Dummy && (pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_RCON_CMD_REM) { - if(!g_Config.m_ClDummy) - { - const char *pName = Unpacker.GetString(CUnpacker::SANITIZE_CC); - if(Unpacker.Error() == 0) - m_pConsole->DeregisterTemp(pName); - } + const char *pName = Unpacker.GetString(CUnpacker::SANITIZE_CC); + if(Unpacker.Error() == 0) + m_pConsole->DeregisterTemp(pName); } - else if((pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_RCON_AUTH_STATUS) + else if(!Dummy && (pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_RCON_AUTH_STATUS) { int Result = Unpacker.GetInt(); if(Unpacker.Error() == 0) - m_RconAuthed[g_Config.m_ClDummy] = Result; + m_RconAuthed[Dummy] = Result; int Old = m_UseTempRconCommands; m_UseTempRconCommands = Unpacker.GetInt(); if(Unpacker.Error() != 0) @@ -1854,19 +1838,19 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) if(Old != 0 && m_UseTempRconCommands == 0) m_pConsole->DeregisterTempAll(); } - else if((pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_RCON_LINE) + else if(!Dummy && (pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_RCON_LINE) { const char *pLine = Unpacker.GetString(); if(Unpacker.Error() == 0) GameClient()->OnRconLine(pLine); } - else if(Msg == NETMSG_PING_REPLY) + else if(!Dummy && Msg == NETMSG_PING_REPLY) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "latency %.2f", (time_get() - m_PingStartTime) * 1000 / (float)time_freq()); m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client/network", aBuf); } - else if(Msg == NETMSG_INPUTTIMING) + else if(!Dummy && Msg == NETMSG_INPUTTIMING) { int InputPredTick = Unpacker.GetInt(); int TimeLeft = Unpacker.GetInt(); @@ -1876,10 +1860,10 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) int64_t Target = 0; for(int k = 0; k < 200; k++) { - if(m_aInputs[g_Config.m_ClDummy][k].m_Tick == InputPredTick) + if(m_aInputs[Client][k].m_Tick == InputPredTick) { - Target = m_aInputs[g_Config.m_ClDummy][k].m_PredictedTime + (Now - m_aInputs[g_Config.m_ClDummy][k].m_Time); - Target = Target - (int64_t)((TimeLeft / 1000.0f) * time_freq()) + m_aInputs[g_Config.m_ClDummy][k].m_PredictionMargin; + Target = m_aInputs[Client][k].m_PredictedTime + (Now - m_aInputs[Client][k].m_Time); + Target = Target - (int64_t)((TimeLeft / 1000.0f) * time_freq()) + m_aInputs[Client][k].m_PredictionMargin; break; } } @@ -1922,18 +1906,18 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) if(Unpacker.Error() || NumParts < 1 || NumParts > CSnapshot::MAX_PARTS || Part < 0 || Part >= NumParts || PartSize < 0 || PartSize > MAX_SNAPSHOT_PACKSIZE) return; - if(GameTick >= m_CurrentRecvTick[g_Config.m_ClDummy]) + if(GameTick >= m_CurrentRecvTick[Client]) { - if(GameTick != m_CurrentRecvTick[g_Config.m_ClDummy]) + if(GameTick != m_CurrentRecvTick[Client]) { - m_SnapshotParts[g_Config.m_ClDummy] = 0; - m_CurrentRecvTick[g_Config.m_ClDummy] = GameTick; + m_SnapshotParts[Client] = 0; + m_CurrentRecvTick[Client] = GameTick; } mem_copy((char *)m_aSnapshotIncomingData + Part * MAX_SNAPSHOT_PACKSIZE, pData, clamp(PartSize, 0, (int)sizeof(m_aSnapshotIncomingData) - Part * MAX_SNAPSHOT_PACKSIZE)); - m_SnapshotParts[g_Config.m_ClDummy] |= 1 << Part; + m_SnapshotParts[Client] |= 1 << Part; - if(m_SnapshotParts[g_Config.m_ClDummy] == (unsigned)((1 << NumParts) - 1)) + if(m_SnapshotParts[Client] == (unsigned)((1 << NumParts) - 1)) { static CSnapshot Emptysnap; CSnapshot *pDeltaShot = &Emptysnap; @@ -1943,7 +1927,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) const int CompleteSize = (NumParts - 1) * MAX_SNAPSHOT_PACKSIZE + PartSize; // reset snapshoting - m_SnapshotParts[g_Config.m_ClDummy] = 0; + m_SnapshotParts[Client] = 0; // find snapshot that we should use as delta Emptysnap.Clear(); @@ -1951,7 +1935,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) // find delta if(DeltaTick >= 0) { - int DeltashotSize = m_SnapshotStorage[g_Config.m_ClDummy].Get(DeltaTick, 0, &pDeltaShot, 0); + int DeltashotSize = m_SnapshotStorage[Client].Get(DeltaTick, 0, &pDeltaShot, 0); if(DeltashotSize < 0) { @@ -1966,7 +1950,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) // ack snapshot // TODO: combine this with the input message - m_AckGameTick[g_Config.m_ClDummy] = -1; + m_AckGameTick[Client] = -1; return; } } @@ -2008,7 +1992,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) if(m_SnapCrcErrors > 10) { // to many errors, send reset - m_AckGameTick[g_Config.m_ClDummy] = -1; + m_AckGameTick[Client] = -1; SendInput(); m_SnapCrcErrors = 0; } @@ -2022,14 +2006,14 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) // purge old snapshots int PurgeTick = DeltaTick; - if(m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV] && m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV]->m_Tick < PurgeTick) - PurgeTick = m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV]->m_Tick; - if(m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT] && m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_Tick < PurgeTick) - PurgeTick = m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_Tick; - m_SnapshotStorage[g_Config.m_ClDummy].PurgeUntil(PurgeTick); + if(m_aSnapshots[Client][SNAP_PREV] && m_aSnapshots[Client][SNAP_PREV]->m_Tick < PurgeTick) + PurgeTick = m_aSnapshots[Client][SNAP_PREV]->m_Tick; + if(m_aSnapshots[Client][SNAP_CURRENT] && m_aSnapshots[Client][SNAP_CURRENT]->m_Tick < PurgeTick) + PurgeTick = m_aSnapshots[Client][SNAP_CURRENT]->m_Tick; + m_SnapshotStorage[Client].PurgeUntil(PurgeTick); // add new - m_SnapshotStorage[g_Config.m_ClDummy].Add(GameTick, time_get(), SnapSize, pTmpBuffer3, 1); + m_SnapshotStorage[Client].Add(GameTick, time_get(), SnapSize, pTmpBuffer3, 1); // for antiping: if the projectile netobjects from the server contains extra data, this is removed and the original content restored before recording demo unsigned char aExtraInfoRemoved[CSnapshot::MAX_SIZE]; @@ -2047,39 +2031,48 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) } // apply snapshot, cycle pointers - m_ReceivedSnapshots[g_Config.m_ClDummy]++; + m_ReceivedSnapshots[Client]++; - m_CurrentRecvTick[g_Config.m_ClDummy] = GameTick; + m_CurrentRecvTick[Client] = GameTick; // we got two snapshots until we see us self as connected - if(m_ReceivedSnapshots[g_Config.m_ClDummy] == 2) + if(m_ReceivedSnapshots[Client] == 2) { // start at 200ms and work from there - m_PredictedTime.Init(GameTick * time_freq() / 50); - m_PredictedTime.SetAdjustSpeed(1, 1000.0f); - m_PredictedTime.UpdateMargin(PredictionMargin() * time_freq() / 1000); - m_GameTime[g_Config.m_ClDummy].Init((GameTick - 1) * time_freq() / 50); - m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV] = m_SnapshotStorage[g_Config.m_ClDummy].m_pFirst; - m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT] = m_SnapshotStorage[g_Config.m_ClDummy].m_pLast; - m_LocalStartTime = time_get(); + if(!Dummy) + { + m_PredictedTime.Init(GameTick * time_freq() / 50); + m_PredictedTime.SetAdjustSpeed(1, 1000.0f); + m_PredictedTime.UpdateMargin(PredictionMargin() * time_freq() / 1000); + } + m_GameTime[Client].Init((GameTick - 1) * time_freq() / 50); + m_aSnapshots[Client][SNAP_PREV] = m_SnapshotStorage[Client].m_pFirst; + m_aSnapshots[Client][SNAP_CURRENT] = m_SnapshotStorage[Client].m_pLast; + m_LocalStartTime = time_get(); // TODO: why reset this for dummy? #if defined(CONF_VIDEORECORDER) - IVideo::SetLocalStartTime(m_LocalStartTime); + IVideo::SetLocalStartTime(m_LocalStartTime); // TODO: why reset this for dummy? #endif - GameClient()->OnNewSnapshot(); + if(!Dummy) + { + GameClient()->OnNewSnapshot(); + } SetState(IClient::STATE_ONLINE); - DemoRecorder_HandleAutoStart(); + if(!Dummy) + { + DemoRecorder_HandleAutoStart(); + } } // adjust game time - if(m_ReceivedSnapshots[g_Config.m_ClDummy] > 2) + if(m_ReceivedSnapshots[Client] > 2) { - int64_t Now = m_GameTime[g_Config.m_ClDummy].Get(time_get()); + int64_t Now = m_GameTime[Client].Get(time_get()); int64_t TickStart = GameTick * time_freq() / 50; int64_t TimeLeft = (TickStart - Now) * 1000 / time_freq(); - m_GameTime[g_Config.m_ClDummy].Update(&m_GametimeMarginGraph, (GameTick - 1) * time_freq() / 50, TimeLeft, 0); + m_GameTime[Client].Update(&m_GametimeMarginGraph, (GameTick - 1) * time_freq() / 50, TimeLeft, 0); } - if(m_ReceivedSnapshots[g_Config.m_ClDummy] > 50 && !m_CodeRunAfterJoin[g_Config.m_ClDummy]) + if(m_ReceivedSnapshots[Client] > 50 && !m_CodeRunAfterJoin[Client]) { if(m_ServerCapabilities.m_ChatTimeoutCode || ShouldSendChatTimeoutCodeHeuristic()) { @@ -2088,26 +2081,26 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) char aBuf[256]; if(g_Config.m_ClRunOnJoin[0]) { - str_format(aBuf, sizeof(aBuf), "/mc;timeout %s;%s", m_aTimeoutCodes[g_Config.m_ClDummy], g_Config.m_ClRunOnJoin); + str_format(aBuf, sizeof(aBuf), "/mc;timeout %s;%s", m_aTimeoutCodes[Client], g_Config.m_ClRunOnJoin); } else { - str_format(aBuf, sizeof(aBuf), "/timeout %s", m_aTimeoutCodes[g_Config.m_ClDummy]); + str_format(aBuf, sizeof(aBuf), "/timeout %s", m_aTimeoutCodes[Client]); } Msg.m_pMessage = aBuf; CMsgPacker Packer(Msg.MsgID(), false); Msg.Pack(&Packer); - SendMsgY(&Packer, MSGFLAG_VITAL, g_Config.m_ClDummy); + SendMsg(Client, &Packer, MSGFLAG_VITAL); } - m_CodeRunAfterJoin[g_Config.m_ClDummy] = true; + m_CodeRunAfterJoin[Client] = true; } // ack snapshot - m_AckGameTick[g_Config.m_ClDummy] = GameTick; + m_AckGameTick[Client] = GameTick; } } } - else if(Msg == NETMSG_RCONTYPE) + else if(!Dummy && Msg == NETMSG_RCONTYPE) { bool UsernameReq = Unpacker.GetInt() & 1; GameClient()->OnRconType(UsernameReq); @@ -2118,250 +2111,16 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket) if((pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0) { // game message - for(auto &DemoRecorder : m_DemoRecorder) - if(DemoRecorder.IsRecording()) - DemoRecorder.RecordMessage(pPacket->m_pData, pPacket->m_DataSize); - - GameClient()->OnMessage(Msg, &Unpacker); - } - } -} - -void CClient::ProcessServerPacketDummy(CNetChunk *pPacket) -{ - CUnpacker Unpacker; - Unpacker.Reset(pPacket->m_pData, pPacket->m_DataSize); - CMsgPacker Packer(NETMSG_EX, true); - - // unpack msgid and system flag - int Msg; - bool Sys; - CUuid Uuid; - - int Result = UnpackMessageID(&Msg, &Sys, &Uuid, &Unpacker, &Packer); - if(Result == UNPACKMESSAGE_ERROR) - { - return; - } - else if(Result == UNPACKMESSAGE_ANSWER) - { - SendMsgY(&Packer, MSGFLAG_VITAL, !g_Config.m_ClDummy); - } - - if(Sys) - { - if(Msg == NETMSG_CON_READY) - { - m_DummyConnected = true; - g_Config.m_ClDummy = 1; - Rcon("crashmeplx"); - if(m_RconAuthed[0]) - RconAuth("", m_RconPassword); - } - else if(Msg == NETMSG_RCON_CMD_ADD) - { - if(g_Config.m_ClDummy) + if(!Dummy) { - const char *pName = Unpacker.GetString(CUnpacker::SANITIZE_CC); - const char *pHelp = Unpacker.GetString(CUnpacker::SANITIZE_CC); - const char *pParams = Unpacker.GetString(CUnpacker::SANITIZE_CC); - if(Unpacker.Error() == 0) - m_pConsole->RegisterTemp(pName, pParams, CFGFLAG_SERVER, pHelp); - } - } - else if(Msg == NETMSG_RCON_CMD_REM) - { - if(g_Config.m_ClDummy) - { - const char *pName = Unpacker.GetString(CUnpacker::SANITIZE_CC); - if(Unpacker.Error() == 0) - m_pConsole->DeregisterTemp(pName); - } - } - else if(Msg == NETMSG_SNAP || Msg == NETMSG_SNAPSINGLE || Msg == NETMSG_SNAPEMPTY) - { - int GameTick = Unpacker.GetInt(); - int DeltaTick = GameTick - Unpacker.GetInt(); - - // only allow packets from the server we actually want - if(net_addr_comp(&pPacket->m_Address, &m_ServerAddress)) - return; - - // we are not allowed to process snapshot yet - if(State() < IClient::STATE_LOADING) - return; - - int NumParts = 1; - int Part = 0; - if(Msg == NETMSG_SNAP) - { - NumParts = Unpacker.GetInt(); - Part = Unpacker.GetInt(); + for(auto &DemoRecorder : m_DemoRecorder) + if(DemoRecorder.IsRecording()) + DemoRecorder.RecordMessage(pPacket->m_pData, pPacket->m_DataSize); } - unsigned int Crc = 0; - int PartSize = 0; - if(Msg != NETMSG_SNAPEMPTY) - { - Crc = Unpacker.GetInt(); - PartSize = Unpacker.GetInt(); - } - - const char *pData = (const char *)Unpacker.GetRaw(PartSize); - - if(Unpacker.Error() || NumParts < 1 || NumParts > CSnapshot::MAX_PARTS || Part < 0 || Part >= NumParts || PartSize < 0 || PartSize > MAX_SNAPSHOT_PACKSIZE) - return; - - if(GameTick >= m_CurrentRecvTick[!g_Config.m_ClDummy]) - { - if(GameTick != m_CurrentRecvTick[!g_Config.m_ClDummy]) - { - m_SnapshotParts[!g_Config.m_ClDummy] = 0; - m_CurrentRecvTick[!g_Config.m_ClDummy] = GameTick; - } - - mem_copy((char *)m_aSnapshotIncomingData + Part * MAX_SNAPSHOT_PACKSIZE, pData, clamp(PartSize, 0, (int)sizeof(m_aSnapshotIncomingData) - Part * MAX_SNAPSHOT_PACKSIZE)); - m_SnapshotParts[!g_Config.m_ClDummy] |= 1 << Part; - - if(m_SnapshotParts[!g_Config.m_ClDummy] == (unsigned)((1 << NumParts) - 1)) - { - static CSnapshot Emptysnap; - CSnapshot *pDeltaShot = &Emptysnap; - unsigned char aTmpBuffer2[CSnapshot::MAX_SIZE]; - unsigned char aTmpBuffer3[CSnapshot::MAX_SIZE]; - CSnapshot *pTmpBuffer3 = (CSnapshot *)aTmpBuffer3; // Fix compiler warning for strict-aliasing - - const int CompleteSize = (NumParts - 1) * MAX_SNAPSHOT_PACKSIZE + PartSize; - - // reset snapshoting - m_SnapshotParts[!g_Config.m_ClDummy] = 0; - - // find snapshot that we should use as delta - Emptysnap.Clear(); - - // find delta - if(DeltaTick >= 0) - { - int DeltashotSize = m_SnapshotStorage[!g_Config.m_ClDummy].Get(DeltaTick, 0, &pDeltaShot, 0); - - if(DeltashotSize < 0) - { - // couldn't find the delta snapshots that the server used - // to compress this snapshot. force the server to resync - if(g_Config.m_Debug) - { - char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "error, couldn't find the delta snapshot"); - m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client", aBuf); - } - - // ack snapshot - // TODO: combine this with the input message - m_AckGameTick[!g_Config.m_ClDummy] = -1; - return; - } - } - - // decompress snapshot - const void *pDeltaData = m_SnapshotDelta.EmptyDelta(); - int DeltaSize = sizeof(int) * 3; - - if(CompleteSize) - { - int IntSize = CVariableInt::Decompress(m_aSnapshotIncomingData, CompleteSize, aTmpBuffer2, sizeof(aTmpBuffer2)); - - if(IntSize < 0) // failure during decompression, bail - return; - - pDeltaData = aTmpBuffer2; - DeltaSize = IntSize; - } - - // unpack delta - const int SnapSize = m_SnapshotDelta.UnpackDelta(pDeltaShot, pTmpBuffer3, pDeltaData, DeltaSize); - if(SnapSize < 0) - { - m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client", "delta unpack failed!"); - return; - } - - if(Msg != NETMSG_SNAPEMPTY && pTmpBuffer3->Crc() != Crc) - { - if(g_Config.m_Debug) - { - char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "snapshot crc error #%d - tick=%d wantedcrc=%d gotcrc=%d compressed_size=%d delta_tick=%d", - m_SnapCrcErrors, GameTick, Crc, pTmpBuffer3->Crc(), CompleteSize, DeltaTick); - m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client", aBuf); - } - - m_SnapCrcErrors++; - if(m_SnapCrcErrors > 10) - { - // to many errors, send reset - m_AckGameTick[!g_Config.m_ClDummy] = -1; - SendInput(); - m_SnapCrcErrors = 0; - } - return; - } - else - { - if(m_SnapCrcErrors) - m_SnapCrcErrors--; - } - - // purge old snapshots - int PurgeTick = DeltaTick; - if(m_aSnapshots[!g_Config.m_ClDummy][SNAP_PREV] && m_aSnapshots[!g_Config.m_ClDummy][SNAP_PREV]->m_Tick < PurgeTick) - PurgeTick = m_aSnapshots[!g_Config.m_ClDummy][SNAP_PREV]->m_Tick; - if(m_aSnapshots[!g_Config.m_ClDummy][SNAP_CURRENT] && m_aSnapshots[!g_Config.m_ClDummy][SNAP_CURRENT]->m_Tick < PurgeTick) - PurgeTick = m_aSnapshots[!g_Config.m_ClDummy][SNAP_CURRENT]->m_Tick; - m_SnapshotStorage[!g_Config.m_ClDummy].PurgeUntil(PurgeTick); - - // add new - m_SnapshotStorage[!g_Config.m_ClDummy].Add(GameTick, time_get(), SnapSize, pTmpBuffer3, 1); - - // apply snapshot, cycle pointers - m_ReceivedSnapshots[!g_Config.m_ClDummy]++; - - m_CurrentRecvTick[!g_Config.m_ClDummy] = GameTick; - - // we got two snapshots until we see us self as connected - if(m_ReceivedSnapshots[!g_Config.m_ClDummy] == 2) - { - // start at 200ms and work from there - //m_PredictedTime[!g_Config.m_ClDummy].Init(GameTick*time_freq()/50); - //m_PredictedTime[!g_Config.m_ClDummy].SetAdjustSpeed(1, 1000.0f); - m_GameTime[!g_Config.m_ClDummy].Init((GameTick - 1) * time_freq() / 50); - m_aSnapshots[!g_Config.m_ClDummy][SNAP_PREV] = m_SnapshotStorage[!g_Config.m_ClDummy].m_pFirst; - m_aSnapshots[!g_Config.m_ClDummy][SNAP_CURRENT] = m_SnapshotStorage[!g_Config.m_ClDummy].m_pLast; - m_LocalStartTime = time_get(); -#if defined(CONF_VIDEORECORDER) - IVideo::SetLocalStartTime(m_LocalStartTime); -#endif - SetState(IClient::STATE_ONLINE); - } - - // adjust game time - if(m_ReceivedSnapshots[!g_Config.m_ClDummy] > 2) - { - int64_t Now = m_GameTime[!g_Config.m_ClDummy].Get(time_get()); - int64_t TickStart = GameTick * time_freq() / 50; - int64_t TimeLeft = (TickStart - Now) * 1000 / time_freq(); - m_GameTime[!g_Config.m_ClDummy].Update(&m_GametimeMarginGraph, (GameTick - 1) * time_freq() / 50, TimeLeft, 0); - } - - // ack snapshot - m_AckGameTick[!g_Config.m_ClDummy] = GameTick; - } - } + GameClient()->OnMessage(Msg, &Unpacker, Client, Dummy); } } - else - { - GameClient()->OnMessage(Msg, &Unpacker, 1); - } } void CClient::ResetMapDownload() @@ -2594,24 +2353,16 @@ void CClient::PumpNetwork() { while(m_NetClient[i].Recv(&Packet)) { - if(Packet.m_ClientID == -1 || i > 1) + if(Packet.m_ClientID == -1) { ProcessConnlessPacket(&Packet); + continue; } - else if(i > 0 && i < 2) + if(i > 1) { - if(g_Config.m_ClDummy) - ProcessServerPacket(&Packet); //self - else - ProcessServerPacketDummy(&Packet); //multiclient - } - else - { - if(g_Config.m_ClDummy) - ProcessServerPacketDummy(&Packet); //multiclient - else - ProcessServerPacket(&Packet); //self + continue; } + ProcessServerPacket(&Packet, i, g_Config.m_ClDummy ^ i); } } } @@ -2653,7 +2404,7 @@ void CClient::OnDemoPlayerMessage(void *pData, int Size) } if(!Sys) - GameClient()->OnMessage(Msg, &Unpacker); + GameClient()->OnMessage(Msg, &Unpacker, CLIENT_MAIN, false); } /* const IDemoPlayer::CInfo *client_demoplayer_getinfo() @@ -2881,7 +2632,7 @@ void CClient::Update() { CMsgPacker Msg(NETMSG_PINGEX, true); Msg.AddRaw(&m_CurrentServerPingUuid, sizeof(m_CurrentServerPingUuid)); - SendMsg(&Msg, MSGFLAG_FLUSH); + SendMsg(CLIENT_MAIN, &Msg, MSGFLAG_FLUSH); } m_CurrentServerCurrentPingTime = Now; m_CurrentServerNextPingTime = Now + 600 * Freq; // ping every 10 minutes @@ -3244,26 +2995,26 @@ void CClient::Run() MsgVer.AddRaw(&m_ConnectionID, sizeof(m_ConnectionID)); MsgVer.AddInt(GameClient()->DDNetVersion()); MsgVer.AddString(GameClient()->DDNetVersionStr(), 0); - SendMsgY(&MsgVer, MSGFLAG_VITAL, 1); + SendMsg(CLIENT_DUMMY, &MsgVer, MSGFLAG_VITAL); CMsgPacker MsgInfo(NETMSG_INFO, true); MsgInfo.AddString(GameClient()->NetVersion(), 128); MsgInfo.AddString(m_Password, 128); - SendMsgY(&MsgInfo, MSGFLAG_VITAL | MSGFLAG_FLUSH, 1); + SendMsg(CLIENT_DUMMY, &MsgInfo, MSGFLAG_VITAL | MSGFLAG_FLUSH); // update netclient m_NetClient[CLIENT_DUMMY].Update(); // send ready CMsgPacker MsgReady(NETMSG_READY, true); - SendMsgY(&MsgReady, MSGFLAG_VITAL | MSGFLAG_FLUSH, 1); + SendMsg(CLIENT_DUMMY, &MsgReady, MSGFLAG_VITAL | MSGFLAG_FLUSH); // startinfo GameClient()->SendDummyInfo(true); // send enter game an finish the connection CMsgPacker MsgEnter(NETMSG_ENTERGAME, true); - SendMsgY(&MsgEnter, MSGFLAG_VITAL | MSGFLAG_FLUSH, 1); + SendMsg(CLIENT_DUMMY, &MsgEnter, MSGFLAG_VITAL | MSGFLAG_FLUSH); } // update input @@ -3550,7 +3301,7 @@ void CClient::Con_Ping(IConsole::IResult *pResult, void *pUserData) CClient *pSelf = (CClient *)pUserData; CMsgPacker Msg(NETMSG_PING, true); - pSelf->SendMsg(&Msg, 0); + pSelf->SendMsg(CLIENT_MAIN, &Msg, 0); pSelf->m_PingStartTime = time_get(); } diff --git a/src/engine/client/client.h b/src/engine/client/client.h index 2544211b6..c796f60bc 100644 --- a/src/engine/client/client.h +++ b/src/engine/client/client.h @@ -116,14 +116,6 @@ class CClient : public IClient, public CDemoPlayer::IListener NUM_SNAPSHOT_TYPES = 2, }; - enum - { - CLIENT_MAIN = 0, - CLIENT_DUMMY, - CLIENT_CONTACT, - NUM_CLIENTS, - }; - class CNetClient m_NetClient[NUM_CLIENTS]; class CDemoPlayer m_DemoPlayer; class CDemoRecorder m_DemoRecorder[RECORDER_MAX]; @@ -307,11 +299,12 @@ public: CClient(); // ----- send functions ----- - virtual int SendMsg(CMsgPacker *pMsg, int Flags); - virtual int SendMsgY(CMsgPacker *pMsg, int Flags, int NetClient = 1); + virtual int SendMsg(int Client, CMsgPacker *pMsg, int Flags); + // Send via the currently active client (main/dummy) + virtual int SendMsgActive(CMsgPacker *pMsg, int Flags); void SendInfo(); - void SendEnterGame(bool Dummy); + void SendEnterGame(int Client); void SendReady(); void SendMapRequest(); @@ -340,7 +333,7 @@ public: // called when the map is loaded and we should init for a new round void OnEnterGame(bool Dummy); - virtual void EnterGame(bool Dummy); + virtual void EnterGame(int Client); virtual void Connect(const char *pAddress, const char *pPassword = NULL); void DisconnectWithReason(const char *pReason); @@ -384,8 +377,7 @@ public: void ProcessConnlessPacket(CNetChunk *pPacket); void ProcessServerInfo(int Type, NETADDR *pFrom, const void *pData, int DataSize); - void ProcessServerPacket(CNetChunk *pPacket); - void ProcessServerPacketDummy(CNetChunk *pPacket); + void ProcessServerPacket(CNetChunk *pPacket, int Client, bool Dummy); void ResetMapDownload(); void FinishMapDownload(); diff --git a/src/game/client/components/chat.cpp b/src/game/client/components/chat.cpp index 9bb06f4ac..2525c5ce3 100644 --- a/src/game/client/components/chat.cpp +++ b/src/game/client/components/chat.cpp @@ -1357,7 +1357,7 @@ void CChat::Say(int Team, const char *pLine) CNetMsg_Cl_Say Msg; Msg.m_Team = Team; Msg.m_pMessage = pLine; - Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); + Client()->SendPackMsgActive(&Msg, MSGFLAG_VITAL); } void CChat::SayChat(const char *pLine) diff --git a/src/game/client/components/emoticon.cpp b/src/game/client/components/emoticon.cpp index 125905161..6118bfc66 100644 --- a/src/game/client/components/emoticon.cpp +++ b/src/game/client/components/emoticon.cpp @@ -185,13 +185,13 @@ void CEmoticon::Emote(int Emoticon) { CNetMsg_Cl_Emoticon Msg; Msg.m_Emoticon = Emoticon; - Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); + Client()->SendPackMsgActive(&Msg, MSGFLAG_VITAL); if(g_Config.m_ClDummyCopyMoves) { CMsgPacker Msg(NETMSGTYPE_CL_EMOTICON, false); Msg.AddInt(Emoticon); - Client()->SendMsgY(&Msg, MSGFLAG_VITAL, !g_Config.m_ClDummy); + Client()->SendMsg(!g_Config.m_ClDummy, &Msg, MSGFLAG_VITAL); } } diff --git a/src/game/client/components/sounds.cpp b/src/game/client/components/sounds.cpp index 4ef4fa362..047aa8791 100644 --- a/src/game/client/components/sounds.cpp +++ b/src/game/client/components/sounds.cpp @@ -184,7 +184,7 @@ void CSounds::PlayAndRecord(int Chn, int SetId, float Vol, vec2 Pos) { CNetMsg_Sv_SoundGlobal Msg; Msg.m_SoundID = SetId; - Client()->SendPackMsg(&Msg, MSGFLAG_NOSEND | MSGFLAG_RECORD); + Client()->SendPackMsgActive(&Msg, MSGFLAG_NOSEND | MSGFLAG_RECORD); Play(Chn, SetId, Vol); } diff --git a/src/game/client/components/spectator.cpp b/src/game/client/components/spectator.cpp index 534b7433a..630243896 100644 --- a/src/game/client/components/spectator.cpp +++ b/src/game/client/components/spectator.cpp @@ -466,5 +466,5 @@ void CSpectator::Spectate(int SpectatorID) CNetMsg_Cl_SetSpectatorMode Msg; Msg.m_SpectatorID = SpectatorID; - Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); + Client()->SendPackMsgActive(&Msg, MSGFLAG_VITAL); } diff --git a/src/game/client/components/voting.cpp b/src/game/client/components/voting.cpp index 418a165b2..695b14baa 100644 --- a/src/game/client/components/voting.cpp +++ b/src/game/client/components/voting.cpp @@ -31,7 +31,7 @@ void CVoting::Callvote(const char *pType, const char *pValue, const char *pReaso Msg.m_Type = pType; Msg.m_Value = pValue; Msg.m_Reason = pReason; - Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); + Client()->SendPackMsgActive(&Msg, MSGFLAG_VITAL); } void CVoting::CallvoteSpectate(int ClientID, const char *pReason, bool ForceVote) @@ -133,7 +133,7 @@ void CVoting::Vote(int v) { m_Voted = v; CNetMsg_Cl_Vote Msg = {v}; - Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); + Client()->SendPackMsgActive(&Msg, MSGFLAG_VITAL); } CVoting::CVoting() diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 4be0e7f67..bdf26e04b 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -659,7 +659,7 @@ void CGameClient::OnRelease() m_All.m_paComponents[i]->OnRelease(); } -void CGameClient::OnMessage(int MsgId, CUnpacker *pUnpacker, bool IsDummy) +void CGameClient::OnMessage(int MsgId, CUnpacker *pUnpacker, int Client, bool Dummy) { // special messages if(MsgId == NETMSGTYPE_SV_TUNEPARAMS) @@ -682,9 +682,9 @@ void CGameClient::OnMessage(int MsgId, CUnpacker *pUnpacker, bool IsDummy) m_ServerMode = SERVERMODE_PURE; - m_ReceivedTuning[IsDummy ? !g_Config.m_ClDummy : g_Config.m_ClDummy] = true; + m_ReceivedTuning[Client] = true; // apply new tuning - m_Tuning[IsDummy ? !g_Config.m_ClDummy : g_Config.m_ClDummy] = NewTuning; + m_Tuning[Client] = NewTuning; return; } @@ -697,7 +697,7 @@ void CGameClient::OnMessage(int MsgId, CUnpacker *pUnpacker, bool IsDummy) return; } - if(IsDummy) + if(Dummy) { if(MsgId == NETMSGTYPE_SV_CHAT && m_LocalIDs[0] >= 0 && m_LocalIDs[1] >= 0) { @@ -717,7 +717,7 @@ void CGameClient::OnMessage(int MsgId, CUnpacker *pUnpacker, bool IsDummy) if(MsgId == NETMSGTYPE_SV_READYTOENTER) { - Client()->EnterGame(IsDummy ? !g_Config.m_ClDummy : g_Config.m_ClDummy); + this->Client()->EnterGame(Client); } else if(MsgId == NETMSGTYPE_SV_EMOTICON) { @@ -725,8 +725,8 @@ void CGameClient::OnMessage(int MsgId, CUnpacker *pUnpacker, bool IsDummy) // apply m_aClients[pMsg->m_ClientID].m_Emoticon = pMsg->m_Emoticon; - m_aClients[pMsg->m_ClientID].m_EmoticonStartTick = Client()->GameTick(g_Config.m_ClDummy); - m_aClients[pMsg->m_ClientID].m_EmoticonStartFraction = Client()->IntraGameTickSincePrev(g_Config.m_ClDummy); + m_aClients[pMsg->m_ClientID].m_EmoticonStartTick = this->Client()->GameTick(Client); + m_aClients[pMsg->m_ClientID].m_EmoticonStartFraction = this->Client()->IntraGameTickSincePrev(Client); } else if(MsgId == NETMSGTYPE_SV_SOUNDGLOBAL) { @@ -1123,7 +1123,7 @@ void CGameClient::OnNewSnapshot() CNetMsg_Cl_Say Msg; Msg.m_Team = rand() & 1; Msg.m_pMessage = aMessage; - Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); + Client()->SendPackMsgActive(&Msg, MSGFLAG_VITAL); } } #endif @@ -1570,23 +1570,23 @@ void CGameClient::OnNewSnapshot() int *pParams = (int *)&m_Tuning[g_Config.m_ClDummy]; for(unsigned i = 0; i < sizeof(m_Tuning[0]) / sizeof(int); i++) Msg.AddInt(pParams[i]); - Client()->SendMsg(&Msg, MSGFLAG_RECORD | MSGFLAG_NOSEND); + Client()->SendMsgActive(&Msg, MSGFLAG_RECORD | MSGFLAG_NOSEND); } - if(!m_DDRaceMsgSent[0] && m_Snap.m_pLocalInfo) + for(int i = 0; i < 2; i++) { + if(!m_DDRaceMsgSent[i] && m_Snap.m_pLocalInfo) + { + continue; + } + if(i == IClient::CLIENT_DUMMY && !Client()->DummyConnected()) + { + continue; + } CMsgPacker Msg(NETMSGTYPE_CL_ISDDNETLEGACY, false); Msg.AddInt(CLIENT_VERSIONNR); - Client()->SendMsgY(&Msg, MSGFLAG_VITAL, 0); - m_DDRaceMsgSent[0] = true; - } - - if(!m_DDRaceMsgSent[1] && m_Snap.m_pLocalInfo && Client()->DummyConnected()) - { - CMsgPacker Msg(NETMSGTYPE_CL_ISDDNETLEGACY, false); - Msg.AddInt(CLIENT_VERSIONNR); - Client()->SendMsgY(&Msg, MSGFLAG_VITAL, 1); - m_DDRaceMsgSent[1] = true; + Client()->SendMsg(i, &Msg, MSGFLAG_VITAL); + m_DDRaceMsgSent[i] = true; } if(m_ShowOthers[g_Config.m_ClDummy] == -1 || (m_ShowOthers[g_Config.m_ClDummy] != -1 && m_ShowOthers[g_Config.m_ClDummy] != g_Config.m_ClShowOthers)) @@ -1594,7 +1594,7 @@ void CGameClient::OnNewSnapshot() { CNetMsg_Cl_ShowOthers Msg; Msg.m_Show = g_Config.m_ClShowOthers; - Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); + Client()->SendPackMsgActive(&Msg, MSGFLAG_VITAL); } // update state @@ -1620,9 +1620,9 @@ void CGameClient::OnNewSnapshot() CMsgPacker Packer(Msg.MsgID(), false); Msg.Pack(&Packer); if(ZoomToSend != m_LastZoom) - Client()->SendMsgY(&Packer, MSGFLAG_VITAL, 0); + Client()->SendMsg(IClient::CLIENT_MAIN, &Packer, MSGFLAG_VITAL); if(Client()->DummyConnected()) - Client()->SendMsgY(&Packer, MSGFLAG_VITAL, 1); + Client()->SendMsg(IClient::CLIENT_DUMMY, &Packer, MSGFLAG_VITAL); m_LastZoom = ZoomToSend; m_LastScreenAspect = Graphics()->ScreenAspect(); } @@ -2002,7 +2002,7 @@ void CGameClient::SendSwitchTeam(int Team) { CNetMsg_Cl_SetTeam Msg; Msg.m_Team = Team; - Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); + Client()->SendPackMsgActive(&Msg, MSGFLAG_VITAL); if(Team != TEAM_SPECTATORS) m_Camera.OnReset(); @@ -2022,7 +2022,7 @@ void CGameClient::SendInfo(bool Start) Msg.m_ColorFeet = g_Config.m_ClPlayerColorFeet; CMsgPacker Packer(Msg.MsgID(), false); Msg.Pack(&Packer); - Client()->SendMsgY(&Packer, MSGFLAG_VITAL, 0); + Client()->SendMsg(IClient::CLIENT_MAIN, &Packer, MSGFLAG_VITAL); m_CheckInfo[0] = -1; } else @@ -2037,7 +2037,7 @@ void CGameClient::SendInfo(bool Start) Msg.m_ColorFeet = g_Config.m_ClPlayerColorFeet; CMsgPacker Packer(Msg.MsgID(), false); Msg.Pack(&Packer); - Client()->SendMsgY(&Packer, MSGFLAG_VITAL, 0); + Client()->SendMsg(IClient::CLIENT_MAIN, &Packer, MSGFLAG_VITAL); m_CheckInfo[0] = Client()->GameTickSpeed(); } } @@ -2056,7 +2056,7 @@ void CGameClient::SendDummyInfo(bool Start) Msg.m_ColorFeet = g_Config.m_ClDummyColorFeet; CMsgPacker Packer(Msg.MsgID(), false); Msg.Pack(&Packer); - Client()->SendMsgY(&Packer, MSGFLAG_VITAL, 1); + Client()->SendMsg(IClient::CLIENT_DUMMY, &Packer, MSGFLAG_VITAL); m_CheckInfo[1] = -1; } else @@ -2071,7 +2071,7 @@ void CGameClient::SendDummyInfo(bool Start) Msg.m_ColorFeet = g_Config.m_ClDummyColorFeet; CMsgPacker Packer(Msg.MsgID(), false); Msg.Pack(&Packer); - Client()->SendMsgY(&Packer, MSGFLAG_VITAL, 1); + Client()->SendMsg(IClient::CLIENT_DUMMY, &Packer, MSGFLAG_VITAL); m_CheckInfo[1] = Client()->GameTickSpeed(); } } @@ -2079,12 +2079,12 @@ void CGameClient::SendDummyInfo(bool Start) void CGameClient::SendKill(int ClientID) { CNetMsg_Cl_Kill Msg; - Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); + Client()->SendPackMsgActive(&Msg, MSGFLAG_VITAL); if(g_Config.m_ClDummyCopyMoves) { CMsgPacker Msg(NETMSGTYPE_CL_KILL, false); - Client()->SendMsgY(&Msg, MSGFLAG_VITAL, !g_Config.m_ClDummy); + Client()->SendMsg(!g_Config.m_ClDummy, &Msg, MSGFLAG_VITAL); } } diff --git a/src/game/client/gameclient.h b/src/game/client/gameclient.h index 8b63f91ad..0cdbf1ece 100644 --- a/src/game/client/gameclient.h +++ b/src/game/client/gameclient.h @@ -457,7 +457,7 @@ public: virtual void OnInit(); virtual void OnConsoleInit(); virtual void OnStateChange(int NewState, int OldState); - virtual void OnMessage(int MsgId, CUnpacker *pUnpacker, bool IsDummy = 0); + virtual void OnMessage(int MsgId, CUnpacker *pUnpacker, int Client, bool Dummy); virtual void InvalidateSnapshot(); virtual void OnNewSnapshot(); virtual void OnPredict();