1032 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
			
		
		
	
	
			1032 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
| #if defined _colorvariables_included
 | |
| 	#endinput
 | |
| #endif
 | |
| #define _colorvariables_included "1.3"
 | |
| 
 | |
| // Author: Raska aka KissLick
 | |
| 
 | |
| // ----------------------------------------------------------------------------------------
 | |
| #define _CV_MAX_MESSAGE_LENGTH 		1024
 | |
| #define _CV_MAX_VARIABLE_REDIRECTS 	10
 | |
| #define _CV_CONFIG_DIRECTORY 		"configs/colorvariables"
 | |
| 
 | |
| static bool:g_bInit = false;
 | |
| static Handle:g_hColors = INVALID_HANDLE;
 | |
| static String:g_sConfigGlobal[PLATFORM_MAX_PATH];
 | |
| static String:g_sConfig[PLATFORM_MAX_PATH];
 | |
| static String:g_sChatPrefix[64] = "";
 | |
| 
 | |
| static bool:g_bIgnorePrefix = false;
 | |
| static g_iAuthor;
 | |
| static bool:g_bSkipPlayers[MAXPLAYERS + 1] = {false, ...};
 | |
| 
 | |
| static Handle:g_hForwardedVariable;
 | |
| 
 | |
| enum triple {
 | |
| 	unknown = -1,
 | |
| 	yes = true,
 | |
| 	no = false
 | |
| }
 | |
| static triple:g_IsSource2009 = unknown;
 | |
| // ----------------------------------------------------------------------------------------
 | |
| 
 | |
| forward COnForwardedVariable(String:sCode[], String:sData[], iDataSize, String:sColor[], iColorSize);
 | |
| 
 | |
| stock CSetPrefix(const String:sPrefix[], any:...)
 | |
| {
 | |
| 	VFormat(g_sChatPrefix, sizeof(g_sChatPrefix), sPrefix, 2);
 | |
| }
 | |
| 
 | |
| stock CSavePrefix(const String:sPrefix[], any:...)
 | |
| {
 | |
| 	new String:m_sPrefix[64];
 | |
| 	VFormat(m_sPrefix, sizeof(m_sPrefix), sPrefix, 2);
 | |
| 
 | |
| 	CAddVariable("&prefix", m_sPrefix, true);
 | |
| }
 | |
| 
 | |
| stock CSkipNextPrefix()
 | |
| {
 | |
| 	g_bIgnorePrefix = true;
 | |
| }
 | |
| 
 | |
| stock CSetNextAuthor(iClient)
 | |
| {
 | |
| 	if (iClient < 1 || iClient > MaxClients || !IsClientInGame(iClient)) {
 | |
| 		ThrowError("Invalid client index %i", iClient);
 | |
| 	}
 | |
| 	g_iAuthor = iClient;
 | |
| }
 | |
| 
 | |
| stock CSkipNextClient(iClient)
 | |
| {
 | |
| 	if (iClient < 1 || iClient > MaxClients) {
 | |
| 		ThrowError("Invalid client index %i", iClient);
 | |
| 	}
 | |
| 	g_bSkipPlayers[iClient] = true;
 | |
| }
 | |
| 
 | |
| stock CPrintToChat(iClient, const String:sMessage[], any:...)
 | |
| {
 | |
| 	if (iClient < 1 || iClient > MaxClients) {
 | |
| 		ThrowError("Invalid client index %d", iClient);
 | |
| 	}
 | |
| 
 | |
| 	if (!IsClientInGame(iClient)) {
 | |
| 		ThrowError("Client %d is not in game", iClient);
 | |
| 	}
 | |
| 
 | |
| 	decl String:sBuffer[_CV_MAX_MESSAGE_LENGTH];
 | |
| 	SetGlobalTransTarget(iClient);
 | |
| 	VFormat(sBuffer, sizeof(sBuffer), sMessage, 3);
 | |
| 
 | |
| 	AddPrefixAndDefaultColor(sBuffer, sizeof(sBuffer));
 | |
| 	g_bIgnorePrefix = false;
 | |
| 
 | |
| 	CProcessVariables(sBuffer, sizeof(sBuffer));
 | |
| 	CAddWhiteSpace(sBuffer, sizeof(sBuffer));
 | |
| 
 | |
| 	SendPlayerMessage(iClient, sBuffer, g_iAuthor);
 | |
| 	g_iAuthor = 0;
 | |
| }
 | |
| 
 | |
| stock CPrintToChatAll(const String:sMessage[], any:...)
 | |
| {
 | |
| 	decl String:sBuffer[_CV_MAX_MESSAGE_LENGTH];
 | |
| 
 | |
| 	for (new iClient = 1; iClient <= MaxClients; iClient++) {
 | |
| 		if (!IsClientInGame(iClient) || g_bSkipPlayers[iClient]) {
 | |
| 			g_bSkipPlayers[iClient] = false;
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		SetGlobalTransTarget(iClient);
 | |
| 		VFormat(sBuffer, sizeof(sBuffer), sMessage, 2);
 | |
| 
 | |
| 		AddPrefixAndDefaultColor(sBuffer, sizeof(sBuffer));
 | |
| 		g_bIgnorePrefix = false;
 | |
| 
 | |
| 		CProcessVariables(sBuffer, sizeof(sBuffer));
 | |
| 		CAddWhiteSpace(sBuffer, sizeof(sBuffer));
 | |
| 
 | |
| 		SendPlayerMessage(iClient, sBuffer, g_iAuthor);
 | |
| 	}
 | |
| 	g_iAuthor = 0;
 | |
| }
 | |
| 
 | |
| stock CPrintToChatTeam(iTeam, const String:sMessage[], any:...)
 | |
| {
 | |
| 	decl String:sBuffer[_CV_MAX_MESSAGE_LENGTH];
 | |
| 
 | |
| 	for (new iClient = 1; iClient <= MaxClients; iClient++) {
 | |
| 		if (!IsClientInGame(iClient) || GetClientTeam(iClient) != iTeam || g_bSkipPlayers[iClient]) {
 | |
| 			g_bSkipPlayers[iClient] = false;
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		SetGlobalTransTarget(iClient);
 | |
| 		VFormat(sBuffer, sizeof(sBuffer), sMessage, 3);
 | |
| 
 | |
| 		AddPrefixAndDefaultColor(sBuffer, sizeof(sBuffer));
 | |
| 		g_bIgnorePrefix = false;
 | |
| 
 | |
| 		CProcessVariables(sBuffer, sizeof(sBuffer));
 | |
| 		CAddWhiteSpace(sBuffer, sizeof(sBuffer));
 | |
| 
 | |
| 		SendPlayerMessage(iClient, sBuffer, g_iAuthor);
 | |
| 	}
 | |
| 	g_iAuthor = 0;
 | |
| }
 | |
| 
 | |
| stock CPrintToChatAdmins(iBitFlags, const String:sMessage[], any:...)
 | |
| {
 | |
| 	decl String:sBuffer[_CV_MAX_MESSAGE_LENGTH];
 | |
| 	new AdminId:iAdminID;
 | |
| 
 | |
| 	for (new iClient = 1; iClient <= MaxClients; iClient++) {
 | |
| 		if (!IsClientInGame(iClient) || GetClientTeam(iClient) != iTeam || g_bSkipPlayers[iClient]) {
 | |
| 			g_bSkipPlayers[iClient] = false;
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		iAdminID = GetUserAdmin(iClient);
 | |
| 		if (iAdminID == INVALID_ADMIN_ID || GetAdminFlags(iAdminID, Access_Effective) ~ iBitFlags) {
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		SetGlobalTransTarget(iClient);
 | |
| 		VFormat(sBuffer, sizeof(sBuffer), sMessage, 3);
 | |
| 
 | |
| 		AddPrefixAndDefaultColor(sBuffer, sizeof(sBuffer));
 | |
| 		g_bIgnorePrefix = false;
 | |
| 
 | |
| 		CProcessVariables(sBuffer, sizeof(sBuffer));
 | |
| 		CAddWhiteSpace(sBuffer, sizeof(sBuffer));
 | |
| 
 | |
| 		SendPlayerMessage(iClient, sBuffer, g_iAuthor);
 | |
| 	}
 | |
| 	g_iAuthor = 0;
 | |
| }
 | |
| 
 | |
| stock CReplyToCommand(iClient, const String:sMessage[], any:...)
 | |
| {
 | |
| 	if (iClient < 0 || iClient > MaxClients) {
 | |
| 		ThrowError("Invalid client index %d", iClient);
 | |
| 	}
 | |
| 
 | |
| 	if (iClient != 0 && !IsClientInGame(iClient)) {
 | |
| 		ThrowError("Client %d is not in game", iClient);
 | |
| 	}
 | |
| 
 | |
| 	decl String:sBuffer[_CV_MAX_MESSAGE_LENGTH];
 | |
| 	SetGlobalTransTarget(iClient);
 | |
| 	VFormat(sBuffer, sizeof(sBuffer), sMessage, 3);
 | |
| 
 | |
| 	AddPrefixAndDefaultColor(sBuffer, sizeof(sBuffer), "reply2cmd");
 | |
| 	g_bIgnorePrefix = false;
 | |
| 
 | |
| 	if (GetCmdReplySource() == SM_REPLY_TO_CONSOLE) {
 | |
| 		CRemoveColors(sBuffer, sizeof(sBuffer));
 | |
| 		PrintToConsole(iClient, "%s", sBuffer);
 | |
| 	} else {
 | |
| 		CPrintToChat(iClient, "%s", sBuffer);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| stock CShowActivity(iClient, const String:sMessage[], any:...)
 | |
| {
 | |
| 	if (iClient < 0 || iClient > MaxClients) {
 | |
| 		ThrowError("Invalid client index %d", iClient);
 | |
| 	}
 | |
| 
 | |
| 	if (iClient != 0 && !IsClientInGame(iClient)) {
 | |
| 		ThrowError("Client %d is not in game", iClient);
 | |
| 	}
 | |
| 
 | |
| 	decl String:sBuffer[_CV_MAX_MESSAGE_LENGTH];
 | |
| 	SetGlobalTransTarget(iClient);
 | |
| 	VFormat(sBuffer, sizeof(sBuffer), sMessage, 3);
 | |
| 	Format(sBuffer, sizeof(sBuffer), "{showactivity}%s", sBuffer);
 | |
| 	CProcessVariables(sBuffer, sizeof(sBuffer));
 | |
| 	CAddWhiteSpace(sBuffer, sizeof(sBuffer));
 | |
| 
 | |
| 	ShowActivity(iClient, "%s", sBuffer);
 | |
| }
 | |
| 
 | |
| stock CShowActivityEx(iClient, const String:sTag[], const String:sMessage[], any:...)
 | |
| {
 | |
| 	if (iClient < 0 || iClient > MaxClients) {
 | |
| 		ThrowError("Invalid client index %d", iClient);
 | |
| 	}
 | |
| 
 | |
| 	if (iClient != 0 && !IsClientInGame(iClient)) {
 | |
| 		ThrowError("Client %d is not in game", iClient);
 | |
| 	}
 | |
| 
 | |
| 	decl String:sBuffer[_CV_MAX_MESSAGE_LENGTH], String:sBufferTag[_CV_MAX_MESSAGE_LENGTH];
 | |
| 	SetGlobalTransTarget(iClient);
 | |
| 	VFormat(sBuffer, sizeof(sBuffer), sMessage, 4);
 | |
| 	Format(sBuffer, sizeof(sBuffer), "{showactivity}%s", sBuffer);
 | |
| 	CProcessVariables(sBuffer, sizeof(sBuffer));
 | |
| 	Format(sBufferTag, sizeof(sBufferTag), "{prefix}%s", sTag);
 | |
| 	CProcessVariables(sBufferTag, sizeof(sBufferTag));
 | |
| 	CAddWhiteSpace(sBuffer, sizeof(sBuffer));
 | |
| 	CAddWhiteSpace(sBufferTag, sizeof(sBufferTag));
 | |
| 
 | |
| 	ShowActivityEx(iClient, sBufferTag, " %s", sBuffer);
 | |
| }
 | |
| 
 | |
| stock CShowActivity2(iClient, const String:sTag[], const String:sMessage[], any:...)
 | |
| {
 | |
| 	if (iClient < 0 || iClient > MaxClients) {
 | |
| 		ThrowError("Invalid client index %d", iClient);
 | |
| 	}
 | |
| 
 | |
| 	if (iClient != 0 && !IsClientInGame(iClient)) {
 | |
| 		ThrowError("Client %d is not in game", iClient);
 | |
| 	}
 | |
| 
 | |
| 	decl String:sBuffer[_CV_MAX_MESSAGE_LENGTH], String:sBufferTag[_CV_MAX_MESSAGE_LENGTH];
 | |
| 	SetGlobalTransTarget(iClient);
 | |
| 	VFormat(sBuffer, sizeof(sBuffer), sMessage, 4);
 | |
| 	Format(sBuffer, sizeof(sBuffer), "{showactivity}%s", sBuffer);
 | |
| 	CProcessVariables(sBuffer, sizeof(sBuffer));
 | |
| 	Format(sBufferTag, sizeof(sBufferTag), "{prefix}%s", sTag);
 | |
| 	CProcessVariables(sBufferTag, sizeof(sBufferTag));
 | |
| 	CAddWhiteSpace(sBuffer, sizeof(sBuffer));
 | |
| 	CAddWhiteSpace(sBufferTag, sizeof(sBufferTag));
 | |
| 
 | |
| 	ShowActivityEx(iClient, sBufferTag, " %s", sBuffer);
 | |
| }
 | |
| 
 | |
| stock CAddVariable(String:sName[], String:sValue[], bool:bOnlySaveToConfig = false)
 | |
| {
 | |
| 	if (Init()) {
 | |
| 		if (!FileExists(g_sConfig)) {
 | |
| 			LogError("Cannot add color variable to '%s' - file doesn't exist!", g_sConfig);
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		new Handle:hKV = CreateKeyValues("colorvariables");
 | |
| 
 | |
| 		if (!FileToKeyValues(hKV, g_sConfig)) {
 | |
| 			delete hKV;
 | |
| 			LogError("Cannot open file (for adding color variable) '%s' !", g_sConfig);
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		if (!KvJumpToKey(hKV, sName)) {
 | |
| 			StringToLower(sName);
 | |
| 			KvSetString(hKV, sName, sValue);
 | |
| 
 | |
| 			if (!bOnlySaveToConfig) {
 | |
| 				new Handle:hRedirect = CreateArray(64);
 | |
| 				PushArrayString(hRedirect, sName);
 | |
| 				SetTrieString(g_hColors, sName, sValue);
 | |
| 				SolveRedirects(g_hColors, hRedirect);
 | |
| 				delete hRedirect;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		KvRewind(hKV);
 | |
| 		KeyValuesToFile(hKV, g_sConfig);
 | |
| 		delete hKV;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| stock CLoadPluginConfig(const String:sPluginName[], bool:bAllowPrefix = true)
 | |
| {
 | |
| 	if (Init()) {
 | |
| 		new String:sConfig[PLATFORM_MAX_PATH];
 | |
| 		strcopy(sConfig, sizeof(sConfig), sPluginName);
 | |
| 		ReplaceStringEx(sConfig, sizeof(sConfig), ".smx", "");
 | |
| 		BuildPath(Path_SM, sConfig, sizeof(sConfig), "%s/plugin.%s.cfg", _CV_CONFIG_DIRECTORY, sConfig);
 | |
| 
 | |
| 		if (!FileExists(sConfig)) {
 | |
| 			LogError("Cannot load color variables from file '%s' - file doesn't exist!", sConfig);
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		new Handle:hRedirect = CreateArray(64);
 | |
| 		LoadConfigFile(g_hColors, sConfig, hRedirect, bAllowPrefix);
 | |
| 		SolveRedirects(g_hColors, hRedirect);
 | |
| 		delete hRedirect;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| stock CLoadPluginVariables(const String:sPluginName[], const String:sVariables[][], iVariablesCount, bool:bAllowPrefix = true)
 | |
| {
 | |
| 	if (Init() && iVariablesCount > 0) {
 | |
| 		new String:sConfig[PLATFORM_MAX_PATH];
 | |
| 		strcopy(sConfig, sizeof(sConfig), sPluginName);
 | |
| 		ReplaceStringEx(sConfig, sizeof(sConfig), ".smx", "");
 | |
| 		BuildPath(Path_SM, sConfig, sizeof(sConfig), "%s/plugin.%s.cfg", _CV_CONFIG_DIRECTORY, sConfig);
 | |
| 
 | |
| 		if (!FileExists(sConfig)) {
 | |
| 			LogError("Cannot load color variables from file '%s' - file doesn't exist!", sConfig);
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		new Handle:hVariables = CreateTrie();
 | |
| 		new Handle:hRedirect = CreateArray(64);
 | |
| 		LoadConfigFile(hVariables, sConfig, hRedirect, bAllowPrefix);
 | |
| 		SolveRedirects(hVariables, hRedirect);
 | |
| 		ClearArray(hRedirect);
 | |
| 
 | |
| 		new String:sCode[64], String:sColor[64];
 | |
| 
 | |
| 		for (new i = 0; i < iVariablesCount; i++) {
 | |
| 			strcopy(sCode, sizeof(sCode), sVariables[i]);
 | |
| 			StringToLower(sCode);
 | |
| 
 | |
| 			if (GetTrieString(hVariables, sCode, sColor, sizeof(sColor))) {
 | |
| 				SetTrieString(g_hColors, sCode, sColor);
 | |
| 				PushArrayString(hRedirect, sCode);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		SolveRedirects(g_hColors, hRedirect);
 | |
| 		delete hRedirect;
 | |
| 		delete hVariables;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| stock CRemoveColors(String:sMsg[], iSize)
 | |
| {
 | |
| 	CProcessVariables(sMsg, iSize, true);
 | |
| }
 | |
| 
 | |
| stock CProcessVariables(String:sMsg[], iSize, bool:bRemoveColors = false)
 | |
| {
 | |
| 	if (!Init()) {
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	new String:sOut[iSize], String:sCode[iSize], String:sColor[iSize];
 | |
| 	new iOutPos = 0, iCodePos = -1;
 | |
| 	new iMsgLen = strlen(sMsg);
 | |
| 
 | |
| 	for (new i = 0; i < iMsgLen; i++) {
 | |
| 		if (sMsg[i] == '{') {
 | |
| 			iCodePos = 0;
 | |
| 		}
 | |
| 
 | |
| 		if (iCodePos > -1) {
 | |
| 			sCode[iCodePos] = sMsg[i];
 | |
| 			sCode[iCodePos + 1] = '\0';
 | |
| 
 | |
| 			if (sMsg[i] == '}' || i == iMsgLen - 1) {
 | |
| 				strcopy(sCode, strlen(sCode) - 1, sCode[1]);
 | |
| 				StringToLower(sCode);
 | |
| 
 | |
| 				if (CGetColor(sCode, sColor, iSize)) {
 | |
| 					if (!bRemoveColors) {
 | |
| 						StrCat(sOut, iSize, sColor);
 | |
| 						iOutPos += strlen(sColor);
 | |
| 					}
 | |
| 				} else {
 | |
| 					Format(sOut, iSize, "%s{%s}", sOut, sCode);
 | |
| 					iOutPos += strlen(sCode) + 2;
 | |
| 				}
 | |
| 
 | |
| 				iCodePos = -1;
 | |
| 				strcopy(sCode, iSize, "");
 | |
| 				strcopy(sColor, iSize, "");
 | |
| 			} else {
 | |
| 				iCodePos++;
 | |
| 			}
 | |
| 
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		sOut[iOutPos] = sMsg[i];
 | |
| 		iOutPos++;
 | |
| 		sOut[iOutPos] = '\0';
 | |
| 	}
 | |
| 
 | |
| 	strcopy(sMsg, iSize, sOut);
 | |
| }
 | |
| 
 | |
| stock bool:CGetColor(const String:sName[], String:sColor[], iColorSize)
 | |
| {
 | |
| 	if (sName[0] == '\0')
 | |
| 		return false;
 | |
| 
 | |
| 	if (sName[0] == '@') {
 | |
| 		new iSpace;
 | |
| 		new String:sData[64], String:m_sName[64];
 | |
| 		strcopy(m_sName, sizeof(m_sName), sName[1]);
 | |
| 
 | |
| 		if ((iSpace = FindCharInString(m_sName, ' ')) != -1 && (iSpace + 1 < strlen(m_sName))) {
 | |
| 			strcopy(m_sName, iSpace + 1, m_sName);
 | |
| 			strcopy(sData, sizeof(sData), m_sName[iSpace + 1]);
 | |
| 		}
 | |
| 
 | |
| 		Call_StartForward(g_hForwardedVariable);
 | |
| 		Call_PushString(m_sName);
 | |
| 		Call_PushStringEx(sData, sizeof(sData), SM_PARAM_STRING_UTF8|SM_PARAM_STRING_COPY, 0);
 | |
| 		Call_PushCell(sizeof(sData));
 | |
| 		Call_PushStringEx(sColor, iColorSize, SM_PARAM_STRING_UTF8|SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);
 | |
| 		Call_PushCell(iColorSize);
 | |
| 		Call_Finish();
 | |
| 
 | |
| 		if (sColor[0] != '\0') {
 | |
| 			return true;
 | |
| 		}
 | |
| 
 | |
| 	} else if (sName[0] == '#') {
 | |
| 		if (strlen(sName) == 7) {
 | |
| 			Format(sColor, iColorSize, "\x07%s", sName[1]);
 | |
| 			return true;
 | |
| 		}
 | |
| 		if (strlen(sName) == 9) {
 | |
| 			Format(sColor, iColorSize, "\x08%s", sName[1]);
 | |
| 			return true;
 | |
| 		}
 | |
| 	} else if (StrContains(sName, "player ", false) == 0 && strlen(sName) > 7) {
 | |
| 		new iClient = StringToInt(sName[7]);
 | |
| 
 | |
| 		if (iClient < 1 || iClient > MaxClients || !IsClientInGame(iClient)) {
 | |
| 			strcopy(sColor, iColorSize, "\x01");
 | |
| 			LogError("Invalid client index %d", iClient);
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		strcopy(sColor, iColorSize, "\x01");
 | |
| 		switch (GetClientTeam(iClient)) {
 | |
| 			case 1: {GetTrieString(g_hColors, "team0", sColor, iColorSize);}
 | |
| 			case 2: {GetTrieString(g_hColors, "team1", sColor, iColorSize);}
 | |
| 			case 3: {GetTrieString(g_hColors, "team2", sColor, iColorSize);}
 | |
| 		}
 | |
| 		return true;
 | |
| 	} else {
 | |
| 		return GetTrieString(g_hColors, sName, sColor, iColorSize);
 | |
| 	}
 | |
| 
 | |
| 	return false;
 | |
| }
 | |
| 
 | |
| stock bool:CExistColor(const String:sName[])
 | |
| {
 | |
| 	if (sName[0] == '\0' || sName[0] == '@' || sName[0] == '#')
 | |
| 		return false;
 | |
| 
 | |
| 	new String:sColor[64];
 | |
| 	return GetTrieString(g_hColors, sName, sColor, sizeof(sColor));
 | |
| }
 | |
| 
 | |
| stock CSayText2(iClient, String:sMessage[], iAuthor)
 | |
| {
 | |
| 	new Handle:hMsg = StartMessageOne("SayText2", iClient, USERMSG_RELIABLE|USERMSG_BLOCKHOOKS);
 | |
| 	if(GetFeatureStatus(FeatureType_Native, "GetUserMessageType") == FeatureStatus_Available && GetUserMessageType() == UM_Protobuf) {
 | |
| 		PbSetInt(hMsg, "ent_idx", iAuthor);
 | |
| 		PbSetBool(hMsg, "chat", true);
 | |
| 		PbSetString(hMsg, "msg_name", sMessage);
 | |
| 		PbAddString(hMsg, "params", "");
 | |
| 		PbAddString(hMsg, "params", "");
 | |
| 		PbAddString(hMsg, "params", "");
 | |
| 		PbAddString(hMsg, "params", "");
 | |
| 	} else {
 | |
| 		BfWriteByte(hMsg, iAuthor);
 | |
| 		BfWriteByte(hMsg, true);
 | |
| 		BfWriteString(hMsg, sMessage);
 | |
| 	}
 | |
| 	EndMessage();
 | |
| }
 | |
| 
 | |
| stock CAddWhiteSpace(String:sBuffer[], iSize)
 | |
| {
 | |
| 	if (!IsSource2009()) {
 | |
| 		Format(sBuffer, iSize, " %s", sBuffer);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // ----------------------------------------------------------------------------------------
 | |
| // Private stuff
 | |
| // ----------------------------------------------------------------------------------------
 | |
| 
 | |
| stock bool:Init()
 | |
| {
 | |
| 	if (g_bInit) {
 | |
| 		LoadColors();
 | |
| 		return true;
 | |
| 	}
 | |
| 
 | |
| 	new String:sPluginName[PLATFORM_MAX_PATH];
 | |
| 	new String:sDirectoryPath[PLATFORM_MAX_PATH];
 | |
| 	new Handle:hConfig = INVALID_HANDLE;
 | |
| 	GetPluginFilename(INVALID_HANDLE, sPluginName, sizeof(sPluginName));
 | |
| 	ReplaceStringEx(sPluginName, sizeof(sPluginName), "\\", "/");
 | |
| 	new iSlash = FindCharInString(sPluginName, '/', true);
 | |
| 	if (iSlash > -1) {
 | |
| 		strcopy(sPluginName, sizeof(sPluginName), sPluginName[iSlash + 1]);
 | |
| 	}
 | |
| 	ReplaceStringEx(sPluginName, sizeof(sPluginName), ".smx", "");
 | |
| 
 | |
| 	BuildPath(Path_SM, sDirectoryPath, sizeof(sDirectoryPath), "%s/", _CV_CONFIG_DIRECTORY);
 | |
| 	if (!DirExists(sDirectoryPath))
 | |
| 		CreateDirectory(sDirectoryPath, 511);
 | |
| 
 | |
| 	new String:sGlobalVariableList[15][2][64] = {
 | |
| 		{"prefix", 		 "{engine 2}"},
 | |
| 		{"default",		 "{engine 1}"},
 | |
| 		{"reply2cmd",  	 "{engine 1}"},
 | |
| 		{"showactivity", "{engine 1}"},
 | |
| 		{"", ""},
 | |
| 		{"error",		 "{engine 3}"},
 | |
| 		{"", ""},
 | |
| 		{"highlight",	 "{engine 2}"},
 | |
| 		{"player",		 "{engine 2}"},
 | |
| 		{"settings",	 "{engine 2}"},
 | |
| 		{"command",		 "{engine 2}"},
 | |
| 		{"", ""},
 | |
| 		{"team0",		 "{engine 8}"},
 | |
| 		{"team1",		 "{engine 9}"},
 | |
| 		{"team2",		 "{engine 11}"}
 | |
| 	};
 | |
| 
 | |
| 	if (IsSource2009()) {
 | |
| 		strcopy(sGlobalVariableList[12][1], 64, "{#cccccc}");
 | |
| 		strcopy(sGlobalVariableList[13][1], 64, "{#ff4040}");
 | |
| 		strcopy(sGlobalVariableList[14][1], 64, "{#4d7942}");
 | |
| 	}
 | |
| 
 | |
| 	BuildPath(Path_SM, g_sConfigGlobal, sizeof(g_sConfigGlobal), "%s/global.cfg", _CV_CONFIG_DIRECTORY);
 | |
| 	if (!FileExists(g_sConfigGlobal)) {
 | |
| 		hConfig = OpenFile(g_sConfigGlobal, "w");
 | |
| 		if (hConfig == INVALID_HANDLE) {
 | |
| 			LogError("Cannot create file '%s' !", g_sConfigGlobal);
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		WriteFileLine(hConfig, "// Version: %s", _colorvariables_included);
 | |
| 		WriteFileLine(hConfig, "\"colorvariables\"");
 | |
| 		WriteFileLine(hConfig, "{");
 | |
| 		for (new i = 0; i < 15; i++) {
 | |
| 			if (sGlobalVariableList[i][0][0] == '\0') {
 | |
| 				WriteFileLine(hConfig, "");
 | |
| 			} else {
 | |
| 				WriteFileLine(hConfig, "\t\"%s\" \"%s\"", sGlobalVariableList[i][0], sGlobalVariableList[i][1]);
 | |
| 			}
 | |
| 		}
 | |
| 		WriteFileLine(hConfig, "}");
 | |
| 
 | |
| 		delete hConfig;
 | |
| 	} else {
 | |
| 		hConfig = OpenFile(g_sConfigGlobal, "r");
 | |
| 		if (hConfig == INVALID_HANDLE) {
 | |
| 			LogError("Cannot read from file '%s' !", g_sConfigGlobal);
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		new String:sVersionLine[64];
 | |
| 		ReadFileLine(hConfig, sVersionLine, sizeof(sVersionLine));
 | |
| 		delete hConfig;
 | |
| 
 | |
| 		TrimString(sVersionLine);
 | |
| 		strcopy(sVersionLine, sizeof(sVersionLine), sVersionLine[FindCharInString(sVersionLine, ':') + 2]);
 | |
| 
 | |
| 		if (StringToFloat(sVersionLine) < StringToFloat(_colorvariables_included)) {
 | |
| 			new Handle:hKV = CreateKeyValues("colorvariables");
 | |
| 
 | |
| 			if (!FileToKeyValues(hKV, g_sConfigGlobal) || !KvGotoFirstSubKey(hKV, false)) {
 | |
| 				delete hKV;
 | |
| 				LogError("Cannot read variables from file '%s' !", g_sConfigGlobal);
 | |
| 				return false;
 | |
| 			}
 | |
| 
 | |
| 			for (new i = 0; i < 15; i++) {
 | |
| 				if (sGlobalVariableList[i][0][0] == '\0')
 | |
| 					continue;
 | |
| 
 | |
| 				if (!KvJumpToKey(hKV, sGlobalVariableList[i][0]))
 | |
| 					KvSetString(hKV, sGlobalVariableList[i][0], sGlobalVariableList[i][1]);
 | |
| 			}
 | |
| 
 | |
| 			hConfig = OpenFile(g_sConfigGlobal, "w");
 | |
| 			if (hConfig == INVALID_HANDLE) {
 | |
| 				LogError("Cannot write to file '%s' !", g_sConfigGlobal);
 | |
| 				return false;
 | |
| 			}
 | |
| 
 | |
| 			WriteFileLine(hConfig, "// Version: %s", _colorvariables_included);
 | |
| 			WriteFileLine(hConfig, "\"colorvariables\"");
 | |
| 			WriteFileLine(hConfig, "{");
 | |
| 
 | |
| 			new String:sCode[64], String:sColor[64];
 | |
| 
 | |
| 			KvGotoFirstSubKey(hKV, false);
 | |
| 			do
 | |
| 			{
 | |
| 				KvGetSectionName(hKV, sCode, sizeof(sCode));
 | |
| 				KvGetString(hKV, NULL_STRING, sColor, sizeof(sColor));
 | |
| 				StringToLower(sCode);
 | |
| 				StringToLower(sColor);
 | |
| 
 | |
| 				WriteFileLine(hConfig, "\t\"%s\" \"%s\"", sCode, sColor);
 | |
| 			} while (KvGotoNextKey(hKV, false));
 | |
| 
 | |
| 			WriteFileLine(hConfig, "}");
 | |
| 
 | |
| 			delete hConfig;
 | |
| 			delete hKV;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	BuildPath(Path_SM, g_sConfig, sizeof(g_sConfig), "%s/plugin.%s.cfg", _CV_CONFIG_DIRECTORY, sPluginName);
 | |
| 	if (!FileExists(g_sConfig)) {
 | |
| 		hConfig = OpenFile(g_sConfig, "w");
 | |
| 		if (hConfig == INVALID_HANDLE) {
 | |
| 			LogError("Cannot create file '%s' !", g_sConfig);
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		WriteFileLine(hConfig, "\"colorvariables\"\n{\n}");
 | |
| 		delete hConfig;
 | |
| 	}
 | |
| 
 | |
| 	for (new iClient = 1; iClient <= MaxClients; iClient++) {
 | |
| 		g_bSkipPlayers[iClient] = false;
 | |
| 	}
 | |
| 
 | |
| 	g_hForwardedVariable = CreateGlobalForward("COnForwardedVariable", ET_Ignore, Param_String, Param_String, Param_Cell, Param_String, Param_Cell);
 | |
| 
 | |
| 	LoadColors();
 | |
| 	g_bInit = true;
 | |
| 	return true;
 | |
| }
 | |
| 
 | |
| stock static LoadColors()
 | |
| {
 | |
| 	if (g_hColors == INVALID_HANDLE) {
 | |
| 		g_hColors = CreateTrie();
 | |
| 		new Handle:hRedirect = CreateArray(64);
 | |
| 
 | |
| 		AddColors(g_hColors);
 | |
| 		LoadConfigFile(g_hColors, g_sConfigGlobal, hRedirect);
 | |
| 		LoadConfigFile(g_hColors, g_sConfig, hRedirect);
 | |
| 
 | |
| 		SolveRedirects(g_hColors, hRedirect);
 | |
| 		CloseHandle(hRedirect);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| stock static LoadConfigFile(Handle:hTrie, String:sPath[], Handle:hRedirect, bool:bAllowPrefix = true)
 | |
| {
 | |
| 	if (!FileExists(sPath)) {
 | |
| 		LogError("Cannot load color variables from file '%s' - file doesn't exist!", sPath);
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	new Handle:hKV = CreateKeyValues("colorvariables");
 | |
| 
 | |
| 	if (!FileToKeyValues(hKV, sPath)) {
 | |
| 		delete hKV;
 | |
| 		LogError("Cannot load color variables from file '%s' !", sPath);
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	if (!KvGotoFirstSubKey(hKV, false)) {
 | |
| 		delete hKV;
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	new String:sCode[64], String:sColor[64];
 | |
| 
 | |
| 	do
 | |
| 	{
 | |
| 		KvGetSectionName(hKV, sCode, sizeof(sCode));
 | |
| 		KvGetString(hKV, NULL_STRING, sColor, sizeof(sColor));
 | |
| 
 | |
| 		if (bAllowPrefix && StrEqual(sCode, "&prefix", false)) {
 | |
| 			CSetPrefix(sColor);
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		StringToLower(sCode);
 | |
| 
 | |
| 		if (HasBrackets(sColor) && sColor[1] == '@') {
 | |
| 			LogError("Variables cannot be redirected to forwarded variables! (variable '%s')", sCode);
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		if (HasBrackets(sColor)) {
 | |
| 			if (sColor[1] == '#') {
 | |
| 				Format(sColor, sizeof(sColor), "\x07%s", sColor[1]);
 | |
| 			} else {
 | |
| 				PushArrayString(hRedirect, sCode);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		SetTrieString(hTrie, sCode, sColor);
 | |
| 	} while (KvGotoNextKey(hKV, false));
 | |
| 
 | |
| 	delete hKV;
 | |
| }
 | |
| 
 | |
| stock static SolveRedirects(Handle:hTrie, Handle:hRedirect)
 | |
| {
 | |
| 	new String:sCode[64], String:sRedirect[64], String:sColor[64], String:sFirstColor[64];
 | |
| 	new iRedirectLife, bool:bHasBrackets;
 | |
| 
 | |
| 	for (new i = 0; i < GetArraySize(hRedirect); i++) {
 | |
| 		GetArrayString(hRedirect, i, sRedirect, sizeof(sRedirect));
 | |
| 		strcopy(sCode, sizeof(sCode), sRedirect);
 | |
| 		bHasBrackets = true;
 | |
| 
 | |
| 		GetTrieString(hTrie, sRedirect, sColor, sizeof(sColor));
 | |
| 		strcopy(sFirstColor, sizeof(sFirstColor), sRedirect);
 | |
| 		iRedirectLife = _CV_MAX_VARIABLE_REDIRECTS;
 | |
| 
 | |
| 		do {
 | |
| 			if (!HasBrackets(sColor)) {
 | |
| 				strcopy(sRedirect, sizeof(sRedirect), sColor);
 | |
| 				bHasBrackets = false;
 | |
| 				break;
 | |
| 			}
 | |
| 
 | |
| 			strcopy(sColor, strlen(sColor) - 1, sColor[1]);
 | |
| 			if (iRedirectLife > 0) {
 | |
| 				strcopy(sRedirect, sizeof(sRedirect), sColor);
 | |
| 				iRedirectLife--;
 | |
| 			} else {
 | |
| 				strcopy(sRedirect, sizeof(sRedirect), sFirstColor);
 | |
| 				LogError("Too many redirects for variable '%s' !", sCode);
 | |
| 				break;
 | |
| 			}
 | |
| 		} while (GetTrieString(hTrie, sRedirect, sColor, sizeof(sColor)));
 | |
| 
 | |
| 		if (bHasBrackets) {
 | |
| 			Format(sRedirect, sizeof(sRedirect), "{%s}", sRedirect);
 | |
| 		}
 | |
| 
 | |
| 		StringToLower(sCode);
 | |
| 		StringToLower(sRedirect);
 | |
| 		SetTrieString(hTrie, sCode, sRedirect);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| stock static HasBrackets(const String:sSource[])
 | |
| {
 | |
| 	return (sSource[0] == '{' && sSource[strlen(sSource) - 1] == '}');
 | |
| }
 | |
| 
 | |
| stock static StringToLower(String:sSource[])
 | |
| {
 | |
| 	for (new i = 0; i < strlen(sSource); i++) {
 | |
| 		if (sSource[i] == '\0')
 | |
| 			break;
 | |
| 
 | |
| 		sSource[i] = CharToLower(sSource[i]);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| stock static AddColors(Handle:hTrie)
 | |
| {
 | |
| 	if (IsSource2009()) {
 | |
| 		SetTrieString(hTrie, "default", "\x01");
 | |
| 		SetTrieString(hTrie, "teamcolor", "\x03");
 | |
| 
 | |
| 		SetTrieString(hTrie, "aliceblue", "\x07F0F8FF");
 | |
| 		SetTrieString(hTrie, "allies", "\x074D7942");
 | |
| 		SetTrieString(hTrie, "ancient", "\x07EB4B4B");
 | |
| 		SetTrieString(hTrie, "antiquewhite", "\x07FAEBD7");
 | |
| 		SetTrieString(hTrie, "aqua", "\x0700FFFF");
 | |
| 		SetTrieString(hTrie, "aquamarine", "\x077FFFD4");
 | |
| 		SetTrieString(hTrie, "arcana", "\x07ADE55C");
 | |
| 		SetTrieString(hTrie, "axis", "\x07FF4040");
 | |
| 		SetTrieString(hTrie, "azure", "\x07007FFF");
 | |
| 		SetTrieString(hTrie, "beige", "\x07F5F5DC");
 | |
| 		SetTrieString(hTrie, "bisque", "\x07FFE4C4");
 | |
| 		SetTrieString(hTrie, "black", "\x07000000");
 | |
| 		SetTrieString(hTrie, "blanchedalmond", "\x07FFEBCD");
 | |
| 		SetTrieString(hTrie, "blue", "\x0799CCFF");
 | |
| 		SetTrieString(hTrie, "blueviolet", "\x078A2BE2");
 | |
| 		SetTrieString(hTrie, "brown", "\x07A52A2A");
 | |
| 		SetTrieString(hTrie, "burlywood", "\x07DEB887");
 | |
| 		SetTrieString(hTrie, "cadetblue", "\x075F9EA0");
 | |
| 		SetTrieString(hTrie, "chartreuse", "\x077FFF00");
 | |
| 		SetTrieString(hTrie, "chocolate", "\x07D2691E");
 | |
| 		SetTrieString(hTrie, "collectors", "\x07AA0000");
 | |
| 		SetTrieString(hTrie, "common", "\x07B0C3D9");
 | |
| 		SetTrieString(hTrie, "community", "\x0770B04A");
 | |
| 		SetTrieString(hTrie, "coral", "\x07FF7F50");
 | |
| 		SetTrieString(hTrie, "cornflowerblue", "\x076495ED");
 | |
| 		SetTrieString(hTrie, "cornsilk", "\x07FFF8DC");
 | |
| 		SetTrieString(hTrie, "corrupted", "\x07A32C2E");
 | |
| 		SetTrieString(hTrie, "crimson", "\x07DC143C");
 | |
| 		SetTrieString(hTrie, "cyan", "\x0700FFFF");
 | |
| 		SetTrieString(hTrie, "darkblue", "\x0700008B");
 | |
| 		SetTrieString(hTrie, "darkcyan", "\x07008B8B");
 | |
| 		SetTrieString(hTrie, "darkgoldenrod", "\x07B8860B");
 | |
| 		SetTrieString(hTrie, "darkgray", "\x07A9A9A9");
 | |
| 		SetTrieString(hTrie, "darkgrey", "\x07A9A9A9");
 | |
| 		SetTrieString(hTrie, "darkgreen", "\x07006400");
 | |
| 		SetTrieString(hTrie, "darkkhaki", "\x07BDB76B");
 | |
| 		SetTrieString(hTrie, "darkmagenta", "\x078B008B");
 | |
| 		SetTrieString(hTrie, "darkolivegreen", "\x07556B2F");
 | |
| 		SetTrieString(hTrie, "darkorange", "\x07FF8C00");
 | |
| 		SetTrieString(hTrie, "darkorchid", "\x079932CC");
 | |
| 		SetTrieString(hTrie, "darkred", "\x078B0000");
 | |
| 		SetTrieString(hTrie, "darksalmon", "\x07E9967A");
 | |
| 		SetTrieString(hTrie, "darkseagreen", "\x078FBC8F");
 | |
| 		SetTrieString(hTrie, "darkslateblue", "\x07483D8B");
 | |
| 		SetTrieString(hTrie, "darkslategray", "\x072F4F4F");
 | |
| 		SetTrieString(hTrie, "darkslategrey", "\x072F4F4F");
 | |
| 		SetTrieString(hTrie, "darkturquoise", "\x0700CED1");
 | |
| 		SetTrieString(hTrie, "darkviolet", "\x079400D3");
 | |
| 		SetTrieString(hTrie, "deeppink", "\x07FF1493");
 | |
| 		SetTrieString(hTrie, "deepskyblue", "\x0700BFFF");
 | |
| 		SetTrieString(hTrie, "dimgray", "\x07696969");
 | |
| 		SetTrieString(hTrie, "dimgrey", "\x07696969");
 | |
| 		SetTrieString(hTrie, "dodgerblue", "\x071E90FF");
 | |
| 		SetTrieString(hTrie, "exalted", "\x07CCCCCD");
 | |
| 		SetTrieString(hTrie, "firebrick", "\x07B22222");
 | |
| 		SetTrieString(hTrie, "floralwhite", "\x07FFFAF0");
 | |
| 		SetTrieString(hTrie, "forestgreen", "\x07228B22");
 | |
| 		SetTrieString(hTrie, "frozen", "\x074983B3");
 | |
| 		SetTrieString(hTrie, "fuchsia", "\x07FF00FF");
 | |
| 		SetTrieString(hTrie, "fullblue", "\x070000FF");
 | |
| 		SetTrieString(hTrie, "fullred", "\x07FF0000");
 | |
| 		SetTrieString(hTrie, "gainsboro", "\x07DCDCDC");
 | |
| 		SetTrieString(hTrie, "genuine", "\x074D7455");
 | |
| 		SetTrieString(hTrie, "ghostwhite", "\x07F8F8FF");
 | |
| 		SetTrieString(hTrie, "gold", "\x07FFD700");
 | |
| 		SetTrieString(hTrie, "goldenrod", "\x07DAA520");
 | |
| 		SetTrieString(hTrie, "gray", "\x07CCCCCC");
 | |
| 		SetTrieString(hTrie, "grey", "\x07CCCCCC");
 | |
| 		SetTrieString(hTrie, "green", "\x073EFF3E");
 | |
| 		SetTrieString(hTrie, "greenyellow", "\x07ADFF2F");
 | |
| 		SetTrieString(hTrie, "haunted", "\x0738F3AB");
 | |
| 		SetTrieString(hTrie, "honeydew", "\x07F0FFF0");
 | |
| 		SetTrieString(hTrie, "hotpink", "\x07FF69B4");
 | |
| 		SetTrieString(hTrie, "immortal", "\x07E4AE33");
 | |
| 		SetTrieString(hTrie, "indianred", "\x07CD5C5C");
 | |
| 		SetTrieString(hTrie, "indigo", "\x074B0082");
 | |
| 		SetTrieString(hTrie, "ivory", "\x07FFFFF0");
 | |
| 		SetTrieString(hTrie, "khaki", "\x07F0E68C");
 | |
| 		SetTrieString(hTrie, "lavender", "\x07E6E6FA");
 | |
| 		SetTrieString(hTrie, "lavenderblush", "\x07FFF0F5");
 | |
| 		SetTrieString(hTrie, "lawngreen", "\x077CFC00");
 | |
| 		SetTrieString(hTrie, "legendary", "\x07D32CE6");
 | |
| 		SetTrieString(hTrie, "lemonchiffon", "\x07FFFACD");
 | |
| 		SetTrieString(hTrie, "lightblue", "\x07ADD8E6");
 | |
| 		SetTrieString(hTrie, "lightcoral", "\x07F08080");
 | |
| 		SetTrieString(hTrie, "lightcyan", "\x07E0FFFF");
 | |
| 		SetTrieString(hTrie, "lightgoldenrodyellow", "\x07FAFAD2");
 | |
| 		SetTrieString(hTrie, "lightgray", "\x07D3D3D3");
 | |
| 		SetTrieString(hTrie, "lightgrey", "\x07D3D3D3");
 | |
| 		SetTrieString(hTrie, "lightgreen", "\x0799FF99");
 | |
| 		SetTrieString(hTrie, "lightpink", "\x07FFB6C1");
 | |
| 		SetTrieString(hTrie, "lightsalmon", "\x07FFA07A");
 | |
| 		SetTrieString(hTrie, "lightseagreen", "\x0720B2AA");
 | |
| 		SetTrieString(hTrie, "lightskyblue", "\x0787CEFA");
 | |
| 		SetTrieString(hTrie, "lightslategray", "\x07778899");
 | |
| 		SetTrieString(hTrie, "lightslategrey", "\x07778899");
 | |
| 		SetTrieString(hTrie, "lightsteelblue", "\x07B0C4DE");
 | |
| 		SetTrieString(hTrie, "lightyellow", "\x07FFFFE0");
 | |
| 		SetTrieString(hTrie, "lime", "\x0700FF00");
 | |
| 		SetTrieString(hTrie, "limegreen", "\x0732CD32");
 | |
| 		SetTrieString(hTrie, "linen", "\x07FAF0E6");
 | |
| 		SetTrieString(hTrie, "magenta", "\x07FF00FF");
 | |
| 		SetTrieString(hTrie, "maroon", "\x07800000");
 | |
| 		SetTrieString(hTrie, "mediumaquamarine", "\x0766CDAA");
 | |
| 		SetTrieString(hTrie, "mediumblue", "\x070000CD");
 | |
| 		SetTrieString(hTrie, "mediumorchid", "\x07BA55D3");
 | |
| 		SetTrieString(hTrie, "mediumpurple", "\x079370D8");
 | |
| 		SetTrieString(hTrie, "mediumseagreen", "\x073CB371");
 | |
| 		SetTrieString(hTrie, "mediumslateblue", "\x077B68EE");
 | |
| 		SetTrieString(hTrie, "mediumspringgreen", "\x0700FA9A");
 | |
| 		SetTrieString(hTrie, "mediumturquoise", "\x0748D1CC");
 | |
| 		SetTrieString(hTrie, "mediumvioletred", "\x07C71585");
 | |
| 		SetTrieString(hTrie, "midnightblue", "\x07191970");
 | |
| 		SetTrieString(hTrie, "mintcream", "\x07F5FFFA");
 | |
| 		SetTrieString(hTrie, "mistyrose", "\x07FFE4E1");
 | |
| 		SetTrieString(hTrie, "moccasin", "\x07FFE4B5");
 | |
| 		SetTrieString(hTrie, "mythical", "\x078847FF");
 | |
| 		SetTrieString(hTrie, "navajowhite", "\x07FFDEAD");
 | |
| 		SetTrieString(hTrie, "navy", "\x07000080");
 | |
| 		SetTrieString(hTrie, "normal", "\x07B2B2B2");
 | |
| 		SetTrieString(hTrie, "oldlace", "\x07FDF5E6");
 | |
| 		SetTrieString(hTrie, "olive", "\x079EC34F");
 | |
| 		SetTrieString(hTrie, "olivedrab", "\x076B8E23");
 | |
| 		SetTrieString(hTrie, "orange", "\x07FFA500");
 | |
| 		SetTrieString(hTrie, "orangered", "\x07FF4500");
 | |
| 		SetTrieString(hTrie, "orchid", "\x07DA70D6");
 | |
| 		SetTrieString(hTrie, "palegoldenrod", "\x07EEE8AA");
 | |
| 		SetTrieString(hTrie, "palegreen", "\x0798FB98");
 | |
| 		SetTrieString(hTrie, "paleturquoise", "\x07AFEEEE");
 | |
| 		SetTrieString(hTrie, "palevioletred", "\x07D87093");
 | |
| 		SetTrieString(hTrie, "papayawhip", "\x07FFEFD5");
 | |
| 		SetTrieString(hTrie, "peachpuff", "\x07FFDAB9");
 | |
| 		SetTrieString(hTrie, "peru", "\x07CD853F");
 | |
| 		SetTrieString(hTrie, "pink", "\x07FFC0CB");
 | |
| 		SetTrieString(hTrie, "plum", "\x07DDA0DD");
 | |
| 		SetTrieString(hTrie, "powderblue", "\x07B0E0E6");
 | |
| 		SetTrieString(hTrie, "purple", "\x07800080");
 | |
| 		SetTrieString(hTrie, "rare", "\x074B69FF");
 | |
| 		SetTrieString(hTrie, "red", "\x07FF4040");
 | |
| 		SetTrieString(hTrie, "rosybrown", "\x07BC8F8F");
 | |
| 		SetTrieString(hTrie, "royalblue", "\x074169E1");
 | |
| 		SetTrieString(hTrie, "saddlebrown", "\x078B4513");
 | |
| 		SetTrieString(hTrie, "salmon", "\x07FA8072");
 | |
| 		SetTrieString(hTrie, "sandybrown", "\x07F4A460");
 | |
| 		SetTrieString(hTrie, "seagreen", "\x072E8B57");
 | |
| 		SetTrieString(hTrie, "seashell", "\x07FFF5EE");
 | |
| 		SetTrieString(hTrie, "selfmade", "\x0770B04A");
 | |
| 		SetTrieString(hTrie, "sienna", "\x07A0522D");
 | |
| 		SetTrieString(hTrie, "silver", "\x07C0C0C0");
 | |
| 		SetTrieString(hTrie, "skyblue", "\x0787CEEB");
 | |
| 		SetTrieString(hTrie, "slateblue", "\x076A5ACD");
 | |
| 		SetTrieString(hTrie, "slategray", "\x07708090");
 | |
| 		SetTrieString(hTrie, "slategrey", "\x07708090");
 | |
| 		SetTrieString(hTrie, "snow", "\x07FFFAFA");
 | |
| 		SetTrieString(hTrie, "springgreen", "\x0700FF7F");
 | |
| 		SetTrieString(hTrie, "steelblue", "\x074682B4");
 | |
| 		SetTrieString(hTrie, "strange", "\x07CF6A32");
 | |
| 		SetTrieString(hTrie, "tan", "\x07D2B48C");
 | |
| 		SetTrieString(hTrie, "teal", "\x07008080");
 | |
| 		SetTrieString(hTrie, "thistle", "\x07D8BFD8");
 | |
| 		SetTrieString(hTrie, "tomato", "\x07FF6347");
 | |
| 		SetTrieString(hTrie, "turquoise", "\x0740E0D0");
 | |
| 		SetTrieString(hTrie, "uncommon", "\x07B0C3D9");
 | |
| 		SetTrieString(hTrie, "unique", "\x07FFD700");
 | |
| 		SetTrieString(hTrie, "unusual", "\x078650AC");
 | |
| 		SetTrieString(hTrie, "valve", "\x07A50F79");
 | |
| 		SetTrieString(hTrie, "vintage", "\x07476291");
 | |
| 		SetTrieString(hTrie, "violet", "\x07EE82EE");
 | |
| 		SetTrieString(hTrie, "wheat", "\x07F5DEB3");
 | |
| 		SetTrieString(hTrie, "white", "\x07FFFFFF");
 | |
| 		SetTrieString(hTrie, "whitesmoke", "\x07F5F5F5");
 | |
| 		SetTrieString(hTrie, "yellow", "\x07FFFF00");
 | |
| 		SetTrieString(hTrie, "yellowgreen", "\x079ACD32");
 | |
| 	} else {
 | |
| 		SetTrieString(hTrie, "default", "\x01");
 | |
| 		SetTrieString(hTrie, "teamcolor", "\x03");
 | |
| 
 | |
| 		SetTrieString(hTrie, "red", "\x07");
 | |
| 		SetTrieString(hTrie, "lightred", "\x0F");
 | |
| 		SetTrieString(hTrie, "darkred", "\x02");
 | |
| 		SetTrieString(hTrie, "bluegrey", "\x0A");
 | |
| 		SetTrieString(hTrie, "blue", "\x0B");
 | |
| 		SetTrieString(hTrie, "darkblue", "\x0C");
 | |
| 		SetTrieString(hTrie, "purple", "\x03");
 | |
| 		SetTrieString(hTrie, "orchid", "\x0E");
 | |
| 		SetTrieString(hTrie, "yellow", "\x09");
 | |
| 		SetTrieString(hTrie, "gold", "\x10");
 | |
| 		SetTrieString(hTrie, "lightgreen", "\x05");
 | |
| 		SetTrieString(hTrie, "green", "\x04");
 | |
| 		SetTrieString(hTrie, "lime", "\x06");
 | |
| 		SetTrieString(hTrie, "grey", "\x08");
 | |
| 		SetTrieString(hTrie, "grey2", "\x0D");
 | |
| 	}
 | |
| 
 | |
| 	SetTrieString(hTrie, "engine 1", "\x01");
 | |
| 	SetTrieString(hTrie, "engine 2", "\x02");
 | |
| 	SetTrieString(hTrie, "engine 3", "\x03");
 | |
| 	SetTrieString(hTrie, "engine 4", "\x04");
 | |
| 	SetTrieString(hTrie, "engine 5", "\x05");
 | |
| 	SetTrieString(hTrie, "engine 6", "\x06");
 | |
| 	SetTrieString(hTrie, "engine 7", "\x07");
 | |
| 	SetTrieString(hTrie, "engine 8", "\x08");
 | |
| 	SetTrieString(hTrie, "engine 9", "\x09");
 | |
| 	SetTrieString(hTrie, "engine 10", "\x0A");
 | |
| 	SetTrieString(hTrie, "engine 11", "\x0B");
 | |
| 	SetTrieString(hTrie, "engine 12", "\x0C");
 | |
| 	SetTrieString(hTrie, "engine 13", "\x0D");
 | |
| 	SetTrieString(hTrie, "engine 14", "\x0E");
 | |
| 	SetTrieString(hTrie, "engine 15", "\x0F");
 | |
| 	SetTrieString(hTrie, "engine 16", "\x10");
 | |
| }
 | |
| 
 | |
| stock static bool:IsSource2009()
 | |
| {
 | |
| 	if (g_IsSource2009 == unknown) {
 | |
| 		new EngineVersion:iEngineVersion = GetEngineVersion();
 | |
| 		g_IsSource2009 = (iEngineVersion == Engine_CSS || iEngineVersion == Engine_TF2 || iEngineVersion == Engine_HL2DM || iEngineVersion == Engine_DODS) ? yes : no;
 | |
| 	}
 | |
| 
 | |
| 	return bool:g_IsSource2009;
 | |
| }
 | |
| 
 | |
| stock static AddPrefixAndDefaultColor(String:sMessage[], iSize, String:sDefaultColor[] = "default", String:sPrefixColor[] = "prefix")
 | |
| {
 | |
| 	if (g_sChatPrefix[0] != '\0' && !g_bIgnorePrefix) {
 | |
| 		Format(sMessage, iSize, "{%s}[%s]{%s} %s", sPrefixColor, g_sChatPrefix, sDefaultColor, sMessage);
 | |
| 	} else {
 | |
| 		Format(sMessage, iSize, "{%s}%s", sDefaultColor, sMessage);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| stock static SendPlayerMessage(iClient, String:sMessage[], iAuthor = 0)
 | |
| {
 | |
| 	if (iAuthor < 1 || iAuthor > MaxClients || !IsClientInGame(iAuthor)) {
 | |
| 		PrintToChat(iClient, sMessage);
 | |
| 
 | |
| 		if (iAuthor != 0) {
 | |
| 			LogError("Client %d is not valid or in game", iAuthor);
 | |
| 		}
 | |
| 	} else {
 | |
| 		CSayText2(iClient, sMessage, iAuthor);
 | |
| 	}
 | |
| } |