Updated class filter to support filtering by classes with no groups set. Fixed default class assignment assigning classes players doesn't have access to.
This commit is contained in:
		| @@ -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); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user