Engine: add reconnect logic and concommand for client

Allow the user to reconnect to a server by running 'reconnect', this also allows for reparsing all client side scripts while debugging the game on a dedicated server.
This commit is contained in:
Kawe Mazidjatari 2024-07-01 00:20:03 +02:00
parent 7ba2d2caf5
commit a1bd8bd012
5 changed files with 44 additions and 1 deletions

View File

@ -219,7 +219,7 @@ bool CRConClient::ShouldReceive(void)
//-----------------------------------------------------------------------------
bool CRConClient::IsRemoteLocal(void)
{
return (g_pNetAdr->ComparePort(m_Address) && g_pNetAdr->CompareAdr(m_Address));
return NET_IsRemoteLocal(m_Address);
}
//-----------------------------------------------------------------------------

View File

@ -50,11 +50,16 @@ static void SetName_f(const CCommand& args)
memset(g_PersonaName, '\0', MAX_PERSONA_NAME_LEN);
strncpy(g_PersonaName, pszName, nLen);
}
static void Reconnect_f(const CCommand& args)
{
g_pClientState->Reconnect();
}
//------------------------------------------------------------------------------
// Purpose: console commands
//------------------------------------------------------------------------------
static ConCommand cl_setname("cl_setname", SetName_f, "Sets the client's persona name", FCVAR_RELEASE);
static ConCommand reconnect("reconnect", Reconnect_f, "Reconnect to current server.", FCVAR_DONTRECORD|FCVAR_RELEASE);
//------------------------------------------------------------------------------
// Purpose: returns true if client simulation is paused
@ -457,6 +462,31 @@ void CClientState::VConnect(CClientState* thisptr, connectparams_t* connectParam
CClientState__Connect(thisptr, connectParams);
}
//------------------------------------------------------------------------------
// Purpose: reconnects to currently connected server
//------------------------------------------------------------------------------
void CClientState::Reconnect()
{
if (!IsConnected())
{
Warning(eDLL_T::CLIENT, "Attempted to reconnect while unconnected, please defer it.\n");
return;
}
const netadr_t& remoteAdr = m_NetChannel->GetRemoteAddress();
if (remoteAdr.IsLoopback() || NET_IsRemoteLocal(remoteAdr))
{
Warning(eDLL_T::CLIENT, "Reconnecting to a listen server isn't supported, use \"reload\" instead.\n");
return;
}
char buf[1024];
V_snprintf(buf, sizeof(buf), "connect \"%s\"", remoteAdr.ToString());
Cbuf_AddText(ECommandTarget_t::CBUF_FIRST_PLAYER, buf, cmd_source_t::kCommandSrcCode);
}
void VClientState::Detour(const bool bAttach) const
{
DetourSetup(&CClientState__ConnectionClosing, &CClientState::VConnectionClosing, bAttach);

View File

@ -64,6 +64,8 @@ public:
bool Authenticate(connectparams_t* connectParams, char* const reasonBuf, const size_t reasonBufLen) const;
void Reconnect();
protected:
FORCEINLINE CClientState* GetShiftedBasePointer(void)
{

View File

@ -288,6 +288,16 @@ bool NET_ReadMessageType(int* outType, bf_read* buffer)
return !buffer->IsOverflowed();
}
//-----------------------------------------------------------------------------
// Purpose: checks whether the provided address is the local server.
// Input : &netAdr -
// Output : true if equal, false otherwise
//-----------------------------------------------------------------------------
bool NET_IsRemoteLocal(const CNetAdr& netAdr)
{
return (g_pNetAdr->ComparePort(netAdr) && g_pNetAdr->CompareAdr(netAdr));
}
#endif // !_TOOLS
//-----------------------------------------------------------------------------

View File

@ -49,6 +49,7 @@ unsigned int NET_BufferToBufferDecompress(uint8_t* pInput, size_t& coBufsize, ui
unsigned int NET_BufferToBufferDecompress_LZSS(CLZSS* lzss, unsigned char* pInput, unsigned char* pOutput, unsigned int unBufSize);
bool NET_ReadMessageType(int* outType, bf_read* buffer);
bool NET_IsRemoteLocal(const CNetAdr& netAdr);
///////////////////////////////////////////////////////////////////////////////
extern netadr_t* g_pNetAdr;