mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Store dummy snapshots for better dummy switching
This commit is contained in:
parent
d57634792d
commit
820926d836
|
@ -315,8 +315,10 @@ CClient::CClient() : m_DemoPlayer(&m_SnapshotDelta), m_DemoRecorder(&m_SnapshotD
|
||||||
m_aServerAddressStr[0] = 0;
|
m_aServerAddressStr[0] = 0;
|
||||||
|
|
||||||
mem_zero(m_aSnapshots, sizeof(m_aSnapshots));
|
mem_zero(m_aSnapshots, sizeof(m_aSnapshots));
|
||||||
m_SnapshotStorage.Init();
|
m_SnapshotStorage[0].Init();
|
||||||
m_RecivedSnapshots = 0;
|
m_SnapshotStorage[1].Init();
|
||||||
|
m_RecivedSnapshots[0] = 0;
|
||||||
|
m_RecivedSnapshots[1] = 0;
|
||||||
|
|
||||||
m_VersionInfo.m_State = CVersionInfo::STATE_INIT;
|
m_VersionInfo.m_State = CVersionInfo::STATE_INIT;
|
||||||
}
|
}
|
||||||
|
@ -577,19 +579,15 @@ void CClient::OnEnterGame()
|
||||||
m_CurrentInput = 0;
|
m_CurrentInput = 0;
|
||||||
|
|
||||||
// reset snapshots
|
// reset snapshots
|
||||||
m_aSnapshots[SNAP_CURRENT] = 0;
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT] = 0;
|
||||||
m_aSnapshots[SNAP_PREV] = 0;
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV] = 0;
|
||||||
m_SnapshotStorage.PurgeAll();
|
m_SnapshotStorage[g_Config.m_ClDummy].PurgeAll();
|
||||||
m_RecivedSnapshots = 0;
|
m_RecivedSnapshots[g_Config.m_ClDummy] = 0;
|
||||||
m_SnapshotParts = 0;
|
m_SnapshotParts = 0;
|
||||||
m_PredTick[0] = 0;
|
m_PredTick[g_Config.m_ClDummy] = 0;
|
||||||
m_PredTick[1] = 0;
|
m_CurrentRecvTick[g_Config.m_ClDummy] = 0;
|
||||||
m_CurrentRecvTick[0] = 0;
|
m_CurGameTick[g_Config.m_ClDummy] = 0;
|
||||||
m_CurrentRecvTick[1] = 0;
|
m_PrevGameTick[g_Config.m_ClDummy] = 0;
|
||||||
m_CurGameTick[0] = 0;
|
|
||||||
m_CurGameTick[1] = 0;
|
|
||||||
m_PrevGameTick[0] = 0;
|
|
||||||
m_PrevGameTick[1] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::EnterGame()
|
void CClient::EnterGame()
|
||||||
|
@ -669,9 +667,9 @@ void CClient::DisconnectWithReason(const char *pReason)
|
||||||
mem_zero(&m_ServerAddress, sizeof(m_ServerAddress));
|
mem_zero(&m_ServerAddress, sizeof(m_ServerAddress));
|
||||||
|
|
||||||
// clear snapshots
|
// clear snapshots
|
||||||
m_aSnapshots[SNAP_CURRENT] = 0;
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT] = 0;
|
||||||
m_aSnapshots[SNAP_PREV] = 0;
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV] = 0;
|
||||||
m_RecivedSnapshots = 0;
|
m_RecivedSnapshots[g_Config.m_ClDummy] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::Disconnect()
|
void CClient::Disconnect()
|
||||||
|
@ -809,8 +807,8 @@ void *CClient::SnapGetItem(int SnapID, int Index, CSnapItem *pItem)
|
||||||
{
|
{
|
||||||
CSnapshotItem *i;
|
CSnapshotItem *i;
|
||||||
dbg_assert(SnapID >= 0 && SnapID < NUM_SNAPSHOT_TYPES, "invalid SnapID");
|
dbg_assert(SnapID >= 0 && SnapID < NUM_SNAPSHOT_TYPES, "invalid SnapID");
|
||||||
i = m_aSnapshots[SnapID]->m_pAltSnap->GetItem(Index);
|
i = m_aSnapshots[g_Config.m_ClDummy][SnapID]->m_pAltSnap->GetItem(Index);
|
||||||
pItem->m_DataSize = m_aSnapshots[SnapID]->m_pAltSnap->GetItemSize(Index);
|
pItem->m_DataSize = m_aSnapshots[g_Config.m_ClDummy][SnapID]->m_pAltSnap->GetItemSize(Index);
|
||||||
pItem->m_Type = i->Type();
|
pItem->m_Type = i->Type();
|
||||||
pItem->m_ID = i->ID();
|
pItem->m_ID = i->ID();
|
||||||
return (void *)i->Data();
|
return (void *)i->Data();
|
||||||
|
@ -820,12 +818,12 @@ void CClient::SnapInvalidateItem(int SnapID, int Index)
|
||||||
{
|
{
|
||||||
CSnapshotItem *i;
|
CSnapshotItem *i;
|
||||||
dbg_assert(SnapID >= 0 && SnapID < NUM_SNAPSHOT_TYPES, "invalid SnapID");
|
dbg_assert(SnapID >= 0 && SnapID < NUM_SNAPSHOT_TYPES, "invalid SnapID");
|
||||||
i = m_aSnapshots[SnapID]->m_pAltSnap->GetItem(Index);
|
i = m_aSnapshots[g_Config.m_ClDummy][SnapID]->m_pAltSnap->GetItem(Index);
|
||||||
if(i)
|
if(i)
|
||||||
{
|
{
|
||||||
if((char *)i < (char *)m_aSnapshots[SnapID]->m_pAltSnap || (char *)i > (char *)m_aSnapshots[SnapID]->m_pAltSnap + m_aSnapshots[SnapID]->m_SnapSize)
|
if((char *)i < (char *)m_aSnapshots[g_Config.m_ClDummy][SnapID]->m_pAltSnap || (char *)i > (char *)m_aSnapshots[g_Config.m_ClDummy][SnapID]->m_pAltSnap + m_aSnapshots[g_Config.m_ClDummy][SnapID]->m_SnapSize)
|
||||||
m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client", "snap invalidate problem");
|
m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client", "snap invalidate problem");
|
||||||
if((char *)i >= (char *)m_aSnapshots[SnapID]->m_pSnap && (char *)i < (char *)m_aSnapshots[SnapID]->m_pSnap + m_aSnapshots[SnapID]->m_SnapSize)
|
if((char *)i >= (char *)m_aSnapshots[g_Config.m_ClDummy][SnapID]->m_pSnap && (char *)i < (char *)m_aSnapshots[g_Config.m_ClDummy][SnapID]->m_pSnap + m_aSnapshots[g_Config.m_ClDummy][SnapID]->m_SnapSize)
|
||||||
m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client", "snap invalidate problem");
|
m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client", "snap invalidate problem");
|
||||||
i->m_TypeAndID = -1;
|
i->m_TypeAndID = -1;
|
||||||
}
|
}
|
||||||
|
@ -836,12 +834,12 @@ void *CClient::SnapFindItem(int SnapID, int Type, int ID)
|
||||||
// TODO: linear search. should be fixed.
|
// TODO: linear search. should be fixed.
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(!m_aSnapshots[SnapID])
|
if(!m_aSnapshots[g_Config.m_ClDummy][SnapID])
|
||||||
return 0x0;
|
return 0x0;
|
||||||
|
|
||||||
for(i = 0; i < m_aSnapshots[SnapID]->m_pSnap->NumItems(); i++)
|
for(i = 0; i < m_aSnapshots[g_Config.m_ClDummy][SnapID]->m_pSnap->NumItems(); i++)
|
||||||
{
|
{
|
||||||
CSnapshotItem *pItem = m_aSnapshots[SnapID]->m_pAltSnap->GetItem(i);
|
CSnapshotItem *pItem = m_aSnapshots[g_Config.m_ClDummy][SnapID]->m_pAltSnap->GetItem(i);
|
||||||
if(pItem->Type() == Type && pItem->ID() == ID)
|
if(pItem->Type() == Type && pItem->ID() == ID)
|
||||||
return (void *)pItem->Data();
|
return (void *)pItem->Data();
|
||||||
}
|
}
|
||||||
|
@ -851,9 +849,9 @@ void *CClient::SnapFindItem(int SnapID, int Type, int ID)
|
||||||
int CClient::SnapNumItems(int SnapID)
|
int CClient::SnapNumItems(int SnapID)
|
||||||
{
|
{
|
||||||
dbg_assert(SnapID >= 0 && SnapID < NUM_SNAPSHOT_TYPES, "invalid SnapID");
|
dbg_assert(SnapID >= 0 && SnapID < NUM_SNAPSHOT_TYPES, "invalid SnapID");
|
||||||
if(!m_aSnapshots[SnapID])
|
if(!m_aSnapshots[g_Config.m_ClDummy][SnapID])
|
||||||
return 0;
|
return 0;
|
||||||
return m_aSnapshots[SnapID]->m_pSnap->NumItems();
|
return m_aSnapshots[g_Config.m_ClDummy][SnapID]->m_pSnap->NumItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::SnapSetStaticsize(int ItemType, int Size)
|
void CClient::SnapSetStaticsize(int ItemType, int Size)
|
||||||
|
@ -1014,7 +1012,7 @@ const char *CClient::LoadMap(const char *pName, const char *pFilename, unsigned
|
||||||
char aBuf[256];
|
char aBuf[256];
|
||||||
str_format(aBuf, sizeof(aBuf), "loaded map '%s'", pFilename);
|
str_format(aBuf, sizeof(aBuf), "loaded map '%s'", pFilename);
|
||||||
m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client", aBuf);
|
m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client", aBuf);
|
||||||
m_RecivedSnapshots = 0;
|
m_RecivedSnapshots[g_Config.m_ClDummy] = 0;
|
||||||
|
|
||||||
str_copy(m_aCurrentMap, pName, sizeof(m_aCurrentMap));
|
str_copy(m_aCurrentMap, pName, sizeof(m_aCurrentMap));
|
||||||
m_CurrentMapCrc = m_pMap->Crc();
|
m_CurrentMapCrc = m_pMap->Crc();
|
||||||
|
@ -1604,9 +1602,9 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket)
|
||||||
// find delta
|
// find delta
|
||||||
if(DeltaTick >= 0)
|
if(DeltaTick >= 0)
|
||||||
{
|
{
|
||||||
int DeltashotSize = m_SnapshotStorage.Get(DeltaTick, 0, &pDeltaShot, 0);
|
int DeltashotSize = m_SnapshotStorage[g_Config.m_ClDummy].Get(DeltaTick, 0, &pDeltaShot, 0);
|
||||||
|
|
||||||
if(DeltashotSize < 0 || g_Config.m_ClDummy != m_LastDummy)
|
if(DeltashotSize < 0)
|
||||||
{
|
{
|
||||||
// couldn't find the delta snapshots that the server used
|
// couldn't find the delta snapshots that the server used
|
||||||
// to compress this snapshot. force the server to resync
|
// to compress this snapshot. force the server to resync
|
||||||
|
@ -1675,14 +1673,14 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket)
|
||||||
|
|
||||||
// purge old snapshots
|
// purge old snapshots
|
||||||
PurgeTick = DeltaTick;
|
PurgeTick = DeltaTick;
|
||||||
if(m_aSnapshots[SNAP_PREV] && m_aSnapshots[SNAP_PREV]->m_Tick < PurgeTick)
|
if(m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV] && m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV]->m_Tick < PurgeTick)
|
||||||
PurgeTick = m_aSnapshots[SNAP_PREV]->m_Tick;
|
PurgeTick = m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV]->m_Tick;
|
||||||
if(m_aSnapshots[SNAP_CURRENT] && m_aSnapshots[SNAP_CURRENT]->m_Tick < PurgeTick)
|
if(m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT] && m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_Tick < PurgeTick)
|
||||||
PurgeTick = m_aSnapshots[SNAP_CURRENT]->m_Tick;
|
PurgeTick = m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_Tick;
|
||||||
m_SnapshotStorage.PurgeUntil(PurgeTick);
|
m_SnapshotStorage[g_Config.m_ClDummy].PurgeUntil(PurgeTick);
|
||||||
|
|
||||||
// add new
|
// add new
|
||||||
m_SnapshotStorage.Add(GameTick, time_get(), SnapSize, pTmpBuffer3, 1);
|
m_SnapshotStorage[g_Config.m_ClDummy].Add(GameTick, time_get(), SnapSize, pTmpBuffer3, 1);
|
||||||
|
|
||||||
// add snapshot to demo
|
// add snapshot to demo
|
||||||
if(m_DemoRecorder.IsRecording())
|
if(m_DemoRecorder.IsRecording())
|
||||||
|
@ -1692,26 +1690,26 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket)
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply snapshot, cycle pointers
|
// apply snapshot, cycle pointers
|
||||||
m_RecivedSnapshots++;
|
m_RecivedSnapshots[g_Config.m_ClDummy]++;
|
||||||
|
|
||||||
m_CurrentRecvTick[g_Config.m_ClDummy] = GameTick;
|
m_CurrentRecvTick[g_Config.m_ClDummy] = GameTick;
|
||||||
|
|
||||||
// we got two snapshots until we see us self as connected
|
// we got two snapshots until we see us self as connected
|
||||||
if(m_RecivedSnapshots == 2)
|
if(m_RecivedSnapshots[g_Config.m_ClDummy] == 2)
|
||||||
{
|
{
|
||||||
// start at 200ms and work from there
|
// start at 200ms and work from there
|
||||||
m_PredictedTime[g_Config.m_ClDummy].Init(GameTick*time_freq()/50);
|
m_PredictedTime[g_Config.m_ClDummy].Init(GameTick*time_freq()/50);
|
||||||
m_PredictedTime[g_Config.m_ClDummy].SetAdjustSpeed(1, 1000.0f);
|
m_PredictedTime[g_Config.m_ClDummy].SetAdjustSpeed(1, 1000.0f);
|
||||||
m_GameTime[g_Config.m_ClDummy].Init((GameTick-1)*time_freq()/50);
|
m_GameTime[g_Config.m_ClDummy].Init((GameTick-1)*time_freq()/50);
|
||||||
m_aSnapshots[SNAP_PREV] = m_SnapshotStorage.m_pFirst;
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV] = m_SnapshotStorage[g_Config.m_ClDummy].m_pFirst;
|
||||||
m_aSnapshots[SNAP_CURRENT] = m_SnapshotStorage.m_pLast;
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT] = m_SnapshotStorage[g_Config.m_ClDummy].m_pLast;
|
||||||
m_LocalStartTime = time_get();
|
m_LocalStartTime = time_get();
|
||||||
SetState(IClient::STATE_ONLINE);
|
SetState(IClient::STATE_ONLINE);
|
||||||
DemoRecorder_HandleAutoStart();
|
DemoRecorder_HandleAutoStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
// adjust game time
|
// adjust game time
|
||||||
if(m_RecivedSnapshots > 2)
|
if(m_RecivedSnapshots[g_Config.m_ClDummy] > 2)
|
||||||
{
|
{
|
||||||
int64 Now = m_GameTime[g_Config.m_ClDummy].Get(time_get());
|
int64 Now = m_GameTime[g_Config.m_ClDummy].Get(time_get());
|
||||||
int64 TickStart = GameTick*time_freq()/50;
|
int64 TickStart = GameTick*time_freq()/50;
|
||||||
|
@ -1750,15 +1748,201 @@ void CClient::ProcessServerPacketDummy(CNetChunk *pPacket)
|
||||||
|
|
||||||
if(Sys)
|
if(Sys)
|
||||||
{
|
{
|
||||||
// system message
|
if(Msg == NETMSG_CON_READY)
|
||||||
if(Msg == NETMSG_MAP_CHANGE || Msg == NETMSG_MAP_DATA || Msg == NETMSG_PING || Msg == NETMSG_RCON_CMD_ADD || Msg == NETMSG_RCON_CMD_REM || Msg == NETMSG_RCON_AUTH_STATUS || Msg == NETMSG_RCON_LINE || Msg == NETMSG_PING_REPLY || Msg == NETMSG_INPUTTIMING || Msg == NETMSG_SNAP || Msg == NETMSG_SNAPSINGLE || Msg == NETMSG_SNAPEMPTY)
|
|
||||||
{
|
|
||||||
return; // no need of all that stuff for the dummy
|
|
||||||
}
|
|
||||||
else if(Msg == NETMSG_CON_READY)
|
|
||||||
{
|
{
|
||||||
GameClient()->OnConnected();
|
GameClient()->OnConnected();
|
||||||
}
|
}
|
||||||
|
else if(Msg == NETMSG_SNAP || Msg == NETMSG_SNAPSINGLE || Msg == NETMSG_SNAPEMPTY)
|
||||||
|
{
|
||||||
|
int NumParts = 1;
|
||||||
|
int Part = 0;
|
||||||
|
int GameTick = Unpacker.GetInt();
|
||||||
|
int DeltaTick = GameTick-Unpacker.GetInt();
|
||||||
|
int PartSize = 0;
|
||||||
|
int Crc = 0;
|
||||||
|
int CompleteSize = 0;
|
||||||
|
const char *pData = 0;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
if(Msg == NETMSG_SNAP)
|
||||||
|
{
|
||||||
|
NumParts = Unpacker.GetInt();
|
||||||
|
Part = Unpacker.GetInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Msg != NETMSG_SNAPEMPTY)
|
||||||
|
{
|
||||||
|
Crc = Unpacker.GetInt();
|
||||||
|
PartSize = Unpacker.GetInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
pData = (const char *)Unpacker.GetRaw(PartSize);
|
||||||
|
|
||||||
|
if(Unpacker.Error())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(GameTick >= m_CurrentRecvTick[!g_Config.m_ClDummy])
|
||||||
|
{
|
||||||
|
if(GameTick != m_CurrentRecvTick[!g_Config.m_ClDummy])
|
||||||
|
{
|
||||||
|
m_SnapshotParts = 0;
|
||||||
|
m_CurrentRecvTick[!g_Config.m_ClDummy] = GameTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: clean this up abit
|
||||||
|
mem_copy((char*)m_aSnapshotIncommingData + Part*MAX_SNAPSHOT_PACKSIZE, pData, PartSize);
|
||||||
|
m_SnapshotParts |= 1<<Part;
|
||||||
|
|
||||||
|
if(m_SnapshotParts == (unsigned)((1<<NumParts)-1))
|
||||||
|
{
|
||||||
|
static CSnapshot Emptysnap;
|
||||||
|
CSnapshot *pDeltaShot = &Emptysnap;
|
||||||
|
int PurgeTick;
|
||||||
|
void *pDeltaData;
|
||||||
|
int DeltaSize;
|
||||||
|
unsigned char aTmpBuffer2[CSnapshot::MAX_SIZE];
|
||||||
|
unsigned char aTmpBuffer3[CSnapshot::MAX_SIZE];
|
||||||
|
CSnapshot *pTmpBuffer3 = (CSnapshot*)aTmpBuffer3; // Fix compiler warning for strict-aliasing
|
||||||
|
int SnapSize;
|
||||||
|
|
||||||
|
CompleteSize = (NumParts-1) * MAX_SNAPSHOT_PACKSIZE + PartSize;
|
||||||
|
|
||||||
|
// reset snapshoting
|
||||||
|
m_SnapshotParts = 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
|
||||||
|
pDeltaData = m_SnapshotDelta.EmptyDelta();
|
||||||
|
DeltaSize = sizeof(int)*3;
|
||||||
|
|
||||||
|
if(CompleteSize)
|
||||||
|
{
|
||||||
|
int IntSize = CVariableInt::Decompress(m_aSnapshotIncommingData, CompleteSize, aTmpBuffer2);
|
||||||
|
|
||||||
|
if(IntSize < 0) // failure during decompression, bail
|
||||||
|
return;
|
||||||
|
|
||||||
|
pDeltaData = aTmpBuffer2;
|
||||||
|
DeltaSize = IntSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unpack delta
|
||||||
|
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
|
||||||
|
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);
|
||||||
|
|
||||||
|
// add snapshot to demo
|
||||||
|
//if(m_DemoRecorder.IsRecording())
|
||||||
|
//{
|
||||||
|
// // write snapshot
|
||||||
|
// m_DemoRecorder.RecordSnapshot(GameTick, pTmpBuffer3, SnapSize);
|
||||||
|
//}
|
||||||
|
|
||||||
|
// apply snapshot, cycle pointers
|
||||||
|
m_RecivedSnapshots[!g_Config.m_ClDummy]++;
|
||||||
|
|
||||||
|
m_CurrentRecvTick[!g_Config.m_ClDummy] = GameTick;
|
||||||
|
|
||||||
|
// we got two snapshots until we see us self as connected
|
||||||
|
if(m_RecivedSnapshots[!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();
|
||||||
|
SetState(IClient::STATE_ONLINE);
|
||||||
|
//DemoRecorder_HandleAutoStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
// adjust game time
|
||||||
|
if(m_RecivedSnapshots[!g_Config.m_ClDummy] > 2)
|
||||||
|
{
|
||||||
|
int64 Now = m_GameTime[!g_Config.m_ClDummy].Get(time_get());
|
||||||
|
int64 TickStart = GameTick*time_freq()/50;
|
||||||
|
int64 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1832,12 +2016,12 @@ void CClient::OnDemoPlayerSnapshot(void *pData, int Size)
|
||||||
m_PrevGameTick[g_Config.m_ClDummy] = pInfo->m_PreviousTick;
|
m_PrevGameTick[g_Config.m_ClDummy] = pInfo->m_PreviousTick;
|
||||||
|
|
||||||
// handle snapshots
|
// handle snapshots
|
||||||
pTemp = m_aSnapshots[SNAP_PREV];
|
pTemp = m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV];
|
||||||
m_aSnapshots[SNAP_PREV] = m_aSnapshots[SNAP_CURRENT];
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV] = m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT];
|
||||||
m_aSnapshots[SNAP_CURRENT] = pTemp;
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT] = pTemp;
|
||||||
|
|
||||||
mem_copy(m_aSnapshots[SNAP_CURRENT]->m_pSnap, pData, Size);
|
mem_copy(m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_pSnap, pData, Size);
|
||||||
mem_copy(m_aSnapshots[SNAP_CURRENT]->m_pAltSnap, pData, Size);
|
mem_copy(m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_pAltSnap, pData, Size);
|
||||||
|
|
||||||
GameClient()->OnNewSnapshot();
|
GameClient()->OnNewSnapshot();
|
||||||
}
|
}
|
||||||
|
@ -1910,7 +2094,7 @@ void CClient::Update()
|
||||||
Disconnect();
|
Disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(State() == IClient::STATE_ONLINE && m_RecivedSnapshots >= 3)
|
else if(State() == IClient::STATE_ONLINE && m_RecivedSnapshots[g_Config.m_ClDummy] >= 3)
|
||||||
{
|
{
|
||||||
// switch snapshot
|
// switch snapshot
|
||||||
int Repredict = 0;
|
int Repredict = 0;
|
||||||
|
@ -1920,22 +2104,22 @@ void CClient::Update()
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
CSnapshotStorage::CHolder *pCur = m_aSnapshots[SNAP_CURRENT];
|
CSnapshotStorage::CHolder *pCur = m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT];
|
||||||
int64 TickStart = (pCur->m_Tick)*time_freq()/50;
|
int64 TickStart = (pCur->m_Tick)*time_freq()/50;
|
||||||
|
|
||||||
if(TickStart < Now)
|
if(TickStart < Now)
|
||||||
{
|
{
|
||||||
CSnapshotStorage::CHolder *pNext = m_aSnapshots[SNAP_CURRENT]->m_pNext;
|
CSnapshotStorage::CHolder *pNext = m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_pNext;
|
||||||
if(pNext)
|
if(pNext)
|
||||||
{
|
{
|
||||||
m_aSnapshots[SNAP_PREV] = m_aSnapshots[SNAP_CURRENT];
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV] = m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT];
|
||||||
m_aSnapshots[SNAP_CURRENT] = pNext;
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT] = pNext;
|
||||||
|
|
||||||
// set ticks
|
// set ticks
|
||||||
m_CurGameTick[g_Config.m_ClDummy] = m_aSnapshots[SNAP_CURRENT]->m_Tick;
|
m_CurGameTick[g_Config.m_ClDummy] = m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_Tick;
|
||||||
m_PrevGameTick[g_Config.m_ClDummy] = m_aSnapshots[SNAP_PREV]->m_Tick;
|
m_PrevGameTick[g_Config.m_ClDummy] = m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV]->m_Tick;
|
||||||
|
|
||||||
if(m_aSnapshots[SNAP_CURRENT] && m_aSnapshots[SNAP_PREV])
|
if(m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT] && m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV])
|
||||||
{
|
{
|
||||||
GameClient()->OnNewSnapshot();
|
GameClient()->OnNewSnapshot();
|
||||||
Repredict = 1;
|
Repredict = 1;
|
||||||
|
@ -1948,10 +2132,10 @@ void CClient::Update()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_aSnapshots[SNAP_CURRENT] && m_aSnapshots[SNAP_PREV])
|
if(m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT] && m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV])
|
||||||
{
|
{
|
||||||
int64 CurtickStart = (m_aSnapshots[SNAP_CURRENT]->m_Tick)*time_freq()/50;
|
int64 CurtickStart = (m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_Tick)*time_freq()/50;
|
||||||
int64 PrevtickStart = (m_aSnapshots[SNAP_PREV]->m_Tick)*time_freq()/50;
|
int64 PrevtickStart = (m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV]->m_Tick)*time_freq()/50;
|
||||||
int PrevPredTick = (int)(PredNow*50/time_freq());
|
int PrevPredTick = (int)(PredNow*50/time_freq());
|
||||||
int NewPredTick = PrevPredTick+1;
|
int NewPredTick = PrevPredTick+1;
|
||||||
|
|
||||||
|
@ -1962,10 +2146,10 @@ void CClient::Update()
|
||||||
PrevtickStart = PrevPredTick*time_freq()/50;
|
PrevtickStart = PrevPredTick*time_freq()/50;
|
||||||
m_PredIntraTick[g_Config.m_ClDummy] = (PredNow - PrevtickStart) / (float)(CurtickStart-PrevtickStart);
|
m_PredIntraTick[g_Config.m_ClDummy] = (PredNow - PrevtickStart) / (float)(CurtickStart-PrevtickStart);
|
||||||
|
|
||||||
if(NewPredTick < m_aSnapshots[SNAP_PREV]->m_Tick-SERVER_TICK_SPEED || NewPredTick > m_aSnapshots[SNAP_PREV]->m_Tick+SERVER_TICK_SPEED)
|
if(NewPredTick < m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV]->m_Tick-SERVER_TICK_SPEED || NewPredTick > m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV]->m_Tick+SERVER_TICK_SPEED)
|
||||||
{
|
{
|
||||||
m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client", "prediction time reset!");
|
m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client", "prediction time reset!");
|
||||||
m_PredictedTime[g_Config.m_ClDummy].Init(m_aSnapshots[SNAP_CURRENT]->m_Tick*time_freq()/50);
|
m_PredictedTime[g_Config.m_ClDummy].Init(m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_Tick*time_freq()/50);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(NewPredTick > m_PredTick[g_Config.m_ClDummy])
|
if(NewPredTick > m_PredTick[g_Config.m_ClDummy])
|
||||||
|
@ -2525,18 +2709,18 @@ const char *CClient::DemoPlayer_Play(const char *pFilename, int StorageType)
|
||||||
// setup buffers
|
// setup buffers
|
||||||
mem_zero(m_aDemorecSnapshotData, sizeof(m_aDemorecSnapshotData));
|
mem_zero(m_aDemorecSnapshotData, sizeof(m_aDemorecSnapshotData));
|
||||||
|
|
||||||
m_aSnapshots[SNAP_CURRENT] = &m_aDemorecSnapshotHolders[SNAP_CURRENT];
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT] = &m_aDemorecSnapshotHolders[SNAP_CURRENT];
|
||||||
m_aSnapshots[SNAP_PREV] = &m_aDemorecSnapshotHolders[SNAP_PREV];
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV] = &m_aDemorecSnapshotHolders[SNAP_PREV];
|
||||||
|
|
||||||
m_aSnapshots[SNAP_CURRENT]->m_pSnap = (CSnapshot *)m_aDemorecSnapshotData[SNAP_CURRENT][0];
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_pSnap = (CSnapshot *)m_aDemorecSnapshotData[SNAP_CURRENT][0];
|
||||||
m_aSnapshots[SNAP_CURRENT]->m_pAltSnap = (CSnapshot *)m_aDemorecSnapshotData[SNAP_CURRENT][1];
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_pAltSnap = (CSnapshot *)m_aDemorecSnapshotData[SNAP_CURRENT][1];
|
||||||
m_aSnapshots[SNAP_CURRENT]->m_SnapSize = 0;
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_SnapSize = 0;
|
||||||
m_aSnapshots[SNAP_CURRENT]->m_Tick = -1;
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_CURRENT]->m_Tick = -1;
|
||||||
|
|
||||||
m_aSnapshots[SNAP_PREV]->m_pSnap = (CSnapshot *)m_aDemorecSnapshotData[SNAP_PREV][0];
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV]->m_pSnap = (CSnapshot *)m_aDemorecSnapshotData[SNAP_PREV][0];
|
||||||
m_aSnapshots[SNAP_PREV]->m_pAltSnap = (CSnapshot *)m_aDemorecSnapshotData[SNAP_PREV][1];
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV]->m_pAltSnap = (CSnapshot *)m_aDemorecSnapshotData[SNAP_PREV][1];
|
||||||
m_aSnapshots[SNAP_PREV]->m_SnapSize = 0;
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV]->m_SnapSize = 0;
|
||||||
m_aSnapshots[SNAP_PREV]->m_Tick = -1;
|
m_aSnapshots[g_Config.m_ClDummy][SNAP_PREV]->m_Tick = -1;
|
||||||
|
|
||||||
// enter demo playback state
|
// enter demo playback state
|
||||||
SetState(IClient::STATE_DEMOPLAYBACK);
|
SetState(IClient::STATE_DEMOPLAYBACK);
|
||||||
|
|
|
@ -155,10 +155,10 @@ class CClient : public IClient, public CDemoPlayer::IListner
|
||||||
CGraph m_FpsGraph;
|
CGraph m_FpsGraph;
|
||||||
|
|
||||||
// the game snapshots are modifiable by the game
|
// the game snapshots are modifiable by the game
|
||||||
class CSnapshotStorage m_SnapshotStorage;
|
class CSnapshotStorage m_SnapshotStorage[2];
|
||||||
CSnapshotStorage::CHolder *m_aSnapshots[NUM_SNAPSHOT_TYPES];
|
CSnapshotStorage::CHolder *m_aSnapshots[2][NUM_SNAPSHOT_TYPES];
|
||||||
|
|
||||||
int m_RecivedSnapshots;
|
int m_RecivedSnapshots[2];
|
||||||
char m_aSnapshotIncommingData[CSnapshot::MAX_SIZE];
|
char m_aSnapshotIncommingData[CSnapshot::MAX_SIZE];
|
||||||
|
|
||||||
class CSnapshotStorage::CHolder m_aDemorecSnapshotHolders[NUM_SNAPSHOT_TYPES];
|
class CSnapshotStorage::CHolder m_aDemorecSnapshotHolders[NUM_SNAPSHOT_TYPES];
|
||||||
|
|
Loading…
Reference in a new issue