From 969aa19b853001aeb78aeaab1f9d9a5afd91b4a1 Mon Sep 17 00:00:00 2001 From: richard Date: Sat, 9 May 2009 17:45:19 +0200 Subject: [PATCH] Added support for post map configs (with workaround for SourceMod bug 3803). Log cleanup. Minior fixes. Removed log check in fatal errors. Those must always log. Stored LogCheckFlag result in a boolean where log is executed more than once. Fixed invalid translation string used in menu title. Fixed index out of bounds in zspawn when a client disconnects. --- src/zombiereloaded.sp | 2 ++ src/zr/config.inc | 50 ++++++++++++++++++++++++++ src/zr/log.inc | 1 + src/zr/menu.inc | 2 +- src/zr/models.inc | 39 ++++++++++++-------- src/zr/playerclasses/filtertools.inc | 7 ++-- src/zr/playerclasses/playerclasses.inc | 34 ++++++++++++------ src/zr/soundeffects/ambientsounds.inc | 11 +++--- src/zr/zspawn.inc | 6 ++++ 9 files changed, 120 insertions(+), 32 deletions(-) diff --git a/src/zombiereloaded.sp b/src/zombiereloaded.sp index ceb36ac..12245b8 100644 --- a/src/zombiereloaded.sp +++ b/src/zombiereloaded.sp @@ -200,6 +200,8 @@ public OnConfigsExecuted() VEffectsLoad(); SEffectsLoad(); ClassLoad(); + + ConfigOnModulesLoaded(); } /** diff --git a/src/zr/config.inc b/src/zr/config.inc index d582631..bdc7c4b 100644 --- a/src/zr/config.inc +++ b/src/zr/config.inc @@ -41,6 +41,9 @@ */ #define CONFIG_OPTION_MAX_LENGTH 32 +/** + * Actions to use when working on key/values. + */ enum ConfigKeyvalueAction { Create, /** Create a key. */ @@ -48,6 +51,9 @@ enum ConfigKeyvalueAction Set, /** Modify setting of a key. */ Get, /** Get setting of a key. */ } +/** + * @endsection + */ /** * @section Global data handle initializations. @@ -57,6 +63,7 @@ new Handle:kvClassData = INVALID_HANDLE; new Handle:kvWeapons = INVALID_HANDLE; new Handle:kvWeaponGroups = INVALID_HANDLE; new Handle:kvHitgroups = INVALID_HANDLE; + /** * Load plugin configs. */ @@ -88,6 +95,48 @@ ConfigLoad() } } +/** + * Executed when modules are done loading. After all init calls in + * OnConfigsExecuted. + * + * Executes post map configs if they exist. + */ +ConfigOnModulesLoaded() +{ + decl String:mapname[256]; + decl String:mapconfig[PLATFORM_MAX_PATH]; + decl String:path[PLATFORM_MAX_PATH]; + new bool:cfgexists; + + // Get map name and format into config path. + GetCurrentMap(mapname, sizeof(mapname)); + Format(mapconfig, sizeof(mapconfig), "sourcemod/zombiereloaded/%s.post.cfg", mapname); + + // Prepend cfg to path. + Format(path, sizeof(path), "cfg/%s", mapconfig); + + // Workaround for bug 3083 in SourceMod compiler. Having FileExist directly + // in the if in this function makes it crash. Storing the result in a + // boolean first works. + + // Check if the file exist. + cfgexists = FileExists(path); + if (!cfgexists) + { + // File doesn't exist, then stop. + return; + } + + // Execute config file. + ServerCommand("exec %s", mapconfig); + + // Log action. + if (LogCheckFlag(LOG_CORE_EVENTS)) + { + LogMessageFormatted(-1, "", "", "Executed post map config file: %s.", LOG_FORMAT_TYPE_SIMPLE, mapconfig); + } +} + /** * Load config file. * @@ -106,6 +155,7 @@ bool:ConfigGetFilePath(CvarsList:cvar, String:path[]) return FileExists(path); } + /** * 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, diff --git a/src/zr/log.inc b/src/zr/log.inc index 5101de6..6544ae9 100644 --- a/src/zr/log.inc +++ b/src/zr/log.inc @@ -92,6 +92,7 @@ LogInit() * LOG_FORMAT_TYPE_SIMPLE - Simple, no module or block info. * LOG_FORMAT_TYPE_FULL - Full, with module and block info, printed in normal log. * LOG_FORMAT_TYPE_ERROR - Full, printed in error log. + * LOG_FORMAT_TYPE_FATALERROR - Full, stops the plugin. * @param any... Formatting parameters. */ LogMessageFormatted(client, const String:module[], const String:block[], const String:message[], type = LOG_FORMAT_TYPE_FULL, any:...) diff --git a/src/zr/menu.inc b/src/zr/menu.inc index 5c05bea..21b952d 100644 --- a/src/zr/menu.inc +++ b/src/zr/menu.inc @@ -24,7 +24,7 @@ MenuMain(client) SetGlobalTransTarget(client); // Set menu title. - SetMenuTitle(menu_main, "%t\n ", "!zmenu title"); + SetMenuTitle(menu_main, "%t\n ", "Menu main title"); // Initialize menu lines. decl String:zadmin[64]; diff --git a/src/zr/models.inc b/src/zr/models.inc index 7b2da1c..2de1e33 100644 --- a/src/zr/models.inc +++ b/src/zr/models.inc @@ -40,6 +40,9 @@ ModelsLoad() */ ModelsPrepModels() { + // Initialize log boolean. + new bool:enablelog = LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CORE); + // Get models file path. decl String:pathmodels[PLATFORM_MAX_PATH]; new bool:exists = ConfigGetFilePath(CVAR_CONFIG_PATH_MODELS, pathmodels); @@ -48,10 +51,7 @@ ModelsPrepModels() if (!exists) { // Log failure and stop plugin. - if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CORE)) - { - LogMessageFormatted(-1, "Models", "Config Validation", "Missing models file: %s", LOG_FORMAT_TYPE_FATALERROR, pathmodels); - } + LogMessageFormatted(-1, "Models", "Config Validation", "Fatal error: Missing models file: \"%s\"", LOG_FORMAT_TYPE_FATALERROR, pathmodels); } // If model array exists, then destroy it. @@ -65,7 +65,7 @@ ModelsPrepModels() // If array couldn't be created, then fail. if (arrayModelsList == INVALID_HANDLE) { - LogMessageFormatted(-1, "Models", "Config Validation", "Error parsing %s", LOG_FORMAT_TYPE_FATALERROR, pathmodels); + LogMessageFormatted(-1, "Models", "Config Validation", "Fatal error: Error parsing \"%s\"", LOG_FORMAT_TYPE_FATALERROR, pathmodels); } new modelcount; @@ -155,7 +155,7 @@ ModelsPrepModels() x--; // Log missing model files. - if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CORE)) + if (enablelog) { LogMessageFormatted(-1, "Models", "Config Validation", "Missing model files on server (%s)", LOG_FORMAT_TYPE_ERROR, modelbase); } @@ -163,12 +163,15 @@ ModelsPrepModels() } // Log model validation info. - LogMessageFormatted(-1, "Models", "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", LOG_FORMAT_TYPE_FULL, modelcount, modelvalidcount, modelcount - modelvalidcount); + if (enablelog) + { + LogMessageFormatted(-1, "Models", "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", LOG_FORMAT_TYPE_FULL, modelcount, modelvalidcount, modelcount - modelvalidcount); + } // If none of the model paths are valid, then log and fail. if (!modelvalidcount) { - if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CORE)) + if (enablelog) { LogMessageFormatted(-1, "Models", "Config Validation", "No usable model paths in %s", LOG_FORMAT_TYPE_FATALERROR, pathmodels); } @@ -180,6 +183,9 @@ ModelsPrepModels() */ ModelsPrepDownloads() { + // Initialize log boolean. + new bool:enablelog = LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CORE); + // Get downloads file path. decl String:pathdownloads[PLATFORM_MAX_PATH]; new bool:exists = ConfigGetFilePath(CVAR_CONFIG_PATH_DOWNLOADS, pathdownloads); @@ -188,9 +194,9 @@ ModelsPrepDownloads() if (!exists) { // Log error, then stop. - if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CORE)) + if (enablelog) { - LogMessageFormatted(-1, "Downloads", "Config Validation", "Missing downloads file: %s", LOG_FORMAT_TYPE_ERROR, pathdownloads); + LogMessageFormatted(-1, "Downloads", "Config Validation", "Missing downloads file: \"%s\"", LOG_FORMAT_TYPE_ERROR, pathdownloads); } return; @@ -201,9 +207,9 @@ ModelsPrepDownloads() // If array couldn't be created, then fail. if (arrayModelsList == INVALID_HANDLE) { - if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CORE)) + if (enablelog) { - LogMessageFormatted(-1, "Downloads", "Config Validation", "Error parsing %s", LOG_FORMAT_TYPE_ERROR, pathdownloads); + LogMessageFormatted(-1, "Downloads", "Config Validation", "Error parsing \"%s\"", LOG_FORMAT_TYPE_ERROR, pathdownloads); } } @@ -232,9 +238,9 @@ ModelsPrepDownloads() // Backtrack one index, because we deleted it out from under the loop. x--; - if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CORE)) + if (enablelog) { - LogMessageFormatted(-1, "Downloads", "Config Validation", "Missing file (%s)", LOG_FORMAT_TYPE_ERROR, downloadpath); + LogMessageFormatted(-1, "Downloads", "Config Validation", "Missing file \"%s\"", LOG_FORMAT_TYPE_ERROR, downloadpath); } continue; @@ -248,5 +254,8 @@ ModelsPrepDownloads() } // Log model validation info. - LogMessageFormatted(-1, "Downloads", "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", LOG_FORMAT_TYPE_FULL, downloadcount, downloadvalidcount, downloadcount - downloadvalidcount); + if (enablelog) + { + LogMessageFormatted(-1, "Downloads", "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", LOG_FORMAT_TYPE_FULL, downloadcount, downloadvalidcount, downloadcount - downloadvalidcount); + } } diff --git a/src/zr/playerclasses/filtertools.inc b/src/zr/playerclasses/filtertools.inc index a84759f..d5230db 100644 --- a/src/zr/playerclasses/filtertools.inc +++ b/src/zr/playerclasses/filtertools.inc @@ -660,6 +660,9 @@ ClassGetDefaultSpawnClass(teamid, cachetype = ZR_CLASS_CACHE_MODIFIED) decl String:classname[64]; new classindex; + // Initialize log boolean. + new bool:enablelog = LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CLASSES); + // Get the default class name from the correct CVAR depending on teamid. switch (teamid) { @@ -723,7 +726,7 @@ ClassGetDefaultSpawnClass(teamid, cachetype = ZR_CLASS_CACHE_MODIFIED) // in the specified team, and log a warning. classindex = ClassGetFirstClass(teamid, _, cachetype); - if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CLASSES)) + if (enablelog) { LogMessageFormatted(-1, "Classes", "DefaultSpawnClass", "Warning: Failed to set \"%s\" as default spawn class for team %d. The class doesn't exist or the team IDs doesn't match. Falling back to the first class in the team.", _, classname, teamid); } @@ -732,7 +735,7 @@ ClassGetDefaultSpawnClass(teamid, cachetype = ZR_CLASS_CACHE_MODIFIED) if (ClassValidateIndex(classindex)) { // Log a warning. - if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CLASSES)) + if (enablelog) { LogMessageFormatted(-1, "Classes", "DefaultSpawnClass", "Warning: The default class name \"%s\" does not exist or matches the team ID.", _, classname); } diff --git a/src/zr/playerclasses/playerclasses.inc b/src/zr/playerclasses/playerclasses.inc index 02b6ee1..b6e8a28 100644 --- a/src/zr/playerclasses/playerclasses.inc +++ b/src/zr/playerclasses/playerclasses.inc @@ -300,6 +300,9 @@ new ClassPlayerNextAdminClass[MAXPLAYERS + 1]; */ ClassLoad() { + // Initialize log boolean. + new bool:enablelog = LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS); + // Make sure kvClassData is ready to use. if (kvClassData != INVALID_HANDLE) { @@ -311,14 +314,16 @@ ClassLoad() decl String:pathclasses[PLATFORM_MAX_PATH]; new bool:exists = ConfigGetFilePath(CVAR_CONFIG_PATH_PLAYERCLASSES, pathclasses); + // Log what class file that is loaded. + if (enablelog) + { + LogMessageFormatted(-1, "Classes", "Load", "Loading classes from file \"%s\".", LOG_FORMAT_TYPE_SIMPLE, pathclasses); + } + // If file doesn't exist, then log and stop. if (!exists) { - // Log failure. - if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS)) - { - LogMessageFormatted(-1, "Classes", "Config Validation", "Missing playerclasses config file: %s", LOG_FORMAT_TYPE_FATALERROR, pathclasses); - } + LogMessageFormatted(-1, "Classes", "Load", "Fatal error: Missing playerclasses config file \"%s\"", LOG_FORMAT_TYPE_FATALERROR, pathclasses); return; } @@ -330,7 +335,7 @@ ClassLoad() KvRewind(kvClassData); if (!KvGotoFirstSubKey(kvClassData)) { - LogMessageFormatted(-1, "Classes", "Config Validation", "Can't find any classes in %s", LOG_FORMAT_TYPE_FATALERROR, pathclasses); + LogMessageFormatted(-1, "Classes", "Load", "Fatal error: Can't find any classes in \"%s\"", LOG_FORMAT_TYPE_FATALERROR, pathclasses); } decl String:name[64]; @@ -339,6 +344,7 @@ ClassLoad() decl String:overlay_path[PLATFORM_MAX_PATH]; ClassCount = 0; + new failedcount; new ClassErrorFlags; // Loop through all classes and store attributes in the ClassData array. @@ -347,7 +353,7 @@ ClassLoad() if (ClassCount > ZR_CLASS_MAX) { // Maximum classes reached. Write a warning and exit the loop. - if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CLASSES)) + if (enablelog) { LogMessageFormatted(-1, "Classes", "Load", "Warning: Maximum classes reached (%d). Skipping other classes.", _, ZR_CLASS_MAX + 1); } @@ -411,10 +417,12 @@ ClassLoad() // There's one or more invalid class attributes. Disable the class // and log an error message. ClassData[ClassCount][class_enabled] = false; - if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CLASSES)) + if (enablelog) { LogMessageFormatted(-1, "Classes", "Config Validation", "Warning: Invalid class at index %d, disabled class. Class error flags: %d.", LOG_FORMAT_TYPE_ERROR, ClassCount, ClassErrorFlags); } + + failedcount++; } // Update the counter. @@ -424,17 +432,23 @@ ClassLoad() // Validate team requirements. if (!ClassValidateTeamRequirements()) { - LogMessageFormatted(-1, "Classes", "Config Validation", "The class configuration doesn't match the team requirements.", LOG_FORMAT_TYPE_FATALERROR); + LogMessageFormatted(-1, "Classes", "Config Validation", "Fatal error: The class configuration doesn't match the team requirements.", LOG_FORMAT_TYPE_FATALERROR); } // Validate team default requirements. if (!ClassValidateTeamDefaults()) { - LogMessageFormatted(-1, "Classes", "Config Validation", "Couldn't find a default class for one or more teams. At least one class per team must be marked as default.", LOG_FORMAT_TYPE_FATALERROR); + LogMessageFormatted(-1, "Classes", "Config Validation", "Fatal error: Couldn't find a default class for one or more teams. At least one class per team must be marked as default.", LOG_FORMAT_TYPE_FATALERROR); } // Cache class data. ClassReloadDataCache(); + + // Log summary. + if (enablelog) + { + LogMessageFormatted(-1, "Classes", "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", _, ClassCount, ClassCount - failedcount, failedcount); + } } /** diff --git a/src/zr/soundeffects/ambientsounds.inc b/src/zr/soundeffects/ambientsounds.inc index e76b17b..2c201a1 100644 --- a/src/zr/soundeffects/ambientsounds.inc +++ b/src/zr/soundeffects/ambientsounds.inc @@ -57,6 +57,9 @@ bool:AmbientSoundsValidateConfig() return false; } + // Initialize log boolean. + new bool:enablelog = LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_AMBIENTSOUNDS); + // Get ambient sound file. decl String:sound[SOUND_MAX_PATH]; GetConVarString(g_hCvarsList[CVAR_AMBIENTSOUNDS_FILE], sound, sizeof(sound)); @@ -66,7 +69,7 @@ bool:AmbientSoundsValidateConfig() if (!FileExists(sound, true)) { // Log invalid sound file error. - if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_AMBIENTSOUNDS)) + if (enablelog) { LogMessageFormatted(-1, "Ambient Sounds", "Config Validation", "Invalid sound file specified in zr_ambientsounds_file.", LOG_FORMAT_TYPE_ERROR); } @@ -79,7 +82,7 @@ bool:AmbientSoundsValidateConfig() if (ambientvolume <= 0.0) { // Log invalid ambient sound volume error. - if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_AMBIENTSOUNDS)) + if (enablelog) { LogMessageFormatted(-1, "Ambient Sounds", "Config Validation", "Ambient sound is either muted or invalid.", LOG_FORMAT_TYPE_ERROR); } @@ -92,9 +95,9 @@ bool:AmbientSoundsValidateConfig() if (ambientlength <= 0.0) { // Log invalid ambient sound length error. - if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_AMBIENTSOUNDS)) + if (enablelog) { - LogMessageFormatted(-1, "Ambient Sounds", "Config Validation", "Ambient sound length is invalid.", LOG_FORMAT_TYPE_ERROR); + LogMessageFormatted(-1, "Ambient Sounds", "Config Validation", "Specified ambient sound length is invalid.", LOG_FORMAT_TYPE_ERROR); } return false; diff --git a/src/zr/zspawn.inc b/src/zr/zspawn.inc index 904fc7a..5b336cb 100644 --- a/src/zr/zspawn.inc +++ b/src/zr/zspawn.inc @@ -36,6 +36,12 @@ ZSpawnOnMapStart() */ ZSpawnOnClientDisconnect(client) { + // Check if client is a bot. + if (!IsFakeClient(client)) + { + return; + } + // Get client's unique serial number. new serial = GetClientSerial(client);