#pragma semicolon 1 #include #include #include #include #pragma newdecls required /* CONVARS */ ConVar g_hCvar_BlockSpoof; ConVar g_hCvar_BlockAdmin; ConVar g_hCvar_BlockVoice; ConVar g_hCvar_AuthenticationTime; /* DATABASE */ Database g_hDatabase; /* STRING */ char g_cPlayerGUID[MAXPLAYERS + 1][40]; //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Plugin myinfo = { name = "PlayerManager: Connect", author = "zaCade + Neon", description = "Manage clients, denying admin access, ect.", version = "2.1.0" }; //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public APLRes AskPluginLoad2(Handle hMyself, bool bLate, char[] sError, int errorSize) { CreateNative("PM_IsPlayerSteam", Native_IsPlayerSteam); CreateNative("PM_GetPlayerType", Native_GetPlayerType); CreateNative("PM_GetPlayerGUID", Native_GetPlayerGUID); RegPluginLibrary("PlayerManager"); return APLRes_Success; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnPluginStart() { LoadTranslations("common.phrases"); g_hCvar_BlockSpoof = CreateConVar("sm_manager_block_spoof", "1", "Kick unauthenticated people that join with known steamids.", FCVAR_NONE, true, 0.0, true, 1.0); g_hCvar_BlockAdmin = CreateConVar("sm_manager_block_admin", "1", "Should unauthenticated people be blocked from admin?", FCVAR_NONE, true, 0.0, true, 1.0); g_hCvar_BlockVoice = CreateConVar("sm_manager_block_voice", "1", "Should unauthenticated people be blocked from voice?", FCVAR_NONE, true, 0.0, true, 1.0); g_hCvar_AuthenticationTime = CreateConVar("sm_manager_authentication_time", "15", "Time in seconds after which a client needs to be assigned to a SteamID", FCVAR_NONE, true, 1.0); AddMultiTargetFilter("@steam", Filter_Steam, "Steam Players", false); AddMultiTargetFilter("@nosteam", Filter_NoSteam, "No-Steam Players", false); RegConsoleCmd("sm_steam", Command_DisplaySteamStats, "Shows No-Steam players"); RegConsoleCmd("sm_nosteam", Command_DisplaySteamStats, "Shows No-Steam players"); RegAdminCmd("sm_auth", Command_GetAuth, ADMFLAG_GENERIC, "Retreives the Steam ID of a player"); RegAdminCmd("sm_debugnosteam", Command_DebugNoSteam, ADMFLAG_GENERIC, "Retreives the amount of No-Steam players"); AutoExecConfig(); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnConfigsExecuted() { if(!g_hCvar_BlockSpoof.BoolValue) return; if (!g_hDatabase) { Database.Connect(SQL_OnDatabaseConnect, "PlayerManager"); } } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnPluginEnd() { RemoveMultiTargetFilter("@steam", Filter_Steam); RemoveMultiTargetFilter("@nosteam", Filter_NoSteam); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public bool SteamClientAuthenticatedEx(const char[] sAuthID) { //neons steam ID. he got a vac ban, this lets him avoid it. told him he should get a new account but he never got a new one. if (StrEqual(sAuthID, "STEAM_0:1:32247009")) return true; return SteamClientAuthenticated(sAuthID); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Command_GetAuth(int client, int args) { if(args < 1) { ReplyToCommand(client, "[SM] Usage: sm_auth <#userid|name>"); return Plugin_Handled; } char sTarget[MAX_TARGET_LENGTH]; GetCmdArg(1, sTarget, sizeof(sTarget)); int iTarget; if ((iTarget = FindTarget(client, sTarget, false, false)) <= 0) return Plugin_Handled; char sAuthID[32]; GetClientAuthId(iTarget, AuthId_Steam2, sAuthID, sizeof(sAuthID)); ReplyToCommand(client, "[SM] The Steam ID of %N is:", iTarget); ReplyToCommand(client, "%s", sAuthID); return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Command_DisplaySteamStats(int client, int args) { char aBuf[1024]; char aBuf2[MAX_NAME_LENGTH]; for(int i = 1; i <= MaxClients; i++) { if(IsClientInGame(i) && !IsFakeClient(i)) { char sAuthID[32]; GetClientAuthId(i, AuthId_Steam2, sAuthID, sizeof(sAuthID), false); if(!SteamClientAuthenticatedEx(sAuthID)) { GetClientName(i, aBuf2, sizeof(aBuf2)); StrCat(aBuf, sizeof(aBuf), aBuf2); StrCat(aBuf, sizeof(aBuf), ", "); } } } if(strlen(aBuf)) { aBuf[strlen(aBuf) - 2] = 0; ReplyToCommand(client, "[SM] No-Steam clients online: %s", aBuf); } else ReplyToCommand(client, "[SM] No-Steam clients online: none"); return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action Command_DebugNoSteam(int client, int args) { int iNoSteamAmount; for(int i = 1; i <= MaxClients; i++) { if(IsClientInGame(i) && !IsFakeClient(i)) { char sAuthID[32]; GetClientAuthId(i, AuthId_Steam2, sAuthID, sizeof(sAuthID), false); if(!SteamClientAuthenticated(sAuthID)) iNoSteamAmount++; } } ReplyToCommand(client, "[SM] There are currently %d No-Steam Clients online.", iNoSteamAmount); return Plugin_Handled; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public bool Filter_Steam(const char[] sPattern, Handle hClients) { for(int i = 1; i <= MaxClients; i++) { if(IsClientInGame(i) && !IsFakeClient(i)) { char sAuthID[32]; GetClientAuthId(i, AuthId_Steam2, sAuthID, sizeof(sAuthID), false); if(SteamClientAuthenticatedEx(sAuthID)) PushArrayCell(hClients, i); } } return true; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public bool Filter_NoSteam(const char[] sPattern, Handle hClients) { for(int i = 1; i <= MaxClients; i++) { if(IsClientInGame(i) && !IsFakeClient(i)) { char sAuthID[32]; GetClientAuthId(i, AuthId_Steam2, sAuthID, sizeof(sAuthID), false); if(!SteamClientAuthenticatedEx(sAuthID)) PushArrayCell(hClients, i); } } return true; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public EConnect OnClientPreConnectEx(const char[] sName, char sPassword[255], const char[] sIP, const char[] sSteam32ID, char sRejectReason[255]) { char sAuthID[32]; for(int client = 1; client <= MaxClients; client++) { if(IsClientInGame(client) && !IsFakeClient(client)) { GetClientAuthId(client, AuthId_Steam2, sAuthID, sizeof(sAuthID), false); if(StrEqual(sAuthID, sSteam32ID, false)) { char sClientIP[32]; GetClientIP(client, sClientIP, sizeof(sClientIP)); if(IsClientTimingOut(client) || StrEqual(sIP, sClientIP, false)) { KickClientEx(client, "Timed out"); return k_OnClientPreConnectEx_Accept; } else { LogAction(client, -1, "\"%L\" got protected from getting kicked by a new connection. Possible spoofing attempt from IP: %s", client, sIP); Format(sRejectReason, sizeof(sRejectReason), "SteamID already on the server"); return k_OnClientPreConnectEx_Reject; } } } } return k_OnClientPreConnectEx_Accept; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnClientPutInServer(int client) { //CreateTimer(g_hCvar_AuthenticationTime.FloatValue, CheckAuth, GetClientSerial(client), TIMER_FLAG_NO_MAPCHANGE); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnClientAuthorized(int client, const char[] sAuthID) { char sAddress[16]; GetClientIP(client, sAddress, sizeof(sAddress)); static char sCountry[32]; //just kicking all nosteamers from algeria. not very cool but so be it. if (GeoipCountry(sAddress, sCountry, sizeof(sCountry)) && StrEqual(sCountry, "Algeria", false)) { if (!SteamClientAuthenticatedEx(sAuthID)) { LogMessage("kicking client for being algerian nosteamer: name: %N. sAuthID: %s", client, sAuthID); KickClient(client, "Bye. if you dont think this was deserved please contact us on discord."); return; } } if(!g_hCvar_BlockSpoof.BoolValue || !g_hDatabase) return; if(IsFakeClient(client) || IsClientSourceTV(client)) return; char sQuery[512]; Format(sQuery, sizeof(sQuery), "SELECT * FROM connections WHERE auth='%s'", sAuthID); g_hDatabase.Query(SQL_OnQueryCompleted, sQuery, GetClientSerial(client), DBPrio_Low); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action OnClientPreAdminCheck(int client) { if(!g_hCvar_BlockAdmin.BoolValue) return Plugin_Continue; if(IsFakeClient(client) || IsClientSourceTV(client)) return Plugin_Continue; char sAuthID[32]; GetClientAuthId(client, AuthId_Steam2, sAuthID, sizeof(sAuthID), false); if(!SteamClientAuthenticatedEx(sAuthID)) { LogMessage("%L was not authenticated with steam, denying admin.", client); NotifyPostAdminCheck(client); return Plugin_Handled; } else return Plugin_Continue; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnClientPostAdminCheck(int client) { if(!g_hCvar_BlockVoice.BoolValue) return; if(IsFakeClient(client) || IsClientSourceTV(client)) return; char sAuthID[32]; GetClientAuthId(client, AuthId_Steam2, sAuthID, sizeof(sAuthID), false); /* if(!SteamClientAuthenticatedEx(sAuthID)) { LogMessage("%L was not authenticated with steam, muting client.", client); BaseComm_SetClientMute(client, true); return; } */ } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action CheckAuth(Handle timer, int data) { int client; if ((client = GetClientFromSerial(data)) == 0) return Plugin_Stop; char sAuthID[32]; if(!GetClientAuthId(client, AuthId_Steam2, sAuthID, sizeof(sAuthID), true)) { LogMessage("%L could not be assigned to a SteamID, kicking client.", client); //KickClient(client, "Invalid STEAMID"); if (IsValidClient(client)) { Panel hNotifyPanel = new Panel(GetMenuStyleHandle(MenuStyle_Radio)); hNotifyPanel.DrawItem("WARNING: Your SteamID is Invalid: Reconnecting you to the server in 8 Seconds.", ITEMDRAW_RAWLINE); hNotifyPanel.DrawItem("", ITEMDRAW_SPACER); hNotifyPanel.DrawItem("IMPORTANT: You may disconnect, reconnect if necessary!", ITEMDRAW_RAWLINE); hNotifyPanel.Send(client, MenuHandler_NotifyPanel, 8); delete hNotifyPanel; for (int i = 0; i < 8; i++) { PrintToChat(client, "WARNING: Your SteamID is Invalid: Reconnecting you to the server in 8 Seconds."); } CreateTimer(8.0, forceClientRetry, GetClientSerial(client)); } } return Plugin_Stop; } public Action forceClientRetry(Handle timer, int data) { int client; if ((client = GetClientFromSerial(data)) == 0) return Plugin_Stop; if (IsValidClient(client)) { ClientCommand(client, "retry"); } return Plugin_Handled; } stock bool IsValidClient(int client) { if (client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client) && !IsClientSourceTV(client) && !IsFakeClient(client)) return true; return false; } int MenuHandler_NotifyPanel(Menu hMenu, MenuAction iAction, int iParam1, int iParam2) { switch (iAction) { case MenuAction_Select, MenuAction_Cancel: delete hMenu; } return 0; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void SQL_OnDatabaseConnect(Database db, const char[] error, any data) { if(!db || strlen(error)) { LogError("Database error: %s", error); return; } g_hDatabase = db; char sQuery[512]; Format(sQuery, sizeof(sQuery), "CREATE TABLE IF NOT EXISTS connections (`auth` varchar(32), `type` varchar(32), `address` varchar(16), PRIMARY KEY (`auth`))"); g_hDatabase.Query(SQL_OnQueryCompleted, sQuery, _, DBPrio_High); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void SQL_OnQueryCompleted(Database db, DBResultSet results, const char[] error, any data) { if(!db || strlen(error)) { LogError("Query error: %s", error); return; } int client; if ((client = GetClientFromSerial(data)) == 0) return; char sAuthID[32]; GetClientAuthId(client, AuthId_Steam2, sAuthID, sizeof(sAuthID), false); char sAddress[16]; GetClientIP(client, sAddress, sizeof(sAddress)); char sConnectionType[32]; if(SteamClientAuthenticatedEx(sAuthID)) sConnectionType = "SteamLegit"; else sConnectionType = "NoAuth"; if(results.RowCount && results.FetchRow()) { int iFieldNum; char sResultAddress[16]; char sResultConnectionType[32]; results.FieldNameToNum("address", iFieldNum); results.FetchString(iFieldNum, sResultAddress, sizeof(sResultAddress)); results.FieldNameToNum("type", iFieldNum); results.FetchString(iFieldNum, sResultConnectionType, sizeof(sResultConnectionType)); delete results; if(!SteamClientAuthenticatedEx(sAuthID)) { if(!StrEqual(sConnectionType, sResultConnectionType, false) && StrEqual(sResultConnectionType, "SteamLegit", false)) { if(StrEqual(sAddress, sResultAddress, false)) { LogMessage("%L tried to join with a legitimate steamid while not authenticated with steam. Allowing connection, IPs match. (Known: %s)", client, sAddress); return; } else { LogAction(client, -1, "\"%L\" tried to join with a legitimate steamid while not authenticated with steam. Refusing connection, IPs dont match. (Known: %s | Current: %s)", client, sResultAddress, sAddress); static char sCountry[32]; //we were directly got a problem with an algerian. this is just a specific issue with a specific solution. if (GeoipCountry(sAddress, sCountry, sizeof(sCountry)) && StrEqual(sCountry, "Algeria", false)) { KickClient(client, "Trying to join with a legitimate steamid while not authenticated with steam."); } return; } } } } char sQuery[512]; Format(sQuery, sizeof(sQuery), "INSERT INTO connections (auth, type, address) VALUES ('%s', '%s', '%s') ON DUPLICATE KEY UPDATE type='%s', address='%s';", sAuthID, sConnectionType, sAddress, sConnectionType, sAddress); g_hDatabase.Query(SQL_OnQueryCompleted, sQuery, _, DBPrio_Low); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public int Native_IsPlayerSteam(Handle hPlugin, int numParams) { int client = GetNativeCell(1); if (client < 1 || client > MaxClients) { return ThrowNativeError(SP_ERROR_NATIVE, "Client index %d is invalid", client); } else if (!IsClientConnected(client)) { return ThrowNativeError(SP_ERROR_NATIVE, "Client %d is not connected", client); } else if (IsFakeClient(client)) { return ThrowNativeError(SP_ERROR_NATIVE, "Client %d is a bot", client); } char sAuthID[32]; GetClientAuthId(client, AuthId_Steam2, sAuthID, sizeof(sAuthID), false); if(SteamClientAuthenticatedEx(sAuthID)) return true; return false; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public int Native_GetPlayerType(Handle hPlugin, int numParams) { int client = GetNativeCell(1); int length = GetNativeCell(3); if (client < 1 || client > MaxClients) { return ThrowNativeError(SP_ERROR_NATIVE, "Client index %d is invalid", client); } else if (!IsClientConnected(client)) { return ThrowNativeError(SP_ERROR_NATIVE, "Client %d is not connected", client); } else if (IsFakeClient(client)) { return ThrowNativeError(SP_ERROR_NATIVE, "Client %d is a bot", client); } char sAuthID[32]; GetClientAuthId(client, AuthId_Steam2, sAuthID, sizeof(sAuthID), false); if(SteamClientAuthenticatedEx(sAuthID)) return !SetNativeString(2, "SteamLegit", length + 1); return !SetNativeString(2, "NoAuth", length + 1); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public int Native_GetPlayerGUID(Handle hPlugin, int numParams) { int client = GetNativeCell(1); int length = GetNativeCell(3); if (client < 1 || client > MaxClients) { return ThrowNativeError(SP_ERROR_NATIVE, "Client index %d is invalid", client); } else if (!IsClientConnected(client)) { return ThrowNativeError(SP_ERROR_NATIVE, "Client %d is not connected", client); } else if (IsFakeClient(client)) { return ThrowNativeError(SP_ERROR_NATIVE, "Client %d is a bot", client); } return !SetNativeString(2, g_cPlayerGUID[client], length + 1); }