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 // General
@ -130,7 +171,7 @@
} }
// =========================== // ===========================
// (core) Overlays // Overlays (core)
// =========================== // ===========================
"Overlays not supported" "Overlays not supported"
@ -141,7 +182,7 @@
} }
// =========================== // ===========================
// (core) Infect // Infect (core)
// =========================== // ===========================
// General // General
@ -158,7 +199,7 @@
} }
// =========================== // ===========================
// (core) Damage // Damage (core)
// =========================== // ===========================
"Damage suicide intercept" "Damage suicide intercept"
@ -215,7 +256,7 @@
} }
// =========================== // ===========================
// (core) Weapons // Weapons (core)
// =========================== // ===========================
// General // General
@ -310,6 +351,18 @@
"ru" "Купить снова" "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 // Menu
"Weapons menu main title" "Weapons menu main title"
@ -370,7 +423,7 @@
} }
// =========================== // ===========================
// Spawn Protect // Spawn Protect (module)
// =========================== // ===========================
// General // General
@ -397,7 +450,7 @@
} }
// =========================== // ===========================
// ZSpawn // ZSpawn (module)
// =========================== // ===========================
"ZSpawn double spawn" "ZSpawn double spawn"
@ -412,7 +465,7 @@
} }
// =========================== // ===========================
// ZTele // ZTele (module)
// =========================== // ===========================
// General // General
@ -459,7 +512,7 @@
} }
// =========================== // ===========================
// ZHP // ZHP (module)
// =========================== // ===========================
// General // General

View File

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

View File

@ -16,6 +16,7 @@
CommandsInit() CommandsInit()
{ {
// Forward event to modules. (create commands) // Forward event to modules. (create commands)
ConfigOnCommandsCreate();
WeaponsOnCommandsCreate(); WeaponsOnCommandsCreate();
// Forward event to modules. (hook commands) // 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_MAX_LENGTH 32
#define CONFIG_FILE_DOWNLOADS 1
#define CONFIG_FILE_PLAYERCLASSES 2 /**
#define CONFIG_FILE_WEAPONS 3 * @section Config file reference aliases.
#define CONFIG_FILE_WEAPONGROUPS 4 */
#define CONFIG_FILE_HITGROUPS 5 #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 * @endsection
*/ */
/** /**
* @section Config file flags. * List of config files used by the plugin.
*/
#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
*/ */
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. * Actions to use when working on key/values.
*/ */
enum ConfigKeyvalueAction enum ConfigKeyvalueAction
{ {
Create, /** Create a key. */ ConfigKVCreate, /** Create a key. */
Delete, /** Delete a key. */ ConfigKVDelete, /** Delete a key. */
Set, /** Modify setting of a key. */ ConfigKVSet, /** Modify setting of a key. */
Get, /** Get setting of a key. */ ConfigKVGet, /** Get setting of a key. */
} }
/**
* @endsection
*/
/** /**
* @section Global data handle initializations. * @section Global data handle initializations.
*/ */
new Handle:arrayModelsList = INVALID_HANDLE; new Handle:arrayModelsList = INVALID_HANDLE;
new Handle:arrayDownloadsList = INVALID_HANDLE;
new Handle:kvClassData = INVALID_HANDLE; new Handle:kvClassData = INVALID_HANDLE;
new Handle:kvWeapons = INVALID_HANDLE; new Handle:kvWeapons = INVALID_HANDLE;
new Handle:kvWeaponGroups = INVALID_HANDLE; new Handle:kvWeaponGroups = INVALID_HANDLE;
new Handle:kvHitgroups = 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. * Load plugin configs.
*/ */
@ -130,13 +155,187 @@ ConfigOnModulesLoaded()
LogPrintToLog(LOG_FORMAT_TYPE_NORMAL, "Config", "Map Configs", "Executed post map config file: %s", path); 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. * Load config file.
* *
* @param file The cvar define of the path to the file. * @param file The cvar define of the path to the file.
* @return True if the file exists, false if not. * @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. // Get cvar's path.
decl String:filepath[PLATFORM_MAX_PATH]; decl String:filepath[PLATFORM_MAX_PATH];
@ -148,6 +347,36 @@ bool:ConfigGetFilePath(CvarsList:cvar, String:path[])
return FileExists(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. * 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, * 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. * @param maxlen (Optional) The maxlength of the gotten value.
* @return True if the change was made successfully, false otherwise. * @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. // Retrieve handle of the keyvalue tree.
new Handle:hConfig = ConfigGetFileHandle(config); new Handle:hConfig = ConfigGetConfigHandle(config);
// If handle is invalid, then stop. // If handle is invalid, then stop.
if (hConfig == INVALID_HANDLE) if (hConfig == INVALID_HANDLE)
@ -199,7 +428,7 @@ bool:ConfigKeyvalueTreeSetting(config, ConfigKeyvalueAction:action = Create, con
switch(action) switch(action)
{ {
case Create: case ConfigKVCreate:
{ {
if (!setting[0] || !value[0]) if (!setting[0] || !value[0])
{ {
@ -210,17 +439,17 @@ bool:ConfigKeyvalueTreeSetting(config, ConfigKeyvalueAction:action = Create, con
// Set new value. // Set new value.
KvSetString(hConfig, setting, value); KvSetString(hConfig, setting, value);
} }
case Delete: case ConfigKVDelete:
{ {
// Return deletion result. // Return deletion result.
return KvDeleteKey(hConfig, setting); return KvDeleteKey(hConfig, setting);
} }
case Set: case ConfigKVSet:
{ {
// Set new value. // Set new value.
KvSetString(hConfig, setting, value); KvSetString(hConfig, setting, value);
} }
case Get: case ConfigKVGet:
{ {
// Get current value. // Get current value.
KvGetString(hConfig, setting, value, maxlen); 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: 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;
// 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;
}
} }
// Invalid config index. // arg1 = file alias being reloaded.
return INVALID_HANDLE; 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_LOG_PRINT_CONSOLE,
Handle:CVAR_CONFIG_PATH_MODELS, Handle:CVAR_CONFIG_PATH_MODELS,
Handle:CVAR_CONFIG_PATH_DOWNLOADS, Handle:CVAR_CONFIG_PATH_DOWNLOADS,
Handle:CVAR_CONFIG_PATH_PLAYERCLASSES, Handle:CVAR_CONFIG_PATH_CLASSES,
Handle:CVAR_CONFIG_PATH_WEAPONS, Handle:CVAR_CONFIG_PATH_WEAPONS,
Handle:CVAR_CONFIG_PATH_WEAPONGROUPS, Handle:CVAR_CONFIG_PATH_WEAPONGROUPS,
Handle:CVAR_CONFIG_PATH_HITGROUPS, 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_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_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_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_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."); 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 // Clear hitgroup data
HitgroupsClearData(); 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. // If module is disabled, then stop.
new bool:hitgroups = GetConVarBool(g_hCvarsList[CVAR_HITGROUPS]); new bool:hitgroups = GetConVarBool(g_hCvarsList[CVAR_HITGROUPS]);
if (!hitgroups) if (!hitgroups)
@ -61,10 +68,6 @@ HitgroupsLoad()
return; 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 file doesn't exist, then log and stop.
if (!exists) if (!exists)
{ {
@ -78,6 +81,24 @@ HitgroupsLoad()
// Validate hitgroups config. // Validate hitgroups config.
HitgroupsValidateConfig(); 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 * File: models.inc
* Type: Core * Type: Core
* Description: Model validation and API * Description: Model validation.
* *
* ============================================================================ * ============================================================================
*/ */
@ -26,23 +26,17 @@
* @redir config.inc * @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. // Get models file path.
decl String:pathmodels[PLATFORM_MAX_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 file doesn't exist, then log and stop.
if (!exists) if (!exists)
@ -164,70 +158,22 @@ ModelsPrepModels()
{ {
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Models", "Config Validation", "Fatal Error: No usable model paths in %s", pathmodels); 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. // Reload model config.
decl String:pathdownloads[PLATFORM_MAX_PATH]; if (config == ConfigModels)
new bool:exists = ConfigGetFilePath(CVAR_CONFIG_PATH_DOWNLOADS, pathdownloads);
// If file doesn't exist, then log.
if (!exists)
{ {
// Log error, then stop. ModelsLoad();
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Downloads", "Config Validation", "Missing downloads file: \"%s\"", pathdownloads);
return;
} }
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 * 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() ClassLoad()
{ {
@ -331,7 +331,10 @@ ClassLoad()
// Get weapons config path. // Get weapons config path.
decl String:pathclasses[PLATFORM_MAX_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 file doesn't exist, then log and stop.
if (!exists) if (!exists)
@ -458,9 +461,24 @@ ClassLoad()
// Log summary. // Log summary.
LogPrintToLog(LOG_FORMAT_TYPE_NORMAL, "Classes", "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", ClassCount, ClassCount - failedcount, failedcount); 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. * 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. * Default sky of current map.
*/ */
@ -25,17 +20,16 @@ new String:g_VEffectsDefaultSky[PLATFORM_MAX_PATH];
*/ */
VEffectsLoad() VEffectsLoad()
{ {
// Get sv_skyname's convar handle, if invalid, log error, then stop. // Apply all visual effects now
g_hSkyname = FindConVar("sv_skyname"); VEffectsApplyAll();
if (g_hSkyname == INVALID_HANDLE)
// Find map's default sky.
new Handle:hSkyname = FindConVar("sv_skyname");
if (hSkyname != INVALID_HANDLE)
{ {
// TODO LOG.
return;
}
// Store map's default sky before applying new one. // Store map's default sky before applying new one.
GetConVarString(g_hSkyname, g_VEffectsDefaultSky, sizeof(g_VEffectsDefaultSky)); GetConVarString(hSkyname, g_VEffectsDefaultSky, sizeof(g_VEffectsDefaultSky));
}
// If sky is disabled, then stop. // If sky is disabled, then stop.
new bool:sky = GetConVarBool(g_hCvarsList[CVAR_VEFFECTS_SKY]); new bool:sky = GetConVarBool(g_hCvarsList[CVAR_VEFFECTS_SKY]);
@ -55,9 +49,6 @@ VEffectsLoad()
// Add skybox file to downloads table. // Add skybox file to downloads table.
AddFileToDownloadsTable(downloadpath); AddFileToDownloadsTable(downloadpath);
// Apply all visual effects now
VEffectsApplyAll();
} }
/** /**
@ -239,11 +230,20 @@ VEffectsApplyLightStyle(bool:disable = false)
VEffectsApplySky(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 default, then set to default sky.
if (disable) if (disable)
{ {
// Set new sky on all clients. if (g_VEffectsDefaultSky[0])
SetConVarString(g_hSkyname, g_VEffectsDefaultSky, true); {
SetConVarString(hSkyname, g_VEffectsDefaultSky, true);
}
return; return;
} }
@ -253,7 +253,7 @@ VEffectsApplySky(bool:disable = false)
GetConVarString(g_hCvarsList[CVAR_VEFFECTS_SKY_PATH], skypath, sizeof(skypath)); GetConVarString(g_hCvarsList[CVAR_VEFFECTS_SKY_PATH], skypath, sizeof(skypath));
// Set new sky on all clients. // Set new sky on all clients.
SetConVarString(g_hSkyname, skypath, true); SetConVarString(hSkyname, skypath, true);
} }
VEffectsApplySunDisable(bool:disable = false) VEffectsApplySunDisable(bool:disable = false)

View File

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

View File

@ -18,7 +18,7 @@
/** /**
* Array that stores the "HookID" to be later unhooked on player disconnect. * 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. * 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. * @param client The client index.
*/ */
WeaponAlphaOnClientDisconnect(client) WeaponAlphaOnClientDisconnect(client)
{ {
// Unhook "Weapon_Drop" on client. // Unhook "Weapon_Drop" callback, and reset variable.
if (g_iWeaponDropHookID[client] != -1)
{
ZRTools_UnhookWeapon_Drop(g_iWeaponDropHookID[client]); ZRTools_UnhookWeapon_Drop(g_iWeaponDropHookID[client]);
g_iWeaponDropHookID[client] = -1;
}
} }
/** /**

View File

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