You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

294 lines
9.3 KiB

#include <sourcemod>
#include <sdktools>
#define PLUGIN_VERSION "1.3"
public Plugin:myinfo = {
name = "[ANY] User Control",
author = "gsd",
description = "Append user connect and disconnect inforamations, for control.Nickname, SteamID, IP, Total game time on server.",
version = PLUGIN_VERSION,
url = "https://kremlin.ru"
};
int iPlayedTime[101] = {-1, ...};
new Handle:hDatabase = INVALID_HANDLE;
////////////////////////////////////////////////////////////
public APLRes:AskPluginLoad2(Handle:hMyself, bool:bLate, String:strError[], iErr_Max){
RegPluginLibrary("usercontrol");
CreateNative("UserControl_PlayedTime", Native_GetClientPlayerTime);
return APLRes_Success;
}
public Native_GetClientPlayerTime(Handle:plugin, numParams){
new client = GetNativeCell(1);
if(client < 1 || client > MaxClients){
ThrowNativeError(SP_ERROR_PARAM, "Invalid client or client index %i", client);
return false;
}
if(!IsClientInGame(client)){
ThrowNativeError(SP_ERROR_PARAM, "Client %i is not in game!", client);
return false;
}
return iPlayedTime[client];
}
////////////////////////////////////////////////////////////
public OnPluginStart() {
VerifyTable();
StartSQL();
CreateConVar("sm_ucontrol_version", PLUGIN_VERSION, "User Connection Version", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY);
HookEvent("player_disconnect", event_PlayerDisconnect, EventHookMode_Pre);
}
StartSQL() {
SQL_TConnect(GotDatabase, "usercontrol");
}
public GotDatabase(Handle:owner, Handle:hndl, const String:error[], any:data) {
if (hndl == INVALID_HANDLE) {
LogError("Database Connection Error: %s", error);
} else {
hDatabase = hndl;
}
}
public int CopyString(const String:Source[], String:Buffer[]){
new EndPos;
for (new CurrentPos = 0; CurrentPos < strlen(Source); CurrentPos++){
Buffer[CurrentPos] = Source[CurrentPos];
EndPos = CurrentPos;
}
Buffer[EndPos+1] = '\0';
return EndPos;
}
bool:VerifyTable() {
decl String:error[255];
decl String:query[512];
query[0] = '\0';
new Handle:db = SQL_Connect("usercontrol", true, error, sizeof(error));
if (db == INVALID_HANDLE) {
LogError("Could Not Connect to Database, error: %s", error);
return false;
}
Format(query, sizeof(query), "%s%s%s%s%s%s%s%s%s%s",
"CREATE TABLE IF NOT EXISTS `user_connections` (",
" `player_name` VARCHAR(64) NOT NULL ,",
" `steam_id` VARCHAR(32) NOT NULL ,",
" `connect_ip` VARCHAR(15) NOT NULL ,",
" `account_id` BIGINT NOT NULL ,",
" `timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,",
" `map` VARCHAR(256) NOT NULL ,",
" `connection_type` VARCHAR(10) NOT NULL ,",
" `connect_duration` INT NOT NULL ",
") ENGINE = MyISAM DEFAULT CHARSET=utf8mb4; ");
new bool:success = SQL_FastQuery(db, query);
if(!success) {
SQL_GetError(db, error, sizeof(error));
LogError("Unable to verify mysql_bans table:%s", query);
}
CloseHandle(db);
return true;
}
public T_SendQuery(Handle:owner, Handle:hndl, const String:error[], any:data) {
if (hndl == INVALID_HANDLE) {
LogError("Query failed! %s", error);
}
return;
}
//////////////////////////////////////////////////////////////////////////////////////////////
public void OnClientAuthorized(int client)
{
GetPlayTimeTotal(client);
}
int GetPlayTimeTotal(int client) {
char Query[512];
int AccountID = GetSteamAccountID(client, true);
char Map[128];
GetCurrentMap(Map,sizeof(Map));
Format(Query, sizeof(Query), "SELECT SUM(connect_duration) total FROM user_connections WHERE connection_type LIKE 'disconnect' AND account_id = %d AND map LIKE '%s'", AccountID, Map);
SQL_TQuery(hDatabase, GetPlayTimeTotalCallback, Query, GetClientUserId(client));
return 0;
}
stock void GetPlayTimeTotalCallback(Handle owner, Handle hndl, char [] error, any data) {
int client;
if((client = GetClientOfUserId(data)) == 0)
{
return;
}
char PlayerName[64];
GetClientName(client, PlayerName, sizeof(PlayerName));
if(hndl == INVALID_HANDLE)
{
LogError("Query failure: %s", error);
return;
}
if (SQL_FetchRow(hndl)) {
iPlayedTime[client] = SQL_FetchInt(hndl, 0);
} else {
iPlayedTime[client] = -1;
}
}
public void OnClientDisconnect(int client)
{
iPlayedTime[client] = -1;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
public OnClientPostAdminCheck(client) {
//User Connect to Server
if(IsFakeClient(client)) {
return;
}
//Vars
new String:error[1024];
DataPack hPayload = new DataPack();
/*
0 - User ID INT
1 - Account ID INT
2 - Steam ID STRING
3 - Connection Type STRING
4 - Conncetion IP STRING
5 - Player Name STRING
6 - Disconnect Reason STRING
7 - Game Time On Server STRING
*/
WritePackCell(hPayload, GetClientUserId(client));
WritePackCell(hPayload, GetSteamAccountID(client, true));
char SteamID[64];
GetClientAuthString(client, SteamID, sizeof(SteamID));
WritePackString(hPayload, SteamID);
char ConnectionType[16];
Format(ConnectionType, sizeof(ConnectionType), "%s", "connect");
WritePackString(hPayload, ConnectionType);
char ConnectionIP[16];
GetClientIP(client, ConnectionIP, sizeof(ConnectionIP));
WritePackString(hPayload, ConnectionIP);
char PlayerName[64];
GetClientName(client, PlayerName, sizeof(PlayerName));
WritePackString(hPayload, PlayerName);
WritePackString(hPayload, "");
WritePackCell(hPayload, 0);
/////////////////////////////////////////////////////////////////////////////////////////
SQL_TQuery(hDatabase, T_QueryPost, error, hPayload);
return;
}
public Action:event_PlayerDisconnect(Handle:event, const String:name[], bool:dontBroadcast) {
new String:error[1024];
DataPack hPayload = new DataPack();
new client = GetClientOfUserId(GetEventInt(event, "userid"));
if(client == 0){
return Plugin_Continue;
}
/*
0 - User ID INT
1 - Account ID INT
2 - Steam ID STRING
3 - Connection Type STRING
4 - Conncetion IP STRING
5 - Player Name STRING
6 - Disconnect Reason STRING
7 - Game Time On Server INT
*/
WritePackCell(hPayload, GetEventInt(event, "userid"));
WritePackCell(hPayload, GetSteamAccountID(client, true));
char SteamID[64];
GetEventString(event, "networkid", SteamID, sizeof(SteamID));
WritePackString(hPayload, SteamID);
char ConnectionType[16];
Format(ConnectionType, sizeof(ConnectionType), "%s", "disconnect");
WritePackString(hPayload, ConnectionType);
char ConnectionIP[16];
GetClientIP(client, ConnectionIP, sizeof(ConnectionIP));
WritePackString(hPayload, ConnectionIP);
char PlayerName[64];
GetEventString(event, "name", PlayerName, sizeof(PlayerName));
WritePackString(hPayload, PlayerName);
char DisconnectReason[256];
GetEventString(event, "reason", DisconnectReason, sizeof(DisconnectReason));
WritePackString(hPayload, DisconnectReason);
WritePackCell(hPayload, RoundFloat(GetClientTime(client)));
SQL_TQuery(hDatabase, T_QueryPost, error, hPayload);
return Plugin_Continue;
}
public T_QueryPost(Handle:owner, Handle:hndl, const String:error[], any:hPayload) {
new String:query[1024];
ResetPack(hPayload);
int UserID;
int AccountID;
char Map[256];
char SteamID[64];
char ConnectionType[16];
char ConnectionIP[16];
char PlayerName[64];
char DisconnectReason[256];
int GameTime;
/*
0 - User ID INT
1 - Account ID INT
2 - Steam ID STRING
3 - Connection Type STRING
4 - Conncetion IP STRING
5 - Player Name STRING
6 - Disconnect Reason STRING
7 - Game Time On Server INT
*/
UserID = ReadPackCell(hPayload);
AccountID = ReadPackCell(hPayload);
ReadPackString(hPayload, SteamID, sizeof(SteamID));
ReadPackString(hPayload, ConnectionType, sizeof(ConnectionType));
ReadPackString(hPayload, ConnectionIP, sizeof(ConnectionIP));
ReadPackString(hPayload, PlayerName, sizeof(PlayerName));
ReadPackString(hPayload, DisconnectReason, sizeof(DisconnectReason));
GameTime = ReadPackCell(hPayload);
GetCurrentMap(Map, sizeof(Map));
//for (new i = 0; i < sizeof(sUserData); i++) {
// SQL_EscapeString(hDatabase, sUserData[i], Payload[i], strlen(Payload[i]) * 2);
//}
char SQL_PlayerName[64];
SQL_EscapeString(hDatabase, PlayerName, SQL_PlayerName, sizeof(SQL_PlayerName));
char SQL_Reason[256];
SQL_EscapeString(hDatabase, DisconnectReason, SQL_Reason, sizeof(SQL_Reason));
char SQL_Map[256];
SQL_EscapeString(hDatabase, Map, SQL_Map, sizeof(SQL_Map));
if (StrEqual(ConnectionType, "connect"))
{
Format(query, sizeof(query), "INSERT INTO user_connections (player_name, steam_id, connect_ip, account_id, timestamp, connection_type, map) VALUES ('%s', '%s', '%s', '%d', CURRENT_TIMESTAMP, '%s', '%s')", SQL_PlayerName, SteamID, ConnectionIP, AccountID, ConnectionType, SQL_Map);
//LogMessage("New connection %s, %s(%s), U:1:%d", sUserData[4], sUserData[0], sUserData[2], iUserData[1]);
LogMessage("Player connected: %s %s|U:1:%d|%s", PlayerName, SteamID, AccountID, ConnectionIP);
}
else
{
Format(query, sizeof(query), "INSERT INTO user_connections (player_name, account_id, connection_type, connect_duration, reason, map) VALUES ('%s', '%d', '%s', '%d', '%s', '%s')", SQL_PlayerName, AccountID, ConnectionType, GameTime, SQL_Reason, SQL_Map);
//LogMessage("%s | U:1:%d disconnect from server, total game time %d seconds", sUserData[0], iUserData[1], iUserData[2]);
LogMessage("Player disconnected: %s %s|U:1:%d|%s\nGame Time: %d sec. Reason: %s", PlayerName, SteamID, AccountID, ConnectionIP,GameTime, DisconnectReason);
}
//LogMessage(query);
CloseHandle(hPayload);
SQL_TQuery(hDatabase, T_SendQuery, query);
return;
}