#include <sourcemod>
#include <SteamWorks>

#pragma semicolon 1
#pragma newdecls required

#include "SteamAPI.secret"

/* BOOLEANS */
bool g_bValid[MAXPLAYERS+1]     = {false, ...};
bool g_bValidated[MAXPLAYERS+1] = {false, ...};

/* FORWARDS */
Handle g_hFwd_OnClientProfileValidated;

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public Plugin myinfo =
{
	name        = "NoSteamDetection",
	author      = "zaCade",
	description = "Mark people as 'NoSteam' if their steam profiles are incorrect",
	version     = "1.0"
};

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public APLRes AskPluginLoad2(Handle myself, bool late, char [] error, int err_max)
{
	CreateNative("IsClientProfileValid",     Native_IsClientProfileValid);
	CreateNative("IsClientProfileValidated", Native_IsClientProfileValidated);

	RegPluginLibrary("NoSteamDetection");
	return APLRes_Success;
}

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnPluginStart()
{
	g_hFwd_OnClientProfileValidated = CreateGlobalForward("OnClientProfileValidated", ET_Ignore, Param_Cell, Param_Cell);

	for(int client = 1; client <= MaxClients; client++)
	{
		if(IsValidClient(client) && IsClientAuthorized(client))
			OnClientAuthorized(client, "");
	}
}

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnClientAuthorized(int client, const char[] auth)
{
	char sSteam64ID[32];
	GetClientAuthId(client, AuthId_SteamID64, sSteam64ID, sizeof(sSteam64ID));

	char sRequest[256];
	Format(sRequest, sizeof(sRequest), "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=%s&steamids=%s&format=vdf", STEAM_API_KEY, sSteam64ID);

	Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, sRequest);
	if (!hRequest ||
		!SteamWorks_SetHTTPCallbacks(hRequest, OnClientAuthorized_OnTransferComplete) ||
		!SteamWorks_SetHTTPRequestContextValue(hRequest, GetClientSerial(client)) ||
		!SteamWorks_SendHTTPRequest(hRequest))
	{
		delete hRequest;
	}
}


//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public int OnClientAuthorized_OnTransferComplete(Handle hRequest, bool bFailure, bool bSuccessful, EHTTPStatusCode eStatusCode, int serial)
{
	if (bFailure || !bSuccessful || eStatusCode != k_EHTTPStatusCode200OK)
	{
		delete hRequest;
		return;
	}

	SteamWorks_GetHTTPResponseBodyCallback(hRequest, OnClientAuthorized_OnTransferResponse, serial);
}

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public int OnClientAuthorized_OnTransferResponse(char[] sData, int serial)
{
	int client;
	if ((client = GetClientFromSerial(serial)) == 0)
		return;

	KeyValues Response = new KeyValues("SteamAPIResponse");

	if(!Response.ImportFromString(sData, "SteamAPIResponse"))
	{
		OnClientAuthorized_FinishCall(client, false);
		delete Response;
		return;
	}

	if(!Response.JumpToKey("players"))
	{
		OnClientAuthorized_FinishCall(client, false);
		delete Response;
		return;
	}

	if(!Response.GotoFirstSubKey())
	{
		OnClientAuthorized_FinishCall(client, false);
		delete Response;
		return;
	}

	if ((Response.GetNum("profilestate")) == 0)
	{
		OnClientAuthorized_FinishCall(client, false);
		delete Response;
		return;
	}

	OnClientAuthorized_FinishCall(client, true);
}

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnClientAuthorized_FinishCall(int client, bool valid)
{
	g_bValid[client]     = valid;
	g_bValidated[client] = true;

	Call_StartForward(g_hFwd_OnClientProfileValidated);
	Call_PushCell(client);
	Call_PushCell(valid);
	Call_Finish();
}

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnClientDisconnect(int client)
{
	g_bValid[client]     = false;
	g_bValidated[client] = false;
}

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public int Native_IsClientProfileValid(Handle hPlugin, int numParams)
{
	int client = GetNativeCell(1);

	if (!IsValidClient(client))
		return false;

	return g_bValid[client];
}

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public int Native_IsClientProfileValidated(Handle hPlugin, int numParams)
{
	int client = GetNativeCell(1);

	if (!IsValidClient(client))
		return false;

	return g_bValidated[client];
}

//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public bool IsValidClient(int client)
{
	if (client < 0)
		return false;

	if (client > GetMaxClients())
		return false;

	return true;
}