Discord: does it work like this?
This commit is contained in:
		
							parent
							
								
									877ad2cc5e
								
							
						
					
					
						commit
						983ee13eff
					
				
							
								
								
									
										779
									
								
								Discord_UNLOZE/scripting/Discord_UNLOZE.sp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										779
									
								
								Discord_UNLOZE/scripting/Discord_UNLOZE.sp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,779 @@ | ||||
| #pragma semicolon 1 | ||||
| 
 | ||||
| #include <basecomm> | ||||
| #include <sourcemod> | ||||
| #include <SteamWorks> | ||||
| #include <regex> | ||||
| #include <smjansson> | ||||
| #include <multicolors> | ||||
| #include <sdktools> | ||||
| 
 | ||||
| #include <SteamAPI.secret> | ||||
| #include <Discord.secret> | ||||
| 
 | ||||
| #tryinclude <AntiBhopCheat> | ||||
| #tryinclude <calladmin> | ||||
| #tryinclude <entWatch_restrictions> | ||||
| 
 | ||||
| #pragma newdecls required | ||||
| 
 | ||||
| Regex g_Regex_Clyde = null; | ||||
| 
 | ||||
| ArrayList g_arrQueuedMessages = null; | ||||
| 
 | ||||
| Handle g_hDataTimer = null; | ||||
| Handle g_hReplaceConfigFile = null; | ||||
| 
 | ||||
| UserMsg g_umSayText2 = INVALID_MESSAGE_ID; | ||||
| 
 | ||||
| bool g_bLoadedLate; | ||||
| bool g_bProcessingData; | ||||
| bool g_bGotReplaceFile; | ||||
| bool g_bTeamChat; | ||||
| 
 | ||||
| char g_sReplacePath[PLATFORM_MAX_PATH]; | ||||
| char g_sAvatarURL[MAXPLAYERS + 1][128]; | ||||
| 
 | ||||
| int g_iRatelimitRemaining = 5; | ||||
| int g_iRatelimitReset; | ||||
| 
 | ||||
| int g_iLastReportID; | ||||
| 
 | ||||
| public Plugin myinfo = | ||||
| { | ||||
| 	name        = "Discord core", | ||||
| 	author      = "Obus and Neon", | ||||
| 	description = "", | ||||
| 	version     = "1.3.0", | ||||
| 	url         = "" | ||||
| } | ||||
| 
 | ||||
| public APLRes AskPluginLoad2(Handle hThis, bool bLate, char[] sError, int err_max) | ||||
| { | ||||
| 	g_bLoadedLate = bLate; | ||||
| 
 | ||||
| 	return APLRes_Success; | ||||
| } | ||||
| 
 | ||||
| public void OnPluginStart() | ||||
| { | ||||
| 	char sRegexErr[32]; | ||||
| 	RegexError RegexErr; | ||||
| 
 | ||||
| 	g_Regex_Clyde = CompileRegex(".*(clyde).*", PCRE_CASELESS, sRegexErr, sizeof(sRegexErr), RegexErr); | ||||
| 
 | ||||
| 	if (RegexErr != REGEX_ERROR_NONE) | ||||
| 		LogError("Could not compile \"Clyde\" regex (err: %s)", sRegexErr); | ||||
| 
 | ||||
| 	g_hReplaceConfigFile = CreateKeyValues("AutoReplace"); | ||||
| 	BuildPath(Path_SM, g_sReplacePath, sizeof(g_sReplacePath), "configs/custom-chatcolorsreplace.cfg"); | ||||
| 
 | ||||
| 	if (FileToKeyValues(g_hReplaceConfigFile, g_sReplacePath)) | ||||
| 		g_bGotReplaceFile = true; | ||||
| 
 | ||||
| 	g_arrQueuedMessages = CreateArray(ByteCountToCells(1024)); | ||||
| 
 | ||||
| 	g_hDataTimer = CreateTimer(0.333, Timer_DataProcessor, INVALID_HANDLE, TIMER_REPEAT); | ||||
| 
 | ||||
| 	g_umSayText2 = GetUserMessageId("SayText2"); | ||||
| 
 | ||||
| 	if (g_umSayText2 == INVALID_MESSAGE_ID) | ||||
| 		SetFailState("This game doesn't support SayText2 user messages."); | ||||
| 
 | ||||
| 	HookUserMessage(g_umSayText2, Hook_UserMessage, false); | ||||
| 
 | ||||
| 	if (g_bLoadedLate) | ||||
| 	{ | ||||
| 		for (int i = 1; i <= MaxClients; i++) | ||||
| 		{ | ||||
| 			if (!IsClientAuthorized(i)) | ||||
| 				continue; | ||||
| 
 | ||||
| 			static char sAuthID32[32]; | ||||
| 
 | ||||
| 			GetClientAuthId(i, AuthId_Steam2, sAuthID32, sizeof(sAuthID32)); | ||||
| 			OnClientAuthorized(i, sAuthID32); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	AddCommandListener(CommandListener_SmChat, "sm_chat"); | ||||
| 
 | ||||
| 	RegServerCmd("sm_printtoadminchat", Command_PrintToAdminChat, "Discord Integration"); | ||||
| 	RegServerCmd("sm_printtoallchat", Command_PrintToAllChat, "Discord Integration"); | ||||
| } | ||||
| 
 | ||||
| public void OnPluginEnd() | ||||
| { | ||||
| 	delete g_arrQueuedMessages; | ||||
| 	delete g_hDataTimer; | ||||
| 
 | ||||
| 	UnhookUserMessage(g_umSayText2, Hook_UserMessage, false); | ||||
| } | ||||
| 
 | ||||
| public void OnClientAuthorized(int client, const char[] sAuthID32) | ||||
| { | ||||
| 	if (IsFakeClient(client)) | ||||
| 		return; | ||||
| 
 | ||||
| 	char sAuthID64[32]; | ||||
| 
 | ||||
| 	if (!Steam32IDtoSteam64ID(sAuthID32, sAuthID64, sizeof(sAuthID64))) | ||||
| 		return; | ||||
| 
 | ||||
| 	static char sRequest[256]; | ||||
| 
 | ||||
| 	FormatEx(sRequest, sizeof(sRequest), "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=%s&steamids=%s&format=vdf", STEAM_API_KEY, sAuthID64); | ||||
| 
 | ||||
| 	Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, sRequest); | ||||
| 
 | ||||
| 	if (!hRequest || | ||||
| 		!SteamWorks_SetHTTPRequestContextValue(hRequest, client) || | ||||
| 		!SteamWorks_SetHTTPCallbacks(hRequest, OnTransferComplete) || | ||||
| 		!SteamWorks_SendHTTPRequest(hRequest)) | ||||
| 	{ | ||||
| 		delete hRequest; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| public Action Command_PrintToAdminChat(int args) | ||||
| { | ||||
| 	char sArgs[1024]; | ||||
| 	char sArgs2[1024]; | ||||
| 
 | ||||
| 	GetCmdArg(1, sArgs, sizeof(sArgs)); | ||||
| 	GetCmdArg(2, sArgs2, sizeof(sArgs2)); | ||||
| 
 | ||||
| 	for(int i = 0; i < MAXPLAYERS; i++) | ||||
| 	{ | ||||
| 		if (IsValidClient(i)) | ||||
| 		{ | ||||
| 			bool bAdmin = CheckCommandAccess(i, "", ADMFLAG_GENERIC, true); | ||||
| 			if (bAdmin) | ||||
| 				CPrintToChat(i, "{azure}[DISCORD](ADMINS) %s: {white}%s", sArgs, sArgs2); | ||||
| 		} | ||||
| 	} | ||||
| 	return Plugin_Handled; | ||||
| } | ||||
| 
 | ||||
| public Action Command_PrintToAllChat(int args) | ||||
| { | ||||
| 	char sArgs[1024]; | ||||
| 	char sArgs2[1024]; | ||||
| 
 | ||||
| 	GetCmdArg(1, sArgs, sizeof(sArgs)); | ||||
| 	GetCmdArg(2, sArgs2, sizeof(sArgs2)); | ||||
| 
 | ||||
| 	CPrintToChatAll("{azure}[DISCORD](ALL) %s: {white}%s", sArgs, sArgs2); | ||||
| 
 | ||||
| 	return Plugin_Handled; | ||||
| } | ||||
| 
 | ||||
| public Action Timer_DataProcessor(Handle hThis) | ||||
| { | ||||
| 	if (!g_bProcessingData) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (g_iRatelimitRemaining == 0 && GetTime() < g_iRatelimitReset) | ||||
| 		return; | ||||
| 
 | ||||
| 	//PrintToServer("[Timer_DataProcessor] Array Length #1: %d", g_arrQueuedMessages.Length); | ||||
| 
 | ||||
| 	char sContent[1024]; | ||||
| 	g_arrQueuedMessages.GetString(0, sContent, sizeof(sContent)); | ||||
| 	g_arrQueuedMessages.Erase(0); | ||||
| 
 | ||||
| 	char sURL[128]; | ||||
| 	g_arrQueuedMessages.GetString(0, sURL, sizeof(sURL)); | ||||
| 	g_arrQueuedMessages.Erase(0); | ||||
| 
 | ||||
| 	if (g_arrQueuedMessages.Length == 0) | ||||
| 		g_bProcessingData = false; | ||||
| 
 | ||||
| 	//PrintToServer("[Timer_DataProcessor] Array Length #2: %d", g_arrQueuedMessages.Length); | ||||
| 
 | ||||
| 	//PrintToServer("%s | %s", sURL, sContent); | ||||
| 
 | ||||
| 	Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodPOST, sURL); | ||||
| 
 | ||||
| 	JSONObject RequestJSON = view_as<JSONObject>(json_load(sContent)); | ||||
| 
 | ||||
| 	if (!hRequest || | ||||
| 		!SteamWorks_SetHTTPRequestContextValue(hRequest, RequestJSON) || | ||||
| 		!SteamWorks_SetHTTPCallbacks(hRequest, OnHTTPRequestCompleted) || | ||||
| 		!SteamWorks_SetHTTPRequestRawPostBody(hRequest, "application/json", sContent, strlen(sContent)) || | ||||
| 		!SteamWorks_SetHTTPRequestNetworkActivityTimeout(hRequest, 10) || | ||||
| 		!SteamWorks_SendHTTPRequest(hRequest)) | ||||
| 	{ | ||||
| 		LogError("Discord SteamWorks_CreateHTTPRequest failed."); | ||||
| 
 | ||||
| 		delete RequestJSON; | ||||
| 		delete hRequest; | ||||
| 
 | ||||
| 		return; | ||||
| 	} | ||||
| } | ||||
| public Action Hook_UserMessage(UserMsg msg_id, Handle bf, const players[], int playersNum, bool reliable, bool init) | ||||
| { | ||||
| 	char sMessageName[32]; | ||||
| 	char sMessageSender[64]; | ||||
| 	int iAuthor = BfReadByte(bf); | ||||
| 	bool bIsChat = view_as<bool>(BfReadByte(bf)); if (bIsChat) bIsChat=false; //fucking compiler shut the fuck up REEEEEE | ||||
| 	BfReadString(bf, sMessageName, sizeof(sMessageName), false); | ||||
| 	BfReadString(bf, sMessageSender, sizeof(sMessageSender), false); | ||||
| 
 | ||||
| 	if (iAuthor <= 0 || iAuthor > MaxClients) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (strlen(sMessageName) == 0 || strlen(sMessageSender) == 0) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (strcmp(sMessageName, "#Cstrike_Name_Change") == 0) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (sMessageName[13] == 'C' || sMessageName[13] == 'T' || sMessageName[13] == 'S') | ||||
| 		g_bTeamChat = true; | ||||
| 	else | ||||
| 		g_bTeamChat = false; | ||||
| } | ||||
| 
 | ||||
| stock bool Steam32IDtoSteam64ID(const char[] sSteam32ID, char[] sSteam64ID, int Size) | ||||
| { | ||||
| 	if (strlen(sSteam32ID) < 11 || strncmp(sSteam32ID[0], "STEAM_0:", 8) || strcmp(sSteam32ID, "STEAM_ID_PENDING") == 0) | ||||
| 	{ | ||||
| 		sSteam64ID[0] = 0; | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	int iUpper = 765611979; | ||||
| 	int isSteam64ID = StringToInt(sSteam32ID[10]) * 2 + 60265728 + sSteam32ID[8] - 48; | ||||
| 
 | ||||
| 	int iDiv = isSteam64ID / 100000000; | ||||
| 	int iIdx = 9 - (iDiv ? (iDiv / 10 + 1) : 0); | ||||
| 	iUpper += iDiv; | ||||
| 
 | ||||
| 	IntToString(isSteam64ID, sSteam64ID[iIdx], Size - iIdx); | ||||
| 	iIdx = sSteam64ID[9]; | ||||
| 	IntToString(iUpper, sSteam64ID, Size); | ||||
| 	sSteam64ID[9] = iIdx; | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| stock void Discord_MakeStringSafe(const char[] sOrigin, char[] sOut, int iOutSize) | ||||
| { | ||||
| 	int iDataLen = strlen(sOrigin); | ||||
| 	int iCurIndex; | ||||
| 
 | ||||
| 	for (int i = 0; i < iDataLen && iCurIndex < iOutSize; i++) | ||||
| 	{ | ||||
| 		if (sOrigin[i] < 0x20 && sOrigin[i] != 0x0) | ||||
| 		{ | ||||
| 			//sOut[iCurIndex] = 0x20; | ||||
| 			//iCurIndex++; | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		switch (sOrigin[i]) | ||||
| 		{ | ||||
| 			// case '"': | ||||
| 			// { | ||||
| 				// strcopy(sOut[iCurIndex], iOutSize, "\\u0022"); | ||||
| 				// iCurIndex += 6; | ||||
| 
 | ||||
| 				// continue; | ||||
| 			// } | ||||
| 			// case '\\': | ||||
| 			// { | ||||
| 				// strcopy(sOut[iCurIndex], iOutSize, "\\u005C"); | ||||
| 				// iCurIndex += 6; | ||||
| 
 | ||||
| 				// continue; | ||||
| 			// } | ||||
| 			case '@': | ||||
| 			{ | ||||
| 				strcopy(sOut[iCurIndex], iOutSize, "@"); //@ + zero-width space | ||||
| 				iCurIndex += 4; | ||||
| 
 | ||||
| 				continue; | ||||
| 			} | ||||
| 			case '`': | ||||
| 			{ | ||||
| 				strcopy(sOut[iCurIndex], iOutSize, "\\`"); | ||||
| 				iCurIndex += 2; | ||||
| 
 | ||||
| 				continue; | ||||
| 			} | ||||
| 			case '_': | ||||
| 			{ | ||||
| 				strcopy(sOut[iCurIndex], iOutSize, "\\_"); | ||||
| 				iCurIndex += 2; | ||||
| 
 | ||||
| 				continue; | ||||
| 			} | ||||
| 			case '~': | ||||
| 			{ | ||||
| 				strcopy(sOut[iCurIndex], iOutSize, "\\~"); | ||||
| 				iCurIndex += 2; | ||||
| 
 | ||||
| 				continue; | ||||
| 			} | ||||
| 			default: | ||||
| 			{ | ||||
| 				sOut[iCurIndex] = sOrigin[i]; | ||||
| 				iCurIndex++; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| stock int OnTransferComplete(Handle hRequest, bool bFailure, bool bRequestSuccessful, EHTTPStatusCode eStatusCode, int client) | ||||
| { | ||||
| 	if (bFailure || !bRequestSuccessful || eStatusCode != k_EHTTPStatusCode200OK) | ||||
| 	{ | ||||
| 		if (eStatusCode != k_EHTTPStatusCode429TooManyRequests) | ||||
| 		{ | ||||
| 			LogError("SteamAPI HTTP Response failed: %d", eStatusCode); | ||||
| 		} | ||||
| 
 | ||||
| 		delete hRequest; | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	int iBodyLength; | ||||
| 	SteamWorks_GetHTTPResponseBodySize(hRequest, iBodyLength); | ||||
| 
 | ||||
| 	char[] sData = new char[iBodyLength]; | ||||
| 	SteamWorks_GetHTTPResponseBodyData(hRequest, sData, iBodyLength); | ||||
| 
 | ||||
| 	delete hRequest; | ||||
| 
 | ||||
| 	APIWebResponse(sData, client); | ||||
| } | ||||
| 
 | ||||
| stock void APIWebResponse(const char[] sData, int client) | ||||
| { | ||||
| 	KeyValues kvResponse = new KeyValues("SteamAPIResponse"); | ||||
| 
 | ||||
| 	if (!kvResponse.ImportFromString(sData, "SteamAPIResponse")) | ||||
| 	{ | ||||
| 		//LogError("kvResponse.ImportFromString(\"SteamAPIResponse\") in APIWebResponse failed."); | ||||
| 
 | ||||
| 		delete kvResponse; | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!kvResponse.JumpToKey("players")) | ||||
| 	{ | ||||
| 		//LogError("kvResponse.JumpToKey(\"players\") in APIWebResponse failed."); | ||||
| 
 | ||||
| 		delete kvResponse; | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!kvResponse.GotoFirstSubKey()) | ||||
| 	{ | ||||
| 		//LogError("kvResponse.GotoFirstSubKey() in APIWebResponse failed."); | ||||
| 
 | ||||
| 		delete kvResponse; | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	kvResponse.GetString("avatarfull", g_sAvatarURL[client], sizeof(g_sAvatarURL[])); | ||||
| 
 | ||||
| 	delete kvResponse; | ||||
| } | ||||
| 
 | ||||
| stock void HTTPPostJSON(const char[] sURL, const char[] sText) | ||||
| { | ||||
| 	// if (g_iRatelimitRemaining > 0 && !g_bProcessingData && GetTime() < g_iRatelimitReset) | ||||
| 	// { | ||||
| 	Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodPOST, sURL); | ||||
| 
 | ||||
| 	JSONObject RequestJSON = view_as<JSONObject>(json_load(sText)); | ||||
| 
 | ||||
| 	if (!hRequest || | ||||
| 		!SteamWorks_SetHTTPRequestContextValue(hRequest, RequestJSON) || | ||||
| 		!SteamWorks_SetHTTPCallbacks(hRequest, OnHTTPRequestCompleted) || | ||||
| 		!SteamWorks_SetHTTPRequestRawPostBody(hRequest, "application/json", sText, strlen(sText)) || | ||||
| 		!SteamWorks_SetHTTPRequestNetworkActivityTimeout(hRequest, 15) || | ||||
| 		!SteamWorks_SendHTTPRequest(hRequest)) | ||||
| 	{ | ||||
| 		LogError("Discord SteamWorks_CreateHTTPRequest failed."); | ||||
| 
 | ||||
| 		delete RequestJSON; | ||||
| 		delete hRequest; | ||||
| 
 | ||||
| 		return; | ||||
| 	} | ||||
| 	// } | ||||
| 	// else | ||||
| 	// { | ||||
| 		// g_arrQueuedMessages.PushString(sText); | ||||
| 		// g_arrQueuedMessages.PushString(sURL); | ||||
| 		// g_bProcessingData = true; | ||||
| 	// } | ||||
| 
 | ||||
| 	//delete hRequest; | ||||
| } | ||||
| 
 | ||||
| stock void Discord_POST(const char[] sURL, char[] sText, bool bUsingUsername=false, char[] sUsername=NULL_STRING, bool bUsingAvatar=false, char[] sAvatarURL=NULL_STRING, bool bSafe=true, bool bTimestamp=true) | ||||
| { | ||||
| 	//PrintToServer("[Discord_POST] Called with text: %s", sText); | ||||
| 
 | ||||
| 	JSONRootNode hJSONRoot = new JSONObject(); | ||||
| 
 | ||||
| 	char sSafeText[4096]; | ||||
| 	char sFinal[4096]; | ||||
| 
 | ||||
| 	if (bUsingUsername) | ||||
| 	{ | ||||
| 		TrimString(sUsername); | ||||
| 
 | ||||
| 		if (g_Regex_Clyde.Match(sUsername) > 0 || strlen(sUsername) < 2) | ||||
| 			(view_as<JSONObject>(hJSONRoot)).SetString("username", "Invalid Name"); | ||||
| 		else | ||||
| 			(view_as<JSONObject>(hJSONRoot)).SetString("username", sUsername); | ||||
| 	} | ||||
| 
 | ||||
| 	if (bUsingAvatar) | ||||
| 		(view_as<JSONObject>(hJSONRoot)).SetString("avatar_url", sAvatarURL); | ||||
| 
 | ||||
| 	if (bSafe) | ||||
| 	{ | ||||
| 		Discord_MakeStringSafe(sText, sSafeText, sizeof(sSafeText)); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		Format(sSafeText, sizeof(sSafeText), "%s", sText); | ||||
| 	} | ||||
| 
 | ||||
| 	if (bTimestamp) | ||||
| 	{ | ||||
| 		int iTime = GetTime(); | ||||
| 		char sTime[32]; | ||||
| 		FormatTime(sTime, sizeof(sTime), "%r", iTime); | ||||
| 		Format(sSafeText, sizeof(sSafeText), "[ *%s* ] %s", sTime, sText); | ||||
| 	} | ||||
| 
 | ||||
| 	(view_as<JSONObject>(hJSONRoot)).SetString("content", sSafeText); | ||||
| 	(view_as<JSONObject>(hJSONRoot)).ToString(sFinal, sizeof(sFinal), 0); | ||||
| 
 | ||||
| 	//hJSONRoot.DumpToServer(); | ||||
| 
 | ||||
| 	delete hJSONRoot; | ||||
| 
 | ||||
| 	if ((g_iRatelimitRemaining > 0 || GetTime() >= g_iRatelimitReset) && !g_bProcessingData) | ||||
| 	{ | ||||
| 		//PrintToServer("[Discord_POST] Have allowances and not processing data"); | ||||
| 
 | ||||
| 		Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodPOST, sURL); | ||||
| 
 | ||||
| 		JSONObject RequestJSON = view_as<JSONObject>(json_load(sFinal)); | ||||
| 
 | ||||
| 		if (!hRequest || | ||||
| 			!SteamWorks_SetHTTPRequestContextValue(hRequest, RequestJSON) || | ||||
| 			!SteamWorks_SetHTTPCallbacks(hRequest, OnHTTPRequestCompleted) || | ||||
| 			!SteamWorks_SetHTTPRequestRawPostBody(hRequest, "application/json", sFinal, strlen(sFinal)) || | ||||
| 			!SteamWorks_SetHTTPRequestNetworkActivityTimeout(hRequest, 10) || | ||||
| 			!SteamWorks_SendHTTPRequest(hRequest)) | ||||
| 		{ | ||||
| 			LogError("Discord SteamWorks_CreateHTTPRequest failed."); | ||||
| 
 | ||||
| 			delete RequestJSON; | ||||
| 			delete hRequest; | ||||
| 
 | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		//PrintToServer("[Discord_POST] Have allowances? [%s] | Is processing data? [%s]", g_iRatelimitRemaining > 0 ? "YES":"NO", g_bProcessingData?"YES":"NO"); | ||||
| 		g_arrQueuedMessages.PushString(sFinal); | ||||
| 		g_arrQueuedMessages.PushString(sURL); | ||||
| 		g_bProcessingData = true; | ||||
| 	} | ||||
| 
 | ||||
| 	//delete hRequest; //nonono | ||||
| } | ||||
| 
 | ||||
| public int OnHTTPRequestCompleted(Handle hRequest, bool bFailure, bool bRequestSuccessful, EHTTPStatusCode eStatusCode, JSONObject RequestJSON) | ||||
| { | ||||
| 	if (bFailure || !bRequestSuccessful || (eStatusCode != k_EHTTPStatusCode200OK && eStatusCode != k_EHTTPStatusCode204NoContent)) | ||||
| 	{ | ||||
| 		if (eStatusCode != k_EHTTPStatusCode429TooManyRequests) | ||||
| 			LogError("Discord HTTP request failed: %d", eStatusCode); | ||||
| 
 | ||||
| 		if (eStatusCode == k_EHTTPStatusCode400BadRequest) | ||||
| 		{ | ||||
| 			char sData[2048]; | ||||
| 
 | ||||
| 			(view_as<JSONRootNode>(RequestJSON)).ToString(sData, sizeof(sData), 0); | ||||
| 
 | ||||
| 			LogError("Malformed request? Dumping request data:\n%s", sData); | ||||
| 		} | ||||
| 		else if (eStatusCode == k_EHTTPStatusCode429TooManyRequests) | ||||
| 		{ | ||||
| 			g_iRatelimitRemaining = 0; | ||||
| 			g_iRatelimitReset = GetTime() + 5; | ||||
| 		} | ||||
| 
 | ||||
| 		delete RequestJSON; | ||||
| 		delete hRequest; | ||||
| 
 | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	static int iLastRatelimitRemaining = 0; | ||||
| 	static int iLastRatelimitReset = 0; | ||||
| 	char sTmp[32]; | ||||
| 	bool bHeaderExists = SteamWorks_GetHTTPResponseHeaderValue(hRequest, "x-ratelimit-remaining", sTmp, sizeof(sTmp)); | ||||
| 
 | ||||
| 	if (!bHeaderExists) | ||||
| 		LogError("x-ratelimit-remaining header value could not be retrieved"); | ||||
| 
 | ||||
| 	int iRatelimitRemaining = StringToInt(sTmp); | ||||
| 
 | ||||
| 	bHeaderExists = SteamWorks_GetHTTPResponseHeaderValue(hRequest, "x-ratelimit-reset", sTmp, sizeof(sTmp)); | ||||
| 
 | ||||
| 	if (!bHeaderExists) | ||||
| 		LogError("x-ratelimit-reset header value could not be retrieved"); | ||||
| 
 | ||||
| 	int iRatelimitReset = StringToInt(sTmp); | ||||
| 
 | ||||
| 	if (iRatelimitRemaining < iLastRatelimitRemaining || iRatelimitReset >= iLastRatelimitReset) //don't be fooled by different completion times | ||||
| 	{ | ||||
| 		g_iRatelimitRemaining = iRatelimitRemaining; | ||||
| 		g_iRatelimitReset = iRatelimitReset; | ||||
| 	} | ||||
| 
 | ||||
| 	//PrintToServer("limit: %d | remaining: %d || reset %d - now %d", g_iRatelimitLimit, g_iRatelimitRemaining, g_iRatelimitReset, GetTime()); | ||||
| 
 | ||||
| 	delete RequestJSON; | ||||
| 	delete hRequest; | ||||
| } | ||||
| 
 | ||||
| stock bool IsValidClient(int client) | ||||
| { | ||||
| 	return (client > 0 && client <= MaxClients && IsClientInGame(client)); | ||||
| } | ||||
| 
 | ||||
| public Action OnLogAction(Handle hSource, Identity ident, int client, int target, const char[] sMsg) | ||||
| { | ||||
| 	if (client <= 0) | ||||
| 		return; | ||||
| 
 | ||||
| 	if ((StrContains(sMsg, "sm_psay", false)!= -1) || (StrContains(sMsg, "sm_chat", false)!= -1)) | ||||
| 		return;// dont log sm_psay and sm_chat | ||||
| 
 | ||||
| 	char sFinal[256]; | ||||
| 	char sCurrentMap[32]; | ||||
| 	char sClientName[64]; | ||||
| 
 | ||||
| 	GetCurrentMap(sCurrentMap, sizeof(sCurrentMap)); | ||||
| 	Format(sFinal, sizeof(sFinal), "[ %s ]```%s```", sCurrentMap, sMsg); | ||||
| 
 | ||||
| 	GetClientName(client, sClientName, sizeof(sClientName)); | ||||
| 
 | ||||
| 	if (g_sAvatarURL[client][0] != '\0') | ||||
| 		Discord_POST(DISCORD_ADMINLOGS_WEBHOOKURL, sFinal, true, sClientName, true, g_sAvatarURL[client], false); | ||||
| 	else | ||||
| 		Discord_POST(DISCORD_ADMINLOGS_WEBHOOKURL, sFinal, true, sClientName, false, "", false); | ||||
| 
 | ||||
| 	return; | ||||
| } | ||||
| 
 | ||||
| public Action CommandListener_SmChat(int client, const char[] sCommand, int argc) | ||||
| { | ||||
| 	if (client <= 0) | ||||
| 		return Plugin_Continue; | ||||
| 
 | ||||
| 	char sText[256]; | ||||
| 	char sUsername[32]; | ||||
| 
 | ||||
| 	GetCmdArgString(sText, sizeof(sText)); | ||||
| 	GetClientName(client, sUsername, sizeof(sUsername)); | ||||
| 
 | ||||
| 	if (g_sAvatarURL[client][0] != '\0') | ||||
| 		Discord_POST(DISCORD_ADMINCHAT_WEBHOOKURL, sText, true, sUsername, true, g_sAvatarURL[client]); | ||||
| 	else | ||||
| 		Discord_POST(DISCORD_ADMINCHAT_WEBHOOKURL, sText, true, sUsername); | ||||
| 
 | ||||
| 	return Plugin_Continue; | ||||
| } | ||||
| 
 | ||||
| public Action OnClientSayCommand(int client, const char[] sCommand, const char[] sArgs) | ||||
| { | ||||
| 	if (client <= 0 || !IsClientInGame(client) || BaseComm_IsClientGagged(client)) | ||||
| 		return Plugin_Continue; | ||||
| 
 | ||||
| 	char sFinal[256]; | ||||
| 	char sUsername[MAX_NAME_LENGTH]; | ||||
| 
 | ||||
| 	GetClientName(client, sUsername, sizeof(sUsername)); | ||||
| 
 | ||||
| 	if (strcmp(sCommand, "say_team") == 0) | ||||
| 	{ | ||||
| 		if (sArgs[0] == '@') | ||||
| 		{ | ||||
| 			bool bAdmin = CheckCommandAccess(client, "", ADMFLAG_GENERIC, true); | ||||
| 			Format(sFinal, sizeof(sFinal), "%s%s", bAdmin ? "" : "To Admins: ", sArgs[1]); | ||||
| 			if (g_sAvatarURL[client][0] != '\0') | ||||
| 				Discord_POST(DISCORD_ADMINCHAT_WEBHOOKURL, sFinal, true, sUsername, true, g_sAvatarURL[client]); | ||||
| 			else | ||||
| 				Discord_POST(DISCORD_ADMINCHAT_WEBHOOKURL, sFinal, true, sUsername); | ||||
| 
 | ||||
| 			if (!bAdmin) | ||||
| 			{ | ||||
| 				//g_iReplyTargetSerial = GetClientSerial(client); | ||||
| 				//g_iReplyType = REPLYTYPE_CHAT; | ||||
| 			} | ||||
| 
 | ||||
| 			return Plugin_Continue; | ||||
| 		} | ||||
| 
 | ||||
| 		char sTeamName[32]; | ||||
| 
 | ||||
| 		GetTeamName(GetClientTeam(client), sTeamName, sizeof(sTeamName)); | ||||
| 		Format(sFinal, sizeof(sFinal), "(%s) ", sTeamName); | ||||
| 	} | ||||
| 
 | ||||
| 	return Plugin_Continue; | ||||
| } | ||||
| 
 | ||||
| public void CallAdmin_OnReportPost(int client, int target, const char[] reason) | ||||
| { | ||||
| 	char sClientName[MAX_NAME_LENGTH]; | ||||
| 	char sClientID[21]; | ||||
| 
 | ||||
| 	char sTargetName[MAX_NAME_LENGTH]; | ||||
| 	char sTargetID[21]; | ||||
| 
 | ||||
| 	char sServerIP[16]; | ||||
| 	int serverPort; | ||||
| 	char sServerName[128]; | ||||
| 
 | ||||
| 	CallAdmin_GetHostIP(sServerIP, sizeof(sServerIP)); | ||||
| 	serverPort = CallAdmin_GetHostPort(); | ||||
| 	CallAdmin_GetHostName(sServerName, sizeof(sServerName)); | ||||
| 
 | ||||
| 	// Reporter wasn't a real client (initiated by a module) | ||||
| 	if (client == REPORTER_CONSOLE) | ||||
| 	{ | ||||
| 		strcopy(sClientName, sizeof(sClientName), "Server/Console"); | ||||
| 		strcopy(sClientID, sizeof(sClientID), "Server/Console"); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		GetClientName(client, sClientName, sizeof(sClientName)); | ||||
| 		GetClientAuthId(client, AuthId_Steam2, sClientID, sizeof(sClientID)); | ||||
| 	} | ||||
| 
 | ||||
| 	GetClientName(target, sTargetName, sizeof(sTargetName)); | ||||
| 	GetClientAuthId(target, AuthId_Steam2, sTargetID, sizeof(sTargetID)); | ||||
| 
 | ||||
| 	g_iLastReportID = CallAdmin_GetReportID(); | ||||
| 
 | ||||
| 	char currentMap[64]; | ||||
| 	GetCurrentMap(currentMap, sizeof(currentMap)); | ||||
| 
 | ||||
| 	char sMessage[4096]; | ||||
| 	Format(sMessage, sizeof(sMessage), "@here\n```%s - Tick: %d``````New report on server: %s (%s:%d)\nReportID: %d\nReporter: %s (%s)\nTarget: %s (%s)\nReason: %s\nJoin Server: steam://connect/%s:%d\nwhen in game, type !calladmin_handle %d or /calladmin_handle %d in chat to handle this report```", currentMap, GetGameTickCount(), sServerName, sServerIP, serverPort, g_iLastReportID, sClientName, sClientID, sTargetName, sTargetID, reason, sServerIP, serverPort, g_iLastReportID, g_iLastReportID); | ||||
| 
 | ||||
| 	char sUsername[MAX_NAME_LENGTH]; | ||||
| 	GetClientName(client, sUsername, sizeof(sUsername)); | ||||
| 
 | ||||
| 	if (g_sAvatarURL[client][0] != '\0') | ||||
| 		Discord_POST(DISCORD_CALLADMIN_WEBHOOKURL, sMessage, true, sUsername, true, g_sAvatarURL[client], false); | ||||
| 	else | ||||
| 		Discord_POST(DISCORD_CALLADMIN_WEBHOOKURL, sMessage, true, sUsername, false, "", false); | ||||
| } | ||||
| 
 | ||||
| public void CallAdmin_OnReportHandled(int client, int id) | ||||
| { | ||||
| 	if (id != g_iLastReportID) | ||||
| 	{ | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	char sMessage[1024]; | ||||
| 	Format(sMessage, sizeof(sMessage), "```Last report (%d) was handled by: %N```", g_iLastReportID, client); | ||||
| 
 | ||||
| 	char sUsername[MAX_NAME_LENGTH]; | ||||
| 	GetClientName(client, sUsername, sizeof(sUsername)); | ||||
| 
 | ||||
| 	if (g_sAvatarURL[client][0] != '\0') | ||||
| 		Discord_POST(DISCORD_CALLADMIN_WEBHOOKURL, sMessage, true, sUsername, true, g_sAvatarURL[client], false); | ||||
| 	else | ||||
| 		Discord_POST(DISCORD_CALLADMIN_WEBHOOKURL, sMessage, true, sUsername, false, "", false); | ||||
| } | ||||
| 
 | ||||
| public void AntiBhopCheat_OnClientDetected(int client, char[] sReason, char[] sStats) | ||||
| { | ||||
| 	char sUsername[MAX_NAME_LENGTH]; | ||||
| 	GetClientName(client, sUsername, sizeof(sUsername)); | ||||
| 
 | ||||
| 	char currentMap[64]; | ||||
| 	GetCurrentMap(currentMap, sizeof(currentMap)); | ||||
| 
 | ||||
| 	char sMessage[4096]; | ||||
| 	Format(sMessage, sizeof(sMessage), "```%s - Tick: %d``````%s\n%s```", currentMap, GetGameTickCount(), sReason, sStats); | ||||
| 
 | ||||
| 	if (g_sAvatarURL[client][0] != '\0') | ||||
| 		Discord_POST(DISCORD_ANTIBHOPCHEAT_WEBHOOKURL, sMessage, true, sUsername, true, g_sAvatarURL[client], false); | ||||
| 	else | ||||
| 		Discord_POST(DISCORD_ANTIBHOPCHEAT_WEBHOOKURL, sMessage, true, sUsername, false, "", false); | ||||
| } | ||||
| 
 | ||||
| public void EW_OnClientRestricted(int client, int target, int length) | ||||
| { | ||||
| 	char sUsername[MAX_NAME_LENGTH]; | ||||
| 	GetClientName(target, sUsername, sizeof(sUsername)); | ||||
| 
 | ||||
| 	char currentMap[64]; | ||||
| 	GetCurrentMap(currentMap, sizeof(currentMap)); | ||||
| 
 | ||||
| 	char sMessageTmp[4096]; | ||||
| 
 | ||||
| 	if (length == -1) | ||||
| 	{ | ||||
| 		Format(sMessageTmp, sizeof(sMessageTmp), "%L got temporarily restricted by %L", target, client); | ||||
| 	} | ||||
| 	else if (length == 0) | ||||
| 	{ | ||||
| 		Format(sMessageTmp, sizeof(sMessageTmp), "%L got PERMANENTLY restricted by %L", target, client); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		Format(sMessageTmp, sizeof(sMessageTmp), "%L got restricted by %L for %d minutes", target, client, length); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	char sMessage[4096]; | ||||
| 	Format(sMessage, sizeof(sMessage), "```%s - Tick: %d``````%s```", currentMap, GetGameTickCount(), sMessageTmp); | ||||
| 
 | ||||
| 	if (g_sAvatarURL[target][0] != '\0') | ||||
| 		Discord_POST(DISCORD_ENTWATCH_WEBHOOKURL, sMessage, true, sUsername, true, g_sAvatarURL[target], false); | ||||
| 	else | ||||
| 		Discord_POST(DISCORD_ENTWATCH_WEBHOOKURL, sMessage, true, sUsername, false, "", false); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| public void EW_OnClientUnrestricted(int client, int target) | ||||
| { | ||||
| 	char sUsername[MAX_NAME_LENGTH]; | ||||
| 	GetClientName(target, sUsername, sizeof(sUsername)); | ||||
| 
 | ||||
| 	char currentMap[64]; | ||||
| 	GetCurrentMap(currentMap, sizeof(currentMap)); | ||||
| 
 | ||||
| 	char sMessageTmp[4096]; | ||||
| 	Format(sMessageTmp, sizeof(sMessageTmp), "%L got unrestricted by %L", target, client); | ||||
| 
 | ||||
| 	char sMessage[4096]; | ||||
| 	Format(sMessage, sizeof(sMessage), "```%s - Tick: %d``````%s```", currentMap, GetGameTickCount(), sMessageTmp); | ||||
| 
 | ||||
| 	if (g_sAvatarURL[target][0] != '\0') | ||||
| 		Discord_POST(DISCORD_ENTWATCH_WEBHOOKURL, sMessage, true, sUsername, true, g_sAvatarURL[target], false); | ||||
| 	else | ||||
| 		Discord_POST(DISCORD_ENTWATCH_WEBHOOKURL, sMessage, true, sUsername, false, "", false); | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 neon
						neon