#include #include #include #include #define PLUGIN "HLKZ Discord WR Notifier" #define VERSION "1.0.0" #define AUTHOR "Th3-822" new const g_iTopList = 5; // Max entries to show on webhook new const g_iTopListMinimum = 1; // Minimum entries on top to trigger webhook new const g_szWRecType[][] = {"Pure", "Pro"}; new const g_szTLPrefix[][] = {"++-", "--+", "**-", "---"}; new CURL:g_cURLHandle, curl_slist:g_cURLHeaders; new bool:g_bIsWorking new g_cvar_webhook, g_cvar_bot_name, g_cvar_bot_avatar; new g_szMapName[64]; public plugin_init() { register_plugin(PLUGIN, VERSION, AUTHOR); g_cvar_webhook = register_cvar("kz_discord_webhook", ""); g_cvar_bot_name = register_cvar("kz_discord_bot_name", "HL KreedZ"); g_cvar_bot_avatar = register_cvar("kz_discord_bot_avatar", "http://212.71.238.124/hlkz/hlkz.png"); get_mapname(g_szMapName, charsmax(g_szMapName)); } public plugin_end() { if (g_cURLHandle) { curl_easy_cleanup(g_cURLHandle); g_cURLHandle = CURL:0; } if (g_cURLHeaders) { curl_slist_free_all(g_cURLHeaders); g_cURLHeaders = SList_Empty; } } public hlkz_worldrecord(id, Float:flWRecTime, iWRecType, Array:arTop) { static iTopSize; if (g_bIsWorking || !(0 <= iWRecType <= 1) || (iTopSize = ArraySize(arTop)) < g_iTopListMinimum) { return; } static szURL[128]; if (get_pcvar_string(g_cvar_webhook, szURL, charsmax(szURL)) < 123) { log_amx("Invalid Webhook URL?"); return; } static szBuffer[128], sTopEntry[STATS], szMessage[2001], iMsgLen, szDate[11], iMinutes, Float:flSeconds; new JSON:jWebhook = json_init_object(); if (get_pcvar_string(g_cvar_bot_name, szBuffer, charsmax(szBuffer))) { json_object_set_string(jWebhook, "username", szBuffer); } if (get_pcvar_string(g_cvar_bot_avatar, szBuffer, charsmax(szBuffer))) { json_object_set_string(jWebhook, "avatar_url", szBuffer); } for (new i, iTop = min(iTopSize, g_iTopList); i < iTop; i++) { ArrayGetArray(arTop, i, sTopEntry); replace_string(sTopEntry[STATS_NAME], charsmax(sTopEntry[STATS_NAME]), "`", "'"); floatToMinSec(sTopEntry[STATS_TIME], iMinutes, flSeconds); if (!i) { copy(szBuffer, charsmax(szBuffer), sTopEntry[STATS_NAME]); replace_string(szBuffer, charsmax(szBuffer), "\", "\\"); replace_string(szBuffer, charsmax(szBuffer), "~", "\~"); replace_string(szBuffer, charsmax(szBuffer), "*", "\*"); replace_string(szBuffer, charsmax(szBuffer), "@", "\@"); iMsgLen = formatex(szMessage, charsmax(szMessage), "[HLKZ] **%s** has now the %s WR for **%s**! Finished in **%02d:%06.3f**^n^n**Top %d %s @ %s**^n```diff", szBuffer, g_szWRecType[iWRecType], g_szMapName, iMinutes, flSeconds, g_iTopList, g_szWRecType[iWRecType], g_szMapName); } format_time(szDate, charsmax(szDate), "%d/%m/%Y", sTopEntry[STATS_TIMESTAMP]); iMsgLen += formatex(szMessage[iMsgLen], charsmax(szMessage) - iMsgLen, "^n%s %-2d %31s %02d:%06.3f @ %s", g_szTLPrefix[min(i, charsmax(g_szTLPrefix))], i + 1, sTopEntry[STATS_NAME], iMinutes, flSeconds, szDate); } iMsgLen += formatex(szMessage[iMsgLen], charsmax(szMessage) - iMsgLen, "```"); json_object_set_string(jWebhook, "content", szMessage); postJSON(szURL, jWebhook); json_free(jWebhook); } floatToMinSec(const Float:flTime, &iMinutes, &Float:flSeconds) { iMinutes = floatround(flTime, floatround_floor) / 60; flSeconds = flTime - (60 * iMinutes); } postJSON(const szUrl[], JSON:jData) { if (!g_cURLHandle) { if (!(g_cURLHandle = curl_easy_init())) { set_fail_state("Cannot init cURL's Handle."); } if (!g_cURLHeaders) { if (!(g_cURLHeaders = curl_slist_append(SList_Empty, "Content-Type: application/json"))) { set_fail_state("Cannot init cURL's Headers."); } curl_slist_append(g_cURLHeaders, "User-Agent: 822_AMXX_PLUGIN/1.1"); // User-Agent curl_slist_append(g_cURLHeaders, "Connection: Keep-Alive"); // Keep-Alive } // Static Options curl_easy_setopt(g_cURLHandle, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(g_cURLHandle, CURLOPT_SSL_VERIFYHOST, 0); curl_easy_setopt(g_cURLHandle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); curl_easy_setopt(g_cURLHandle, CURLOPT_FAILONERROR, 0); curl_easy_setopt(g_cURLHandle, CURLOPT_FOLLOWLOCATION, 0); curl_easy_setopt(g_cURLHandle, CURLOPT_FORBID_REUSE, 0); curl_easy_setopt(g_cURLHandle, CURLOPT_FRESH_CONNECT, 0); curl_easy_setopt(g_cURLHandle, CURLOPT_CONNECTTIMEOUT, 10); curl_easy_setopt(g_cURLHandle, CURLOPT_TIMEOUT, 10); curl_easy_setopt(g_cURLHandle, CURLOPT_HTTPHEADER, g_cURLHeaders); curl_easy_setopt(g_cURLHandle, CURLOPT_POST, 1); } static szPostData[4096]; json_serial_to_string(jData, szPostData, charsmax(szPostData)); curl_easy_setopt(g_cURLHandle, CURLOPT_URL, szUrl); curl_easy_setopt(g_cURLHandle, CURLOPT_COPYPOSTFIELDS, szPostData); g_bIsWorking = true; curl_easy_perform(g_cURLHandle, "postJSON_done"); } public postJSON_done(CURL:curl, CURLcode:code) { g_bIsWorking = false; if (code == CURLE_OK) { static iStatusCode; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, iStatusCode); if (iStatusCode >= 400) { log_amx("[Error] HTTP Error: %d", iStatusCode); } } else { log_amx("[Error] cURL Error: %d", code); curl_easy_cleanup(g_cURLHandle); g_cURLHandle = CURL:0; } }