Skip to content

Commit

Permalink
API: Implement *_Precache_*, ClientPrintf, CheckUserInfo and …
Browse files Browse the repository at this point in the history
…`AddResource` hooks (#903)

* Added SV_CheckUserInfo hook

* Implemented PF_precache_*  hooks

- PF_precache_sound_I
- PF_precache_model_I
- PF_precache_generic_I

* Added EV_Precache and SV_AddResource hooks

and update API minor version

* Added SV_AddResource_internal and fixed pointers

* Added SV_AddResource_hook, fixed chain EV_Precache

* Reworked SV_AddResource for Rehlds API

* Reverted RehldsFuncs_t's SV_AddResource API

* Updated chains

* Update rehlds_api_impl.h

* Implement `SV_ClientPrintf` hook

* Changed `SV_ClientPrintf` chain type to void

* Revert `SV_ClientPrintf` code refactor

* Removed `const` string type

in order to resize the string.

* Changes according to var type

* Fixing function's functionality

* Moved vars declaration after `host_client` check

* revert variable naming in SV_ClientPrintf

* `SV_ClientPrintf_internal`: more safe string copy

Co-authored-by: wopox1337 <wopox1337@ya.ru>
  • Loading branch information
ShadowsAdi and wopox1337 committed Sep 19, 2022
1 parent d76b06d commit d6ebe82
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 11 deletions.
20 changes: 13 additions & 7 deletions rehlds/engine/host.cpp
Expand Up @@ -351,22 +351,28 @@ void Host_WriteCustomConfig(void)

void SV_ClientPrintf(const char *fmt, ...)
{
va_list va;
char string[1024];

if (!host_client->fakeclient)
{
va_list va;
char string[1024];

va_start(va, fmt);
Q_vsnprintf(string, ARRAYSIZE(string) - 1, fmt, va);
va_end(va);

string[ARRAYSIZE(string) - 1] = 0;

MSG_WriteByte(&host_client->netchan.message, svc_print);
MSG_WriteString(&host_client->netchan.message, string);
g_RehldsHookchains.m_SV_ClientPrintf.callChain(SV_ClientPrintf_internal, string);
}
}

void EXT_FUNC SV_ClientPrintf_internal(const char *Dest)
{
char string[1024];

Q_strlcpy(string, Dest, min(strlen(Dest) + 1, sizeof(string)));
MSG_WriteByte(&host_client->netchan.message, svc_print);
MSG_WriteString(&host_client->netchan.message, string);
}

void SV_BroadcastPrintf(const char *fmt, ...)
{
va_list argptr;
Expand Down
1 change: 1 addition & 0 deletions rehlds/engine/host.h
Expand Up @@ -85,6 +85,7 @@ NOXREF void Info_WriteVars(FileHandle_t fp);
void Host_WriteConfiguration(void);
void Host_WriteCustomConfig(void);
void SV_ClientPrintf(const char *fmt, ...);
void SV_ClientPrintf_internal(const char *Dest);
void SV_BroadcastPrintf(const char *fmt, ...);
void Host_ClientCommands(const char *fmt, ...);
void SV_DropClient_api(IGameClient* cl, bool crash, const char* fmt, ...);
Expand Down
24 changes: 22 additions & 2 deletions rehlds/engine/pr_cmds.cpp
Expand Up @@ -1011,6 +1011,11 @@ qboolean EXT_FUNC PR_IsEmptyString(const char *s)
}

int EXT_FUNC PF_precache_sound_I(const char *s)
{
return g_RehldsHookchains.m_PF_precache_sound_I.callChain(PF_precache_sound_I_internal, s);
}

int EXT_FUNC PF_precache_sound_I_internal(const char *s)
{
if (!s)
Host_Error("%s: NULL pointer", __func__);
Expand Down Expand Up @@ -1058,6 +1063,11 @@ int EXT_FUNC PF_precache_sound_I(const char *s)
}

unsigned short EXT_FUNC EV_Precache(int type, const char *psz)
{
return g_RehldsHookchains.m_EV_Precache.callChain(EV_Precache_internal, type, psz);
}

unsigned short EXT_FUNC EV_Precache_internal(int type, const char *psz)
{
if (!psz)
Host_Error("%s: NULL pointer", __func__);
Expand Down Expand Up @@ -1377,6 +1387,11 @@ int SV_LookupModelIndex(const char *name)
}

int EXT_FUNC PF_precache_model_I(const char *s)
{
return g_RehldsHookchains.m_PF_precache_model_I.callChain(PF_precache_model_I_internal, s);
}

int EXT_FUNC PF_precache_model_I_internal(const char *s)
{
int iOptional = 0;
if (!s)
Expand Down Expand Up @@ -1445,8 +1460,13 @@ int EXT_FUNC PF_precache_model_I(const char *s)
}
}

#ifdef REHLDS_FIXES
int EXT_FUNC PF_precache_generic_I(const char *s)
{
return g_RehldsHookchains.m_PF_precache_generic_I.callChain(PF_precache_generic_I_internal, s);
}

#ifdef REHLDS_FIXES
int EXT_FUNC PF_precache_generic_I_internal(const char *s)
{
if (!s)
Host_Error("%s: NULL pointer", __func__);
Expand Down Expand Up @@ -1493,7 +1513,7 @@ int EXT_FUNC PF_precache_generic_I(const char *s)
return g_rehlds_sv.precachedGenericResourceCount++;
}
#else // REHLDS_FIXES
int EXT_FUNC PF_precache_generic_I(const char *s)
int EXT_FUNC PF_precache_generic_I_internal(const char *s)
{
if (!s)
Host_Error("%s: NULL pointer", __func__);
Expand Down
4 changes: 4 additions & 0 deletions rehlds/engine/pr_cmds.h
Expand Up @@ -120,14 +120,18 @@ edict_t *FindEntityByString(edict_t *pEdictStartSearchAfter, const char *pszFiel
int GetEntityIllum(edict_t *pEnt);
qboolean PR_IsEmptyString(const char *s);
int PF_precache_sound_I(const char *s);
int PF_precache_sound_I_internal(const char *s);
unsigned short EV_Precache(int type, const char *psz);
unsigned short EV_Precache_internal(int type, const char *psz);
void EV_PlayReliableEvent_api(IGameClient *cl, int entindex, unsigned short eventindex, float delay, event_args_t *pargs);
void EV_PlayReliableEvent(client_t *cl, int entindex, unsigned short eventindex, float delay, event_args_t *pargs);
void EV_PlayReliableEvent_internal(client_t *cl, int entindex, unsigned short eventindex, float delay, event_args_t *pargs);
void EV_Playback(int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2);
void EV_SV_Playback(int flags, int clientindex, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2);
int PF_precache_model_I(const char *s);
int PF_precache_model_I_internal(const char *s);
int PF_precache_generic_I(const char *s);
int PF_precache_generic_I_internal(const char *s);
int PF_IsMapValid_I(const char *mapname);
int PF_NumberOfEntities_I(void);
char *PF_GetInfoKeyBuffer_I(edict_t *e);
Expand Down
2 changes: 2 additions & 0 deletions rehlds/engine/server.h
Expand Up @@ -498,6 +498,7 @@ int SV_CheckKeyInfo_internal(netadr_t *adr, char *protinfo, unsigned short *port
int SV_CheckForDuplicateSteamID(client_t *client);
qboolean SV_CheckForDuplicateNames(char *userinfo, qboolean bIsReconnecting, int nExcludeSlot);
int SV_CheckUserInfo(netadr_t *adr, char *userinfo, qboolean bIsReconnecting, int nReconnectSlot, char *name);
int SV_CheckUserInfo_internal(netadr_t *adr, char *userinfo, qboolean bIsReconnecting, int nReconnectSlot, char *name);
int SV_FindEmptySlot(netadr_t *adr, int *pslot, client_t ** ppClient);
void SV_ConnectClient(void);
void SV_ConnectClient_internal(void);
Expand Down Expand Up @@ -569,6 +570,7 @@ void SV_SendClientMessages(void);
void SV_ExtractFromUserinfo(client_t *cl);
int SV_ModelIndex(const char *name);
void SV_AddResource(resourcetype_t type, const char *name, int size, unsigned char flags, int index);
void SV_AddResource_internal(resourcetype_t type, const char *name, int size, unsigned char flags, int index);
size_t SV_CountResourceByType(resourcetype_t type, resource_t **pResourceList = nullptr, size_t nListMax = 0, size_t *nWidthFileNameMax = nullptr);
void SV_CreateGenericResources(void);
void SV_CreateResourceList(void);
Expand Down
15 changes: 15 additions & 0 deletions rehlds/engine/sv_main.cpp
Expand Up @@ -2115,6 +2115,11 @@ void SV_ReplaceSpecialCharactersInName(char *newname, const char *oldname)
#endif

int SV_CheckUserInfo(netadr_t *adr, char *userinfo, qboolean bIsReconnecting, int nReconnectSlot, char *name)
{
return g_RehldsHookchains.m_SV_CheckUserInfo.callChain(SV_CheckUserInfo_internal, adr, userinfo, bIsReconnecting, nReconnectSlot, name);
}

int EXT_FUNC SV_CheckUserInfo_internal(netadr_t *adr, char *userinfo, qboolean bIsReconnecting, int nReconnectSlot, char *name)
{
const char *s;
char newname[MAX_NAME];
Expand Down Expand Up @@ -5120,7 +5125,17 @@ int SV_ModelIndex(const char *name)
Sys_Error("%s: SV_ModelIndex: model %s not precached", __func__, name);
}

void EXT_FUNC SV_AddResource_hook(resourcetype_t type, const char *name, int size, unsigned char flags, int index)
{
SV_AddResource_internal(type, name, size, flags, index);
}

void EXT_FUNC SV_AddResource(resourcetype_t type, const char *name, int size, unsigned char flags, int index)
{
g_RehldsHookchains.m_SV_AddResource.callChain(SV_AddResource_hook, type, name, size, flags, index);
}

void SV_AddResource_internal(resourcetype_t type, const char *name, int size, unsigned char flags, int index)
{
resource_t *r;
#ifdef REHLDS_FIXES
Expand Down
36 changes: 35 additions & 1 deletion rehlds/public/rehlds/rehlds_api.h
Expand Up @@ -37,7 +37,7 @@
#include "pr_dlls.h"

#define REHLDS_API_VERSION_MAJOR 3
#define REHLDS_API_VERSION_MINOR 11
#define REHLDS_API_VERSION_MINOR 12

//Steam_NotifyClientConnect hook
typedef IHookChain<qboolean, IGameClient*, const void*, unsigned int> IRehldsHook_Steam_NotifyClientConnect;
Expand Down Expand Up @@ -227,6 +227,33 @@ typedef IVoidHookChainRegistry<edict_t *> IRehldsHookRegistry_ED_Free;
typedef IHookChain<void, const char *> IRehldsHook_Con_Printf;
typedef IHookChainRegistry<void, const char *> IRehldsHookRegistry_Con_Printf;

//SV_CheckUserInfo hook
typedef IHookChain<int, netadr_t *, char *, qboolean, int, char *> IRehldsHook_SV_CheckUserInfo;
typedef IHookChainRegistry<int, netadr_t *, char *, qboolean, int, char *> IRehldsHookRegistry_SV_CheckUserInfo;

//PF_precache_generic_I hook
typedef IHookChain<int, const char *> IRehldsHook_PF_precache_generic_I;
typedef IHookChainRegistry<int, const char *> IRehldsHookRegistry_PF_precache_generic_I;

//PF_precache_model_I hook
typedef IHookChain<int, const char *> IRehldsHook_PF_precache_model_I;
typedef IHookChainRegistry<int, const char *> IRehldsHookRegistry_PF_precache_model_I;

//PF_precache_sound_I hook
typedef IHookChain<int, const char *> IRehldsHook_PF_precache_sound_I;
typedef IHookChainRegistry<int, const char *> IRehldsHookRegistry_PF_precache_sound_I;

//EV_Precache hook
typedef IHookChain<unsigned short, int, const char *> IRehldsHook_EV_Precache;
typedef IHookChainRegistry<unsigned short, int, const char *> IRehldsHookRegistry_EV_Precache;

//SV_AddResource hook
typedef IVoidHookChain<resourcetype_t, const char *, int, unsigned char, int> IRehldsHook_SV_AddResource;
typedef IVoidHookChainRegistry<resourcetype_t, const char *, int, unsigned char, int> IRehldsHookRegistry_SV_AddResource;

//SV_ClientPrintf hook
typedef IVoidHookChain<const char *> IRehldsHook_SV_ClientPrintf;
typedef IVoidHookChainRegistry<const char *> IRehldsHookRegistry_SV_ClientPrintf;

class IRehldsHookchains {
public:
Expand Down Expand Up @@ -279,6 +306,13 @@ class IRehldsHookchains {
virtual IRehldsHookRegistry_ED_Alloc* ED_Alloc() = 0;
virtual IRehldsHookRegistry_ED_Free* ED_Free() = 0;
virtual IRehldsHookRegistry_Con_Printf* Con_Printf() = 0;
virtual IRehldsHookRegistry_SV_CheckUserInfo* SV_CheckUserInfo() = 0;
virtual IRehldsHookRegistry_PF_precache_generic_I* PF_precache_generic_I() = 0;
virtual IRehldsHookRegistry_PF_precache_model_I* PF_precache_model_I() = 0;
virtual IRehldsHookRegistry_PF_precache_sound_I* PF_precache_sound_I() = 0;
virtual IRehldsHookRegistry_EV_Precache* EV_Precache() = 0;
virtual IRehldsHookRegistry_SV_AddResource* SV_AddResource() = 0;
virtual IRehldsHookRegistry_SV_ClientPrintf* SV_ClientPrintf() = 0;
};

struct RehldsFuncs_t {
Expand Down
28 changes: 28 additions & 0 deletions rehlds/rehlds/rehlds_api_impl.cpp
Expand Up @@ -851,6 +851,34 @@ IRehldsHookRegistry_Con_Printf* CRehldsHookchains::Con_Printf() {
return &m_Con_Printf;
}

IRehldsHookRegistry_SV_CheckUserInfo* CRehldsHookchains::SV_CheckUserInfo() {
return &m_SV_CheckUserInfo;
}

IRehldsHookRegistry_PF_precache_generic_I* CRehldsHookchains::PF_precache_generic_I() {
return &m_PF_precache_generic_I;
}

IRehldsHookRegistry_PF_precache_model_I* CRehldsHookchains::PF_precache_model_I() {
return &m_PF_precache_model_I;
}

IRehldsHookRegistry_PF_precache_sound_I* CRehldsHookchains::PF_precache_sound_I() {
return &m_PF_precache_sound_I;
}

IRehldsHookRegistry_EV_Precache* CRehldsHookchains::EV_Precache() {
return &m_EV_Precache;
}

IRehldsHookRegistry_SV_AddResource* CRehldsHookchains::SV_AddResource(){
return &m_SV_AddResource;
}

IRehldsHookRegistry_SV_ClientPrintf* CRehldsHookchains::SV_ClientPrintf(){
return &m_SV_ClientPrintf;
}

int EXT_FUNC CRehldsApi::GetMajorVersion()
{
return REHLDS_API_VERSION_MAJOR;
Expand Down
42 changes: 42 additions & 0 deletions rehlds/rehlds/rehlds_api_impl.h
Expand Up @@ -222,6 +222,34 @@ typedef IVoidHookChainRegistryImpl<edict_t *> CRehldsHookRegistry_ED_Free;
typedef IHookChainImpl<void, const char *> CRehldsHook_Con_Printf;
typedef IHookChainRegistryImpl<void, const char *> CRehldsHookRegistry_Con_Printf;

//SV_CheckUserInfo hook
typedef IHookChainImpl<int, netadr_t*, char*, qboolean, int, char*> CRehldsHook_SV_CheckUserInfo;
typedef IHookChainRegistryImpl<int, netadr_t*, char*, qboolean, int, char*> CRehldsHookRegistry_SV_CheckUserInfo;

//PF_precache_generic_I hook
typedef IHookChainImpl<int, const char*> CRehldsHook_PF_precache_generic_I;
typedef IHookChainRegistryImpl<int, const char*> CRehldsHookRegistry_PF_precache_generic_I;

//PF_precache_model_I hook
typedef IHookChainImpl<int, const char*> CRehldsHook_PF_precache_model_I;
typedef IHookChainRegistryImpl<int, const char*> CRehldsHookRegistry_PF_precache_model_I;

//PF_precache_sound_I hook
typedef IHookChainImpl<int, const char*> CRehldsHook_PF_precache_sound_I;
typedef IHookChainRegistryImpl<int, const char*> CRehldsHookRegistry_PF_precache_sound_I;

//EV_Precache hook
typedef IHookChainImpl<unsigned short, int, const char*> CRehldsHook_EV_Precache;
typedef IHookChainRegistryImpl<unsigned short, int, const char*> CRehldsHookRegistry_EV_Precache;

//SV_AddResource hook
typedef IVoidHookChainImpl<resourcetype_t, const char*, int, unsigned char, int> CRehldsHook_SV_AddResource;
typedef IVoidHookChainRegistryImpl<resourcetype_t, const char*, int, unsigned char, int> CRehldsHookRegistry_SV_AddResource;

//SV_ClientPrintf hook
typedef IVoidHookChainImpl<const char*> CRehldsHook_SV_ClientPrintf;
typedef IVoidHookChainRegistryImpl<const char*> CRehldsHookRegistry_SV_ClientPrintf;

class CRehldsHookchains : public IRehldsHookchains {
public:
CRehldsHookRegistry_Steam_NotifyClientConnect m_Steam_NotifyClientConnect;
Expand Down Expand Up @@ -271,6 +299,13 @@ class CRehldsHookchains : public IRehldsHookchains {
CRehldsHookRegistry_ED_Alloc m_ED_Alloc;
CRehldsHookRegistry_ED_Free m_ED_Free;
CRehldsHookRegistry_Con_Printf m_Con_Printf;
CRehldsHookRegistry_SV_CheckUserInfo m_SV_CheckUserInfo;
CRehldsHookRegistry_PF_precache_generic_I m_PF_precache_generic_I;
CRehldsHookRegistry_PF_precache_model_I m_PF_precache_model_I;
CRehldsHookRegistry_PF_precache_sound_I m_PF_precache_sound_I;
CRehldsHookRegistry_EV_Precache m_EV_Precache;
CRehldsHookRegistry_SV_AddResource m_SV_AddResource;
CRehldsHookRegistry_SV_ClientPrintf m_SV_ClientPrintf;

public:
EXT_FUNC virtual IRehldsHookRegistry_Steam_NotifyClientConnect* Steam_NotifyClientConnect();
Expand Down Expand Up @@ -320,6 +355,13 @@ class CRehldsHookchains : public IRehldsHookchains {
EXT_FUNC virtual IRehldsHookRegistry_ED_Alloc* ED_Alloc();
EXT_FUNC virtual IRehldsHookRegistry_ED_Free* ED_Free();
EXT_FUNC virtual IRehldsHookRegistry_Con_Printf* Con_Printf();
EXT_FUNC virtual IRehldsHookRegistry_SV_CheckUserInfo* SV_CheckUserInfo();
EXT_FUNC virtual IRehldsHookRegistry_PF_precache_generic_I* PF_precache_generic_I();
EXT_FUNC virtual IRehldsHookRegistry_PF_precache_model_I* PF_precache_model_I();
EXT_FUNC virtual IRehldsHookRegistry_PF_precache_sound_I* PF_precache_sound_I();
EXT_FUNC virtual IRehldsHookRegistry_EV_Precache* EV_Precache();
EXT_FUNC virtual IRehldsHookRegistry_SV_AddResource* SV_AddResource();
EXT_FUNC virtual IRehldsHookRegistry_SV_ClientPrintf* SV_ClientPrintf();
};

extern CRehldsHookchains g_RehldsHookchains;
Expand Down
2 changes: 1 addition & 1 deletion rehlds/version/version.h
Expand Up @@ -6,5 +6,5 @@
#pragma once

#define VERSION_MAJOR 3
#define VERSION_MINOR 11
#define VERSION_MINOR 12
#define VERSION_MAINTENANCE 0

1 comment on commit d6ebe82

@StevenKal
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic!!!
PS: So cute picture wopox!

Please sign in to comment.