From 39d4e187c207ca20aad254c69ac1ea79b41ac940 Mon Sep 17 00:00:00 2001 From: BotoX Date: Tue, 7 Aug 2018 22:31:09 +0200 Subject: [PATCH] add Discord --- Discord/scripting/Discord.sp | 816 +++++++++++++++++++++++++++++++++++ includes/AntiBhopCheat.inc | 1 + 2 files changed, 817 insertions(+) create mode 100644 Discord/scripting/Discord.sp create mode 120000 includes/AntiBhopCheat.inc diff --git a/Discord/scripting/Discord.sp b/Discord/scripting/Discord.sp new file mode 100644 index 00000000..8aaf6567 --- /dev/null +++ b/Discord/scripting/Discord.sp @@ -0,0 +1,816 @@ +#pragma semicolon 1 + +#include +#include +#include +#include +#include +#include "sdktools_functions.inc" + +#include +#include + +#pragma newdecls required + +#include "SteamAPI.secret" // #define STEAM_API_KEY "" +#include "Discord.secret" // #define DISCORD_* + +Regex g_Regex_Clyde = null; + +ConVar g_Cvar_HostIP = null; +ConVar g_Cvar_HostPort = null; +ConVar g_Cvar_HostName = null; + +ArrayList g_arrQueuedMessages = null; + +Handle g_hDataTimer = null; +Handle g_hReplaceConfigFile = null; + +UserMsg g_umSayText2 = INVALID_MESSAGE_ID; + +bool g_bLoadedLate; +bool g_bTimerDone; +bool g_bProcessingData; +bool g_bGotReplaceFile; +bool g_bTeamChat; + +char g_sReplacePath[PLATFORM_MAX_PATH]; +char g_sAvatarURL[MAXPLAYERS + 1][128]; + +int g_iPlayersAtPOST = 0; +int g_iRatelimitRemaining = 5; +int g_iRatelimitReset; + +public Plugin myinfo = +{ + name = "Discord core", + author = "Obus", + description = "Implements live chat and map reporting for Discord.", + version = "1.1.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_Cvar_HostIP = FindConVar("hostip"); + g_Cvar_HostPort = FindConVar("hostport"); + g_Cvar_HostName = FindConVar("hostname"); + + 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); + + HookEvent("player_say", EventHook_PlayerSay, EventHookMode_Post); + + AddCommandListener(CommandListener_SmChat, "sm_chat"); + + 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); + } + } +} + +public void OnPluginEnd() +{ + delete g_arrQueuedMessages; + delete g_hDataTimer; + + UnhookUserMessage(g_umSayText2, Hook_UserMessage, false); + UnhookEvent("player_say", EventHook_PlayerSay, EventHookMode_Post); +} + +public void OnClientPutInServer(int client) +{ + if (!g_bTimerDone) + return; + + int iClientCount = GetClientCount(false); + + if (iClientCount >= g_iPlayersAtPOST+10) + FormatStatusAndPOST(g_iPlayersAtPOST = iClientCount); +} + +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 void OnMapStart() +{ + g_bTimerDone = false; + CreateTimer(10.0, Timer_OnMapStart); +} + +public Action Timer_OnMapStart(Handle hThis) +{ + g_bTimerDone = true; + FormatStatusAndPOST(g_iPlayersAtPOST = GetClientCount(false)); +} + +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(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 void FormatStatusAndPOST(int iCurrentClients) +{ + char sFinal[512]; + char sCurrentMap[32]; + char sServerName[64]; + int iServerIP = g_Cvar_HostIP.IntValue; + int iServerPort = g_Cvar_HostPort.IntValue; + + GetCurrentMap(sCurrentMap, sizeof(sCurrentMap)); + g_Cvar_HostName.GetString(sServerName, sizeof(sServerName)); + + char sTitle[64]; + char sDescription[256]; + + strcopy(sTitle, sizeof(sTitle), sServerName); + Format(sDescription, sizeof(sDescription), "Current Map: **%s**\nCurrent Players: **%d/%d**\nQuick Join: **steam://connect/%d.%d.%d.%d:%d**", + sCurrentMap, iCurrentClients, MaxClients, iServerIP >>> 24 & 255, iServerIP >>> 16 & 255, iServerIP >>> 8 & 255, iServerIP & 255, iServerPort); + + JSONRootNode hJSONFinal = new JSONObject(); + JSONObject hEmbeds = new JSONObject(); + JSONArray arrEmbeds = new JSONArray(); + + (view_as(hJSONFinal)).SetString("username", "MapInfo"); + hEmbeds.SetInt("color", 0xFF0000); + hEmbeds.SetString("title", sTitle); + hEmbeds.SetString("description", sDescription); + arrEmbeds.Append(hEmbeds); + (view_as(hJSONFinal)).Set("embeds", arrEmbeds); + + //hJSONFinal.DumpToServer(); + + hJSONFinal.ToString(sFinal, sizeof(sFinal), 0); + + HTTPPostJSON(DISCORD_MAPWEBHOOK_URL, sFinal); + + delete hJSONFinal; +} + +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(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; +} + +public void EventHook_PlayerSay(Event hThis, const char[] sName, bool bDontBroadcast) +{ + int iUserID = GetEventInt(hThis, "userid"); + int iClient = GetClientOfUserId(iUserID); + char sMessageText[192]; + + GetEventString(hThis, "text", sMessageText, sizeof(sMessageText)); + + //PrintToServer("[EventHook_PlayerSay] Fired for %N: %s", iClient, sMessageText); + + TrimString(sMessageText); + + if (strlen(sMessageText) == 0) + return; + + char sClientName[64]; + + GetClientName(iClient, sClientName, sizeof(sClientName)); + + if (g_bGotReplaceFile) + { + char sPart[192]; + char sBuff[192]; + int CurrentIndex = 0; + int NextIndex = 0; + + while(NextIndex != -1 && CurrentIndex < sizeof(sMessageText)) + { + NextIndex = BreakString(sMessageText[CurrentIndex], sPart, sizeof(sPart)); + + KvGetString(g_hReplaceConfigFile, sPart, sBuff, sizeof(sBuff), NULL_STRING); + + if(sBuff[0]) + { + ReplaceString(sMessageText[CurrentIndex], sizeof(sMessageText) - CurrentIndex, sPart, sBuff); + CurrentIndex += strlen(sBuff); + } + else + CurrentIndex += NextIndex; + } + } + + if (g_bTeamChat) + { + if (sMessageText[0] == '@') + return; + + char sMessageFinal[256]; + char sTeamName[32]; + + GetTeamName(GetClientTeam(iClient), sTeamName, sizeof(sTeamName)); + + if (sTeamName[0] == 'C') + Format(sMessageFinal, sizeof(sMessageFinal), "(Counter-Terrorist) %s", sMessageText); + else if (sTeamName[0] == 'T') + Format(sMessageFinal, sizeof(sMessageFinal), "(Terrorist) %s", sMessageText); + else + Format(sMessageFinal, sizeof(sMessageFinal), "(Spectator) %s", sMessageText); + + if (g_sAvatarURL[iClient][0] != '\0') + Discord_POST(DISCORD_LIVEWEBHOOK_URL, sMessageFinal, true, sClientName, true, g_sAvatarURL[iClient]); + else + Discord_POST(DISCORD_LIVEWEBHOOK_URL, sMessageFinal, true, sClientName); + + return; + } + + if (g_sAvatarURL[iClient][0] != '\0') + Discord_POST(DISCORD_LIVEWEBHOOK_URL, sMessageText, true, sClientName, true, g_sAvatarURL[iClient]); + else + Discord_POST(DISCORD_LIVEWEBHOOK_URL, sMessageText, true, sClientName); +} + +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(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); + + if (bTimestamp) + { + int iTime = GetTime(); + char sTime[32]; + FormatTime(sTime, sizeof(sTime), "%r", iTime); + Format(sText, 2048, "[%s] %s", sTime, 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(hJSONRoot)).SetString("username", "Invalid Name"); + else + (view_as(hJSONRoot)).SetString("username", sUsername); + } + + if (bUsingAvatar) + (view_as(hJSONRoot)).SetString("avatar_url", sAvatarURL); + + if (bSafe) + { + Discord_MakeStringSafe(sText, sSafeText, sizeof(sSafeText)); + } + else + { + Format(sSafeText, sizeof(sSafeText), "%s", sText); + } + + (view_as(hJSONRoot)).SetString("content", sSafeText); + (view_as(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(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)) + { + LogError("Discord HTTP request failed: %d", eStatusCode); + + if (eStatusCode == k_EHTTPStatusCode400BadRequest) + { + char sData[2048]; + + (view_as(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 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 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 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 int entWatch_OnClientBanned(int admin, int iLenght, int client) +{ + char sUsername[MAX_NAME_LENGTH]; + GetClientName(client, sUsername, sizeof(sUsername)); + + char currentMap[64]; + GetCurrentMap(currentMap, sizeof(currentMap)); + + char sMessageTmp[4096]; + + if (iLenght == 0) + { + Format(sMessageTmp, sizeof(sMessageTmp), "%L got temporarily restricted by %L", client, admin); + } + else if (iLenght == -1) + { + Format(sMessageTmp, sizeof(sMessageTmp), "%L got PERMANENTLY restricted by %L", client, admin); + } + else + { + Format(sMessageTmp, sizeof(sMessageTmp), "%L got restricted by %L for %d minutes", client, admin, iLenght); + } + + + char sMessage[4096]; + Format(sMessage, sizeof(sMessage), "```%s - Tick: %d``````%s```", currentMap, GetGameTickCount(), sMessageTmp); + + if (g_sAvatarURL[client][0] != '\0') + Discord_POST(DISCORD_ENTWATCH_WEBHOOKURL, sMessage, true, sUsername, true, g_sAvatarURL[client], false); + else + Discord_POST(DISCORD_ENTWATCH_WEBHOOKURL, sMessage, true, sUsername, false, "", false); +} + +public int entWatch_OnClientUnbanned(int admin, int client) +{ + char sUsername[MAX_NAME_LENGTH]; + GetClientName(client, sUsername, sizeof(sUsername)); + + char currentMap[64]; + GetCurrentMap(currentMap, sizeof(currentMap)); + + char sMessageTmp[4096]; + Format(sMessageTmp, sizeof(sMessageTmp), "%L got unrestricted by %L", client, admin); + + char sMessage[4096]; + Format(sMessage, sizeof(sMessage), "```%s - Tick: %d``````%s```", currentMap, GetGameTickCount(), sMessageTmp); + + if (g_sAvatarURL[client][0] != '\0') + Discord_POST(DISCORD_ENTWATCH_WEBHOOKURL, sMessage, true, sUsername, true, g_sAvatarURL[client], false); + else + Discord_POST(DISCORD_ENTWATCH_WEBHOOKURL, sMessage, true, sUsername, false, "", false); +} diff --git a/includes/AntiBhopCheat.inc b/includes/AntiBhopCheat.inc new file mode 120000 index 00000000..05d85e1e --- /dev/null +++ b/includes/AntiBhopCheat.inc @@ -0,0 +1 @@ +../AntiBhopCheat/scripting/include/AntiBhopCheat.inc \ No newline at end of file