Skip to content

Commit

Permalink
Fix crash after GameSpy client query
Browse files Browse the repository at this point in the history
In CGameSpy_QR2::Init we should not pass local object of the caller as userdata because invalid pointer will be received in GameSpy callbacks after the client's query is arrived.
  • Loading branch information
FreeZoneMods committed Sep 13, 2018
1 parent c70d802 commit aa8207b
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 22 deletions.
16 changes: 8 additions & 8 deletions src/xrGame/gamespy/GameSpy_QR2_callbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void __cdecl callback_serverkey(int keyid, qr2_buffer_t outbuf, void* userdata)
{
if (!userdata)
return;
xrGameSpyServer* pServer = static_cast<CGameSpy_QR2::Context*>(userdata)->GSServer;
xrGameSpyServer* pServer = static_cast<xrGameSpyServer*>(userdata);
if (!pServer)
return;
CGameSpy_QR2* pQR2 = pServer->QR2();
Expand Down Expand Up @@ -195,7 +195,7 @@ void __cdecl callback_serverkey(int keyid, qr2_buffer_t outbuf, void* userdata)

void __cdecl callback_playerkey(int keyid, int index, qr2_buffer_t outbuf, void* userdata)
{
xrGameSpyServer* pServer = static_cast<CGameSpy_QR2::Context*>(userdata)->GSServer;
xrGameSpyServer* pServer = static_cast<xrGameSpyServer*>(userdata);
if (!pServer)
return;
if (u32(index) >= pServer->GetClientsCount())
Expand Down Expand Up @@ -262,7 +262,7 @@ void __cdecl callback_playerkey(int keyid, int index, qr2_buffer_t outbuf, void*

void __cdecl callback_teamkey(int keyid, int index, qr2_buffer_t outbuf, void* userdata)
{
xrGameSpyServer* pServer = static_cast<CGameSpy_QR2::Context*>(userdata)->GSServer;
xrGameSpyServer* pServer = static_cast<xrGameSpyServer*>(userdata);
if (!pServer)
return;

Expand Down Expand Up @@ -290,7 +290,7 @@ void __cdecl callback_keylist(qr2_key_type keytype, qr2_keybuffer_t keybuffer, v
{
if (!userdata)
return;
xrGameSpyServer* pServer = static_cast<CGameSpy_QR2::Context*>(userdata)->GSServer;
xrGameSpyServer* pServer = static_cast<xrGameSpyServer*>(userdata);
CGameSpy_QR2* pQR2 = pServer->QR2();
if (!pQR2)
return;
Expand Down Expand Up @@ -375,7 +375,7 @@ int __cdecl callback_count(qr2_key_type keytype, void* userdata)
{
if (!userdata)
return 0;
xrGameSpyServer* pServer = static_cast<CGameSpy_QR2::Context*>(userdata)->GSServer;
xrGameSpyServer* pServer = static_cast<xrGameSpyServer*>(userdata);
switch (keytype)
{
case key_player: { return pServer->GetPlayersCount();
Expand Down Expand Up @@ -405,7 +405,7 @@ int __cdecl callback_count(qr2_key_type keytype, void* userdata)
void __cdecl callback_adderror(qr2_error_t error, gsi_char* errmsg, void* userdata)
{
Msg("! Error while adding this server to master list ->%s.", errmsg);
xrGameSpyServer* pServer = static_cast<CGameSpy_QR2::Context*>(userdata)->GSServer;
xrGameSpyServer* pServer = static_cast<xrGameSpyServer*>(userdata);
if (pServer)
pServer->OnError_Add(error);
};
Expand All @@ -416,7 +416,7 @@ void __cdecl callback_cm(char* data, int len, void* userdata){};
void __cdecl callback_deny_ip(void* userdata, unsigned int sender_ip, int* result)
{
*result = 0;
IPureServer* pServer = static_cast<CGameSpy_QR2::Context*>(userdata)->GSServer;
IPureServer* pServer = static_cast<xrGameSpyServer*>(userdata);
if (pServer && pServer->IsPlayerIPDenied(static_cast<u32>(sender_ip)))
{
*result = 1;
Expand All @@ -425,7 +425,7 @@ void __cdecl callback_deny_ip(void* userdata, unsigned int sender_ip, int* resul
/*
void __cdecl callback_public(unsigned int ip, unsigned short port, void* userdata)
{
xrGameSpyServer* pServer = static_cast<CGameSpy_QR2::Context *>(userdata)->GSServer;
xrGameSpyServer* pServer = static_cast<xrGameSpyServer*>(userdata);
if (!pServer)
{
VERIFY2(pServer, "xrGameSpyServer is NULL");
Expand Down
2 changes: 1 addition & 1 deletion src/xrGame/xrGameSpy_GameSpyFuncs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// void xrGameSpyServer::QR2_Init (u32 PortID)
void xrGameSpyServer::QR2_Init(int PortID)
{
CGameSpy_QR2::Context ctx;
CGameSpy_QR2::SInitConfig ctx;
ctx.OnServerKey = callback_serverkey;
ctx.OnPlayerKey = callback_playerkey;
ctx.OnTeamKey = callback_teamkey;
Expand Down
27 changes: 16 additions & 11 deletions src/xrGameSpy/GameSpy_QR2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,21 +85,27 @@ void CGameSpy_QR2::RegisterAdditionalKeys()
qr2_register_keyA(SERVER_UP_TIME_KEY, ("server_up_time"));
};

bool CGameSpy_QR2::Init(int PortID, int Public, Context& ctx)
{
//--------- QR2 Init -------------------------/
// call qr_init with the query port number and gamename, default IP address, and no user data

// if (qr2_initA(NULL,NULL,PortID, GAMESPY_GAMENAME, m_SecretKey, Public, 0,
qr2_error_t err = xrGS_qr2_initA(NULL, NULL, PortID, Public, 0, ctx.OnServerKey, ctx.OnPlayerKey, ctx.OnTeamKey,
ctx.OnKeyList, ctx.OnCount, ctx.OnError, &ctx);
bool CGameSpy_QR2::Init(int PortID, int Public, SInitConfig& ctx)
{
qr2_error_t err = xrGS_qr2_initA(nullptr,
nullptr,
PortID,
Public,
0,
ctx.OnServerKey,
ctx.OnPlayerKey,
ctx.OnTeamKey,
ctx.OnKeyList,
ctx.OnCount,
ctx.OnError,
ctx.GSServer);

#ifndef MASTER_GOLD
Msg("xrGS::xrGS_qr2_initA returned code is [%d]", err);
#endif // #ifndef MASTER_GOLD

if (err != e_qrnoerror)
{
// _tprintf(_T("Error starting query sockets\n"));
Msg("xrGS::QR2 : Failes to Initialize!");
return false;
}
Expand All @@ -112,8 +118,7 @@ bool CGameSpy_QR2::Init(int PortID, int Public, Context& ctx)
// Set a function to be called when we receive a nat negotiation request
qr2_register_natneg_callback(NULL, ctx.OnNatNeg);

// Set a function to be called when gamespy responds my IP and port number
// qr2_register_publicaddress_callback(NULL, callback_public);
// Set a function to be called when gamespy responds my IP and port number
qr2_register_denyresponsetoip_callback(NULL, ctx.OnDenyIP);

#ifndef MASTER_GOLD
Expand Down
4 changes: 2 additions & 2 deletions src/xrGameSpy/GameSpy_QR2.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class xrGameSpyServer;
class XRGAMESPY_API CGameSpy_QR2
{
public:
class Context
struct SInitConfig
{
public:
void(__cdecl* OnServerKey)(int keyid, qr2_buffer_t outbuf, void* userdata);
Expand All @@ -25,7 +25,7 @@ class XRGAMESPY_API CGameSpy_QR2
// string16 m_SecretKey;

public:
bool Init(int PortID, int Public, Context& ctx);
bool Init(int PortID, int Public, SInitConfig& ctx);
void Think(void* qrec);
void ShutDown(void* qrec);
void RegisterAdditionalKeys();
Expand Down

0 comments on commit aa8207b

Please sign in to comment.