Implemented SV_GetChallenge for API.

This commit is contained in:
asmodai 2015-10-10 20:02:29 +03:00
parent aedbcd1380
commit 5a8aa9ce8b
4 changed files with 33 additions and 57 deletions

View File

@ -40,6 +40,11 @@
#define MAX_NAME 32 #define MAX_NAME 32
#define MAX_LIGHTSTYLES 64 #define MAX_LIGHTSTYLES 64
#define MAX_PACKET_ENTITIES 256 #define MAX_PACKET_ENTITIES 256
#ifdef REHLDS_OPT_PEDANTIC
#define MAX_CHALLENGES 64
#else
#define MAX_CHALLENGES 1024
#endif
#include "custom_int.h" #include "custom_int.h"
#include "crc.h" #include "crc.h"
@ -573,7 +578,7 @@ extern int numipfilters;
extern userfilter_t userfilters[32768]; extern userfilter_t userfilters[32768];
extern int numuserfilters; extern int numuserfilters;
extern challenge_t g_rg_sv_challenges[1024]; extern challenge_t g_rg_sv_challenges[MAX_CHALLENGES];
#ifdef HOOK_ENGINE #ifdef HOOK_ENGINE
@ -647,6 +652,7 @@ int SV_FindEmptySlot(netadr_t *adr, int *pslot, client_t ** ppClient);
void SV_ConnectClient(void); void SV_ConnectClient(void);
void SV_ConnectClient_internal(void); void SV_ConnectClient_internal(void);
void SVC_Ping(void); void SVC_Ping(void);
int SV_GetChallenge(netadr_t& adr);
void SVC_GetChallenge(void); void SVC_GetChallenge(void);
void SVC_ServiceChallenge(void); void SVC_ServiceChallenge(void);
void SV_ResetModInfo(void); void SV_ResetModInfo(void);

View File

@ -1831,7 +1831,7 @@ typedef struct challenge_s
int time; int time;
} challenge_t; } challenge_t;
challenge_t g_rg_sv_challenges[1024]; challenge_t g_rg_sv_challenges[MAX_CHALLENGES];
#ifdef REHLDS_OPT_PEDANTIC #ifdef REHLDS_OPT_PEDANTIC
int g_oldest_challenge = 0; int g_oldest_challenge = 0;
#endif #endif
@ -2418,25 +2418,17 @@ void SVC_Ping(void)
NET_SendPacket(NS_SERVER, sizeof(data), data, net_from); NET_SendPacket(NS_SERVER, sizeof(data), data, net_from);
} }
/* <a78d3> ../engine/sv_main.c:3208 */ int SV_GetChallenge(netadr_t& adr)
void SVC_GetChallenge(void)
{ {
int i; int i;
#ifndef REHLDS_OPT_PEDANTIC #ifndef REHLDS_OPT_PEDANTIC
int oldest = 0; int oldest = 0;
int oldestTime = INT_MAX; int oldestTime = INT_MAX;
#endif #endif
char data[1024];
qboolean steam = FALSE;
if (Cmd_Argc() == 2 && !Q_stricmp(Cmd_Argv(1), "steam"))
{
steam = TRUE;
}
for (i = 0; i < MAX_CHALLENGES; i++) for (i = 0; i < MAX_CHALLENGES; i++)
{ {
if (NET_CompareBaseAdr(net_from, g_rg_sv_challenges[i].adr)) if (NET_CompareBaseAdr(adr, g_rg_sv_challenges[i].adr))
break; break;
#ifndef REHLDS_OPT_PEDANTIC #ifndef REHLDS_OPT_PEDANTIC
if (g_rg_sv_challenges[i].time < oldestTime) if (g_rg_sv_challenges[i].time < oldestTime)
@ -2446,7 +2438,7 @@ void SVC_GetChallenge(void)
} }
#endif #endif
} }
if (i == MAX_CHALLENGES) if (i == MAX_CHALLENGES)
{ {
#ifdef REHLDS_OPT_PEDANTIC #ifdef REHLDS_OPT_PEDANTIC
@ -2464,32 +2456,39 @@ void SVC_GetChallenge(void)
#else // REHLDS_FIXES #else // REHLDS_FIXES
g_rg_sv_challenges[i].challenge = (RandomLong(0, 36863) << 16) | (RandomLong(0, 65535)); g_rg_sv_challenges[i].challenge = (RandomLong(0, 36863) << 16) | (RandomLong(0, 65535));
#endif // REHLDS_FIXES #endif // REHLDS_FIXES
g_rg_sv_challenges[i].adr = net_from; g_rg_sv_challenges[i].adr = adr;
g_rg_sv_challenges[i].time = (int)realtime; g_rg_sv_challenges[i].time = (int)realtime;
} }
return g_rg_sv_challenges[i].challenge;
}
/* <a78d3> ../engine/sv_main.c:3208 */
void SVC_GetChallenge(void)
{
char data[1024];
qboolean steam = (Cmd_Argc() == 2 && !Q_stricmp(Cmd_Argv(1), "steam"));
int challenge = SV_GetChallenge(net_from);
if (steam) if (steam)
Q_snprintf(data, sizeof(data), "\xFF\xFF\xFF\xFF%c00000000 %u 3 %I64i %d\n", S2C_CHALLENGE, g_rg_sv_challenges[i].challenge, Steam_GSGetSteamID(), Steam_GSBSecure()); Q_snprintf(data, sizeof(data), "\xFF\xFF\xFF\xFF%c00000000 %u 3 %I64i %d\n", S2C_CHALLENGE, challenge, Steam_GSGetSteamID(), Steam_GSBSecure());
else else
{ {
Con_DPrintf("Server requiring authentication\n"); Con_DPrintf("Server requiring authentication\n");
Q_snprintf(data, sizeof(data), "\xFF\xFF\xFF\xFF%c00000000 %u 2\n", S2C_CHALLENGE, g_rg_sv_challenges[i].challenge); Q_snprintf(data, sizeof(data), "\xFF\xFF\xFF\xFF%c00000000 %u 2\n", S2C_CHALLENGE, challenge);
} }
// Give 3-rd party plugins a chance to modify challenge response // Give 3-rd party plugins a chance to modify challenge response
g_RehldsHookchains.m_SVC_GetChallenge_mod.callChain(NULL, data, g_rg_sv_challenges[i].challenge); g_RehldsHookchains.m_SVC_GetChallenge_mod.callChain(NULL, data, challenge);
NET_SendPacket(NS_SERVER, Q_strlen(data) + 1, data, net_from); NET_SendPacket(NS_SERVER, Q_strlen(data) + 1, data, net_from);
} }
/* <a794c> ../engine/sv_main.c:3292 */ /* <a794c> ../engine/sv_main.c:3292 */
void SVC_ServiceChallenge(void) void SVC_ServiceChallenge(void)
{ {
int i;
#ifndef REHLDS_OPT_PEDANTIC
int oldest = 0;
int oldestTime = INT_MAX;
#endif
char data[128]; char data[128];
const char *type; const char *type;
int challenge;
if (Cmd_Argc() != 2) if (Cmd_Argc() != 2)
return; return;
@ -2501,40 +2500,9 @@ void SVC_ServiceChallenge(void)
if (!type[0] || Q_stricmp(type, "rcon")) if (!type[0] || Q_stricmp(type, "rcon"))
return; return;
for (i = 0; i < MAX_CHALLENGES; i++) challenge = SV_GetChallenge(net_from);
{
if (NET_CompareBaseAdr(net_from, g_rg_sv_challenges[i].adr))
break;
#ifndef REHLDS_OPT_PEDANTIC Q_snprintf(data, sizeof(data), "%c%c%c%cchallenge %s %u\n", 255, 255, 255, 255, type, challenge);
if (g_rg_sv_challenges[i].time < oldestTime)
{
oldestTime = g_rg_sv_challenges[i].time;
oldest = i;
}
#endif
}
if (i == MAX_CHALLENGES) // no challenge for ip
{
#ifdef REHLDS_OPT_PEDANTIC
// oldest challenge is always next after last generated
i = g_oldest_challenge++;
if(g_oldest_challenge >= MAX_CHALLENGES)
g_oldest_challenge = 0;
#else
i = oldest;
#endif
// generate new challenge number
#ifdef REHLDS_FIXES
g_rg_sv_challenges[i].challenge = (RandomLong(0, 0x7fff) << 16) | (RandomLong(0, 0xffff));
#else // REHLDS_FIXES
g_rg_sv_challenges[i].challenge = (RandomLong(0, 36863) << 16) | (RandomLong(0, 65535));
#endif // REHLDS_FIXES
g_rg_sv_challenges[i].adr = net_from;
g_rg_sv_challenges[i].time = (int)realtime;
}
Q_snprintf(data, sizeof(data), "%c%c%c%cchallenge %s %u\n", 255, 255, 255, 255, type, g_rg_sv_challenges[i].challenge);
NET_SendPacket(NS_SERVER, Q_strlen(data) + 1, data, net_from); NET_SendPacket(NS_SERVER, Q_strlen(data) + 1, data, net_from);
} }

View File

@ -35,7 +35,7 @@
#include "model.h" #include "model.h"
#define REHLDS_API_VERSION_MAJOR 2 #define REHLDS_API_VERSION_MAJOR 2
#define REHLDS_API_VERSION_MINOR 1 #define REHLDS_API_VERSION_MINOR 2
//Steam_NotifyClientConnect hook //Steam_NotifyClientConnect hook
typedef IHookChain<qboolean, IGameClient*, const void*, unsigned int> IRehldsHook_Steam_NotifyClientConnect; typedef IHookChain<qboolean, IGameClient*, const void*, unsigned int> IRehldsHook_Steam_NotifyClientConnect;
@ -210,6 +210,7 @@ struct RehldsFuncs_t {
void(*MSG_EndBitWriting)(sizebuf_t *buf); void(*MSG_EndBitWriting)(sizebuf_t *buf);
void*(*SZ_GetSpace)(sizebuf_t *buf, int length); void*(*SZ_GetSpace)(sizebuf_t *buf, int length);
cvar_t*(*GetCvarVars)(); cvar_t*(*GetCvarVars)();
int (*SV_GetChallenge)(netadr_t& adr);
}; };
class IRehldsApi { class IRehldsApi {

View File

@ -120,7 +120,8 @@ RehldsFuncs_t g_RehldsApiFuncs =
&MSG_WriteBitVec3Coord_api, &MSG_WriteBitVec3Coord_api,
&MSG_EndBitWriting_api, &MSG_EndBitWriting_api,
&SZ_GetSpace, &SZ_GetSpace,
&GetCvarVars_api &GetCvarVars_api,
&SV_GetChallenge
}; };
sizebuf_t* EXT_FUNC GetNetMessage_api() sizebuf_t* EXT_FUNC GetNetMessage_api()