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.
This commit is contained in:
richard 2009-05-09 17:45:19 +02:00
parent e9c611b476
commit 969aa19b85
9 changed files with 120 additions and 32 deletions

View File

@ -200,6 +200,8 @@ public OnConfigsExecuted()
VEffectsLoad(); VEffectsLoad();
SEffectsLoad(); SEffectsLoad();
ClassLoad(); ClassLoad();
ConfigOnModulesLoaded();
} }
/** /**

View File

@ -41,6 +41,9 @@
*/ */
#define CONFIG_OPTION_MAX_LENGTH 32 #define CONFIG_OPTION_MAX_LENGTH 32
/**
* Actions to use when working on key/values.
*/
enum ConfigKeyvalueAction enum ConfigKeyvalueAction
{ {
Create, /** Create a key. */ Create, /** Create a key. */
@ -48,6 +51,9 @@ enum ConfigKeyvalueAction
Set, /** Modify setting of a key. */ Set, /** Modify setting of a key. */
Get, /** Get setting of a key. */ Get, /** Get setting of a key. */
} }
/**
* @endsection
*/
/** /**
* @section Global data handle initializations. * @section Global data handle initializations.
@ -57,6 +63,7 @@ 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;
/** /**
* Load plugin configs. * 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. * Load config file.
* *
@ -106,6 +155,7 @@ bool:ConfigGetFilePath(CvarsList:cvar, String:path[])
return FileExists(path); return FileExists(path);
} }
/** /**
* 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,

View File

@ -92,6 +92,7 @@ LogInit()
* LOG_FORMAT_TYPE_SIMPLE - Simple, no module or block info. * 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_FULL - Full, with module and block info, printed in normal log.
* LOG_FORMAT_TYPE_ERROR - Full, printed in error log. * LOG_FORMAT_TYPE_ERROR - Full, printed in error log.
* LOG_FORMAT_TYPE_FATALERROR - Full, stops the plugin.
* @param any... Formatting parameters. * @param any... Formatting parameters.
*/ */
LogMessageFormatted(client, const String:module[], const String:block[], const String:message[], type = LOG_FORMAT_TYPE_FULL, any:...) LogMessageFormatted(client, const String:module[], const String:block[], const String:message[], type = LOG_FORMAT_TYPE_FULL, any:...)

View File

@ -24,7 +24,7 @@ MenuMain(client)
SetGlobalTransTarget(client); SetGlobalTransTarget(client);
// Set menu title. // Set menu title.
SetMenuTitle(menu_main, "%t\n ", "!zmenu title"); SetMenuTitle(menu_main, "%t\n ", "Menu main title");
// Initialize menu lines. // Initialize menu lines.
decl String:zadmin[64]; decl String:zadmin[64];

View File

@ -40,6 +40,9 @@ ModelsLoad()
*/ */
ModelsPrepModels() ModelsPrepModels()
{ {
// Initialize log boolean.
new bool:enablelog = LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CORE);
// 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 = ConfigGetFilePath(CVAR_CONFIG_PATH_MODELS, pathmodels);
@ -48,10 +51,7 @@ ModelsPrepModels()
if (!exists) if (!exists)
{ {
// Log failure and stop plugin. // Log failure and stop plugin.
if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CORE)) LogMessageFormatted(-1, "Models", "Config Validation", "Fatal error: Missing models file: \"%s\"", LOG_FORMAT_TYPE_FATALERROR, pathmodels);
{
LogMessageFormatted(-1, "Models", "Config Validation", "Missing models file: %s", LOG_FORMAT_TYPE_FATALERROR, pathmodels);
}
} }
// If model array exists, then destroy it. // If model array exists, then destroy it.
@ -65,7 +65,7 @@ ModelsPrepModels()
// If array couldn't be created, then fail. // If array couldn't be created, then fail.
if (arrayModelsList == INVALID_HANDLE) 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; new modelcount;
@ -155,7 +155,7 @@ ModelsPrepModels()
x--; x--;
// Log missing model files. // 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); 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. // Log model validation info.
if (enablelog)
{
LogMessageFormatted(-1, "Models", "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", LOG_FORMAT_TYPE_FULL, modelcount, modelvalidcount, modelcount - modelvalidcount); 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 none of the model paths are valid, then log and fail.
if (!modelvalidcount) 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); LogMessageFormatted(-1, "Models", "Config Validation", "No usable model paths in %s", LOG_FORMAT_TYPE_FATALERROR, pathmodels);
} }
@ -180,6 +183,9 @@ ModelsPrepModels()
*/ */
ModelsPrepDownloads() ModelsPrepDownloads()
{ {
// Initialize log boolean.
new bool:enablelog = LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CORE);
// Get downloads file path. // Get downloads file path.
decl String:pathdownloads[PLATFORM_MAX_PATH]; decl String:pathdownloads[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetFilePath(CVAR_CONFIG_PATH_DOWNLOADS, pathdownloads); new bool:exists = ConfigGetFilePath(CVAR_CONFIG_PATH_DOWNLOADS, pathdownloads);
@ -188,9 +194,9 @@ ModelsPrepDownloads()
if (!exists) if (!exists)
{ {
// Log error, then stop. // 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; return;
@ -201,9 +207,9 @@ ModelsPrepDownloads()
// If array couldn't be created, then fail. // If array couldn't be created, then fail.
if (arrayModelsList == INVALID_HANDLE) 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. // Backtrack one index, because we deleted it out from under the loop.
x--; 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; continue;
@ -248,5 +254,8 @@ ModelsPrepDownloads()
} }
// Log model validation info. // Log model validation info.
if (enablelog)
{
LogMessageFormatted(-1, "Downloads", "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", LOG_FORMAT_TYPE_FULL, downloadcount, downloadvalidcount, downloadcount - downloadvalidcount); LogMessageFormatted(-1, "Downloads", "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", LOG_FORMAT_TYPE_FULL, downloadcount, downloadvalidcount, downloadcount - downloadvalidcount);
}
} }

View File

@ -660,6 +660,9 @@ ClassGetDefaultSpawnClass(teamid, cachetype = ZR_CLASS_CACHE_MODIFIED)
decl String:classname[64]; decl String:classname[64];
new classindex; 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. // Get the default class name from the correct CVAR depending on teamid.
switch (teamid) switch (teamid)
{ {
@ -723,7 +726,7 @@ ClassGetDefaultSpawnClass(teamid, cachetype = ZR_CLASS_CACHE_MODIFIED)
// in the specified team, and log a warning. // in the specified team, and log a warning.
classindex = ClassGetFirstClass(teamid, _, cachetype); 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); 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)) if (ClassValidateIndex(classindex))
{ {
// Log a warning. // 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); LogMessageFormatted(-1, "Classes", "DefaultSpawnClass", "Warning: The default class name \"%s\" does not exist or matches the team ID.", _, classname);
} }

View File

@ -300,6 +300,9 @@ new ClassPlayerNextAdminClass[MAXPLAYERS + 1];
*/ */
ClassLoad() ClassLoad()
{ {
// Initialize log boolean.
new bool:enablelog = LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS);
// Make sure kvClassData is ready to use. // Make sure kvClassData is ready to use.
if (kvClassData != INVALID_HANDLE) if (kvClassData != INVALID_HANDLE)
{ {
@ -311,14 +314,16 @@ ClassLoad()
decl String:pathclasses[PLATFORM_MAX_PATH]; decl String:pathclasses[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetFilePath(CVAR_CONFIG_PATH_PLAYERCLASSES, pathclasses); 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 file doesn't exist, then log and stop.
if (!exists) if (!exists)
{ {
// Log failure. LogMessageFormatted(-1, "Classes", "Load", "Fatal error: Missing playerclasses config file \"%s\"", LOG_FORMAT_TYPE_FATALERROR, pathclasses);
if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS))
{
LogMessageFormatted(-1, "Classes", "Config Validation", "Missing playerclasses config file: %s", LOG_FORMAT_TYPE_FATALERROR, pathclasses);
}
return; return;
} }
@ -330,7 +335,7 @@ ClassLoad()
KvRewind(kvClassData); KvRewind(kvClassData);
if (!KvGotoFirstSubKey(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]; decl String:name[64];
@ -339,6 +344,7 @@ ClassLoad()
decl String:overlay_path[PLATFORM_MAX_PATH]; decl String:overlay_path[PLATFORM_MAX_PATH];
ClassCount = 0; ClassCount = 0;
new failedcount;
new ClassErrorFlags; new ClassErrorFlags;
// Loop through all classes and store attributes in the ClassData array. // Loop through all classes and store attributes in the ClassData array.
@ -347,7 +353,7 @@ ClassLoad()
if (ClassCount > ZR_CLASS_MAX) if (ClassCount > ZR_CLASS_MAX)
{ {
// Maximum classes reached. Write a warning and exit the loop. // 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); 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 // There's one or more invalid class attributes. Disable the class
// and log an error message. // and log an error message.
ClassData[ClassCount][class_enabled] = false; 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); 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. // Update the counter.
@ -424,17 +432,23 @@ ClassLoad()
// Validate team requirements. // Validate team requirements.
if (!ClassValidateTeamRequirements()) 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. // Validate team default requirements.
if (!ClassValidateTeamDefaults()) 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. // Cache class data.
ClassReloadDataCache(); ClassReloadDataCache();
// Log summary.
if (enablelog)
{
LogMessageFormatted(-1, "Classes", "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", _, ClassCount, ClassCount - failedcount, failedcount);
}
} }
/** /**

View File

@ -57,6 +57,9 @@ bool:AmbientSoundsValidateConfig()
return false; return false;
} }
// Initialize log boolean.
new bool:enablelog = LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_AMBIENTSOUNDS);
// Get ambient sound file. // Get ambient sound file.
decl String:sound[SOUND_MAX_PATH]; decl String:sound[SOUND_MAX_PATH];
GetConVarString(g_hCvarsList[CVAR_AMBIENTSOUNDS_FILE], sound, sizeof(sound)); GetConVarString(g_hCvarsList[CVAR_AMBIENTSOUNDS_FILE], sound, sizeof(sound));
@ -66,7 +69,7 @@ bool:AmbientSoundsValidateConfig()
if (!FileExists(sound, true)) if (!FileExists(sound, true))
{ {
// Log invalid sound file error. // 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); 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) if (ambientvolume <= 0.0)
{ {
// Log invalid ambient sound volume error. // 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); 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) if (ambientlength <= 0.0)
{ {
// Log invalid ambient sound length error. // 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; return false;

View File

@ -36,6 +36,12 @@ ZSpawnOnMapStart()
*/ */
ZSpawnOnClientDisconnect(client) ZSpawnOnClientDisconnect(client)
{ {
// Check if client is a bot.
if (!IsFakeClient(client))
{
return;
}
// Get client's unique serial number. // Get client's unique serial number.
new serial = GetClientSerial(client); new serial = GetClientSerial(client);