[CS: Source] Система рангов в синхронизации HLSTATSX

  • Автор темы console1988
  • Дата начала
Статус
В этой теме нельзя размещать новые ответы.
C

console1988

Ищу скриптёра, который синхронизирует мой HLSTATSX через плагин, который будет проверять KD игрока и в соответствии с его отношением убийств смертей выдавать звание как в CSGO:
зоны отображения званий:
1. Клантег. Но чтобы во время убийств они не отображались
2. Перехватить все STEAM аватарки в TAB и вставлять туда свои картинки
3. Для высоких званий приветствие при входе на сервере и замена цвета чата
4. Также нужно чтобы в начале раунда зоне keyhint выводилась общая позиция игрока его звание по KD и звание по колву убийств (а если игрок умер. Мог посмотреть у играющих позицию и звание з.ы. стиль gameME)

Если пункт 2 не выполним в SM приму реализацию в Metamod

цена договорная.
Отписывайте в теме ваши варианты если что отпишу в личные сообщения
 

Danyas

Участник
Сообщения
2,173
Реакции
1,072
Для тех кто возьмется:
PHP:
#pragma semicolon 1
 
#include <sourcemod>
 
#define NAME "HLstatsX:CE SQL API for Sourcemod"
#define VERSION "0.5 alpha"
 
#define RANKINGTYPE_SKILL 0
#define RANKINGTYPE_KILLS 1

enum HLXCE_PlayerData
{
	PData_Skill,
	PData_Kills,
	PData_Deaths,
	PData_Headshots,
	PData_Conntime,
	PData_Shots,
	PData_Hits,
	PData_Rank
}

#define DEBUG 0
 
public Plugin:myinfo = {
	name = NAME,
	author = "psychonic // Fix by DoPe^",
	description = "Provides easy access to HLX:CE data via Sourcemod",
	version = VERSION,
	url = "http://www.hlxcommunity.com"
};

new g_iClientHLXPlayerId[MAXPLAYERS+1] = { -1, ... };
new Handle:g_hFwdHLXClientReady;
new Handle:g_hFwdHLXGotPlayerData;
new Handle:g_hHLXDatabase = INVALID_HANDLE;
new Handle:g_hCvarServerIp;
new Handle:g_hCvarServerPort;
new Handle:g_hCvarGameCode;
new String:g_szHLXGameCode[33];
new g_iGameCodeLen;
new String:g_szRankingType[2][] = { "skill", "kills" };
new g_iRankingType;
new g_iPlayerCounts[MAXPLAYERS+1][HLXCE_PlayerData];
 
public OnPluginStart()
{
	#if DEBUG == 1
		LogToGame("[HLX-API] Plugin Started");
	#endif
	
	CreateConVar("hlxce_api_version", VERSION, NAME, FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY);
	g_hCvarServerIp = CreateConVar("hlxce_api_serverip", "", "Server IP Override (only needed if IP on commandline doesn't match IP in HLXCE)", FCVAR_PLUGIN);
	g_hCvarServerPort = CreateConVar("hlxce_api_serverport", "0", "Server Port Override (only needed if port on commandline doesn't match port in HLXCE)", FCVAR_PLUGIN);
	g_hCvarGameCode = CreateConVar("hlxce_api_gamecode", "", "Game Code Override (only needed if your game code is not being auto-detected)", FCVAR_PLUGIN);
	
	g_hFwdHLXClientReady = CreateGlobalForward("HLXCE_OnClientReady", ET_Ignore, Param_Cell);
	g_hFwdHLXGotPlayerData = CreateGlobalForward("HLXCE_OnGotPlayerData", ET_Ignore, Param_Cell, Param_Array);

	// Initiate Database
	InitDB();
}

#if SOURCEMOD_V_MAJOR >= 1 && SOURCEMOD_V_MINOR >= 3
public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
#else
public bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max)
#endif
{
	RegPluginLibrary("hlxce-sm-api");
	
	CreateNative("HLXCE_GetPlayerData", Native_HLXCE_GetPlayerData);
	CreateNative("HLXCE_IsClientReady", Native_HLXCE_IsClientReady);
	
#if SOURCEMOD_V_MAJOR >= 1 && SOURCEMOD_V_MINOR >= 3
	return APLRes_Success;
#else
	return true;
#endif
}

//public OnConfigsExecuted()
//{
//	if (g_hHLXDatabase == INVALID_HANDLE)
//	{
//		SQL_TConnect(OnConnectedToDatabase, "hlxce");
//	}
//}

public InitDB()
{
	if (g_hHLXDatabase == INVALID_HANDLE)
	{
		SQL_TConnect(OnConnectedToDatabase, "hlxce");
	}
}

public OnConnectedToDatabase(Handle:owner, Handle:hndl, const String:error[], any:data)
{	
	if (hndl == INVALID_HANDLE)
	{
		SetFailState("Cannot connect to database");
	}
	
	#if DEBUG == 1
		LogToGame("[HLX-API] Connected to database");
	#endif
	
	g_hHLXDatabase = hndl;
	
	// If gamecode is specified in hlxce_api_gamecode, use it and skip query for it
	decl String:szGameOverride[33];
	GetConVarString(g_hCvarGameCode, szGameOverride, sizeof(szGameOverride));
	
	if (strcmp("", szGameOverride) != 0)
	{
		strcopy(g_szHLXGameCode, sizeof(g_szHLXGameCode), szGameOverride);
		g_iGameCodeLen = strlen(g_szHLXGameCode);
		GetRankingType();
	}
	else
	{
		// If server ip is specified in hlxce_api_serverip, use that instead of attempting to auto-detect
		decl String:szServerIp[16];
		GetConVarString(g_hCvarServerIp, szServerIp, sizeof(szServerIp));
		if (strcmp("", szServerIp) == 0)
		{
			new iIp = GetConVarInt(FindConVar("hostip"));
			//thx Tsunami
			Format(szServerIp, sizeof(szServerIp), "%i.%i.%i.%i",
				(iIp >> 24) & 0x000000FF,
				(iIp >> 16) & 0x000000FF,
				(iIp >>  8) & 0x000000FF,
				(iIp & 0x000000FF));
		}
		
		// If server port is specified in hlxce_api_serverport, use that instead of attempting to auto-detect
		new iPort = GetConVarInt(g_hCvarServerPort);
		if (iPort == 0)
		{
			iPort = GetConVarInt(FindConVar("hostport"));
		}
	
		decl String:szQueryText[80];
		// should return no more than one row because address/port is a unique key
		Format(szQueryText, sizeof(szQueryText), "SELECT game FROM hlstats_Servers WHERE address='%s' AND port=%d", szServerIp, iPort);
		
		#if DEBUG == 1
			LogToGame("[HLX-API] Sending query \"%s\"", szQueryText);
		#endif
		
		SQL_TQuery(g_hHLXDatabase, OnGotGameCode, szQueryText);
	}
}

public OnGotGameCode(Handle:owner, Handle:hndl, const String:error[], any:client)
{	
	if (hndl == INVALID_HANDLE)
	{
		SetFailState("Game code query failed (no handle)");
	}
	
	if (SQL_GetRowCount(hndl) < 1)
	{
		SetFailState("Game code query failed (not found)");
	}
	
	#if DEBUG == 1
		LogToGame("[HLX-API] Got game code from lookup");
	#endif
	
	SQL_FetchRow(hndl);
	SQL_FetchString(hndl, 0, g_szHLXGameCode, sizeof(g_szHLXGameCode));
	g_iGameCodeLen = strlen(g_szHLXGameCode);
	
	#if DEBUG == 1
		LogToGame("[HLX-API] Game code is %s, len %d", g_szHLXGameCode, g_iGameCodeLen);
		LogToGame("[HLX-API] Sending query \"SELECT `value` FROM hlstats_Options WHERE `keyname`='rankingtype'\"");
	#endif
	
	// so far, so good. now we have to get/cache ranking type. then we can lookup everyone's id.
	GetRankingType();
}

GetRankingType()
{
	SQL_TQuery(g_hHLXDatabase, OnGotRankingType, "SELECT `value` FROM hlstats_Options WHERE `keyname`='rankingtype'");
}

public OnGotRankingType(Handle:owner, Handle:hndl, const String:error[], any:client)
{
	if (hndl == INVALID_HANDLE)
	{
		SetFailState("Ranking type lookup failed (no handle)");
	}
	
	if (SQL_GetRowCount(hndl) < 1)
	{
		SetFailState("Ranking type lookup failed (no rows)");
	}
	
	#if DEBUG == 1
		LogToGame("[HLX-API] Got Ranking Type");
	#endif
	
	decl String:szTempRankingType[6];
	SQL_FetchRow(hndl); // should only be one row returned. we don't care if there are more.
	SQL_FetchString(hndl, 0, szTempRankingType, sizeof(szTempRankingType));
	
	if (strcmp(szTempRankingType, g_szRankingType[RANKINGTYPE_KILLS], false) == 0)
	{
		g_iRankingType = RANKINGTYPE_KILLS;
	}
	
	#if DEBUG == 1
		LogToGame("[HLX-API] Ranking type is %d (skill:0;kills:1)", g_iRankingType);
	#endif
	
	// Got all startup info we need, now let's get hlx player ids for everyone in game
	GetAllPlayerIds();
}

public OnClientPostAdminCheck(client)
{
	GetClientHLXPlayerId(client);
}

public OnClientDisconnect(client)
{
	g_iClientHLXPlayerId[client] = -1;
}

public Native_HLXCE_IsClientReady(Handle:plugin, numParams)
{
	if (g_iClientHLXPlayerId[GetNativeCell(1)] > -1)
	{
		return true;
	}
	
	return false;
}

GetClientHLXPlayerId(client)
{
	if (g_hHLXDatabase == INVALID_HANDLE)
	{
		SetFailState("Lost database connection");
	}
	
	if (IsClientInGame(client) && IsClientConnected(client) && !IsFakeClient(client))
	{
		decl String:szAuthId[32];
		if (GetClientAuthString(client, szAuthId, sizeof(szAuthId)))
		{
			decl String:szAuthIdEsc[49];
			new iAuthIdLen;
			SQL_EscapeString(g_hHLXDatabase, szAuthId[8], szAuthIdEsc, sizeof(szAuthIdEsc), iAuthIdLen);
			new iQSize = 75+iAuthIdLen+g_iGameCodeLen;
			decl String:szPlayerIdQuery[iQSize];
			// should return no more than 1 row between game/uniqueId is a unique key
			Format(szPlayerIdQuery, iQSize, "SELECT playerId FROM hlstats_PlayerUniqueIds WHERE game='%s' AND uniqueId='%s'", g_szHLXGameCode, szAuthIdEsc);
			#if DEBUG == 1
				LogToGame("[HLX-API] Sending query \"%s\"", szPlayerIdQuery);
			#endif
			SQL_TQuery(g_hHLXDatabase, OnGotClientHLXPlayerId, szPlayerIdQuery, GetClientUserId(client));
		}
	}
	#if DEBUG == 1
	else
	{
		LogToGame("[HLX-API] Player %N not in game, not connected, or is bot", client);
	}
	#endif
}

public OnGotClientHLXPlayerId(Handle:owner, Handle:hndl, const String:error[], any:userid)
{
	new client = GetClientOfUserId(userid);
	if (client == 0 || !IsClientInGame(client))
	{
		// player disconnected
		return;
	}
	
	if (hndl == INVALID_HANDLE)
	{
		ThrowError("Error retrieving playerId for %N", client);
	}
	
	if (SQL_GetRowCount(hndl) < 1)
	{
		ThrowNativeError(100, "Player %N not found in HLXCE database", client);
	}
	
	#if DEBUG == 1
		LogToGame("[HLX-API] Got PlayerId");
	#endif
	
	SQL_FetchRow(hndl);
	new pid = SQL_FetchInt(hndl, 0);

	g_iClientHLXPlayerId[client] = pid;
	
	#if DEBUG == 1
		LogToGame("[HLX-API] Firing HLXCE_OnClientReady Forward %N/%d", client, pid);
	#endif
	
	if (g_hFwdHLXClientReady != INVALID_HANDLE)
	{
		Call_StartForward(g_hFwdHLXClientReady);
		Call_PushCell(client);
		Call_Finish();
	}
	else
	{
		ThrowError("Handle to OnClientReady forward is invalid");
	}
}

GetAllPlayerIds()
{
	for (new i = 1; i <= MaxClients; i++)
	{
		if (g_iClientHLXPlayerId[i] == -1)
		{
			#if DEBUG == 1
				LogToGame("[HLX-API] Getting PlayerId for client %d", i);
			#endif
			GetClientHLXPlayerId(i);
		}
	}
}

public Native_HLXCE_GetPlayerData(Handle:plugin, numParams)
{
	if (g_hHLXDatabase == INVALID_HANDLE)
	{
		SetFailState("Lost database connection");
	}
	
	new client = GetNativeCell(1);
	
	if (g_iClientHLXPlayerId[client] < 0)
	{
		ThrowNativeError(101, "Client %d \"%N\" is not HLX ready yet!", client, client);
	}
	
	#if DEBUG == 1
		LogToGame("[HLX-API] Get client data for %N", client);
	#endif
	
	decl String:szQueryText[109];
	// should return no more than 1 row between game/uniqueId is a unique key
	Format(szQueryText, sizeof(szQueryText), "SELECT skill,kills,deaths,headshots,connection_time,shots,hits FROM hlstats_Players WHERE playerId=%d", g_iClientHLXPlayerId[client]);
	
	#if DEBUG == 1
		LogToGame("[HLX-API] Sending query \"%s\"", szQueryText);
	#endif
	
	SQL_TQuery(g_hHLXDatabase, OnGotPlayerData, szQueryText, GetClientUserId(client));
}

public OnGotPlayerData(Handle:owner, Handle:hndl, const String:error[], any:userid)
{
	new client = GetClientOfUserId(userid);
	
	if (hndl == INVALID_HANDLE)
	{
		ThrowError("Error retrieving playerdata for %N (no handle)", client);
	}
	
	if (SQL_GetRowCount(hndl) < 1)
	{
		ThrowError("Error retrieving playerdata for %N (no rows)", client);
	}
	
	if (client == 0 || !IsClientInGame(client))
	{
		// client disconnected
		return;
	}
	
	SQL_FetchRow(hndl); // there will only be one row because playerId is unique
	for (new i = 0; i < 7; i++)
	{
		g_iPlayerCounts[client][i] = SQL_FetchInt(hndl, i);
		
		#if DEBUG == 1
			LogToGame("[HLX-API] %N data %d is %d", client, i, g_iPlayerCounts[client][i]);
		#endif
	}
	
	new iTempDeaths = g_iPlayerCounts[client][PData_Deaths];
	if (iTempDeaths == 0)
	{
		iTempDeaths = 1;
	}
	
	new iQSize = 180+g_iGameCodeLen;
	decl String:szQueryText[iQSize];
	Format(szQueryText, iQSize, "SELECT COUNT(*) FROM hlstats_Players WHERE game='%s' AND hideranking=0 AND kills>=1 AND((%s>%d)OR((%s=%d)AND(kills/IF(deaths=0,1,deaths)>%.3f)))", g_szHLXGameCode, g_szRankingType[g_iRankingType], g_iPlayerCounts[client][g_iRankingType], g_szRankingType[g_iRankingType], g_iPlayerCounts[client][g_iRankingType], FloatDiv(float(g_iPlayerCounts[client][PData_Kills]),float(iTempDeaths)));
	
	#if DEBUG == 1
		LogToGame("[HLX-API] Sending query \"%s\"", szQueryText);
	#endif
	
	SQL_TQuery(g_hHLXDatabase, OnGotPlayerRank, szQueryText, GetClientUserId(client));
}

public OnGotPlayerRank(Handle:owner, Handle:hndl, const String:error[], any:userid)
{
	new client = GetClientOfUserId(userid);
	
	if (hndl == INVALID_HANDLE)
	{
		ThrowError("Error retrieving rank for %N (no handle)", client);
	}
	
	if (SQL_GetRowCount(hndl) < 1)
	{
		ThrowError("Error retrieving rank for %N (no rows)", client);
	}
	
	if (client == 0 || !IsClientInGame(client))
	{
		// player disconnected
		return;
	}
	
	SQL_FetchRow(hndl);
	g_iPlayerCounts[client][PData_Rank] = (SQL_FetchInt(hndl, 0) + 1);
	
	#if DEBUG == 1
		LogToGame("[HLX-API] %N rank is %d", client, g_iPlayerCounts[client][PData_Rank]);
		LogToGame("[HLX-API] Firing HLXCE_OnGotPlayerData Forward %N/%d", client, pid);
	#endif
	
	if (g_hFwdHLXGotPlayerData != INVALID_HANDLE)
	{
		Call_StartForward(g_hFwdHLXGotPlayerData);
		Call_PushCell(client);
		Call_PushArray(g_iPlayerCounts[client][0], 8);
		Call_Finish();
	}
	else
	{
		ThrowError("Handle to GotPlayerData forward is invalid");
	}
}

public OnPluginEnd()
{
	if (g_hHLXDatabase != INVALID_HANDLE)
	{
		CloseHandle(g_hHLXDatabase);
		#if DEBUG == 1
			LogToGame("[HLX-API] Connected to the Database - Closing Connection");
		#endif
	}
	else
	{
		#if DEBUG == 1
			LogToGame("[HLX-API] Not Connected to the Database");
		#endif
	}
}
 

gibs

Фитиль народного волненья
Сообщения
722
Реакции
407
Мошенник
Аватарки качаются со стима. Это клиент сайд онли.
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху Снизу