Added config reloading support.

Revision also includes:
* Added syntax checking on recoded/new console commands.
* Fixed sv_skyname handle being used when invalid.
* Fixed unhooking error on Weapon_Drop.
* Prefixed some API-style functions with 'stock' to stop compiler
warning.
* Separated downloads into its own file.
This commit is contained in:
Greyscale 2009-05-18 06:26:13 +02:00
parent 363be11591
commit 25b0caa68a
13 changed files with 675 additions and 216 deletions

View File

@ -77,7 +77,48 @@
}
// ===========================
// Player Classes
// Config (core)
// ===========================
// Commands
"Config command reload syntax"
{
"#format" "{1:s},{2:s},{3:s},{4:s},{5:s},{6:s}"
"en" "Syntax: zr_reloadconfig <file alias> - Reloads a config file.\n File Aliases:\n * \"{1}\"\n * \"{2}\"\n * \"{3}\"\n * \"{4}\"\n * \"{5}\"\n * \"{6}\""
}
"Config command reload invalid"
{
"#format" "{1:s}"
"en" "Invalid file alias: \"{1}\""
}
"Config command reload not loaded"
{
"#format" "{1:s}"
"en" "File failed to load: \"{1}\" (Either disabled or invalid file content.)"
}
"Config command reload all stats begin"
{
"en" "Reloading all Zombie:Reloaded config files...\n ------------------------------------------"
}
"Config command reload all stats successful"
{
"#format" "{1:s}"
"en" "\"{1}\" - Successful."
}
"Config command reload all stats failed"
{
"#format" "{1:s}"
"en" "\"{1}\" - Failed. (Either disabled or invalid file content.)"
}
// ===========================
// Classes (core)
// ===========================
// General
@ -130,7 +171,7 @@
}
// ===========================
// (core) Overlays
// Overlays (core)
// ===========================
"Overlays not supported"
@ -141,7 +182,7 @@
}
// ===========================
// (core) Infect
// Infect (core)
// ===========================
// General
@ -158,7 +199,7 @@
}
// ===========================
// (core) Damage
// Damage (core)
// ===========================
"Damage suicide intercept"
@ -215,7 +256,7 @@
}
// ===========================
// (core) Weapons
// Weapons (core)
// ===========================
// General
@ -310,6 +351,18 @@
"ru" "Купить снова"
}
// Commands
"Weapons command restrict syntax"
{
"en" "Syntax: zr_restrict <weapon> (\"weapon_\" prefix is ignored)"
}
"Weapons command unrestrict syntax"
{
"en" "Syntax: zr_unrestrict <weapon> (\"weapon_\" prefix is ignored)"
}
// Menu
"Weapons menu main title"
@ -370,7 +423,7 @@
}
// ===========================
// Spawn Protect
// Spawn Protect (module)
// ===========================
// General
@ -397,7 +450,7 @@
}
// ===========================
// ZSpawn
// ZSpawn (module)
// ===========================
"ZSpawn double spawn"
@ -412,7 +465,7 @@
}
// ===========================
// ZTele
// ZTele (module)
// ===========================
// General
@ -459,7 +512,7 @@
}
// ===========================
// ZHP
// ZHP (module)
// ===========================
// General

View File

@ -31,6 +31,7 @@
#include "zr/sayhooks"
#include "zr/tools"
#include "zr/models"
#include "zr/downloads"
#include "zr/overlays"
#include "zr/playerclasses/playerclasses"
#include "zr/weapons/weapons"
@ -165,6 +166,7 @@ public OnConfigsExecuted()
// Forward event to modules.
ConfigLoad();
ModelsLoad();
DownloadsLoad();
WeaponsLoad();
HitgroupsLoad();
InfectLoad();

View File

@ -16,6 +16,7 @@
CommandsInit()
{
// Forward event to modules. (create commands)
ConfigOnCommandsCreate();
WeaponsOnCommandsCreate();
// Forward event to modules. (hook commands)

View File

@ -11,59 +11,84 @@
*/
/**
* @section List of config files under this modules control.
* The max length of any config string value.
*/
#define CONFIG_FILE_MODELS 0
#define CONFIG_FILE_DOWNLOADS 1
#define CONFIG_FILE_PLAYERCLASSES 2
#define CONFIG_FILE_WEAPONS 3
#define CONFIG_FILE_WEAPONGROUPS 4
#define CONFIG_FILE_HITGROUPS 5
#define CONFIG_MAX_LENGTH 32
/**
* @section Config file reference aliases.
*/
#define CONFIG_FILE_ALIAS_MODELS "models"
#define CONFIG_FILE_ALIAS_DOWNLOADS "downloads"
#define CONFIG_FILE_ALIAS_CLASSES "classes"
#define CONFIG_FILE_ALIAS_WEAPONS "weapons"
#define CONFIG_FILE_ALIAS_WEAPONGROUPS "weapongroups"
#define CONFIG_FILE_ALIAS_HITGROUPS "hitgroups"
/**
* @endsection
*/
/**
* @section Config file flags.
*/
#define CONFIG_FILE_FLAG_MODELS 1
#define CONFIG_FILE_FLAG_DOWNLOADS 2
#define CONFIG_FILE_FLAG_PLAYERCLASSES 4
#define CONFIG_FILE_FLAG_WEAPONS 8
#define CONFIG_FILE_FLAG_WEAPONGROUPS 16
#define CONFIG_FILE_FLAG_HITGROUPS 32
/**
* @endsection
* List of config files used by the plugin.
*/
enum ConfigFile
{
ConfigInvalid = -1, /** Invalid config file. */
ConfigModels, /** <sourcemod root>/configs/zr/models.txt (default) */
ConfigDownloads, /** <sourcemod root>/configs/zr/downloads.txt (default) */
ConfigClasses, /** <sourcemod root>/configs/zr/playerclasses.txt (default) */
ConfigWeapons, /** <sourcemod root>/configs/zr/weapons/weapons.txt/weapongroups.txt (default) */
ConfigHitgroups, /** <sourcemod root>/configs/zr/hitgroups.txt (default) */
}
/**
* The max length of a config/value string.
* Data container for each config file.
*/
#define CONFIG_OPTION_MAX_LENGTH 32
enum ConfigData
{
bool:ConfigLoaded, /** True if config is loaded, false if not. */
Function:ConfigReloadFunc, /** Function to call to reload config. */
Handle:ConfigHandle, /** Handle of the config file. */
String:ConfigPath[PLATFORM_MAX_PATH], /** Full path to config file. */
String:ConfigAlias[CONFIG_MAX_LENGTH], /** Config file alias, used for client interaction. */
}
/**
* Stores all config data.
*/
new g_ConfigData[ConfigFile][ConfigData];
/**
* Actions to use when working on key/values.
*/
enum ConfigKeyvalueAction
{
Create, /** Create a key. */
Delete, /** Delete a key. */
Set, /** Modify setting of a key. */
Get, /** Get setting of a key. */
ConfigKVCreate, /** Create a key. */
ConfigKVDelete, /** Delete a key. */
ConfigKVSet, /** Modify setting of a key. */
ConfigKVGet, /** Get setting of a key. */
}
/**
* @endsection
*/
/**
* @section Global data handle initializations.
*/
new Handle:arrayModelsList = INVALID_HANDLE;
new Handle:arrayDownloadsList = INVALID_HANDLE;
new Handle:kvClassData = INVALID_HANDLE;
new Handle:kvWeapons = INVALID_HANDLE;
new Handle:kvWeaponGroups = INVALID_HANDLE;
new Handle:kvHitgroups = INVALID_HANDLE;
/**
* Create commands related to config here.
*/
ConfigOnCommandsCreate()
{
// Create config admin commands.
RegAdminCmd("zr_reloadconfig", ConfigReloadCommand, ADMFLAG_GENERIC, "zr_reloadconfig <file alias> - Reloads a config file.");
RegAdminCmd("zr_reloadconfigall", ConfigReloadAllCommand, ADMFLAG_GENERIC, "zr_reloadconfigall - Reloads all config files.");
}
/**
* Load plugin configs.
*/
@ -130,13 +155,187 @@ ConfigOnModulesLoaded()
LogPrintToLog(LOG_FORMAT_TYPE_NORMAL, "Config", "Map Configs", "Executed post map config file: %s", path);
}
/**
* Used by modules that rely on configs to register their config file info.
*
* @param file Config file entry to register.
* @param loaded True if the config should be loaded, false if not.
* @param path (Optional) Full path to config file.
* @param alias (Optional) Config file alias, used for client interaction.
*/
stock ConfigRegisterConfig(ConfigFile:file, bool:loaded, Function:reloadfunc, Handle:filehandle = INVALID_HANDLE, const String:path[] = "", const String:alias[] = "")
{
// Copy file info to data container.
g_ConfigData[file][ConfigLoaded] = loaded;
g_ConfigData[file][ConfigHandle] = filehandle;
g_ConfigData[file][ConfigReloadFunc] = reloadfunc;
strcopy(g_ConfigData[file][ConfigPath], PLATFORM_MAX_PATH, path);
strcopy(g_ConfigData[file][ConfigAlias], CONFIG_MAX_LENGTH, alias);
}
/**
* Set the loaded state of a config file entry.
*
* @param config Config file to set load state of.
* @param loaded True to set as loaded, false to set as unloaded.
*/
stock ConfigSetConfigLoaded(ConfigFile:config, bool:loaded)
{
// Set load state.
g_ConfigData[config][ConfigLoaded] = loaded;
}
/**
* Set the reload function of a config file entry.
*
* @param config Config file to set reload function of.
* @param reloadfunc Reload function.
*/
stock ConfigSetConfigReloadFunc(ConfigFile:config, Function:reloadfunc)
{
// Set reload function.
g_ConfigData[config][ConfigReloadFunc] = reloadfunc;
}
/**
* Set the file handle of a config file entry.
*
* @param config Config file to set handle of.
* @param loaded Config file handle.
*/
stock ConfigSetConfigHandle(ConfigFile:config, Handle:file)
{
// Set file handle.
g_ConfigData[config][ConfigHandle] = file;
}
/**
* Set the config file path of a config file entry.
*
* @param config Config file to set file path of.
* @param loaded File path.
*/
stock ConfigSetConfigPath(ConfigFile:config, const String:path[])
{
// Set config file path.
strcopy(g_ConfigData[config][ConfigPath], PLATFORM_MAX_PATH, path);
}
/**
* Set the alias of a config file entry.
*
* @param config Config file to set alias of.
* @param loaded Alias of the config file entry.
*/
stock ConfigSetConfigAlias(ConfigFile:config, const String:alias[])
{
// Set config alias.
strcopy(g_ConfigData[config][ConfigAlias], CONFIG_MAX_LENGTH, alias);
}
/**
* Returns if a config was successfully loaded.
*
* @param config Config file to check load status of.
* @return True if config is loaded, false otherwise.
*/
stock bool:ConfigIsConfigLoaded(ConfigFile:config)
{
// Return load status.
return g_ConfigData[config][ConfigLoaded];
}
/**
* Returns config's reload function.
*
* @param config Config file to get reload function of.
* @return Config reload function.
*/
stock Function:ConfigGetConfigReloadFunc(ConfigFile:config)
{
// Return load status.
return g_ConfigData[config][ConfigReloadFunc];
}
/**
* Returns config's file handle.
*
* @param config Config file to get file handle of.
* @return Config file handle.
*/
stock Handle:ConfigGetConfigHandle(ConfigFile:config)
{
// Return load status.
return g_ConfigData[config][ConfigHandle];
}
/**
* Returns the path for a given config file entry.
*
* @param config Config file to get path of. (see ConfigFile enum)
*/
stock ConfigGetConfigPath(ConfigFile:config, String:path[], maxlen)
{
// Copy path to return string.
strcopy(path, maxlen, g_ConfigData[config][ConfigPath]);
}
/**
* Returns the alias for a given config file entry.
*
* @param config Config file to get alias of. (see ConfigFile enum)
*/
stock ConfigGetConfigAlias(ConfigFile:config, String:alias[], maxlen)
{
// Copy alias to return string.
strcopy(alias, maxlen, g_ConfigData[config][ConfigAlias]);
}
/**
* Reload a config file.
*
* @param config The config file entry to reload.
* @return True if the config is loaded, false if not.
*/
stock bool:ConfigReloadFile(ConfigFile:config)
{
// If file isn't loaded, then stop.
new bool:loaded = ConfigIsConfigLoaded(config);
if (!loaded)
{
return false;
}
// Call reload function
new Function:reloadfunc = ConfigGetConfigReloadFunc(config);
if (reloadfunc == INVALID_FUNCTION)
{
// Get config alias.
decl String:configalias[CONFIG_MAX_LENGTH];
ConfigGetConfigAlias(config, configalias, sizeof(configalias));
// Print reload failure to logs.
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Config", "Reload Function", "Invalid reload function for config: \"%s\"", configalias);
return true;
}
// Call reload function.
Call_StartFunction(GetMyHandle(), reloadfunc);
Call_PushCell(config);
Call_Finish();
return true;
}
/**
* Load config file.
*
* @param file The cvar define of the path to the file.
* @return True if the file exists, false if not.
*/
bool:ConfigGetFilePath(CvarsList:cvar, String:path[])
stock bool:ConfigGetCvarFilePath(CvarsList:cvar, String:path[])
{
// Get cvar's path.
decl String:filepath[PLATFORM_MAX_PATH];
@ -148,6 +347,36 @@ bool:ConfigGetFilePath(CvarsList:cvar, String:path[])
return FileExists(path);
}
/**
* Finds a config file entry, (see ConfigFile enum) for a given alias.
*
* @param alias The alias to find config file entry of.
* @return Config file entry, ConfigInvalid is returned if alias was not found.
*/
stock ConfigFile:ConfigAliasToConfigFile(const String:alias[])
{
decl String:checkalias[CONFIG_MAX_LENGTH];
// x = config file entry index.
for (new x = 0; x < sizeof(g_ConfigData); x++)
{
// Get config alias.
ConfigGetConfigAlias(ConfigFile:x, checkalias, sizeof(checkalias));
// If alias doesn't match, then stop.
if (!StrEqual(alias, checkalias, false))
{
continue;
}
// Return config file entry.
return ConfigFile:x;
}
// Invalid config file.
return ConfigInvalid;
}
/**
* Creates, deletes, sets, or gets any key/setting of any ZR config keyvalue file in memory.
* Only use when interacting with a command or manipulating single keys/values,
@ -162,10 +391,10 @@ bool:ConfigGetFilePath(CvarsList:cvar, String:path[])
* @param maxlen (Optional) The maxlength of the gotten value.
* @return True if the change was made successfully, false otherwise.
*/
bool:ConfigKeyvalueTreeSetting(config, ConfigKeyvalueAction:action = Create, const String:keys[][], keysMax, const String:setting[] = "", String:value[] = "", maxlen = 0)
stock bool:ConfigKeyvalueTreeSetting(config, ConfigKeyvalueAction:action = ConfigKVCreate, const String:keys[][], keysMax, const String:setting[] = "", String:value[] = "", maxlen = 0)
{
// Retrieve handle of the keyvalue tree.
new Handle:hConfig = ConfigGetFileHandle(config);
new Handle:hConfig = ConfigGetConfigHandle(config);
// If handle is invalid, then stop.
if (hConfig == INVALID_HANDLE)
@ -199,7 +428,7 @@ bool:ConfigKeyvalueTreeSetting(config, ConfigKeyvalueAction:action = Create, con
switch(action)
{
case Create:
case ConfigKVCreate:
{
if (!setting[0] || !value[0])
{
@ -210,17 +439,17 @@ bool:ConfigKeyvalueTreeSetting(config, ConfigKeyvalueAction:action = Create, con
// Set new value.
KvSetString(hConfig, setting, value);
}
case Delete:
case ConfigKVDelete:
{
// Return deletion result.
return KvDeleteKey(hConfig, setting);
}
case Set:
case ConfigKVSet:
{
// Set new value.
KvSetString(hConfig, setting, value);
}
case Get:
case ConfigKVGet:
{
// Get current value.
KvGetString(hConfig, setting, value, maxlen);
@ -232,48 +461,82 @@ bool:ConfigKeyvalueTreeSetting(config, ConfigKeyvalueAction:action = Create, con
}
/**
* Return handle to array or keygroup for globally stored data.
* Command callback (zr_reloadconfig)
* Reloads a config file and forwards event to modules.
*
* @param configindex Index of the config. (see CONFIG_FILE_* defines)
* @param client The client index.
* @param argc Argument count.
*/
Handle:ConfigGetFileHandle(config)
public Action:ConfigReloadCommand(client, argc)
{
switch(config)
// If not enough arguments given, then stop.
if (argc < 1)
{
case CONFIG_FILE_MODELS:
{
// Return model list array handle.
return arrayModelsList;
}
case CONFIG_FILE_DOWNLOADS:
{
// We don't store download data.
return INVALID_HANDLE;
}
case CONFIG_FILE_PLAYERCLASSES:
{
// Return class config keyvalue file handle.
return kvClassData;
}
case CONFIG_FILE_WEAPONS:
{
// Return weapon config keyvalue file handle.
return kvWeapons;
}
case CONFIG_FILE_WEAPONGROUPS:
{
// Return weapon groups config keyvalue file handle.
return kvWeaponGroups;
}
case CONFIG_FILE_HITGROUPS:
{
// Return hitgroups config keyvalue file handle.
return kvHitgroups;
}
TranslationReplyToCommand(client, "Config command reload syntax", CONFIG_FILE_ALIAS_MODELS, CONFIG_FILE_ALIAS_DOWNLOADS, CONFIG_FILE_ALIAS_CLASSES, CONFIG_FILE_ALIAS_WEAPONS, CONFIG_FILE_ALIAS_WEAPONGROUPS, CONFIG_FILE_ALIAS_HITGROUPS);
return Plugin_Handled;
}
// Invalid config index.
return INVALID_HANDLE;
// arg1 = file alias being reloaded.
decl String:arg1[32];
GetCmdArg(1, arg1, sizeof(arg1));
// If alias is invalid, then stop.
new ConfigFile:config = ConfigAliasToConfigFile(arg1);
if (config == ConfigInvalid)
{
TranslationReplyToCommand(client, "Config command reload invalid", arg1);
return Plugin_Handled;
}
// Reload config file.
new bool:loaded = ConfigReloadFile(config);
// Get config file path.
decl String:path[PLATFORM_MAX_PATH];
ConfigGetConfigPath(config, path, sizeof(path));
// If file isn't loaded then tell client, then stop.
if (!loaded)
{
TranslationReplyToCommand(client, "Config command reload not loaded", path);
return Plugin_Handled;
}
return Plugin_Handled;
}
/**
* Command callback (zr_reloadconfigall)
* Reloads all config files and forwards event to all modules.
*
* @param client The client index.
* @param argc Argument count.
*/
public Action:ConfigReloadAllCommand(client, argc)
{
// Begin statistics.
TranslationReplyToCommand(client, "Config command reload all stats begin");
decl String:configalias[CONFIG_MAX_LENGTH];
// x = config file entry index.
for (new x = 0; x < sizeof(g_ConfigData); x++)
{
// Reload config file.
new bool:successful = ConfigReloadFile(ConfigFile:x);
// Get config's alias.
ConfigGetConfigAlias(ConfigFile:x, configalias, sizeof(configalias));
if (successful)
{
TranslationReplyToCommand(client, "Config command reload all stats successful", configalias);
}
else
{
TranslationReplyToCommand(client, "Config command reload all stats failed", configalias);
}
}
}
/**

View File

@ -36,7 +36,7 @@ enum CvarsList
Handle:CVAR_LOG_PRINT_CONSOLE,
Handle:CVAR_CONFIG_PATH_MODELS,
Handle:CVAR_CONFIG_PATH_DOWNLOADS,
Handle:CVAR_CONFIG_PATH_PLAYERCLASSES,
Handle:CVAR_CONFIG_PATH_CLASSES,
Handle:CVAR_CONFIG_PATH_WEAPONS,
Handle:CVAR_CONFIG_PATH_WEAPONGROUPS,
Handle:CVAR_CONFIG_PATH_HITGROUPS,
@ -207,7 +207,7 @@ CvarsCreate()
g_hCvarsList[CVAR_CONFIG_PATH_MODELS] = CreateConVar("zr_config_path_models", "configs/zr/models.txt", "Path, relative to root sourcemod directory, to models config file.");
g_hCvarsList[CVAR_CONFIG_PATH_DOWNLOADS] = CreateConVar("zr_config_path_downloads", "configs/zr/downloads.txt", "Path, relative to root sourcemod directory, to downloads file.");
g_hCvarsList[CVAR_CONFIG_PATH_PLAYERCLASSES] = CreateConVar("zr_config_path_playerclasses", "configs/zr/playerclasses.txt", "Path, relative to root sourcemod directory, to playerclasses config file.");
g_hCvarsList[CVAR_CONFIG_PATH_CLASSES] = CreateConVar("zr_config_path_playerclasses", "configs/zr/playerclasses.txt", "Path, relative to root sourcemod directory, to playerclasses config file.");
g_hCvarsList[CVAR_CONFIG_PATH_WEAPONS] = CreateConVar("zr_config_path_weapons", "configs/zr/weapons/weapons.txt", "Path, relative to root sourcemod directory, to weapons config file.");
g_hCvarsList[CVAR_CONFIG_PATH_WEAPONGROUPS] = CreateConVar("zr_config_path_weapongroups", "configs/zr/weapons/weapongroups.txt", "Path, relative to root sourcemod directory, to weapongroups config file.");
g_hCvarsList[CVAR_CONFIG_PATH_HITGROUPS] = CreateConVar("zr_config_path_hitgroups", "configs/zr/hitgroups.txt", "Path, relative to root sourcemod directory, to hitgroups config file.");

110
src/zr/downloads.inc Normal file
View File

@ -0,0 +1,110 @@
/*
* ============================================================================
*
* Zombie:Reloaded
*
* File: downloads.inc
* Type: Core
* Description: Download validation.
*
* ============================================================================
*/
/**
* Array that stores a list of downloadable files.
*
* @redir config.inc
*/
/**
* Prepare all model/download data.
*/
DownloadsLoad()
{
// Get downloads file path.
decl String:pathdownloads[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_DOWNLOADS, pathdownloads);
// Register config info.
ConfigRegisterConfig(ConfigDownloads, false, GetFunctionByName(GetMyHandle(), "DownloadsOnConfigReload"), _, pathdownloads, CONFIG_FILE_ALIAS_DOWNLOADS);
// If file doesn't exist, then log.
if (!exists)
{
// Log error, then stop.
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Downloads", "Config Validation", "Missing downloads file: \"%s\"", pathdownloads);
return;
}
// If download array exists, then destroy it.
if (arrayDownloadsList != INVALID_HANDLE)
{
CloseHandle(arrayDownloadsList);
}
arrayDownloadsList = ConfigLinesToArray(pathdownloads);
// If array couldn't be created, then fail.
if (arrayDownloadsList == INVALID_HANDLE)
{
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Downloads", "Config Validation", "Error parsing \"%s\"", pathdownloads);
}
new downloadcount;
new downloadvalidcount;
decl String:downloadpath[PLATFORM_MAX_PATH];
new downloads = downloadcount = GetArraySize(arrayDownloadsList);
// x = download array index.
for (new x = 0; x < downloads; x++)
{
// Get base model path (rawline in models.txt)
GetArrayString(arrayDownloadsList, x, downloadpath, sizeof(downloadpath));
// If file doesn't exist, then remove, log, and stop.
if (!FileExists(downloadpath))
{
// Remove client from array.
RemoveFromArray(arrayDownloadsList, x);
// Subtract one from count.
downloads--;
// Backtrack one index, because we deleted it out from under the loop.
x--;
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Downloads", "Config Validation", "Missing file \"%s\"", downloadpath);
continue;
}
// Increment downloadvalidcount
downloadvalidcount++;
// Precache model file and add to downloads table.
AddFileToDownloadsTable(downloadpath);
}
// Log model validation info.
LogPrintToLog(LOG_FORMAT_TYPE_NORMAL, "Downloads", "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", downloadcount, downloadvalidcount, downloadcount - downloadvalidcount);
// Set config data.
ConfigSetConfigLoaded(ConfigDownloads, true);
ConfigSetConfigHandle(ConfigDownloads, arrayDownloadsList);
}
/**
* Called when configs are being reloaded.
*
* @param config The config being reloaded. (only if 'all' is false)
*/
public DownloadsOnConfigReload(ConfigFile:config)
{
// Reload download config.
if (config == ConfigDownloads)
{
DownloadsLoad();
}
}

View File

@ -54,6 +54,13 @@ HitgroupsLoad()
// Clear hitgroup data
HitgroupsClearData();
// Get hitgroups config path.
decl String:pathhitgroups[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_HITGROUPS, pathhitgroups);
// Register config info.
ConfigRegisterConfig(ConfigHitgroups, false, GetFunctionByName(GetMyHandle(), "HitgroupsOnConfigReload"), _, pathhitgroups, CONFIG_FILE_ALIAS_HITGROUPS);
// If module is disabled, then stop.
new bool:hitgroups = GetConVarBool(g_hCvarsList[CVAR_HITGROUPS]);
if (!hitgroups)
@ -61,10 +68,6 @@ HitgroupsLoad()
return;
}
// Get hitgroups config path.
decl String:pathhitgroups[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetFilePath(CVAR_CONFIG_PATH_HITGROUPS, pathhitgroups);
// If file doesn't exist, then log and stop.
if (!exists)
{
@ -78,6 +81,24 @@ HitgroupsLoad()
// Validate hitgroups config.
HitgroupsValidateConfig();
// Set config data.
ConfigSetConfigLoaded(ConfigHitgroups, true);
ConfigSetConfigHandle(ConfigHitgroups, kvHitgroups);
}
/**
* Called when configs are being reloaded.
*
* @param config The config being reloaded. (only if 'all' is false)
*/
public HitgroupsOnConfigReload(ConfigFile:config)
{
// Reload hitgroups config.
if (config == ConfigHitgroups)
{
HitgroupsLoad();
}
}
/**

View File

@ -5,7 +5,7 @@
*
* File: models.inc
* Type: Core
* Description: Model validation and API
* Description: Model validation.
*
* ============================================================================
*/
@ -26,23 +26,17 @@
* @redir config.inc
*/
ModelsLoad()
{
// Add models to downloads table and validate.
ModelsPrepModels();
// Add download entries to downloads table and validate.
ModelsPrepDownloads();
}
/**
* Validate model paths and add to downloads table.
* Prepare all model/download data.
*/
ModelsPrepModels()
ModelsLoad()
{
// Get models file path.
decl String:pathmodels[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetFilePath(CVAR_CONFIG_PATH_MODELS, pathmodels);
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_MODELS, pathmodels);
// Register config info.
ConfigRegisterConfig(ConfigModels, false, GetFunctionByName(GetMyHandle(), "ModelsOnConfigReload"), _, pathmodels, CONFIG_FILE_ALIAS_MODELS);
// If file doesn't exist, then log and stop.
if (!exists)
@ -164,70 +158,22 @@ ModelsPrepModels()
{
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Models", "Config Validation", "Fatal Error: No usable model paths in %s", pathmodels);
}
// Set config data.
ConfigSetConfigLoaded(ConfigModels, true);
ConfigSetConfigHandle(ConfigModels, arrayModelsList);
}
/**
* Validate custom download paths and add to downloads table.
* Called when configs are being reloaded.
*
* @param config The config being reloaded. (only if 'all' is false)
*/
ModelsPrepDownloads()
public ModelsOnConfigReload(ConfigFile:config)
{
// Get downloads file path.
decl String:pathdownloads[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetFilePath(CVAR_CONFIG_PATH_DOWNLOADS, pathdownloads);
// If file doesn't exist, then log.
if (!exists)
// Reload model config.
if (config == ConfigModels)
{
// Log error, then stop.
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Downloads", "Config Validation", "Missing downloads file: \"%s\"", pathdownloads);
return;
ModelsLoad();
}
new Handle:arrayDownloadsList = ConfigLinesToArray(pathdownloads);
// If array couldn't be created, then fail.
if (arrayModelsList == INVALID_HANDLE)
{
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Downloads", "Config Validation", "Error parsing \"%s\"", pathdownloads);
}
new downloadcount;
new downloadvalidcount;
decl String:downloadpath[PLATFORM_MAX_PATH];
new downloads = downloadcount = GetArraySize(arrayDownloadsList);
// x = download array index.
for (new x = 0; x < downloads; x++)
{
// Get base model path (rawline in models.txt)
GetArrayString(arrayDownloadsList, x, downloadpath, sizeof(downloadpath));
// If file doesn't exist, then remove, log, and stop.
if (!FileExists(downloadpath))
{
// Remove client from array.
RemoveFromArray(arrayDownloadsList, x);
// Subtract one from count.
downloads--;
// Backtrack one index, because we deleted it out from under the loop.
x--;
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Downloads", "Config Validation", "Missing file \"%s\"", downloadpath);
continue;
}
// Increment downloadvalidcount
downloadvalidcount++;
// Precache model file and add to downloads table.
AddFileToDownloadsTable(downloadpath);
}
// Log model validation info.
LogPrintToLog(LOG_FORMAT_TYPE_NORMAL, "Downloads", "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", downloadcount, downloadvalidcount, downloadcount - downloadvalidcount);
}
}

View File

@ -318,7 +318,7 @@ new ClassPlayerNextAdminClass[MAXPLAYERS + 1];
/**
* Loads class attributes from the class file into ClassData array. If any
* error occour the plugin load will fail, and errors will be logged.
* error occur the plugin load will fail, and errors will be logged.
*/
ClassLoad()
{
@ -331,7 +331,10 @@ ClassLoad()
// Get weapons config path.
decl String:pathclasses[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetFilePath(CVAR_CONFIG_PATH_PLAYERCLASSES, pathclasses);
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_CLASSES, pathclasses);
// Register config info.
ConfigRegisterConfig(ConfigClasses, false, GetFunctionByName(GetMyHandle(), "ClassOnConfigReload"), _, pathclasses, CONFIG_FILE_ALIAS_CLASSES);
// If file doesn't exist, then log and stop.
if (!exists)
@ -458,9 +461,24 @@ ClassLoad()
// Log summary.
LogPrintToLog(LOG_FORMAT_TYPE_NORMAL, "Classes", "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", ClassCount, ClassCount - failedcount, failedcount);
// Set config data.
ConfigSetConfigLoaded(ConfigClasses, true);
ConfigSetConfigHandle(ConfigClasses, kvClassData);
}
/**
* Called when configs are being reloaded.
*
* @param config The config being reloaded. (only if 'all' is false)
*/
public ClassOnConfigReload(ConfigFile:config)
{
// Reload class config.
if (config == ConfigClasses)
{
}
}
/**
* Updates the class data cache. Original values are retrieved from ClassData.

View File

@ -10,11 +10,6 @@
* ============================================================================
*/
/**
* Handle of cvar "sv_skyname."
*/
new Handle:g_hSkyname = INVALID_HANDLE;
/**
* Default sky of current map.
*/
@ -25,17 +20,16 @@ new String:g_VEffectsDefaultSky[PLATFORM_MAX_PATH];
*/
VEffectsLoad()
{
// Get sv_skyname's convar handle, if invalid, log error, then stop.
g_hSkyname = FindConVar("sv_skyname");
if (g_hSkyname == INVALID_HANDLE)
{
// TODO LOG.
return;
}
// Apply all visual effects now
VEffectsApplyAll();
// Store map's default sky before applying new one.
GetConVarString(g_hSkyname, g_VEffectsDefaultSky, sizeof(g_VEffectsDefaultSky));
// Find map's default sky.
new Handle:hSkyname = FindConVar("sv_skyname");
if (hSkyname != INVALID_HANDLE)
{
// Store map's default sky before applying new one.
GetConVarString(hSkyname, g_VEffectsDefaultSky, sizeof(g_VEffectsDefaultSky));
}
// If sky is disabled, then stop.
new bool:sky = GetConVarBool(g_hCvarsList[CVAR_VEFFECTS_SKY]);
@ -55,9 +49,6 @@ VEffectsLoad()
// Add skybox file to downloads table.
AddFileToDownloadsTable(downloadpath);
// Apply all visual effects now
VEffectsApplyAll();
}
/**
@ -239,11 +230,20 @@ VEffectsApplyLightStyle(bool:disable = false)
VEffectsApplySky(bool:disable = false)
{
// if we can't find the sv_skyname cvar, then stop.
new Handle:hSkyname = FindConVar("sv_skyname");
if (hSkyname == INVALID_HANDLE)
{
return;
}
// If default, then set to default sky.
if (disable)
{
// Set new sky on all clients.
SetConVarString(g_hSkyname, g_VEffectsDefaultSky, true);
if (g_VEffectsDefaultSky[0])
{
SetConVarString(hSkyname, g_VEffectsDefaultSky, true);
}
return;
}
@ -253,7 +253,7 @@ VEffectsApplySky(bool:disable = false)
GetConVarString(g_hCvarsList[CVAR_VEFFECTS_SKY_PATH], skypath, sizeof(skypath));
// Set new sky on all clients.
SetConVarString(g_hSkyname, skypath, true);
SetConVarString(hSkyname, skypath, true);
}
VEffectsApplySunDisable(bool:disable = false)

View File

@ -35,7 +35,7 @@ enum WpnRestrictQuery
Successful_Group, /** Group (un)restrict query was successful. */
Failed_Weapon, /** Weapon (un)restrict was unsuccessful */
Failed_Group, /** Group (un)restrict was unsuccessful */
Invalid, /** Weapon/Group invalid */
WeaponInvalid, /** Weapon/Group invalid */
}
/**
@ -57,7 +57,7 @@ RestrictInit()
*/
RestrictOnCommandsCreate()
{
// Create admin commands.
// Create weapon admin commands.
RegAdminCmd("zr_restrict", RestrictRestrictCommand, ADMFLAG_GENERIC, "zr_restrict <weapon> - Restrict a weapon.");
RegAdminCmd("zr_unrestrict", RestrictUnrestrictCommand, ADMFLAG_GENERIC, "zr_unrestrict <weapon> - Unrestrict a weapon.");
}
@ -82,7 +82,7 @@ RestrictClearData()
/**
* Loads weapon data from file.
*/
RestrictOnMapStart()
RestrictLoad()
{
// Clear weapon restrict data.
RestrictClearData();
@ -99,7 +99,7 @@ RestrictOnMapStart()
// Get weapon groups config path.
decl String:pathweapongroups[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetFilePath(CVAR_CONFIG_PATH_WEAPONGROUPS, pathweapongroups);
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_WEAPONGROUPS, pathweapongroups);
// If file doesn't exist, then log and stop.
if (!exists)
@ -221,7 +221,6 @@ RestrictClientInit(client)
RestrictOnClientDisconnect(client)
{
// Unhook "Weapon_CanUse" callback, and reset variable.
if (g_iCanUseHookID[client] != -1)
{
ZRTools_UnhookWeapon_CanUse(g_iCanUseHookID[client]);
@ -287,7 +286,7 @@ public Action:RestrictBuyCommand(client, argc)
* Successful_Group: The call successfully restricted a weapon group.
* Failed_Weapon: The call failed to restrict a weapon.
* Failed_Group: The call failed to restrict a weapon group.
* Invalid: The call was unsuccessful due to invalid weapon.
* WeaponInvalid: The call was unsuccessful due to invalid weapon.
*/
WpnRestrictQuery:RestrictRestrict(const String:weapon[], String:display[] = "")
{
@ -340,7 +339,7 @@ WpnRestrictQuery:RestrictRestrict(const String:weapon[], String:display[] = "")
strcopy(display, WEAPONS_MAX_LENGTH, weapon);
// Weapon name was invalid.
return Invalid;
return WeaponInvalid;
}
// Get display name of the weapon.
@ -368,7 +367,7 @@ WpnRestrictQuery:RestrictRestrict(const String:weapon[], String:display[] = "")
* Successful_Group: The call successfully restricted a weapon group.
* Failed_Weapon: The call failed to restrict a weapon.
* Failed_Group: The call failed to restrict a weapon group.
* Invalid: The call was unsuccessful due to invalid weapon.
* WeaponInvalid: The call was unsuccessful due to invalid weapon.
*/
WpnRestrictQuery:RestrictUnrestrict(const String:weapon[], String:display[] = "")
{
@ -425,7 +424,7 @@ WpnRestrictQuery:RestrictUnrestrict(const String:weapon[], String:display[] = ""
{
strcopy(display, WEAPONS_MAX_LENGTH, weapon);
return Invalid;
return WeaponInvalid;
}
// Get display name of the weapon.
@ -502,7 +501,7 @@ RestrictPrintRestrictOutput(client, WpnRestrictQuery:output, const String:weapon
}
}
// Weapon name was invalid.
case Invalid:
case WeaponInvalid:
{
if (reply)
{
@ -571,7 +570,7 @@ RestrictPrintUnrestrictOutput(client, WpnRestrictQuery:output, const String:weap
}
}
// Weapon name was invalid.
case Invalid:
case WeaponInvalid:
{
if (reply)
{
@ -886,6 +885,10 @@ public ZRTools_Action:RestrictCanUse(client, weapon)
return ZRTools_Continue;
}
/**
* Command callbacks.
*/
/**
* Command callback (zr_restrict)
* Restricts a weapon or group
@ -895,6 +898,13 @@ public ZRTools_Action:RestrictCanUse(client, weapon)
*/
public Action:RestrictRestrictCommand(client, argc)
{
// If not enough arguments given, then stop.
if (argc < 1)
{
TranslationReplyToCommand(client, "Weapons command restrict syntax");
return Plugin_Handled;
}
// If weapons module is disabled, then stop.
new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]);
if (!weapons)
@ -937,6 +947,13 @@ public Action:RestrictRestrictCommand(client, argc)
*/
public Action:RestrictUnrestrictCommand(client, argc)
{
// If not enough arguments given, then stop.
if (argc < 1)
{
TranslationReplyToCommand(client, "Weapons command unrestrict syntax");
return Plugin_Handled;
}
// If weapons module is disabled, then stop.
new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]);
if (!weapons)

View File

@ -18,7 +18,7 @@
/**
* Array that stores the "HookID" to be later unhooked on player disconnect.
*/
new g_iWeaponDropHookID[MAXPLAYERS + 1];
new g_iWeaponDropHookID[MAXPLAYERS + 1] = {-1, ...};
/**
* Client is joining the server.
@ -32,14 +32,18 @@ WeaponAlphaClientInit(client)
}
/**
* Unhook Weapon_CanUse function on a client.
* Client is leaving the server.
*
* @param client The client index.
*/
WeaponAlphaOnClientDisconnect(client)
{
// Unhook "Weapon_Drop" on client.
ZRTools_UnhookWeapon_Drop(g_iWeaponDropHookID[client]);
// Unhook "Weapon_Drop" callback, and reset variable.
if (g_iWeaponDropHookID[client] != -1)
{
ZRTools_UnhookWeapon_Drop(g_iWeaponDropHookID[client]);
g_iWeaponDropHookID[client] = -1;
}
}
/**

View File

@ -56,6 +56,15 @@ WeaponsInit()
RestrictInit();
}
/**
* Create commands related to weapons here.
*/
WeaponsOnCommandsCreate()
{
// Forward event to sub-modules.
RestrictOnCommandsCreate();
}
/**
* Clears weapon data.
*/
@ -78,6 +87,13 @@ WeaponsLoad()
// Clear weapon data.
WeaponsClearData();
// Get weapons config path.
decl String:pathweapons[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_WEAPONS, pathweapons);
// Register config info.
ConfigRegisterConfig(ConfigWeapons, false, GetFunctionByName(GetMyHandle(), "WeaponsOnConfigReload"), _, pathweapons, CONFIG_FILE_ALIAS_WEAPONS);
// If module is disabled, then stop.
new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]);
if (!weapons)
@ -85,10 +101,6 @@ WeaponsLoad()
return;
}
// Get weapons config path.
decl String:pathweapons[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetFilePath(CVAR_CONFIG_PATH_WEAPONS, pathweapons);
// If file doesn't exist, then log and stop.
if (!exists)
{
@ -104,8 +116,26 @@ WeaponsLoad()
// Validate weapons config.
WeaponsValidateConfig();
// Set config data.
ConfigSetConfigLoaded(ConfigWeapons, true);
ConfigSetConfigHandle(ConfigWeapons, kvWeapons);
// Forward event to sub-module.
RestrictOnMapStart();
RestrictLoad();
}
/**
* Called when configs are being reloaded.
*
* @param config The config being reloaded. (only if 'all' is false)
*/
public WeaponsOnConfigReload(ConfigFile:config)
{
// Reload weapons config.
if (config == ConfigWeapons)
{
WeaponsLoad();
}
}
/**
@ -120,12 +150,6 @@ WeaponsValidateConfig()
}
}
WeaponsOnCommandsCreate()
{
// Forward event to sub-modules.
RestrictOnCommandsCreate();
}
/**
* Client is joining the server.
*
@ -156,7 +180,7 @@ WeaponsOnClientDisconnect(client)
* on it when finished!
* @return The size of the array.
*/
WeaponsCreateWeaponArray(&Handle:arrayWeapons, maxlen = WEAPONS_MAX_LENGTH)
stock WeaponsCreateWeaponArray(&Handle:arrayWeapons, maxlen = WEAPONS_MAX_LENGTH)
{
// Initialize array handle.
arrayWeapons = CreateArray(maxlen);
@ -189,7 +213,7 @@ WeaponsCreateWeaponArray(&Handle:arrayWeapons, maxlen = WEAPONS_MAX_LENGTH)
* @param weapon The weapon name.
* @return Returns true if valid, false it not.
*/
bool:WeaponsIsValidWeapon(const String:weapon[])
stock bool:WeaponsIsValidWeapon(const String:weapon[])
{
// Reset keyvalue's traversal stack.
KvRewind(kvWeapons);
@ -219,7 +243,7 @@ bool:WeaponsIsValidWeapon(const String:weapon[])
* @param weapon The weapon name.
* @param display Returns with the display name, is not changed if weapon is invalid.
*/
WeaponsGetDisplayName(const String:weapon[], String:display[])
stock WeaponsGetDisplayName(const String:weapon[], String:display[])
{
// Reset keyvalue's traversal stack.
KvRewind(kvWeapons);
@ -246,7 +270,7 @@ WeaponsGetDisplayName(const String:weapon[], String:display[])
* @param weapon The weapon name.
* @return Returns true if restricted, false it not.
*/
bool:WeaponsIsWeaponMenu(const String:weapon[])
stock bool:WeaponsIsWeaponMenu(const String:weapon[])
{
// Reset keyvalue's traversal stack.
KvRewind(kvWeapons);
@ -278,7 +302,7 @@ bool:WeaponsIsWeaponMenu(const String:weapon[])
* @param weapon The weapon name.
* @return The float value of the knockback multiplier, 1.0 if not found.
*/
Float:WeaponGetWeaponKnockback(const String:weapon[])
stock Float:WeaponGetWeaponKnockback(const String:weapon[])
{
// Reset keyvalue's traversal stack.
KvRewind(kvWeapons);
@ -312,7 +336,7 @@ Float:WeaponGetWeaponKnockback(const String:weapon[])
* @param weapons The weapon index array.
* -1 if no weapon in slot.
*/
WeaponsGetClientWeapons(client, weapons[WeaponsType])
stock WeaponsGetClientWeapons(client, weapons[WeaponsType])
{
// x = weapon slot.
for (new x = 0; x < WEAPONS_SLOTS_MAX; x++)
@ -328,7 +352,7 @@ WeaponsGetClientWeapons(client, weapons[WeaponsType])
* @return The weapon index of the deployed weapon.
* -1 if no weapon is deployed.
*/
WeaponsGetDeployedWeaponIndex(client)
stock WeaponsGetDeployedWeaponIndex(client)
{
// Return the client's active weapon.
return GetEntDataEnt2(client, offsActiveWeapon);
@ -340,7 +364,7 @@ WeaponsGetDeployedWeaponIndex(client)
* @param client The client index.
* @return The slot number of deployed weapon.
*/
WeaponsType:WeaponsGetDeployedWeaponSlot(client)
stock WeaponsType:WeaponsGetDeployedWeaponSlot(client)
{
// Get all client's weapon indexes.
new weapons[WeaponsType];
@ -373,7 +397,7 @@ WeaponsType:WeaponsGetDeployedWeaponSlot(client)
* @param client The client index.
* @param weapon The weapon index to force client to drop.
*/
WeaponsForceClientDrop(client, weapon)
stock WeaponsForceClientDrop(client, weapon)
{
// Force client to drop weapon.
SDKCall(g_hToolsCSWeaponDrop, client, weapon, true, false);