2022-05-20 11:52:19 +02:00
|
|
|
//=============================================================================//
|
2021-12-25 22:36:38 +01:00
|
|
|
//
|
2022-05-20 11:52:19 +02:00
|
|
|
// Purpose:
|
2021-12-25 22:36:38 +01:00
|
|
|
//
|
2022-05-20 11:52:19 +02:00
|
|
|
// $NoKeywords: $
|
|
|
|
//
|
|
|
|
//=============================================================================//
|
|
|
|
// clientstate.cpp: implementation of the CClientState class.
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
2021-12-25 22:36:38 +01:00
|
|
|
#include "core/stdafx.h"
|
2023-06-18 17:10:57 +02:00
|
|
|
#include "vpc/keyvalues.h"
|
|
|
|
#include "tier0/frametask.h"
|
2022-08-18 02:15:23 +02:00
|
|
|
#include "engine/host.h"
|
2023-05-10 00:05:38 +02:00
|
|
|
#include "clientstate.h"
|
2023-06-18 17:10:57 +02:00
|
|
|
#include "common/callback.h"
|
2023-05-10 00:05:38 +02:00
|
|
|
#include "cdll_engine_int.h"
|
2023-06-03 18:06:35 +02:00
|
|
|
#include "vgui/vgui_baseui_interface.h"
|
2022-01-04 11:53:54 +01:00
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Purpose: returns true if client simulation is paused
|
|
|
|
//------------------------------------------------------------------------------
|
2022-10-29 00:01:10 +02:00
|
|
|
bool CClientState::IsPaused() const
|
2022-01-04 11:53:54 +01:00
|
|
|
{
|
2023-06-03 18:06:35 +02:00
|
|
|
return m_bPaused || !*host_initialized || g_pEngineVGui->ShouldPause();
|
2022-01-04 11:53:54 +01:00
|
|
|
}
|
|
|
|
|
2022-11-10 11:47:02 +01:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Purpose: returns true if client is fully connected and active
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
bool CClientState::IsActive(void) const
|
|
|
|
{
|
|
|
|
return m_nSignonState == SIGNONSTATE::SIGNONSTATE_FULL;
|
|
|
|
};
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Purpose: returns true if client connected but not active
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
bool CClientState::IsConnected(void) const
|
|
|
|
{
|
|
|
|
return m_nSignonState >= SIGNONSTATE::SIGNONSTATE_CONNECTED;
|
|
|
|
};
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Purpose: returns true if client is still connecting
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
bool CClientState::IsConnecting(void) const
|
|
|
|
{
|
|
|
|
return m_nSignonState >= SIGNONSTATE::SIGNONSTATE_NONE;
|
|
|
|
}
|
|
|
|
|
2022-01-04 11:53:54 +01:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Purpose: gets the client time
|
2022-02-19 02:31:16 +01:00
|
|
|
// Technically doesn't belong here
|
2022-01-04 11:53:54 +01:00
|
|
|
//------------------------------------------------------------------------------
|
2022-10-29 00:01:10 +02:00
|
|
|
float CClientState::GetClientTime() const
|
2022-01-04 11:53:54 +01:00
|
|
|
{
|
2022-08-18 02:15:23 +02:00
|
|
|
if (m_bClockCorrectionEnabled)
|
2022-01-04 11:53:54 +01:00
|
|
|
{
|
2023-09-17 16:44:18 +02:00
|
|
|
return (float)m_ClockDriftMgr.m_nSimulationTick * g_pCommonHostState->interval_per_tick;
|
2022-01-04 11:53:54 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-08-18 11:35:32 +02:00
|
|
|
return m_flClockDriftFrameTime;
|
2022-01-04 11:53:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2022-07-03 11:03:25 +02:00
|
|
|
// Purpose: gets the simulation tick count
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
int CClientState::GetTick() const
|
|
|
|
{
|
|
|
|
return m_ClockDriftMgr.m_nSimulationTick;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Purpose: gets the last-received server tick count
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
int CClientState::GetServerTickCount() const
|
|
|
|
{
|
|
|
|
return m_ClockDriftMgr.m_nServerTick;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Purpose: sets the server tick count
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void CClientState::SetServerTickCount(int tick)
|
|
|
|
{
|
|
|
|
m_ClockDriftMgr.m_nServerTick = tick;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Purpose: gets the client tick count
|
2022-01-04 11:53:54 +01:00
|
|
|
//------------------------------------------------------------------------------
|
2022-05-20 11:52:19 +02:00
|
|
|
int CClientState::GetClientTickCount() const
|
2022-01-04 11:53:54 +01:00
|
|
|
{
|
2022-05-20 20:14:39 +02:00
|
|
|
return m_ClockDriftMgr.m_nClientTick;
|
2022-01-04 11:53:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2022-07-03 11:03:25 +02:00
|
|
|
// Purpose: sets the client tick count
|
2022-01-04 11:53:54 +01:00
|
|
|
//------------------------------------------------------------------------------
|
2022-05-20 11:52:19 +02:00
|
|
|
void CClientState::SetClientTickCount(int tick)
|
2022-01-04 11:53:54 +01:00
|
|
|
{
|
2022-05-20 20:14:39 +02:00
|
|
|
m_ClockDriftMgr.m_nClientTick = tick;
|
2022-01-04 11:53:54 +01:00
|
|
|
}
|
|
|
|
|
2023-06-03 18:06:35 +02:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Purpose: gets the client frame time
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
float CClientState::GetFrameTime() const
|
|
|
|
{
|
|
|
|
if (IsPaused())
|
|
|
|
{
|
|
|
|
return 0.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_flFrameTime;
|
|
|
|
}
|
|
|
|
|
2023-02-18 00:31:57 +01:00
|
|
|
//------------------------------------------------------------------------------
|
2023-06-18 17:10:57 +02:00
|
|
|
// Purpose: called when connection to the server has been closed
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
void CClientState::VConnectionClosing(CClientState* thisptr, const char* szReason)
|
|
|
|
{
|
|
|
|
CClientState__ConnectionClosing(thisptr, szReason);
|
|
|
|
|
|
|
|
// Delay execution to the next frame; this is required to avoid a rare crash.
|
|
|
|
// Cannot reload playlists while still disconnecting.
|
|
|
|
g_TaskScheduler->Dispatch([]()
|
|
|
|
{
|
|
|
|
// Reload the local playlist to override the cached
|
|
|
|
// one from the server we got disconnected from.
|
|
|
|
_DownloadPlaylists_f();
|
|
|
|
KeyValues::InitPlaylists();
|
|
|
|
}, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// Purpose: called when a SVC_ServerTick messages comes in.
|
|
|
|
// This function has an additional check for the command tick against '-1',
|
|
|
|
// if it is '-1', we process statistics only. This is required as the game
|
|
|
|
// no longer can process server ticks every frame unlike previous games.
|
|
|
|
// Without this, the server CPU and frame time don't get updated to the client.
|
2023-02-18 00:31:57 +01:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
bool CClientState::VProcessServerTick(CClientState* pClientState, SVC_ServerTick* pServerTick)
|
|
|
|
{
|
|
|
|
if (pServerTick->m_NetTick.m_nCommandTick != -1)
|
|
|
|
{
|
|
|
|
return CClientState__ProcessServerTick(pClientState, pServerTick);
|
|
|
|
}
|
|
|
|
else // Statistics only.
|
|
|
|
{
|
2023-04-09 11:06:55 +02:00
|
|
|
char* pShifted = reinterpret_cast<char*>(pClientState) - 0x10; // Shifted due to compiler optimizations.
|
2023-02-18 00:31:57 +01:00
|
|
|
CClientState* pClient_Adj = reinterpret_cast<CClientState*>(pShifted);
|
|
|
|
|
|
|
|
CNetChan* pChan = pClient_Adj->m_NetChannel;
|
|
|
|
pChan->SetRemoteFramerate(pServerTick->m_NetTick.m_flHostFrameTime, pServerTick->m_NetTick.m_flHostFrameTimeStdDeviation);
|
|
|
|
pChan->SetRemoteCPUStatistics(pServerTick->m_NetTick.m_nServerCPU);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void VClientState::Attach() const
|
|
|
|
{
|
2023-06-18 17:10:57 +02:00
|
|
|
DetourAttach(&CClientState__ConnectionClosing, &CClientState::VConnectionClosing);
|
2023-02-18 00:31:57 +01:00
|
|
|
DetourAttach(&CClientState__ProcessServerTick, &CClientState::VProcessServerTick);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VClientState::Detach() const
|
|
|
|
{
|
2023-06-18 17:10:57 +02:00
|
|
|
DetourDetach(&CClientState__ConnectionClosing, &CClientState::VConnectionClosing);
|
2023-02-18 00:31:57 +01:00
|
|
|
DetourDetach(&CClientState__ProcessServerTick, &CClientState::VProcessServerTick);
|
|
|
|
}
|
|
|
|
|
2022-05-20 20:14:39 +02:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
CClientState* g_pClientState = nullptr;
|
2022-08-18 02:15:23 +02:00
|
|
|
CClientState** g_pClientState_Shifted = nullptr;
|