Refactor: Distinguish between two concepts previously called "Dummy"

On the one hand variables called "Dummy" would tell us whether the
current action refers to the currently inactive tee ("dummy"). On the
other hand, these variables could tell us whether the current action
refers to the main connection to the server, or the secondary one. The
latter use case is now renamed to "Client", with the choices
`CLIENT_MAIN`, `CLIENT_DUMMY` (and `CLIENT_CONTACT`).

Perhaps better names could be found, especially since `Client` also
refers to the engine client class in the game code.

I tried to not fix bugs unless it would complicate the code.
This commit is contained in:
heinrich5991 2022-01-21 01:54:14 +01:00
parent 670c47fa60
commit 49bc150afd
10 changed files with 191 additions and 440 deletions

View file

@ -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<class T>
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;

View file

@ -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();
}

View file

@ -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();

View file

@ -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)

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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()

View file

@ -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);
}
}

View file

@ -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();