//---------------------------------------------------------------------------------------------------- // Leader3 whitelist: players allowed to self-assign leader without a vote or admin flags. // Stored in the SourceMod database ("sourcemod" config when defined, else storage-local). //---------------------------------------------------------------------------------------------------- void Whitelist_OnPluginStart() { char conf[64]; strcopy(conf, sizeof(conf), SQL_CheckConfig("sourcemod") ? "sourcemod" : "storage-local"); Database.Connect(Whitelist_OnDBConnected, conf); } public void Whitelist_OnDBConnected(Database db, const char[] error, any data) { if (db == null) { LogError("[Leader3] Whitelist database connection failed: %s", error); return; } g_hWhitelistDB = db; g_hWhitelistDB.SetCharset("utf8"); g_hWhitelistDB.Query(Whitelist_OnTableCreated, "CREATE TABLE IF NOT EXISTS leader_whitelist (" ... "steam_id VARCHAR(32) NOT NULL PRIMARY KEY, " ... "name VARCHAR(64) NOT NULL DEFAULT '', " ... "added_by VARCHAR(96) NOT NULL DEFAULT '', " ... "added_at INTEGER NOT NULL DEFAULT 0)"); } public void Whitelist_OnTableCreated(Database db, DBResultSet results, const char[] error, any data) { if (results == null) { LogError("[Leader3] Failed to create leader_whitelist table: %s", error); delete g_hWhitelistDB; return; } // Late load / slow connect: check everyone already on. for (int i = 1; i <= MaxClients; i++) { if (IsClientInGame(i) && IsClientAuthorized(i)) Whitelist_CheckClient(i); } } void Whitelist_CheckClient(int client) { g_bLeaderWhitelisted[client] = false; char auth[32]; if (g_hWhitelistDB == null || IsFakeClient(client) || !GetClientAuthId(client, AuthId_Steam2, auth, sizeof(auth))) return; char query[128]; g_hWhitelistDB.Format(query, sizeof(query), "SELECT 1 FROM leader_whitelist WHERE steam_id = '%s'", auth); g_hWhitelistDB.Query(Whitelist_OnCheckDone, query, GetClientUserId(client)); } public void Whitelist_OnCheckDone(Database db, DBResultSet results, const char[] error, any userid) { if (results == null) { LogError("[Leader3] Whitelist lookup failed: %s", error); return; } int client = GetClientOfUserId(userid); if (client > 0) g_bLeaderWhitelisted[client] = results.FetchRow(); } bool Whitelist_IsWhitelisted(int client) { return client >= 1 && client <= MaxClients && g_bLeaderWhitelisted[client]; } void Whitelist_Add(int admin, int target) { if (g_hWhitelistDB == null) { ReplyToCommand(admin, "%s The whitelist database is not available.", PREFIX_PLAIN); return; } char auth[32]; if (!GetClientAuthId(target, AuthId_Steam2, auth, sizeof(auth))) { ReplyToCommand(admin, "%s %N is not authorized with Steam yet, try again shortly.", PREFIX_PLAIN, target); return; } if (g_bLeaderWhitelisted[target]) { ReplyToCommand(admin, "%s %N is already on the leader whitelist.", PREFIX_PLAIN, target); return; } char name[MAX_NAME_LENGTH], adminAuth[96]; GetClientName(target, name, sizeof(name)); if (admin > 0) GetClientAuthId(admin, AuthId_Steam2, adminAuth, sizeof(adminAuth)); else strcopy(adminAuth, sizeof(adminAuth), "CONSOLE"); char query[512]; g_hWhitelistDB.Format(query, sizeof(query), "REPLACE INTO leader_whitelist (steam_id, name, added_by, added_at) VALUES ('%s', '%s', '%s', %d)", auth, name, adminAuth, GetTime()); g_hWhitelistDB.Query(Whitelist_OnWriteDone, query); g_bLeaderWhitelisted[target] = true; ReplyToCommand(admin, "%s Added %N (%s) to the leader whitelist.", PREFIX_PLAIN, target, auth); PrintToChat(target, "%sYou are now on the \x04leader whitelist\x01! Type \x04!leader\x01 to lead at any time.", PREFIX); LogAction(admin, target, "\"%L\" added \"%L\" to the leader whitelist", admin, target); } // Normalize a typed SteamID to canonical upper-case Steam2 form (STEAM_X:Y:Z). // The steam_id column comparison is case-sensitive, so lower-case input must not reach the DB. static bool Whitelist_NormalizeSteam2(const char[] input, char[] auth, int maxlen) { strcopy(auth, maxlen, input); for (int i = 0; auth[i] != '\0'; i++) auth[i] = CharToUpper(auth[i]); if (StrContains(auth, "STEAM_", true) != 0) return false; if (!IsCharNumeric(auth[6]) || auth[7] != ':' || (auth[8] != '0' && auth[8] != '1') || auth[9] != ':' || !IsCharNumeric(auth[10])) return false; for (int i = 11; auth[i] != '\0'; i++) { if (!IsCharNumeric(auth[i])) return false; } return true; } // Add a possibly offline player by SteamID (sm_addleaderwhitelist STEAM_0:X:XXXX [name]). void Whitelist_AddAuth(int admin, const char[] authArg, const char[] name) { if (g_hWhitelistDB == null) { ReplyToCommand(admin, "%s The whitelist database is not available.", PREFIX_PLAIN); return; } char auth[32]; if (!Whitelist_NormalizeSteam2(authArg, auth, sizeof(auth))) { ReplyToCommand(admin, "%s '%s' is not a valid SteamID (expected STEAM_0:X:XXXX).", PREFIX_PLAIN, authArg); return; } char adminAuth[96]; if (admin > 0) GetClientAuthId(admin, AuthId_Steam2, adminAuth, sizeof(adminAuth)); else strcopy(adminAuth, sizeof(adminAuth), "CONSOLE"); char query[512]; g_hWhitelistDB.Format(query, sizeof(query), "REPLACE INTO leader_whitelist (steam_id, name, added_by, added_at) VALUES ('%s', '%s', '%s', %d)", auth, name, adminAuth, GetTime()); g_hWhitelistDB.Query(Whitelist_OnWriteDone, query); // Update the cache should that player be connected under this ID. char clientAuth[32]; for (int i = 1; i <= MaxClients; i++) { if (!g_bLeaderWhitelisted[i] && IsClientInGame(i) && !IsFakeClient(i) && GetClientAuthId(i, AuthId_Steam2, clientAuth, sizeof(clientAuth)) && StrEqual(auth, clientAuth)) { g_bLeaderWhitelisted[i] = true; PrintToChat(i, "%sYou are now on the \x04leader whitelist\x01! Type \x04!leader\x01 to lead at any time.", PREFIX); } } ReplyToCommand(admin, "%s Added %s to the leader whitelist.", PREFIX_PLAIN, auth); LogAction(admin, -1, "\"%L\" added \"%s\" to the leader whitelist", admin, auth); } // Remove a connected client from the whitelist. Returns true if they were on it. bool Whitelist_Remove(int admin, int target) { if (!g_bLeaderWhitelisted[target]) return false; g_bLeaderWhitelisted[target] = false; char auth[32]; if (GetClientAuthId(target, AuthId_Steam2, auth, sizeof(auth))) Whitelist_DeleteAuth(auth); ReplyToCommand(admin, "%s Removed %N from the leader whitelist.", PREFIX_PLAIN, target); LogAction(admin, target, "\"%L\" removed \"%L\" from the leader whitelist", admin, target); return true; } // Remove an offline player by SteamID (sm_removeleaderwhitelist STEAM_0:X:XXXX). void Whitelist_RemoveAuth(int admin, const char[] authArg) { if (g_hWhitelistDB == null) { ReplyToCommand(admin, "%s The whitelist database is not available.", PREFIX_PLAIN); return; } char auth[32]; if (!Whitelist_NormalizeSteam2(authArg, auth, sizeof(auth))) { ReplyToCommand(admin, "%s '%s' is not a valid SteamID (expected STEAM_0:X:XXXX).", PREFIX_PLAIN, authArg); return; } Whitelist_DeleteAuth(auth); // Clear the cache should that player be connected under this ID. char clientAuth[32]; for (int i = 1; i <= MaxClients; i++) { if (g_bLeaderWhitelisted[i] && IsClientInGame(i) && GetClientAuthId(i, AuthId_Steam2, clientAuth, sizeof(clientAuth)) && StrEqual(auth, clientAuth)) { g_bLeaderWhitelisted[i] = false; } } ReplyToCommand(admin, "%s Removed %s from the leader whitelist (if present).", PREFIX_PLAIN, auth); LogAction(admin, -1, "\"%L\" removed \"%s\" from the leader whitelist", admin, auth); } void Whitelist_DeleteAuth(const char[] auth) { if (g_hWhitelistDB == null) return; char query[128]; g_hWhitelistDB.Format(query, sizeof(query), "DELETE FROM leader_whitelist WHERE steam_id = '%s'", auth); g_hWhitelistDB.Query(Whitelist_OnWriteDone, query); } public void Whitelist_OnWriteDone(Database db, DBResultSet results, const char[] error, any data) { if (results == null) LogError("[Leader3] Whitelist write failed: %s", error); } //---------------------------------------------------------------------------------------------------- // Commands //---------------------------------------------------------------------------------------------------- public Action Cmd_AddLeaderWhitelist(int client, int args) { if (args < 1) { ReplyToCommand(client, "%s Usage: sm_addleaderwhitelist [name] - adds a player to the leader whitelist.", PREFIX_PLAIN); return Plugin_Handled; } char arg[65], targetName[MAX_TARGET_LENGTH]; int targets[MAXPLAYERS]; bool tnIsMl; GetCmdArg(1, arg, sizeof(arg)); int count = ProcessTargetString(arg, client, targets, sizeof(targets), COMMAND_FILTER_CONNECTED | COMMAND_FILTER_NO_BOTS, targetName, sizeof(targetName), tnIsMl); if (count <= 0) { // Offline whitelist add by SteamID. if (StrContains(arg, "STEAM_", false) == 0) { char name[MAX_NAME_LENGTH]; if (args >= 2) GetCmdArg(2, name, sizeof(name)); Whitelist_AddAuth(client, arg, name); return Plugin_Handled; } ReplyToTargetError(client, count); return Plugin_Handled; } for (int i = 0; i < count; i++) Whitelist_Add(client, targets[i]); return Plugin_Handled; } public Action Cmd_RemoveLeaderWhitelist(int client, int args) { if (args < 1) { ReplyToCommand(client, "%s Usage: sm_removeleaderwhitelist - removes a player from the leader whitelist.", PREFIX_PLAIN); return Plugin_Handled; } char arg[65], targetName[MAX_TARGET_LENGTH]; int targets[MAXPLAYERS]; bool tnIsMl; GetCmdArg(1, arg, sizeof(arg)); int count = ProcessTargetString(arg, client, targets, sizeof(targets), COMMAND_FILTER_CONNECTED | COMMAND_FILTER_NO_BOTS, targetName, sizeof(targetName), tnIsMl); if (count <= 0) { // Offline whitelist removal by SteamID. if (StrContains(arg, "STEAM_", false) == 0) { Whitelist_RemoveAuth(client, arg); return Plugin_Handled; } ReplyToTargetError(client, count); return Plugin_Handled; } for (int i = 0; i < count; i++) { if (!Whitelist_Remove(client, targets[i])) ReplyToCommand(client, "%s %N is not on the leader whitelist.", PREFIX_PLAIN, targets[i]); } return Plugin_Handled; } public Action Cmd_LeaderWhitelist(int client, int args) { if (g_hWhitelistDB == null) { ReplyToCommand(client, "%s The whitelist database is not available.", PREFIX_PLAIN); return Plugin_Handled; } g_hWhitelistDB.Query(Whitelist_OnListDone, "SELECT steam_id, name FROM leader_whitelist ORDER BY added_at DESC", client > 0 ? GetClientUserId(client) : 0); return Plugin_Handled; } public void Whitelist_OnListDone(Database db, DBResultSet results, const char[] error, any userid) { int client = (userid == 0) ? 0 : GetClientOfUserId(userid); if (userid != 0 && client == 0) return; if (results == null) { LogError("[Leader3] Whitelist listing failed: %s", error); ReplyToCommand(client, "%s Failed to read the leader whitelist.", PREFIX_PLAIN); return; } if (results.RowCount == 0) { ReplyToCommand(client, "%s The leader whitelist is empty.", PREFIX_PLAIN); return; } ReplyToCommand(client, "%s Leader whitelist (%d):", PREFIX_PLAIN, results.RowCount); char auth[32], name[MAX_NAME_LENGTH]; while (results.FetchRow()) { results.FetchString(0, auth, sizeof(auth)); results.FetchString(1, name, sizeof(name)); ReplyToCommand(client, " %s - %s", auth, name); } }