Simple implementation for cvar queries

This commit is contained in:
Pavol Marko 2005-08-27 23:00:44 +00:00
parent ca1544564c
commit dc57ef1e0c
5 changed files with 118 additions and 4 deletions

View File

@ -59,6 +59,10 @@ void CPlayer::Disconnect() {
ingame = false;
initialized = false;
authorized = false;
while (!cvarQueryQueue.empty())
cvarQueryQueue.pop();
bot = 0;
}

View File

@ -62,9 +62,15 @@ public:
// class CPlayer
// *****************************************************
struct ClientCvarQuery_Info
{
bool querying; // Are we actually waiting for a response at the moment?
String cvarName;
int resultFwd;
};
class CPlayer
{
public:
edict_t* pEdict;
@ -106,6 +112,8 @@ public:
Vector thisTrace;
Vector lastHit;
CQueue<ClientCvarQuery_Info*> cvarQueryQueue;
void Init( edict_t* e , int i );
void Disconnect();
void PutInServer();

View File

@ -2921,6 +2921,56 @@ static cell AMX_NATIVE_CALL int3(AMX *amx, cell *params)
return 0;
}
/*********************************************************************/
// native query_client_cvar(id, const cvar[], const resultfunc[])
static cell AMX_NATIVE_CALL query_client_cvar(AMX *amx, cell *params)
{
if (!g_NewDLL_Available)
{
LogError(amx, AMX_ERR_NATIVE, "NewDLL functions are not available. Blame (your) metamod (version)");
return 0;
}
int id = params[1];
if (id < 1 || id > gpGlobals->maxClients)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", id);
return 0;
}
CPlayer *pPlayer = GET_PLAYER_POINTER_I(id);
if (!pPlayer->initialized || pPlayer->bot)
{
LogError(amx, AMX_ERR_NATIVE, "Player %d is either not connected or a bot", id);
return 0;
}
int dummy;
const char *cvarname = get_amxstring(amx, params[2], 0, dummy);
const char *resultfuncname = get_amxstring(amx, params[3], 1, dummy);
// public clientcvarquery_result(id, const cvar[], const result[])
int iFunc = registerSPForwardByName(amx, resultfuncname, FP_CELL, FP_STRING, FP_STRING, FP_DONE);
if (iFunc == -1)
{
LogError(amx, AMX_ERR_NATIVE, "Function \"%s\" is not present", resultfuncname);
return 0;
}
ClientCvarQuery_Info *queryObject = new ClientCvarQuery_Info;
queryObject->querying = false;
queryObject->cvarName.assign(cvarname);
queryObject->resultFwd = iFunc;
pPlayer->cvarQueryQueue.push(queryObject);
return 1;
}
AMX_NATIVE_INFO amxmod_Natives[] = {
{ "client_cmd", client_cmd },
{ "client_print", client_print },
@ -3089,5 +3139,6 @@ AMX_NATIVE_INFO amxmod_Natives[] = {
{ "lang_phrase", lang_phrase},
{ "mkdir", amx_mkdir},
{ "int3", int3},
{ "query_client_cvar", query_client_cvar },
{ NULL, NULL }
};

View File

@ -176,6 +176,7 @@ extern float g_game_restarting;
extern float g_game_timeleft;
extern float g_task_time;
extern float g_auth_time;
extern bool g_NewDLL_Available;
extern hudtextparms_t g_hudset;
//extern int g_edict_point;
extern int g_players_num;

View File

@ -97,6 +97,7 @@ bool g_IsNewMM = false;
bool g_NeedsP = false;
bool g_coloredmenus;
bool g_activated = false;
bool g_NewDLL_Available=false;
#ifdef MEMORY_TEST
float g_next_memreport_time;
@ -818,6 +819,22 @@ void C_StartFrame_Post( void )
g_tasksMngr.startFrame();
// Dispatch client cvar queries
for(int i = 1; i <= gpGlobals->maxClients; ++i)
{
CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
if (pPlayer->pEdict && pPlayer->initialized && !pPlayer->cvarQueryQueue.empty())
{
if (!IS_QUERYING_CLIENT_CVAR(PLID, pPlayer->pEdict))
{
QUERY_CLIENT_CVAR_VALUE(pPlayer->pEdict, pPlayer->cvarQueryQueue.front()->cvarName.c_str());
pPlayer->cvarQueryQueue.front()->querying = true;
}
}
}
RETURN_META(MRES_IGNORED);
}
@ -1004,6 +1021,26 @@ void C_AlertMessage_Post(ALERT_TYPE atype, char *szFmt, ...)
RETURN_META(MRES_IGNORED);
}
void C_CvarValue(const edict_t *pEdict, const char *value)
{
CPlayer *pPlayer = GET_PLAYER_POINTER(pEdict);
if (pPlayer->cvarQueryQueue.empty())
RETURN_META(MRES_IGNORED);
ClientCvarQuery_Info *pQuery = pPlayer->cvarQueryQueue.front();
if (pPlayer->cvarQueryQueue.front()->querying)
{
executeForwards(pQuery->resultFwd, ENTINDEX(pEdict), pQuery->cvarName.c_str(), value);
unregisterSPForward(pQuery->resultFwd);
delete pQuery;
pPlayer->cvarQueryQueue.pop();
RETURN_META(MRES_HANDLED);
}
RETURN_META(MRES_IGNORED);
}
bool m_NeedsP = false;
C_DLLEXPORT int Meta_Query(char *ifvers, plugin_info_t **pPlugInfo, mutil_funcs_t *pMetaUtilFuncs)
@ -1091,8 +1128,8 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
gMetaFunctionTable.pfnGetEntityAPI2_Post = GetEntityAPI2_Post;
gMetaFunctionTable.pfnGetEngineFunctions = GetEngineFunctions;
gMetaFunctionTable.pfnGetEngineFunctions_Post = GetEngineFunctions_Post;
#ifdef FAKEMETA
gMetaFunctionTable.pfnGetNewDLLFunctions = GetNewDLLFunctions;
#ifdef FAKEMETA
gMetaFunctionTable.pfnGetNewDLLFunctions_Post = GetNewDLLFunctions_Post;
#endif
@ -1354,17 +1391,30 @@ C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int
#endif
}
#ifdef FAKEMETA
NEW_DLL_FUNCTIONS gNewDLLFunctionTable;
C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion)
{
// default metamod does not call this if the gamedll doesn't provide it
g_NewDLL_Available = true;
gNewDLLFunctionTable.pfnCvarValue = C_CvarValue;
#ifdef FAKEMETA
return g_FakeMeta.GetNewDLLFunctions(pNewFunctionTable, interfaceVersion, &gNewDLLFunctionTable);
#else
memcpy(pNewFunctionTable, &gNewDLLFunctionTable, sizeof(NEW_DLL_FUNCTIONS));
return 1;
#endif
}
#ifdef FAKEMETA
NEW_DLL_FUNCTIONS gNewDLLFunctionTable_Post;
C_DLLEXPORT int GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion)
{
return g_FakeMeta.GetNewDLLFunctions_Post(pNewFunctionTable, interfaceVersion, &gNewDLLFunctionTable_Post);
memcpy(pNewFunctionTable, &gNewDLLFunctionTable_Post, sizeof(NEW_DLL_FUNCTIONS));
return 1;
}
#endif
#endif