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();
SEffectsLoad();
ClassLoad();
ConfigOnModulesLoaded();
}
/**

View File

@ -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,

View File

@ -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:...)

View File

@ -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];

View File

@ -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.
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.
if (enablelog)
{
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];
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);
}

View File

@ -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);
}
}
/**

View File

@ -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;

View File

@ -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);