Cvars: Adjust more things
- Moved some functions in CvarManager - Fixed detour enabled all the time - Fixed bounds not properly handled - Refreshed data of regisetered cvars at map change
This commit is contained in:
parent
187b187ef2
commit
f8baef15ca
|
@ -154,7 +154,7 @@ void CvarManager::CreateCvarHook(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cvar_t* CvarManager::CreateCvar(const char* name, const char* value, const char* plugin, int pluginId, int flags,
|
CvarInfo* CvarManager::CreateCvar(const char* name, const char* value, const char* plugin, int pluginId, int flags,
|
||||||
const char* helpText, bool hasMin, float min, bool hasMax, float max)
|
const char* helpText, bool hasMin, float min, bool hasMax, float max)
|
||||||
{
|
{
|
||||||
cvar_t* var = nullptr;
|
cvar_t* var = nullptr;
|
||||||
|
@ -215,11 +215,27 @@ cvar_t* CvarManager::CreateCvar(const char* name, const char* value, const char*
|
||||||
// Make sure that whether an existing or new cvar is set to the given value.
|
// Make sure that whether an existing or new cvar is set to the given value.
|
||||||
CVAR_DIRECTSET(var, value);
|
CVAR_DIRECTSET(var, value);
|
||||||
}
|
}
|
||||||
|
else if (info->pluginId == -1)
|
||||||
|
{
|
||||||
|
// In situation where a plugin has been modified/recompiled
|
||||||
|
// or new added plugins, and a change map occurs. We want to keep data up to date.
|
||||||
|
info->bound.hasMin = hasMin;
|
||||||
|
info->bound.minVal = min;
|
||||||
|
info->bound.hasMax = hasMax;
|
||||||
|
info->bound.maxVal = max;
|
||||||
|
info->defaultval = value;
|
||||||
|
info->description = helpText;
|
||||||
|
info->pluginId = pluginId;
|
||||||
|
}
|
||||||
|
|
||||||
// Detour is disabled on map change.
|
// Detour is disabled on map change.
|
||||||
m_HookDetour->EnableDetour();
|
// Don't enable it unless there are things to do.
|
||||||
|
if (info->bound.hasMin || info->bound.hasMax)
|
||||||
|
{
|
||||||
|
m_HookDetour->EnableDetour();
|
||||||
|
}
|
||||||
|
|
||||||
return info->var;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
CvarInfo* CvarManager::FindCvar(const char* name)
|
CvarInfo* CvarManager::FindCvar(const char* name)
|
||||||
|
@ -227,9 +243,6 @@ CvarInfo* CvarManager::FindCvar(const char* name)
|
||||||
cvar_t* var = nullptr;
|
cvar_t* var = nullptr;
|
||||||
CvarInfo* info = nullptr;
|
CvarInfo* info = nullptr;
|
||||||
|
|
||||||
// Detour is disabled on map change.
|
|
||||||
m_HookDetour->EnableDetour();
|
|
||||||
|
|
||||||
// Do we have already cvar in cache?
|
// Do we have already cvar in cache?
|
||||||
if (CacheLookup(name, &info))
|
if (CacheLookup(name, &info))
|
||||||
{
|
{
|
||||||
|
@ -316,6 +329,104 @@ AutoForward* CvarManager::HookCvarChange(cvar_t* var, AMX* amx, cell param, cons
|
||||||
return forward;
|
return forward;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CvarManager::BindCvar(CvarInfo* info, CvarBind::CvarType type, AMX* amx, cell varofs, size_t varlen)
|
||||||
|
{
|
||||||
|
if (varofs > amx->hlw) // If variable address is not inside global area, we can't bind it.
|
||||||
|
{
|
||||||
|
LogError(amx, AMX_ERR_NATIVE, "A global variable must be provided");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pluginId = g_plugins.findPluginFast(amx)->getId();
|
||||||
|
cell* address = get_amxaddr(amx, varofs);
|
||||||
|
|
||||||
|
// To avoid unexpected behavior, probably better to error such situations.
|
||||||
|
for (size_t i = 0; i < info->binds.length(); ++i)
|
||||||
|
{
|
||||||
|
CvarBind* bind = info->binds[i];
|
||||||
|
|
||||||
|
if (bind->pluginId == pluginId)
|
||||||
|
{
|
||||||
|
if (bind->varAddress == address)
|
||||||
|
{
|
||||||
|
LogError(amx, AMX_ERR_NATIVE, "A same variable can't be binded with several cvars");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CvarBind* bind = new CvarBind(pluginId, type, get_amxaddr(amx, varofs), varlen);
|
||||||
|
|
||||||
|
info->binds.append(bind);
|
||||||
|
|
||||||
|
// Update right away variable with current cvar value.
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case CvarBind::CvarType_Int:
|
||||||
|
*bind->varAddress = atoi(info->var->string);
|
||||||
|
break;
|
||||||
|
case CvarBind::CvarType_Float:
|
||||||
|
*bind->varAddress = amx_ftoc(info->var->value);
|
||||||
|
break;
|
||||||
|
case CvarBind::CvarType_String:
|
||||||
|
set_amxstring_simple(bind->varAddress, info->var->string, bind->varLength);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detour is disabled on map change.
|
||||||
|
m_HookDetour->EnableDetour();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CvarManager::SetCvarMin(CvarInfo* info, bool set, float value, int pluginId)
|
||||||
|
{
|
||||||
|
info->bound.hasMin = set;
|
||||||
|
info->bound.minPluginId = pluginId;
|
||||||
|
|
||||||
|
if (set)
|
||||||
|
{
|
||||||
|
if (info->bound.hasMax && value > info->bound.maxVal)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
info->bound.minVal = value;
|
||||||
|
|
||||||
|
// Detour is disabled on map change.
|
||||||
|
m_HookDetour->EnableDetour();
|
||||||
|
|
||||||
|
// Update if needed.
|
||||||
|
CVAR_SET_FLOAT(info->var->name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CvarManager::SetCvarMax(CvarInfo* info, bool set, float value, int pluginId)
|
||||||
|
{
|
||||||
|
info->bound.hasMax = set;
|
||||||
|
info->bound.maxPluginId = pluginId;
|
||||||
|
|
||||||
|
if (set)
|
||||||
|
{
|
||||||
|
if (info->bound.hasMin && value < info->bound.minVal)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
info->bound.maxVal = value;
|
||||||
|
|
||||||
|
// Detour is disabled on map change.
|
||||||
|
m_HookDetour->EnableDetour();
|
||||||
|
|
||||||
|
// Update if needed.
|
||||||
|
CVAR_SET_FLOAT(info->var->name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
size_t CvarManager::GetRegCvarsCount()
|
size_t CvarManager::GetRegCvarsCount()
|
||||||
{
|
{
|
||||||
return m_AmxmodxCvars;
|
return m_AmxmodxCvars;
|
||||||
|
@ -475,6 +586,11 @@ void CvarManager::OnPluginUnloaded()
|
||||||
delete (*cvar)->hooks[i];
|
delete (*cvar)->hooks[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((*cvar)->amxmodx) // Mark registered cvars so we can refresh default datas at next map.
|
||||||
|
{
|
||||||
|
(*cvar)->pluginId = -1;
|
||||||
|
}
|
||||||
|
|
||||||
(*cvar)->binds.clear();
|
(*cvar)->binds.clear();
|
||||||
(*cvar)->hooks.clear();
|
(*cvar)->hooks.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,7 +150,7 @@ class CvarManager
|
||||||
|
|
||||||
void CreateCvarHook();
|
void CreateCvarHook();
|
||||||
|
|
||||||
cvar_t* CreateCvar(const char* name, const char* value, const char* plugin, int pluginId,
|
CvarInfo* CreateCvar(const char* name, const char* value, const char* plugin, int pluginId,
|
||||||
int flags = 0, const char* helpText = "",
|
int flags = 0, const char* helpText = "",
|
||||||
bool hasMin = false, float min = 0,
|
bool hasMin = false, float min = 0,
|
||||||
bool hasMax = false, float max = 0);
|
bool hasMax = false, float max = 0);
|
||||||
|
@ -160,6 +160,9 @@ class CvarManager
|
||||||
bool CacheLookup(const char* name, CvarInfo** info);
|
bool CacheLookup(const char* name, CvarInfo** info);
|
||||||
|
|
||||||
AutoForward* HookCvarChange(cvar_t* var, AMX* amx, cell param, const char** callback);
|
AutoForward* HookCvarChange(cvar_t* var, AMX* amx, cell param, const char** callback);
|
||||||
|
bool BindCvar(CvarInfo* info, CvarBind::CvarType type, AMX* amx, cell varofs, size_t varlen = 0);
|
||||||
|
bool SetCvarMin(CvarInfo* info, bool set, float value, int pluginId);
|
||||||
|
bool SetCvarMax(CvarInfo* info, bool set, float value, int pluginId);
|
||||||
|
|
||||||
size_t GetRegCvarsCount();
|
size_t GetRegCvarsCount();
|
||||||
|
|
||||||
|
|
|
@ -22,34 +22,8 @@ static cell AMX_NATIVE_CALL create_cvar(AMX *amx, cell *params)
|
||||||
const char* value = get_amxstring(amx, params[2], 1, length);
|
const char* value = get_amxstring(amx, params[2], 1, length);
|
||||||
const char* helpText = get_amxstring(amx, params[4], 2, length);
|
const char* helpText = get_amxstring(amx, params[4], 2, length);
|
||||||
|
|
||||||
int flags = params[3];
|
int flags = params[3];
|
||||||
bool hasMin = params[5] != 0;
|
|
||||||
bool hasMax = params[7] != 0;
|
|
||||||
float minVal = 0;
|
|
||||||
float maxVal = 0;
|
|
||||||
|
|
||||||
if (hasMin)
|
|
||||||
{
|
|
||||||
minVal = amx_ctof(params[6]);
|
|
||||||
|
|
||||||
if (hasMax && minVal > maxVal)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "A lower bound can't be above an upper bound");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasMax)
|
|
||||||
{
|
|
||||||
maxVal = amx_ctof(params[8]);
|
|
||||||
|
|
||||||
if (hasMin && maxVal < minVal)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "An upper bound can't be below a lower bound");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CPluginMngr::CPlugin *plugin = g_plugins.findPluginFast(amx);
|
CPluginMngr::CPlugin *plugin = g_plugins.findPluginFast(amx);
|
||||||
|
|
||||||
if (CheckBadConList(name, 0))
|
if (CheckBadConList(name, 0))
|
||||||
|
@ -57,9 +31,31 @@ static cell AMX_NATIVE_CALL create_cvar(AMX *amx, cell *params)
|
||||||
plugin->AddToFailCounter(1);
|
plugin->AddToFailCounter(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
cvar_t* var = g_CvarManager.CreateCvar(name, value, plugin->getName(), plugin->getId(), flags, helpText, hasMin, minVal, hasMax, maxVal);
|
CvarInfo* info = g_CvarManager.CreateCvar(name, value, plugin->getName(), plugin->getId(), flags, helpText);
|
||||||
|
|
||||||
return reinterpret_cast<cell>(var);
|
if (info)
|
||||||
|
{
|
||||||
|
bool hasMin = params[5] != 0;
|
||||||
|
bool hasMax = params[7] != 0;
|
||||||
|
float minVal = amx_ctof(params[6]);
|
||||||
|
float maxVal = amx_ctof(params[8]);
|
||||||
|
|
||||||
|
if (!g_CvarManager.SetCvarMin(info, hasMin, minVal, plugin->getId()))
|
||||||
|
{
|
||||||
|
LogError(amx, AMX_ERR_NATIVE, "A lower bound can't be above an upper bound");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_CvarManager.SetCvarMax(info, hasMax, maxVal, plugin->getId()))
|
||||||
|
{
|
||||||
|
LogError(amx, AMX_ERR_NATIVE, "An upper bound can't be below a lower bound");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return reinterpret_cast<cell>(info->var);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// register_cvar(const name[], const string[], flags=0, Float:fvalue=0.0)
|
// register_cvar(const name[], const string[], flags=0, Float:fvalue=0.0)
|
||||||
|
@ -79,9 +75,14 @@ static cell AMX_NATIVE_CALL register_cvar(AMX *amx, cell *params)
|
||||||
plugin->AddToFailCounter(1);
|
plugin->AddToFailCounter(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
cvar_t* var = g_CvarManager.CreateCvar(name, value, plugin->getName(), plugin->getId(), flags);
|
CvarInfo* info = g_CvarManager.CreateCvar(name, value, plugin->getName(), plugin->getId(), flags);
|
||||||
|
|
||||||
return reinterpret_cast<cell>(var);
|
if (info)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<cell>(info->var);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cvar_exists(const cvar[])
|
// cvar_exists(const cvar[])
|
||||||
|
@ -368,53 +369,6 @@ static cell AMX_NATIVE_CALL get_pcvar_bounds(AMX *amx, cell *params)
|
||||||
return hasBound;
|
return hasBound;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bind_pcvar(CvarInfo* info, CvarBind::CvarType type, AMX* amx, cell varofs, size_t varlen = 0)
|
|
||||||
{
|
|
||||||
if (varofs > amx->hlw) // If variable address is not inside global area, we can't bind it.
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "A global variable must be provided");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pluginId = g_plugins.findPluginFast(amx)->getId();
|
|
||||||
cell* address = get_amxaddr(amx, varofs);
|
|
||||||
|
|
||||||
// To avoid unexpected behavior, probably better to error such situations.
|
|
||||||
for (size_t i = 0; i < info->binds.length(); ++i)
|
|
||||||
{
|
|
||||||
CvarBind* bind = info->binds[i];
|
|
||||||
|
|
||||||
if (bind->pluginId == pluginId)
|
|
||||||
{
|
|
||||||
if (bind->varAddress == address)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "A same variable can't be binded with several cvars");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CvarBind* bind = new CvarBind(pluginId, type, get_amxaddr(amx, varofs), varlen);
|
|
||||||
|
|
||||||
info->binds.append(bind);
|
|
||||||
|
|
||||||
// Update right away variable with current cvar value.
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case CvarBind::CvarType_Int:
|
|
||||||
*bind->varAddress = atoi(info->var->string);
|
|
||||||
break;
|
|
||||||
case CvarBind::CvarType_Float:
|
|
||||||
*bind->varAddress = amx_ftoc(info->var->value);
|
|
||||||
break;
|
|
||||||
case CvarBind::CvarType_String:
|
|
||||||
set_amxstring_simple(bind->varAddress, info->var->string, bind->varLength);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// bind_pcvar_float(pcvar, &Float:var)
|
// bind_pcvar_float(pcvar, &Float:var)
|
||||||
static cell AMX_NATIVE_CALL bind_pcvar_float(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL bind_pcvar_float(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
|
@ -427,7 +381,7 @@ static cell AMX_NATIVE_CALL bind_pcvar_float(AMX *amx, cell *params)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bind_pcvar(info, CvarBind::CvarType_Float, amx, params[2]);
|
return g_CvarManager.BindCvar(info, CvarBind::CvarType_Float, amx, params[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind_pcvar_num(pcvar, &any:var)
|
// bind_pcvar_num(pcvar, &any:var)
|
||||||
|
@ -442,7 +396,7 @@ static cell AMX_NATIVE_CALL bind_pcvar_num(AMX *amx, cell *params)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bind_pcvar(info, CvarBind::CvarType_Int, amx, params[2]);
|
return g_CvarManager.BindCvar(info, CvarBind::CvarType_Int, amx, params[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind_pcvar_string(pcvar, any:var[], varlen)
|
// bind_pcvar_string(pcvar, any:var[], varlen)
|
||||||
|
@ -457,7 +411,7 @@ static cell AMX_NATIVE_CALL bind_pcvar_string(AMX *amx, cell *params)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bind_pcvar(info, CvarBind::CvarType_String, amx, params[2], params[3]);
|
return g_CvarManager.BindCvar(info, CvarBind::CvarType_String, amx, params[2], params[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set_pcvar_flags(pcvar, flags)
|
// set_pcvar_flags(pcvar, flags)
|
||||||
|
@ -538,53 +492,26 @@ static cell AMX_NATIVE_CALL set_pcvar_bounds(AMX *amx, cell *params)
|
||||||
|
|
||||||
bool set = params[3] != 0;
|
bool set = params[3] != 0;
|
||||||
int pluginId = g_plugins.findPluginFast(amx)->getId();
|
int pluginId = g_plugins.findPluginFast(amx)->getId();
|
||||||
float value = 0;
|
float value = amx_ctof(params[4]);
|
||||||
bool should_update = false;
|
|
||||||
|
|
||||||
switch (params[2])
|
switch (params[2])
|
||||||
{
|
{
|
||||||
case CvarBound_Lower:
|
case CvarBound_Lower:
|
||||||
{
|
{
|
||||||
info->bound.hasMin = set;
|
if (!g_CvarManager.SetCvarMin(info, set, value, pluginId))
|
||||||
|
|
||||||
if (set)
|
|
||||||
{
|
{
|
||||||
value = amx_ctof(params[4]);
|
LogError(amx, AMX_ERR_NATIVE, "A lower bound can't be above an upper bound");
|
||||||
|
return 0;
|
||||||
if (info->bound.hasMax && value > info->bound.maxVal)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "A lower bound can't be above an upper bound");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
should_update = true;
|
|
||||||
|
|
||||||
info->bound.minVal = value;
|
|
||||||
info->bound.minPluginId = pluginId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CvarBound_Upper:
|
case CvarBound_Upper:
|
||||||
{
|
{
|
||||||
info->bound.hasMax = set;
|
if (!g_CvarManager.SetCvarMax(info, set, value, pluginId))
|
||||||
|
|
||||||
if (set)
|
|
||||||
{
|
{
|
||||||
value = amx_ctof(params[4]);
|
LogError(amx, AMX_ERR_NATIVE, "An upper bound can't be below a lower bound");
|
||||||
|
return 0;
|
||||||
if (info->bound.hasMin && value < info->bound.minVal)
|
|
||||||
{
|
|
||||||
LogError(amx, AMX_ERR_NATIVE, "An upper bound can't be below a lower bound");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
should_update = true;
|
|
||||||
|
|
||||||
info->bound.maxVal = value;
|
|
||||||
info->bound.maxPluginId = pluginId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -594,11 +521,6 @@ static cell AMX_NATIVE_CALL set_pcvar_bounds(AMX *amx, cell *params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (should_update)
|
|
||||||
{
|
|
||||||
CVAR_SET_FLOAT(ptr->name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user