271 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
			
		
		
	
	
			271 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
| #pragma semicolon 1
 | |
| 
 | |
| #include <sourcemod>
 | |
| #include <zombiereloaded>
 | |
| 
 | |
| #define PLUGIN_VERSION	"1.6.1"
 | |
| 
 | |
| new Handle:kv;
 | |
| new Handle:hPlayerClasses, String:sClassPath[PLATFORM_MAX_PATH] = "configs/zr/playerclasses.txt";
 | |
| new bool:g_RoundEnd = false;
 | |
| 
 | |
| public Plugin:myinfo = 
 | |
| {
 | |
| 	name = "[ZR] Tools",
 | |
| 	author = "FrozDark",
 | |
| 	description = "Useful tools for Zombie:Reloaded",
 | |
| 	version = PLUGIN_VERSION,
 | |
| 	url = "www.hlmod.ru"
 | |
| }
 | |
| 
 | |
| public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
 | |
| {
 | |
| 	CreateNative("ZRT_GetClientClassSectionName", Native_GetClientClassSectionName);
 | |
| 	CreateNative("ZRT_GetClientAttributeString", Native_GetClientAttributeString);
 | |
| 	CreateNative("ZRT_GetClientAttributeValue", Native_GetClientAttributeValue);
 | |
| 	CreateNative("ZRT_GetClientAttributeValueFloat", Native_GetClientAttributeValueFloat);
 | |
| 	CreateNative("ZRT_PlayerHasAttribute", Native_PlayerHasAttribute);
 | |
| 	CreateNative("ZRT_IsRoundActive", Native_IsRoundActive);
 | |
| 	
 | |
| 	RegPluginLibrary("zr_tools");
 | |
| 	
 | |
| 	return APLRes_Success;
 | |
| }
 | |
| 
 | |
| public OnPluginStart()
 | |
| {
 | |
| 	CreateConVar("zr_tools_version", PLUGIN_VERSION, "Zombie:Reloaded tools plugin version", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_CHEAT|FCVAR_DONTRECORD);
 | |
| 	
 | |
| 	RegAdminCmd("zr_tools_reload", Command_Reload, ADMFLAG_ROOT);
 | |
| 	
 | |
| 	HookEvent("round_start", Event_RoundStart);
 | |
| 	HookEvent("round_end", Event_RoundEnd);
 | |
| }
 | |
| 
 | |
| public OnAllPluginsLoaded()
 | |
| {
 | |
| 	if (hPlayerClasses != INVALID_HANDLE)
 | |
| 	{
 | |
| 		UnhookConVarChange(hPlayerClasses, OnClassPathChange);
 | |
| 		CloseHandle(hPlayerClasses);
 | |
| 	}
 | |
| 	if ((hPlayerClasses = FindConVar("zr_config_path_playerclasses")) == INVALID_HANDLE)
 | |
| 	{
 | |
| 		SetFailState("Zombie:Reloaded is not running on this server");
 | |
| 	}
 | |
| 	HookConVarChange(hPlayerClasses, OnClassPathChange);
 | |
| }
 | |
| 
 | |
| public OnClassPathChange(Handle:convar, const String:oldValue[], const String:newValue[])
 | |
| {
 | |
| 	strcopy(sClassPath, sizeof(sClassPath), newValue);
 | |
| 	OnConfigsExecuted();
 | |
| }
 | |
| 
 | |
| public OnConfigsExecuted()
 | |
| {
 | |
| 	if (kv != INVALID_HANDLE)
 | |
| 	{
 | |
| 		CloseHandle(kv);
 | |
| 	}
 | |
| 	kv = CreateKeyValues("classes");
 | |
| 	
 | |
| 	decl String:buffer[PLATFORM_MAX_PATH];
 | |
| 	BuildPath(Path_SM, buffer, sizeof(buffer), "%s", sClassPath);
 | |
| 	
 | |
| 	if (!FileToKeyValues(kv, buffer))
 | |
| 	{
 | |
| 		SetFailState("Class data file \"%s\" not found", buffer);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| public Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
 | |
| {
 | |
| 	g_RoundEnd = false;
 | |
| }
 | |
| 
 | |
| public Event_RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
 | |
| {
 | |
| 	g_RoundEnd = true;
 | |
| }
 | |
| 
 | |
| public Action:Command_Reload(client, args)
 | |
| {
 | |
| 	OnConfigsExecuted();
 | |
| 	return Plugin_Handled;
 | |
| }
 | |
| 
 | |
| public Native_IsRoundActive(Handle:plugin, numParams)
 | |
| {
 | |
| 	return !g_RoundEnd;
 | |
| }
 | |
| 
 | |
| public Native_PlayerHasAttribute(Handle:plugin, numParams)
 | |
| {
 | |
| 	new client = GetNativeCell(1);
 | |
| 	ValidateClient(client);
 | |
| 	
 | |
| 	decl String:attrib[32];
 | |
| 	GetNativeString(2, attrib, sizeof(attrib));
 | |
| 	
 | |
| 	decl String:className[64], String:buffer[64];
 | |
| 	ZR_GetClassDisplayName(client, className, sizeof(className), ZR_CLASS_CACHE_PLAYER);
 | |
| 	
 | |
| 	new bool:result = false;
 | |
| 	if (KvGotoFirstSubKey(kv))
 | |
| 	{
 | |
| 		do
 | |
| 		{
 | |
| 			KvGetString(kv, "name", buffer, sizeof(buffer));
 | |
| 			if (StrEqual(buffer, className, false))
 | |
| 			{
 | |
| 				KvGetString(kv, attrib, buffer, sizeof(buffer), "0");
 | |
| 				
 | |
| 				result = bool:(StrContains("yes|1|true", buffer, false) != -1);
 | |
| 				break;
 | |
| 			}
 | |
| 		} while (KvGotoNextKey(kv));
 | |
| 	}
 | |
| 	KvRewind(kv);
 | |
| 	
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| public Native_GetClientAttributeString(Handle:plugin, numParams)
 | |
| {
 | |
| 	new client = GetNativeCell(1);
 | |
| 	ValidateClient(client);
 | |
| 	
 | |
| 	decl String:attrib[32];
 | |
| 	GetNativeString(2, attrib, sizeof(attrib));
 | |
| 	
 | |
| 	decl String:className[64], String:buffer[PLATFORM_MAX_PATH];
 | |
| 	buffer[0] = '\0';
 | |
| 	ZR_GetClassDisplayName(client, className, sizeof(className), ZR_CLASS_CACHE_PLAYER);
 | |
| 	
 | |
| 	new bytes;
 | |
| 	if (KvGotoFirstSubKey(kv))
 | |
| 	{
 | |
| 		do
 | |
| 		{
 | |
| 			KvGetString(kv, "name", buffer, sizeof(buffer));
 | |
| 			if (StrEqual(buffer, className, false))
 | |
| 			{
 | |
| 				KvGetString(kv, attrib, buffer, sizeof(buffer), "");
 | |
| 				
 | |
| 				SetNativeString(3, buffer, GetNativeCell(4), true, bytes);
 | |
| 				break;
 | |
| 			}
 | |
| 		} while (KvGotoNextKey(kv));
 | |
| 	}
 | |
| 	KvRewind(kv);
 | |
| 	
 | |
| 	if (!buffer[0])
 | |
| 	{
 | |
| 		GetNativeString(5, buffer, sizeof(buffer));
 | |
| 		SetNativeString(3, buffer, GetNativeCell(4), true, bytes);
 | |
| 	}
 | |
| 	return bytes;
 | |
| }
 | |
| 
 | |
| public Native_GetClientAttributeValue(Handle:plugin, numParams)
 | |
| {
 | |
| 	new client = GetNativeCell(1);
 | |
| 	ValidateClient(client);
 | |
| 	
 | |
| 	decl String:attrib[32];
 | |
| 	GetNativeString(2, attrib, sizeof(attrib));
 | |
| 	
 | |
| 	decl String:className[64], String:buffer[PLATFORM_MAX_PATH];
 | |
| 	ZR_GetClassDisplayName(client, className, sizeof(className), ZR_CLASS_CACHE_PLAYER);
 | |
| 	
 | |
| 	new result = -1;
 | |
| 	
 | |
| 	if (KvGotoFirstSubKey(kv))
 | |
| 	{
 | |
| 		do
 | |
| 		{
 | |
| 			KvGetString(kv, "name", buffer, sizeof(buffer));
 | |
| 			if (StrEqual(buffer, className, false))
 | |
| 			{
 | |
| 				result = KvGetNum(kv, attrib, GetNativeCell(3));
 | |
| 				break;
 | |
| 			}
 | |
| 		} while (KvGotoNextKey(kv));
 | |
| 	}
 | |
| 	KvRewind(kv);
 | |
| 	
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| public Native_GetClientAttributeValueFloat(Handle:plugin, numParams)
 | |
| {
 | |
| 	new client = GetNativeCell(1);
 | |
| 	ValidateClient(client);
 | |
| 	
 | |
| 	decl String:attrib[32];
 | |
| 	GetNativeString(2, attrib, sizeof(attrib));
 | |
| 	
 | |
| 	decl String:className[64], String:buffer[PLATFORM_MAX_PATH];
 | |
| 	ZR_GetClassDisplayName(client, className, sizeof(className), ZR_CLASS_CACHE_PLAYER);
 | |
| 	
 | |
| 	new Float:result = -1.0;
 | |
| 	
 | |
| 	if (KvGotoFirstSubKey(kv))
 | |
| 	{
 | |
| 		do
 | |
| 		{
 | |
| 			KvGetString(kv, "name", buffer, sizeof(buffer));
 | |
| 			if (StrEqual(buffer, className, false))
 | |
| 			{
 | |
| 				result = KvGetFloat(kv, attrib, Float:GetNativeCell(3));
 | |
| 				break;
 | |
| 			}
 | |
| 		} while (KvGotoNextKey(kv));
 | |
| 	}
 | |
| 	KvRewind(kv);
 | |
| 	
 | |
| 	return _:result;
 | |
| }
 | |
| 
 | |
| public Native_GetClientClassSectionName(Handle:plugin, numParams)
 | |
| {
 | |
| 	new client = GetNativeCell(1);
 | |
| 	ValidateClient(client);
 | |
| 	
 | |
| 	decl String:className[64], String:buffer[64];
 | |
| 	ZR_GetClassDisplayName(client, className, sizeof(className), ZR_CLASS_CACHE_PLAYER);
 | |
| 	
 | |
| 	new bytes;
 | |
| 	if (KvGotoFirstSubKey(kv))
 | |
| 	{
 | |
| 		do
 | |
| 		{
 | |
| 			KvGetString(kv, "name", buffer, sizeof(buffer));
 | |
| 			if (StrEqual(buffer, className, false))
 | |
| 			{
 | |
| 				KvGetSectionName(kv, buffer, sizeof(buffer));
 | |
| 				
 | |
| 				SetNativeString(2, buffer, GetNativeCell(3), true, bytes);
 | |
| 				break;
 | |
| 			}
 | |
| 		} while (KvGotoNextKey(kv));
 | |
| 	}
 | |
| 	KvRewind(kv);
 | |
| 	
 | |
| 	return bytes;
 | |
| }
 | |
| 
 | |
| ValidateClient(client)
 | |
| {
 | |
| 	if (client < 1 || client > MaxClients)
 | |
| 	{
 | |
| 		ThrowNativeError(SP_ERROR_INDEX, "Client index %i is invalid", client);
 | |
| 		return;
 | |
| 	}
 | |
| 	else if (!IsClientInGame(client))
 | |
| 	{
 | |
| 		ThrowNativeError(SP_ERROR_NOT_FOUND, "Client %i is not in game", client);
 | |
| 		return;
 | |
| 	}
 | |
| } |