From 855ffc3c0da632ef6ea8f5d6e3db28e53eb3fdf4 Mon Sep 17 00:00:00 2001 From: richard Date: Sat, 15 Aug 2009 17:37:30 +0200 Subject: [PATCH] Updated class filter to support filtering by classes with no groups set. Fixed default class assignment assigning classes players doesn't have access to. --- src/zr/playerclasses/filtertools.inc | 37 +++++++++++++++--------- src/zr/playerclasses/playerclasses.inc | 39 ++++++++++++++++---------- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/src/zr/playerclasses/filtertools.inc b/src/zr/playerclasses/filtertools.inc index c8ece10..79f8656 100644 --- a/src/zr/playerclasses/filtertools.inc +++ b/src/zr/playerclasses/filtertools.inc @@ -485,26 +485,25 @@ stock bool:ClassFilterMatch(index, filter[ClassFilter], cachetype = ZR_CLASS_CAC return false; } - // Check class flags pass the flag filter. + // Check if class flags pass the flag filter. if (!ClassFlagFilterMatch(index, filter[ClassFilter_RequireFlags], filter[ClassFilter_DenyFlags], cachetype)) { return false; } + // Get class group name. + decl String:groupname[64]; + groupname[0] = 0; + ClassGetGroup(index, groupname, sizeof(groupname), cachetype); + // Check if a client is specified in the filter. new client = filter[ClassFilter_Client]; if (ZRIsClientValid(client)) { - // Get class group name. - decl String:groupname[64]; - groupname[0] = 0; - ClassGetGroup(index, groupname, sizeof(groupname), cachetype); - - // Check if a group is set on the class. Note: This group name is - // validated when classes are loaded. + // Check if a group is set on the class. if (strlen(groupname)) { - // Check if the client is a member of that group. + // Check if the client is not a member of that group. if (!ZRIsClientInGroup(client, groupname)) { return false; @@ -512,6 +511,16 @@ stock bool:ClassFilterMatch(index, filter[ClassFilter], cachetype = ZR_CLASS_CAC } } + // Check if classes with groups are set to be excluded. + if (client < 0) + { + // Exclude class if it has a group name. + if (strlen(groupname)) + { + return false; + } + } + // The class passed the filter. return true; } @@ -921,6 +930,8 @@ stock ClassGetDefaultClass(teamid, filter[ClassFilter] = ClassNoSpecialClasses, * when players join the server. * * @param teamid The team ID. + * @param filter Optional. Structure with filter settings. Default is to + * deny classes with special flags (ZR_CLASS_SPECIALFLAGS). * @param cachetype Optional. Specifies what class cache to read from. Options: * ZR_CLASS_CACHE_ORIGINAL - Unchanced class data. * ZR_CLASS_CACHE_MODIFIED (default) - Changed/newest class @@ -929,7 +940,7 @@ stock ClassGetDefaultClass(teamid, filter[ClassFilter] = ClassNoSpecialClasses, * successful. -1 on critical errors. Otherwise it will try to fall * back on the first class in the specified team. */ -stock ClassGetDefaultSpawnClass(teamid, cachetype = ZR_CLASS_CACHE_MODIFIED) +stock ClassGetDefaultSpawnClass(teamid, filter[ClassFilter] = ClassNoSpecialClasses, cachetype = ZR_CLASS_CACHE_MODIFIED) { decl String:classname[64]; new classindex; @@ -964,7 +975,7 @@ stock ClassGetDefaultSpawnClass(teamid, cachetype = ZR_CLASS_CACHE_MODIFIED) { // Get a list of all classes with the specified team ID. Deny // classes with special flags. - classindex = ClassGetRandomClass(teamid, _, cachetype); + classindex = ClassGetRandomClass(teamid, filter, cachetype); // Validate the result, in case there were errors. if (ClassValidateIndex(classindex)) @@ -996,7 +1007,7 @@ stock ClassGetDefaultSpawnClass(teamid, cachetype = ZR_CLASS_CACHE_MODIFIED) // The class index is invalid or the team IDs didn't match. // Because it's user input, we'll fall back to the first class // in the specified team, and log a warning. - classindex = ClassGetFirstClass(teamid, _, cachetype); + classindex = ClassGetFirstClass(teamid, filter, cachetype); LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Default Spawn Class", "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); @@ -1019,6 +1030,6 @@ stock ClassGetDefaultSpawnClass(teamid, cachetype = ZR_CLASS_CACHE_MODIFIED) else { // Blank class name, get the default class and return the index. - return ClassGetDefaultClass(teamid, _, cachetype); + return ClassGetDefaultClass(teamid, filter, cachetype); } } diff --git a/src/zr/playerclasses/playerclasses.inc b/src/zr/playerclasses/playerclasses.inc index 2d84994..abdb3c2 100644 --- a/src/zr/playerclasses/playerclasses.inc +++ b/src/zr/playerclasses/playerclasses.inc @@ -320,7 +320,7 @@ enum ClassFilter bool:ClassFilter_IgnoreEnabled, /** Ignore whether the class is disabled or not. */ ClassFilter_RequireFlags, /** Flags the classes must have set. */ ClassFilter_DenyFlags, /** Flags the classes cannot have set. */ - ClassFilter_Client /** The client to check for class group permissions. Use 0 or less to ignore group filter. */ + ClassFilter_Client /** The client to check for class group permissions. Use 0 to ignore group filter and negative to exclude classes with groups set. */ } /** @@ -930,6 +930,8 @@ ClassRestoreNextIndexes(client, excludeTeam = -1) ClassClientSetDefaultIndexes(client = -1) { new bool:clientvalid = ZRIsClientValid(client); + new filter[ClassFilter]; + new zombieindex; new humanindex; new adminindex; @@ -950,11 +952,15 @@ ClassClientSetDefaultIndexes(client = -1) // one so zero means no class set and will result in a invalid // class index when restored. - // Check if class indexes are set. If not, fall back to default class - // indexes. Otherwise substract index by one. - if (zombieindex <= 0) + // Setup filtering so group permission is checked on player first. + filter[ClassFilter_Client] = client; + + // Check if class indexes are set and that the client pass group + // permissions. If not, fall back to default class indexes. Otherwise + // substract index by one. + if (zombieindex <= 0 || !ClassFilterMatch(zombieindex, filter)) { - zombieindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_ZOMBIES); + zombieindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_ZOMBIES, filter); } else { @@ -962,9 +968,9 @@ ClassClientSetDefaultIndexes(client = -1) haszombie = true; } - if (humanindex <= 0) + if (humanindex <= 0 || !ClassFilterMatch(humanindex, filter)) { - humanindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_HUMANS); + humanindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_HUMANS, filter); } else { @@ -972,9 +978,9 @@ ClassClientSetDefaultIndexes(client = -1) hashuman = true; } - if (adminindex <= 0) + if (adminindex <= 0 || !ClassFilterMatch(adminindex, filter)) { - adminindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_ADMINS); + adminindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_ADMINS, filter); } else { @@ -984,10 +990,13 @@ ClassClientSetDefaultIndexes(client = -1) } else { + // Setup filtering so classes with groups set are excluded. + filter[ClassFilter_Client] = -1; + // Get default class indexes. - zombieindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_ZOMBIES); - humanindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_HUMANS); - adminindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_ADMINS); + zombieindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_ZOMBIES, filter); + humanindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_HUMANS, filter); + adminindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_ADMINS, filter); } // Validate indexes. @@ -998,7 +1007,7 @@ ClassClientSetDefaultIndexes(client = -1) LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Set Default Indexes", "Warning: Failed to get specified zombie class, falling back to default class in class config. Check spelling in \"zr_classes_default_zombie\"."); // Use default class. - zombieindex = ClassGetDefaultClass(ZR_CLASS_TEAM_ZOMBIES); + zombieindex = ClassGetDefaultClass(ZR_CLASS_TEAM_ZOMBIES, filter); } // Get human class index. @@ -1009,7 +1018,7 @@ ClassClientSetDefaultIndexes(client = -1) LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Set Default Indexes", "Warning: Failed to get specified human class, falling back to default class in class config. Check spelling in \"zr_classes_default_human\"."); // Use default class. - humanindex = ClassGetDefaultClass(ZR_CLASS_TEAM_HUMANS); + humanindex = ClassGetDefaultClass(ZR_CLASS_TEAM_HUMANS, filter); } // Get admin class index. @@ -1018,7 +1027,7 @@ ClassClientSetDefaultIndexes(client = -1) // Invalid class index. Fall back to default class in class config if // possible. A invalid class index (-1) can also be stored if there are // no admin classes at all. - adminindex = ClassGetDefaultClass(ZR_CLASS_TEAM_ADMINS); + adminindex = ClassGetDefaultClass(ZR_CLASS_TEAM_ADMINS, filter); } // Check if a client is specified.