Simple implementation for cvar queries
This commit is contained in:
parent
ca1544564c
commit
dc57ef1e0c
|
@ -59,6 +59,10 @@ void CPlayer::Disconnect() {
|
|||
ingame = false;
|
||||
initialized = false;
|
||||
authorized = false;
|
||||
|
||||
while (!cvarQueryQueue.empty())
|
||||
cvarQueryQueue.pop();
|
||||
|
||||
bot = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue
Block a user