mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Proper fix for playlists reloading on disconnect
This fixes a crash/exception that would occur when getting disconnected from your own listenserver due to the playlists reload task dispatch. Moving this to client only code, in the disconnect routine (post disconnect) fixes this problem.
This commit is contained in:
parent
f5151a74cf
commit
a33f569ad5
r5dev/engine
@ -9,8 +9,11 @@
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#include "core/stdafx.h"
|
||||
#include "vpc/keyvalues.h"
|
||||
#include "tier0/frametask.h"
|
||||
#include "engine/host.h"
|
||||
#include "clientstate.h"
|
||||
#include "common/callback.h"
|
||||
#include "cdll_engine_int.h"
|
||||
#include "vgui/vgui_baseui_interface.h"
|
||||
|
||||
@ -117,7 +120,29 @@ float CClientState::GetFrameTime() const
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// 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.
|
||||
//------------------------------------------------------------------------------
|
||||
bool CClientState::VProcessServerTick(CClientState* pClientState, SVC_ServerTick* pServerTick)
|
||||
{
|
||||
@ -140,11 +165,13 @@ bool CClientState::VProcessServerTick(CClientState* pClientState, SVC_ServerTick
|
||||
|
||||
void VClientState::Attach() const
|
||||
{
|
||||
DetourAttach(&CClientState__ConnectionClosing, &CClientState::VConnectionClosing);
|
||||
DetourAttach(&CClientState__ProcessServerTick, &CClientState::VProcessServerTick);
|
||||
}
|
||||
|
||||
void VClientState::Detach() const
|
||||
{
|
||||
DetourDetach(&CClientState__ConnectionClosing, &CClientState::VConnectionClosing);
|
||||
DetourDetach(&CClientState__ProcessServerTick, &CClientState::VProcessServerTick);
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ public:
|
||||
class CClientState : CS_INetChannelHandler, IConnectionlessPacketHandler, IServerMessageHandler, CClientSnapshotManager
|
||||
{
|
||||
public: // Hook statics.
|
||||
static void VConnectionClosing(CClientState* thisptr, const char* szReason);
|
||||
static bool VProcessServerTick(CClientState* thisptr, SVC_ServerTick* msg);
|
||||
|
||||
public:
|
||||
@ -202,13 +203,15 @@ extern CClientState** g_pClientState_Shifted; // Shifted by 0x10 forward!
|
||||
inline CMemory p_CClientState__RunFrame;
|
||||
inline auto CClientState__RunFrame = p_CClientState__RunFrame.RCast<void(*)(CClientState* thisptr)>();
|
||||
|
||||
inline CMemory p_CClientState__Disconnect; /*48 89 5C 24 ?? 55 57 41 56 48 83 EC 30 0F B6 EA*/
|
||||
inline CMemory p_CClientState__Disconnect;
|
||||
inline auto CClientState__Disconnect = p_CClientState__Disconnect.RCast<void(*)(CClientState* thisptr, bool bSendTrackingContext)>();
|
||||
|
||||
inline CMemory p_CClientState__ConnectionClosing;
|
||||
inline auto CClientState__ConnectionClosing = p_CClientState__ConnectionClosing.RCast<void(*)(CClientState* thisptr, const char* szReason)>();
|
||||
|
||||
inline CMemory p_CClientState__ProcessServerTick;
|
||||
inline auto CClientState__ProcessServerTick = p_CClientState__ProcessServerTick.RCast<bool(*)(CClientState* thisptr, SVC_ServerTick* msg)>();
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class VClientState : public IDetour
|
||||
{
|
||||
@ -216,26 +219,28 @@ class VClientState : public IDetour
|
||||
{
|
||||
LogFunAdr("CClientState::RunFrame", p_CClientState__RunFrame.GetPtr());
|
||||
LogFunAdr("CClientState::Disconnect", p_CClientState__Disconnect.GetPtr());
|
||||
LogFunAdr("CClientState::ConnectionClosing", p_CClientState__ConnectionClosing.GetPtr());
|
||||
LogFunAdr("CClientState::ProcessServerTick", p_CClientState__ProcessServerTick.GetPtr());
|
||||
LogVarAdr("g_pClientState", reinterpret_cast<uintptr_t>(g_pClientState));
|
||||
LogVarAdr("g_pClientState_Shifted", reinterpret_cast<uintptr_t>(g_pClientState_Shifted));
|
||||
}
|
||||
virtual void GetFun(void) const
|
||||
{
|
||||
|
||||
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
|
||||
p_CClientState__RunFrame = g_GameDll.FindPatternSIMD("48 89 4C 24 ?? 57 48 81 EC ?? ?? ?? ?? 83 B9 ?? ?? ?? ?? ??");
|
||||
CClientState__RunFrame = p_CClientState__RunFrame.RCast<void(*)(CClientState* thisptr)>();
|
||||
|
||||
p_CClientState__Disconnect = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 57 41 56 48 83 EC 30 0F B6 EA");
|
||||
CClientState__Disconnect = p_CClientState__Disconnect.RCast<void(*)(CClientState* thisptr, bool bSendTrackingContext)>(); /*48 89 5C 24 ?? 55 57 41 56 48 83 EC 30 0F B6 EA*/
|
||||
p_CClientState__ConnectionClosing = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 83 B9 ?? ?? ?? ?? ?? 48 8B DA 7E 6E");
|
||||
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
|
||||
p_CClientState__RunFrame = g_GameDll.FindPatternSIMD("40 53 48 81 EC ?? ?? ?? ?? 83 B9 ?? ?? ?? ?? ?? 48 8B D9 7D 0B");
|
||||
CClientState__RunFrame = p_CClientState__RunFrame.RCast<void(*)(CClientState* thisptr)>();
|
||||
|
||||
p_CClientState__Disconnect = g_GameDll.FindPatternSIMD("40 56 57 41 54 41 55 41 57 48 83 EC 30 44 0F B6 FA");
|
||||
CClientState__Disconnect = p_CClientState__Disconnect.RCast<void(*)(CClientState* thisptr, bool bSendTrackingContext)>(); /*40 56 57 41 54 41 55 41 57 48 83 EC 30 44 0F B6 FA*/
|
||||
p_CClientState__ConnectionClosing = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 83 B9 ?? ?? ?? ?? ?? 48 8B DA 0F 8E ?? ?? ?? ??");
|
||||
#endif
|
||||
p_CClientState__ProcessServerTick = g_GameDll.FindPatternSIMD("40 57 48 83 EC 20 83 B9 ?? ?? ?? ?? ?? 48 8B F9 7C 66");
|
||||
|
||||
CClientState__RunFrame = p_CClientState__RunFrame.RCast<void(*)(CClientState*)>();
|
||||
CClientState__Disconnect = p_CClientState__Disconnect.RCast<void(*)(CClientState*, bool)>();
|
||||
CClientState__ConnectionClosing = p_CClientState__ConnectionClosing.RCast<void(*)(CClientState*, const char*)>();
|
||||
CClientState__ProcessServerTick = p_CClientState__ProcessServerTick.RCast<bool(*)(CClientState*, SVC_ServerTick*)>();
|
||||
}
|
||||
virtual void GetVar(void) const
|
||||
|
@ -233,17 +233,6 @@ void CNetChan::Clear(bool bStopProcessing)
|
||||
void CNetChan::_Shutdown(CNetChan* pChan, const char* szReason, uint8_t bBadRep, bool bRemoveNow)
|
||||
{
|
||||
v_NetChan_Shutdown(pChan, szReason, bBadRep, bRemoveNow);
|
||||
|
||||
#ifndef DEDICATED
|
||||
// Delay execution to the next frame; this is required to avoid a rare crash.
|
||||
// Cannot reload playlists while still disconnecting.
|
||||
g_TaskScheduler->Dispatch([]()
|
||||
{
|
||||
// Re-load and re-init playlists from the disk to replace the cached one we received from the server.
|
||||
_DownloadPlaylists_f();
|
||||
KeyValues::InitPlaylists();
|
||||
}, 0);
|
||||
#endif // !DEDICATED
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user