added amb1235, added support for the IServer interface

added a native to retrieve the spray file of a client
added a native to get the net traffic of the server

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401775
This commit is contained in:
Borja Ferrer 2007-12-06 02:25:35 +00:00
parent 04c0684879
commit 9ab9eba5d7
10 changed files with 183 additions and 0 deletions

View File

@ -64,6 +64,7 @@ IServerGameClients *serverClients = NULL;
IVoiceServer *voiceserver = NULL; IVoiceServer *voiceserver = NULL;
IPlayerInfoManager *playerinfomngr = NULL; IPlayerInfoManager *playerinfomngr = NULL;
ICvar *icvar = NULL; ICvar *icvar = NULL;
IServer *iserver = NULL;
SourceHook::CallClass<IVEngineServer> *enginePatch = NULL; SourceHook::CallClass<IVEngineServer> *enginePatch = NULL;
SourceHook::CallClass<IEngineSound> *enginesoundPatch = NULL; SourceHook::CallClass<IEngineSound> *enginesoundPatch = NULL;
HandleType_t g_CallHandle = 0; HandleType_t g_CallHandle = 0;
@ -204,6 +205,7 @@ void SDKTools::SDK_OnAllLoaded()
s_TempEntHooks.Initialize(); s_TempEntHooks.Initialize();
s_SoundHooks.Initialize(); s_SoundHooks.Initialize();
InitializeValveGlobals(); InitializeValveGlobals();
GetIServer();
} }
bool SDKTools::QueryRunning(char *error, size_t maxlength) bool SDKTools::QueryRunning(char *error, size_t maxlength)

View File

@ -46,6 +46,8 @@
#include <ivoiceserver.h> #include <ivoiceserver.h>
#include <iplayerinfo.h> #include <iplayerinfo.h>
#include <convar.h> #include <convar.h>
#include <iserver.h>
#include <cdll_int.h>
#include <compat_wrappers.h> #include <compat_wrappers.h>
/** /**
@ -99,6 +101,7 @@ extern IServerGameClients *serverClients;
extern IVoiceServer *voiceserver; extern IVoiceServer *voiceserver;
extern IPlayerInfoManager *playerinfomngr; extern IPlayerInfoManager *playerinfomngr;
extern ICvar *icvar; extern ICvar *icvar;
extern IServer *iserver;
/* Interfaces from SourceMod */ /* Interfaces from SourceMod */
extern IBinTools *g_pBinTools; extern IBinTools *g_pBinTools;
extern IGameConfig *g_pGameConf; extern IGameConfig *g_pGameConf;

View File

@ -82,3 +82,60 @@ void InitializeValveGlobals()
g_pGameRules = reinterpret_cast<void **>(addr); g_pGameRules = reinterpret_cast<void **>(addr);
} }
#endif #endif
#if defined PLATFORM_WINDOWS
/* Thanks to DS for the sigs */
#define ISERVER_WIN_SIG "\x8B\x44\x24\x2A\x50\xB9\x2A\x2A\x2A\x2A\xE8"
#define ISERVER_WIN_SIG_LEN 11
void GetIServer()
{
/* First check that the IVEngineServer::CreateFakeClient exists */
if (!memutils->FindPattern(engine, ISERVER_WIN_SIG, ISERVER_WIN_SIG_LEN))
{
return;
}
int offset;
void *vfunc = NULL;
/* Get the offset into CreateFakeClient */
if (!g_pGameConf->GetOffset("sv", &offset))
{
return;
}
#if defined METAMOD_PLAPI_VERSION
/* Get the CreateFakeClient function pointer */
if (!(vfunc=SH_GET_ORIG_VFNPTR_ENTRY(engine, &IVEngineServer::CreateFakeClient)))
{
return;
}
/* Finally we have the interface we were looking for */
iserver = *reinterpret_cast<IServer **>(reinterpret_cast<unsigned char *>(vfunc) + offset);
#else
/* Get the interface manually */
SourceHook::MemFuncInfo info = {true, -1, 0, 0};
SourceHook::GetFuncInfo(&IVEngineServer::CreateFakeClient, info);
vfunc = enginePatch->GetOrigFunc(info.vtbloffs, info.vtblindex);
if (!vfunc)
{
void **vtable = *reinterpret_cast<void ***>(enginePatch->GetThisPtr() + info.thisptroffs + info.vtbloffs);
vfunc = vtable[info.vtblindex];
}
iserver = *reinterpret_cast<IServer **>(reinterpret_cast<unsigned char *>(vfunc) + offset);
#endif
}
#elif defined PLATFORM_POSIX
void GetIServer()
{
void *addr;
if (!g_pGameConf->GetMemSig("sv", &addr) || !addr)
{
return;
}
iserver = *reinterpret_cast<IServer **>(addr);
}
#endif

View File

@ -36,5 +36,6 @@ extern void **g_pGameRules;
extern void *g_EntList; extern void *g_EntList;
void InitializeValveGlobals(); void InitializeValveGlobals();
void GetIServer();
#endif // _INCLUDE_SDKTOOLS_VGLOBALS_H_ #endif // _INCLUDE_SDKTOOLS_VGLOBALS_H_

View File

@ -267,6 +267,15 @@ bool IsEyeAnglesSupported()
return SetupGetEyeAngles(); return SetupGetEyeAngles();
} }
bool GetPlayerInfo(int client, player_info_t *info)
{
#if defined ORANGEBOX_BUILD
return engine->GetPlayerInfo(client, info);
#else
return iserver->GetPlayerInfo(client, info);
#endif
}
void ShutdownHelpers() void ShutdownHelpers()
{ {
s_Teleport.Shutdown(); s_Teleport.Shutdown();

View File

@ -68,6 +68,8 @@ bool IsEyeAnglesSupported();
int GetClientAimTarget(edict_t *pEdict, bool only_players); int GetClientAimTarget(edict_t *pEdict, bool only_players);
bool GetPlayerInfo(int client, player_info_t *info);
void ShutdownHelpers(); void ShutdownHelpers();
#endif //_INCLUDE_SDKTOOLS_VHELPERS_H_ #endif //_INCLUDE_SDKTOOLS_VHELPERS_H_

View File

@ -825,6 +825,47 @@ static cell_t sm_SetEntityModel(IPluginContext *pContext, const cell_t *params)
return 1; return 1;
} }
static cell_t GetPlayerDecalFile(IPluginContext *pContext, const cell_t *params)
{
IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]);
if (player == NULL)
{
return pContext->ThrowNativeError("Invalid client index %d", params[1]);
}
if (!player->IsInGame())
{
return pContext->ThrowNativeError("Client %d is not in game", params[1]);
}
player_info_t info;
char *buffer;
if (!GetPlayerInfo(params[1], &info) || !info.customFiles[0])
{
return 0;
}
pContext->LocalToString(params[2], &buffer);
Q_binarytohex((byte *)&info.customFiles[0], sizeof(info.customFiles[0]), buffer, params[3]);
return 1;
}
static cell_t GetServerNetStats(IPluginContext *pContext, const cell_t *params)
{
float in, out;
cell_t *pIn, *pOut;
pContext->LocalToPhysAddr(params[1], &pIn);
pContext->LocalToPhysAddr(params[2], &pOut);
iserver->GetNetStats(in, out);
*pIn = sp_ftoc(in);
*pOut = sp_ftoc(out);
return 1;
}
sp_nativeinfo_t g_Natives[] = sp_nativeinfo_t g_Natives[] =
{ {
{"ExtinguishPlayer", ExtinguishEntity}, {"ExtinguishPlayer", ExtinguishEntity},
@ -850,5 +891,7 @@ sp_nativeinfo_t g_Natives[] =
{"DispatchKeyValueVector", DispatchKeyValueVector}, {"DispatchKeyValueVector", DispatchKeyValueVector},
{"GetClientAimTarget", sm_GetClientAimTarget}, {"GetClientAimTarget", sm_GetClientAimTarget},
{"SetEntityModel", sm_SetEntityModel}, {"SetEntityModel", sm_SetEntityModel},
{"GetPlayerDecalFile", GetPlayerDecalFile},
{"GetServerNetStats", GetServerNetStats},
{NULL, NULL}, {NULL, NULL},
}; };

View File

@ -178,6 +178,29 @@
} }
} }
/* IServer interface pointer */
"#default"
{
"Offsets"
{
/* Offset into IVEngineServer::CreateFakeClient */
"sv"
{
"windows" "6"
}
}
"Signatures"
{
/* CBaseServer object for IServer interface */
"sv"
{
"library" "engine"
"linux" "@sv"
}
}
}
/* Team Fortress 2 Offsets */ /* Team Fortress 2 Offsets */
"tf" "tf"
{ {

View File

@ -216,6 +216,29 @@
} }
} }
/* IServer interface pointer */
"#default"
{
"Offsets"
{
/* Offset into IVEngineServer::CreateFakeClient */
"sv"
{
"windows" "6"
}
}
"Signatures"
{
/* CBaseServer object for IServer interface */
"sv"
{
"library" "engine"
"linux" "@sv"
}
}
}
/* Counter-Strike: Source */ /* Counter-Strike: Source */
"cstrike" "cstrike"
{ {

View File

@ -264,6 +264,26 @@ native GetTeamClientCount(index);
*/ */
native SetEntityModel(entity, const String:model[]); native SetEntityModel(entity, const String:model[]);
/**
* Retrieves the decal file name associated to a given client.
*
* @param client Player's index.
* @param hex Buffer to store the logo filename.
* @param maxlength Maximum length of string buffer.
* @return True on success, otherwise false.
* @error Invalid client or client not in game.
*/
native bool:GetPlayerDecalFile(client, String:hex[], maxlength);
/**
* Returns the average server network traffic in bytes/sec.
*
* @param in Buffer to store the input traffic velocity.
* @param out Buffer to store the output traffic velocity.
* @noreturn
*/
native GetServerNetStats(&Float:in, &Float:out);
/** /**
* @deprecated * @deprecated
*/ */