#include #include #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; }