2019-09-23 17:25:44 +02:00
# pragma semicolon 1
# include <basecomm>
# include <sourcemod>
# include <SteamWorks>
# include <regex>
# include <smjansson>
# include <multicolors>
# include <sdktools>
2019-10-22 19:19:21 +02:00
# include <AFKManager>
2023-07-07 10:34:38 +02:00
# include <AutoRecorder>
2019-09-23 17:25:44 +02:00
# include <SteamAPI.secret>
# include <Discord.secret>
# tryinclude <AntiBhopCheat>
# tryinclude <calladmin>
2022-06-11 20:06:10 +02:00
# tryinclude <oryx>
2019-09-23 17:25:44 +02:00
# tryinclude <entWatch_restrictions>
2023-02-03 11:39:34 +01:00
# tryinclude <jenz_ban_detector>
2019-09-23 17:25:44 +02:00
# 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 ;
2019-10-22 19:19:21 +02:00
int g_iAdminAFKTime ;
ConVar g_cvAdminAFKTime ;
2019-09-23 17:25:44 +02:00
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 ) ;
}
2019-10-22 19:19:21 +02:00
public void OnAllPluginsLoaded ( )
{
if ( ( g_cvAdminAFKTime = FindConVar ( " sm_admin_afk_time " ) ) = = INVALID_HANDLE )
SetFailState ( " Failed to find sm_admin_afk_time cvar. " ) ;
else
g_iAdminAFKTime = g_cvAdminAFKTime . IntValue ;
HookConVarChange ( g_cvAdminAFKTime , OnAdminAFKTimeChanged ) ;
}
public void OnAdminAFKTimeChanged ( ConVar convar , const char [ ] oldValue , const char [ ] newValue )
{
g_iAdminAFKTime = g_cvAdminAFKTime . IntValue ;
}
2019-09-23 17:25:44 +02:00
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 )
2019-10-16 22:20:39 +02:00
CPrintToChat ( i , " {green}(DISCORD ADMINS) %s: {yellow}%s " , sArgs , sArgs2 ) ;
2019-09-23 17:25:44 +02:00
}
}
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 ) ) ;
2019-10-16 22:20:39 +02:00
CPrintToChatAll ( " {azure}[DISCORD] (ALL) %s: {white}%s " , sArgs , sArgs2 ) ;
2019-09-23 17:25:44 +02:00
return Plugin_Handled ;
}
public Action Timer_DataProcessor ( Handle hThis )
{
2023-08-29 18:10:57 +02:00
if ( ! g_bProcessingData )
return Plugin_Handled ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
if ( g_iRatelimitRemaining = = 0 & & GetTime ( ) < g_iRatelimitReset )
return Plugin_Handled ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
//PrintToServer("[Timer_DataProcessor] Array Length #1: %d", g_arrQueuedMessages.Length);
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
char sContent [ 1024 ] ;
g_arrQueuedMessages . GetString ( 0 , sContent , sizeof ( sContent ) ) ;
g_arrQueuedMessages . Erase ( 0 ) ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
char sURL [ 128 ] ;
g_arrQueuedMessages . GetString ( 0 , sURL , sizeof ( sURL ) ) ;
g_arrQueuedMessages . Erase ( 0 ) ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
if ( g_arrQueuedMessages . Length = = 0 )
g_bProcessingData = false ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
//PrintToServer("[Timer_DataProcessor] Array Length #2: %d", g_arrQueuedMessages.Length);
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
//PrintToServer("%s | %s", sURL, sContent);
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
Handle hRequest = SteamWorks_CreateHTTPRequest ( k_EHTTPMethodPOST , sURL ) ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
JSONObject RequestJSON = view_as < JSONObject > ( json_load ( sContent ) ) ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
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. " ) ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
delete RequestJSON ;
delete hRequest ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
return Plugin_Handled ;
}
return Plugin_Handled ;
2019-09-23 17:25:44 +02:00
}
2023-08-29 18:10:57 +02:00
public Action Hook_UserMessage ( UserMsg msg_id , Handle bf , const int [ ] 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 Plugin_Handled ;
if ( strlen ( sMessageName ) = = 0 | | strlen ( sMessageSender ) = = 0 )
return Plugin_Handled ;
if ( strcmp ( sMessageName , " #Cstrike_Name_Change " ) = = 0 )
return Plugin_Handled ;
if ( sMessageName [ 13 ] = = 'C' | | sMessageName [ 13 ] = = 'T' | | sMessageName [ 13 ] = = 'S' )
g_bTeamChat = true ;
else
g_bTeamChat = false ;
return Plugin_Handled ;
2019-09-23 17:25:44 +02:00
}
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 )
{
2023-08-29 18:10:57 +02:00
if ( bFailure | | ! bRequestSuccessful | | eStatusCode ! = k_EHTTPStatusCode200OK )
{
if ( eStatusCode ! = k_EHTTPStatusCode429TooManyRequests )
{
LogError ( " SteamAPI HTTP Response failed: %d " , eStatusCode ) ;
}
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
delete hRequest ;
return 0 ;
}
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
int iBodyLength ;
SteamWorks_GetHTTPResponseBodySize ( hRequest , iBodyLength ) ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
char [ ] sData = new char [ iBodyLength ] ;
SteamWorks_GetHTTPResponseBodyData ( hRequest , sData , iBodyLength ) ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
delete hRequest ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
APIWebResponse ( sData , client ) ;
return 0 ;
2019-09-23 17:25:44 +02:00
}
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 )
{
2023-08-29 18:10:57 +02:00
if ( bFailure | | ! bRequestSuccessful | | ( eStatusCode ! = k_EHTTPStatusCode200OK & & eStatusCode ! = k_EHTTPStatusCode204NoContent ) )
{
if ( eStatusCode ! = k_EHTTPStatusCode429TooManyRequests )
LogError ( " Discord HTTP request failed: %d " , eStatusCode ) ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
if ( eStatusCode = = k_EHTTPStatusCode400BadRequest )
{
char sData [ 2048 ] ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
( view_as < JSONRootNode > ( RequestJSON ) ) . ToString ( sData , sizeof ( sData ) , 0 ) ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
LogError ( " Malformed request? Dumping request data: \n %s " , sData ) ;
}
else if ( eStatusCode = = k_EHTTPStatusCode429TooManyRequests )
{
g_iRatelimitRemaining = 0 ;
g_iRatelimitReset = GetTime ( ) + 5 ;
}
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
delete RequestJSON ;
delete hRequest ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
return 0 ;
}
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
static int iLastRatelimitRemaining = 0 ;
static int iLastRatelimitReset = 0 ;
char sTmp [ 32 ] ;
bool bHeaderExists = SteamWorks_GetHTTPResponseHeaderValue ( hRequest , " x-ratelimit-remaining " , sTmp , sizeof ( sTmp ) ) ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
if ( ! bHeaderExists )
LogError ( " x-ratelimit-remaining header value could not be retrieved " ) ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
int iRatelimitRemaining = StringToInt ( sTmp ) ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
bHeaderExists = SteamWorks_GetHTTPResponseHeaderValue ( hRequest , " x-ratelimit-reset " , sTmp , sizeof ( sTmp ) ) ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
if ( ! bHeaderExists )
LogError ( " x-ratelimit-reset header value could not be retrieved " ) ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
int iRatelimitReset = StringToInt ( sTmp ) ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
if ( iRatelimitRemaining < iLastRatelimitRemaining | | iRatelimitReset > = iLastRatelimitReset ) //don't be fooled by different completion times
{
g_iRatelimitRemaining = iRatelimitRemaining ;
g_iRatelimitReset = iRatelimitReset ;
}
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
//PrintToServer("limit: %d | remaining: %d || reset %d - now %d", g_iRatelimitLimit, g_iRatelimitRemaining, g_iRatelimitReset, GetTime());
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
delete RequestJSON ;
delete hRequest ;
return 0 ;
2019-09-23 17:25:44 +02:00
}
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 )
{
2023-08-29 18:10:57 +02:00
if ( client < = 0 )
return Plugin_Handled ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
if ( ( StrContains ( sMsg , " sm_psay " , false ) ! = - 1 ) | | ( StrContains ( sMsg , " sm_chat " , false ) ! = - 1 ) )
return Plugin_Handled ; // dont log sm_psay and sm_chat
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
char sFinal [ 256 ] ;
char sCurrentMap [ 32 ] ;
char sDemoInfo [ 64 ] ;
char sClientName [ 64 ] ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
GetCurrentMap ( sCurrentMap , sizeof ( sCurrentMap ) ) ;
2023-07-07 13:59:22 +02:00
2023-08-29 18:10:57 +02:00
if ( IsDemoRecording ( ) )
Format ( sDemoInfo , sizeof ( sDemoInfo ) , " Demo: %d @ Tick: %d " , GetDemoRecordingNumber ( ) , GetDemoRecordingTick ( ) ) ;
else
Format ( sDemoInfo , sizeof ( sDemoInfo ) , " Not recording " ) ;
2023-07-07 13:59:22 +02:00
2023-08-29 18:10:57 +02:00
Format ( sFinal , sizeof ( sFinal ) , " [ %s ][ %s ]```%s``` " , sCurrentMap , sDemoInfo , sMsg ) ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
GetClientName ( client , sClientName , sizeof ( sClientName ) ) ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
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 ) ;
2019-09-23 17:25:44 +02:00
2023-08-29 18:10:57 +02:00
return Plugin_Handled ;
2019-09-23 17:25:44 +02:00
}
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 ;
}
2023-02-03 11:39:34 +01:00
public void BanDetectorPost ( int client , const char [ ] detected_sourceban )
{
char sClientName [ MAX_NAME_LENGTH ] ;
char sClientID [ 21 ] ;
GetClientName ( client , sClientName , sizeof ( sClientName ) ) ;
GetClientAuthId ( client , AuthId_Steam2 , sClientID , sizeof ( sClientID ) ) ;
char currentMap [ 64 ] ;
GetCurrentMap ( currentMap , sizeof ( currentMap ) ) ;
char sMessage [ 1900 ] ;
char sAuthID64 [ 32 ] ;
if ( ! Steam32IDtoSteam64ID ( sClientID , sAuthID64 , sizeof ( sAuthID64 ) ) )
return ;
Format ( sMessage , sizeof ( sMessage ) , " https://steamcommunity.com/profiles/%s \n Name: %s \n SteamID: %s \n Client is ban avoiding the ban: https://bans.unloze.com/index.php?p=banlist&searchText=%s&Submit=Search " , sAuthID64 , sClientName , sClientID , detected_sourceban ) ;
if ( g_sAvatarURL [ client ] [ 0 ] ! = '\0' )
Discord_POST ( DISCORD_BAN_DETECTOR , sMessage , true , sClientName , true , g_sAvatarURL [ client ] , false ) ;
else
Discord_POST ( DISCORD_BAN_DETECTOR , sMessage , true , sClientName , false , " " , false ) ;
}
2019-09-23 17:25:44 +02:00
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 ) ) ;
2019-10-22 19:19:21 +02:00
bool ActiveAdmins = false ;
for ( int i = 1 ; i < = MaxClients ; i + + )
{
if ( IsClientInGame ( i ) & & ( CheckCommandAccess ( i , " " , ADMFLAG_GENERIC , true ) ) & & GetClientIdleTime ( i ) < g_iAdminAFKTime )
{
ActiveAdmins = true ;
break ;
}
}
2022-06-16 22:17:35 +02:00
char sMessage [ 1900 ] ;
2019-10-22 19:19:21 +02:00
if ( ActiveAdmins )
Format ( sMessage , sizeof ( sMessage ) , " ```***ACTIVE ADMINS IN-GAME***`````` \n %s - Tick: %d``````New report on server: %s (%s:%d) \n ReportID: %d \n Reporter: %s (%s) \n Target: %s (%s) \n Reason: %s \n Join Server: steam://connect/%s:%d \n when 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 ) ;
else
Format ( sMessage , sizeof ( sMessage ) , " @here ```***NO ACTIVE ADMINS IN-GAME***`````` \n %s - Tick: %d``````New report on server: %s (%s:%d) \n ReportID: %d \n Reporter: %s (%s) \n Target: %s (%s) \n Reason: %s \n Join Server: steam://connect/%s:%d \n when 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 ) ;
2019-09-23 17:25:44 +02:00
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 ;
}
2022-06-16 22:17:35 +02:00
char sMessage [ 1900 ] ;
2019-09-23 17:25:44 +02:00
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 ) ;
}
2022-06-11 20:06:10 +02:00
//'
2023-07-09 14:16:54 +02:00
/ *
2022-06-11 20:06:10 +02:00
public Action Oryx_OnTrigger ( int client , int & level , char [ ] cheat )
{
char sUsername [ MAX_NAME_LENGTH ] ;
GetClientName ( client , sUsername , sizeof ( sUsername ) ) ;
char currentMap [ 64 ] ;
GetCurrentMap ( currentMap , sizeof ( currentMap ) ) ;
2022-06-11 23:00:53 +02:00
char sAuthID [ 32 ] ;
GetClientAuthId ( client , AuthId_Steam2 , sAuthID , sizeof ( sAuthID ) , false ) ;
2022-06-16 22:17:35 +02:00
char sMessage [ 1900 ] ;
2022-06-11 23:00:53 +02:00
Format ( sMessage , sizeof ( sMessage ) , " ```%s - Tick: %d``````NAME: %N \n STEAMID: %s \n TRIGGER LEVEL: %i \n %s``` " , currentMap , GetGameTickCount ( ) , client , sAuthID , level , cheat ) ;
2022-06-11 20:06:10 +02:00
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 ) ;
return Plugin_Continue ;
}
2023-07-09 14:16:54 +02:00
* /
2019-09-23 17:25:44 +02:00
public void AntiBhopCheat_OnClientDetected ( int client , char [ ] sReason , char [ ] sStats )
{
2023-07-09 14:16:54 +02:00
char sCurrentMap [ 64 ] ;
GetCurrentMap ( sCurrentMap , sizeof ( sCurrentMap ) ) ;
2019-09-23 17:25:44 +02:00
2023-07-09 14:16:54 +02:00
char sDemoInfo [ 64 ] ;
if ( IsDemoRecording ( ) )
Format ( sDemoInfo , sizeof ( sDemoInfo ) , " Demo: %d @ Tick: %d " , GetDemoRecordingNumber ( ) , GetDemoRecordingTick ( ) ) ;
else
Format ( sDemoInfo , sizeof ( sDemoInfo ) , " Not recording " ) ;
2019-09-23 17:25:44 +02:00
2023-07-09 14:16:54 +02:00
char sTrimmedStats [ 1792 ] ; // 128 x 14
strcopy ( sTrimmedStats , sizeof ( sTrimmedStats ) , sStats ) ;
char sMessage [ 1920 ] ; // 128 x 15
Format ( sMessage , sizeof ( sMessage ) , " [ %s ][ %s ]```%s \n %s``` " , sCurrentMap , sDemoInfo , sReason , sTrimmedStats ) ;
char sUsername [ MAX_NAME_LENGTH ] ;
GetClientName ( client , sUsername , sizeof ( sUsername ) ) ;
2019-09-23 17:25:44 +02:00
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 )
{
2023-07-09 14:16:54 +02:00
char sCurrentMap [ 64 ] ;
GetCurrentMap ( sCurrentMap , sizeof ( sCurrentMap ) ) ;
2019-09-23 17:25:44 +02:00
2023-07-09 14:16:54 +02:00
char sDemoInfo [ 64 ] ;
if ( IsDemoRecording ( ) )
Format ( sDemoInfo , sizeof ( sDemoInfo ) , " Demo: %d @ Tick: %d " , GetDemoRecordingNumber ( ) , GetDemoRecordingTick ( ) ) ;
else
Format ( sDemoInfo , sizeof ( sDemoInfo ) , " Not recording " ) ;
2019-09-23 17:25:44 +02:00
2023-07-09 14:16:54 +02:00
char sMessageTemp [ 1280 ] ; // 128 x 10
2019-09-23 17:25:44 +02:00
if ( length = = - 1 )
2023-07-09 14:16:54 +02:00
Format ( sMessageTemp , sizeof ( sMessageTemp ) , " %L got temporarily restricted by %L " , target , client ) ;
2019-09-23 17:25:44 +02:00
else if ( length = = 0 )
2023-07-09 14:16:54 +02:00
Format ( sMessageTemp , sizeof ( sMessageTemp ) , " %L got permanently restricted by %L " , target , client ) ;
2019-09-23 17:25:44 +02:00
else
2023-07-09 14:16:54 +02:00
Format ( sMessageTemp , sizeof ( sMessageTemp ) , " %L got restricted by %L for %d minutes " , target , client , length ) ;
2019-09-23 17:25:44 +02:00
2023-07-09 14:16:54 +02:00
char sMessage [ 1920 ] ; // 128 x 15
Format ( sMessage , sizeof ( sMessage ) , " [ %s ][ %s ]```%s``` " , sCurrentMap , sDemoInfo , sMessageTemp ) ;
2019-09-23 17:25:44 +02:00
2023-07-09 14:16:54 +02:00
char sUsername [ MAX_NAME_LENGTH ] ;
GetClientName ( client , sUsername , sizeof ( sUsername ) ) ;
2019-09-23 17:25:44 +02:00
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 )
{
2023-07-09 14:16:54 +02:00
char sCurrentMap [ 64 ] ;
GetCurrentMap ( sCurrentMap , sizeof ( sCurrentMap ) ) ;
2019-09-23 17:25:44 +02:00
2023-07-09 14:16:54 +02:00
char sDemoInfo [ 64 ] ;
if ( IsDemoRecording ( ) )
Format ( sDemoInfo , sizeof ( sDemoInfo ) , " Demo: %d @ Tick: %d " , GetDemoRecordingNumber ( ) , GetDemoRecordingTick ( ) ) ;
else
Format ( sDemoInfo , sizeof ( sDemoInfo ) , " Not recording " ) ;
2019-09-23 17:25:44 +02:00
2023-07-09 14:16:54 +02:00
char sMessageTemp [ 1280 ] ; // 128 x 10
Format ( sMessageTemp , sizeof ( sMessageTemp ) , " %L got unrestricted by %L " , target , client ) ;
2019-09-23 17:25:44 +02:00
2023-07-09 14:16:54 +02:00
char sMessage [ 1920 ] ; // 128 x 15
Format ( sMessage , sizeof ( sMessage ) , " [ %s ][ %s ]```%s``` " , sCurrentMap , sDemoInfo , sMessageTemp ) ;
char sUsername [ MAX_NAME_LENGTH ] ;
GetClientName ( client , sUsername , sizeof ( sUsername ) ) ;
2019-09-23 17:25:44 +02:00
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 ) ;
2023-02-03 11:39:34 +01:00
}