#pragma semicolon 1

#define PLUGIN_AUTHOR "null138"
#define PLUGIN_VERSION "1.00"

#include <sourcemod>
#include <sdktools>
#include <dhooks>
// linux
#define GetPlayerSlotOffs 3
#pragma newdecls required
Handle hExecuteStringCommand;
Handle hGetPlayerSlot;

public Plugin myinfo = 
{
	name = "cmd reader",
	author = PLUGIN_AUTHOR,
	description = "reads all client cmd commands",
	version = PLUGIN_VERSION,
	url = "https://steamcommunity.com/id/null138/"
}

//written by madness
public void OnPluginStart()
{
	Handle conf = LoadGameConfigFile("readcmds.css");
	if (conf == INVALID_HANDLE)
		SetFailState("Failed to load gamedata readcmds.css");
	
	hExecuteStringCommand = DHookCreateDetour(Address_Null, CallConv_THISCALL, ReturnType_Bool, ThisPointer_Address);
	if (!hExecuteStringCommand)
		SetFailState("Failed to setup detour for CGameClient::ExecuteStringCommand()");
	
	if (!DHookSetFromConf(hExecuteStringCommand, conf, SDKConf_Signature, "CGameClient::ExecuteStringCommand()"))
		SetFailState("Failed to load CGameClient::ExecuteStringCommand() signature from gamedata");
	
	DHookAddParam(hExecuteStringCommand, HookParamType_CharPtr);
	
	if (!DHookEnableDetour(hExecuteStringCommand, false, ExecuteStringCommand))
		SetFailState("Failed to detour CGameClient::ExecuteStringCommand()");

	// And a post hook.
	if (!DHookEnableDetour(hExecuteStringCommand, true, Detour_OnExecuteStringCommand_Post))
		SetFailState("Failed to detour ExecuteStringCommand post.");

	 // Setup quick hack to get the client index of the IClient this pointer in the detour callback.
	StartPrepSDKCall(SDKCall_Raw);
        PrepSDKCall_SetVirtual(GetPlayerSlotOffs);
        PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain);
        hGetPlayerSlot = EndPrepSDKCall();
	delete conf;
}


public MRESReturn Detour_OnExecuteStringCommand_Post(Address pThis, Handle hReturn, Handle hParams)
{
    int client = SDKCall(hGetPlayerSlot, pThis) + 1;
    char sBuffer[512];
    DHookGetParamString(hParams, 1, sBuffer, sizeof(sBuffer));
    if((sBuffer[0] == 'r' && sBuffer[1] == 'p' && sBuffer[2] == 't'))
        {
                if(IsClientInGame(client) && !IsClientSourceTV(client))
		{
			 LogMessage("client: %N wanted command pre: %s", client, sBuffer);
			 KickClient(client, "DO NOT USE EXPLOITS ON THIS SERVER"); 
		}
        }

}  


public MRESReturn ExecuteStringCommand(Address addrThis, Handle hReturn, Handle hParams) 
{
	int client = SDKCall(hGetPlayerSlot, addrThis) + 1;
	
	char cmd[512];
	DHookGetParamString(hParams, 1, cmd, 512);
	// "rpt", "rpt_"
	if((cmd[0] == 'r' && cmd[1] == 'p' && cmd[2] == 't'))
	{
		if(IsClientInGame(client) && !IsClientSourceTV(client)) 
		{
			LogMessage("client: %N wanted command pre: %s", client, cmd);
			KickClient(client, "DO NOT USE EXPLOITS ON THIS SERVER");
		}
	}
	return MRES_Ignored;
}