From 39204beeeeadb5f249b2839e792c6922f1d68b0a Mon Sep 17 00:00:00 2001 From: Rushaway Date: Wed, 4 Jun 2025 18:56:12 +0200 Subject: [PATCH 1/6] fix: Handle admin permissions for VIP users without admin flags --- .../sourcemod/scripting/VIP_SourcemodFlags.sp | 68 +++++++++++++++++-- 1 file changed, 63 insertions(+), 5 deletions(-) diff --git a/addons/sourcemod/scripting/VIP_SourcemodFlags.sp b/addons/sourcemod/scripting/VIP_SourcemodFlags.sp index 2ea53b3..d38302f 100644 --- a/addons/sourcemod/scripting/VIP_SourcemodFlags.sp +++ b/addons/sourcemod/scripting/VIP_SourcemodFlags.sp @@ -255,6 +255,53 @@ stock void LoadClient(int client) return; } } + else + { + // Check if admin has important flags + bool hasImportantFlags = false; + AdminFlag importantFlags[] = { + Admin_Kick, + Admin_Ban, + Admin_Unban, + Admin_Slay, + Admin_Changemap, + Admin_Convars, + Admin_Config, + Admin_RCON, + Admin_Root + }; + + for (int i = 0; i < sizeof(importantFlags); i++) + { + if (GetAdminFlag(curAdm, importantFlags[i])) + { + hasImportantFlags = true; + break; + } + } + + // Only remove admin if they don't have important flags + if (!hasImportantFlags) + { + // Remove the admin completely and recreate it + char sName[254]; + GetClientName(client, sName, sizeof(sName)); + RemoveAdmin(curAdm); + curAdm = CreateAdmin(sName); + if (!curAdm.BindIdentity(sAuthType, sAuth)) + { + RemoveAdmin(curAdm); + delete Groups; + return; + } + } + else + { + // Admin has important flags, don't modify their permissions + delete Groups; + return; + } + } for (int i = 0; i < Groups.Length; i++) { @@ -265,15 +312,26 @@ stock void LoadClient(int client) if((grp = FindAdmGroup(sGroup)) == INVALID_GROUP_ID) { grp = CreateAdmGroup(sGroup); - if (StrEqual(sGroup, sVIPGroupName)) + if (grp == INVALID_GROUP_ID) { - SetAdmGroupAddFlag(grp, Admin_Custom1, true); - SetAdmGroupAddFlag(grp, Admin_Custom2, true); - SetAdmGroupImmunityLevel(grp, g_cvVIPGroupImmunity.IntValue); + LogError("Failed to create admin group: %s", sGroup); + continue; } } - AdminInheritGroup(curAdm, grp); + if (StrEqual(sGroup, sVIPGroupName)) + { + // Force set the flags for VIP group + SetAdmGroupAddFlag(grp, Admin_Custom1, true); + SetAdmGroupAddFlag(grp, Admin_Custom2, true); + SetAdmGroupImmunityLevel(grp, g_cvVIPGroupImmunity.IntValue); + } + + // Force inherit the group + if (!AdminInheritGroup(curAdm, grp)) + { + LogError("Failed to inherit admin group %s for admin %s", sGroup, sAuth); + } } } From 03d57ba4cfcf3dc42334f79f323a684cd13dcb5b Mon Sep 17 00:00:00 2001 From: Rushaway Date: Thu, 5 Jun 2025 10:06:44 +0200 Subject: [PATCH 2/6] Drop group logic leading to conflict with sbpp --- .../sourcemod/scripting/VIP_SourcemodFlags.sp | 204 ++++++------------ 1 file changed, 70 insertions(+), 134 deletions(-) diff --git a/addons/sourcemod/scripting/VIP_SourcemodFlags.sp b/addons/sourcemod/scripting/VIP_SourcemodFlags.sp index d38302f..2dfc44c 100644 --- a/addons/sourcemod/scripting/VIP_SourcemodFlags.sp +++ b/addons/sourcemod/scripting/VIP_SourcemodFlags.sp @@ -14,13 +14,13 @@ #define VIP_FEATURE_NAME "VIP" -ConVar g_cvVIPGroupName; ConVar g_cvVIPGroupImmunity; bool g_bClientLoaded[MAXPLAYERS + 1] = { false, ... }; bool g_bSbppClientsLoaded = false; bool g_bReloadVips = false; bool g_bLibraryCCC = false; +bool g_bLateLoaded = false; public Plugin myinfo = { @@ -30,10 +30,19 @@ public Plugin myinfo = version = "3.2.3" }; +public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) +{ + g_bLateLoaded = late; + return APLRes_Success; +} + public void OnAllPluginsLoaded() { if (LibraryExists("ccc")) g_bLibraryCCC = true; + + if (g_bLateLoaded) + ReloadVIPs(); } public void OnLibraryAdded(const char[] name) @@ -51,8 +60,6 @@ public void OnLibraryRemoved(const char[] name) public void OnPluginStart() { LoadTranslations("common.phrases"); - - g_cvVIPGroupName = CreateConVar("sm_vip_group_name", "VIP", "Group name of vip users"); g_cvVIPGroupImmunity = CreateConVar("sm_vip_group_immunity", "5", "Immunity level of vip users", 0, true, 0.0, true, 100.0); RegAdminCmd("sm_reloadvips", Command_ReloadVips, ADMFLAG_BAN); @@ -135,25 +142,29 @@ public void OnClientDisconnect(int client) public Action OnClientPreAdminCheck(int client) { - return g_bSbppClientsLoaded && g_bClientLoaded[client] ? Plugin_Continue : Plugin_Handled; + // If the client is VIP but not loaded yet, load them + if (!g_bClientLoaded[client] && VIP_IsClientVIP(client)) + { + LoadVIPClient(client); + NotifyPostAdminCheck(client); + return Plugin_Handled; + } + + return Plugin_Continue; } #if defined _sourcebanspp_included public bool SBPP_OnClientPreAdminCheck(AdminCachePart part) { if (part == AdminCache_Admins) + { g_bSbppClientsLoaded = true; - for (int client = 1; client <= MaxClients; client++) - CheckLoadAdmin(client); - - if (part == AdminCache_Admins) - { if (g_bReloadVips) ReloadVIPs(); + g_bReloadVips = false; } - return false; } #endif @@ -179,27 +190,15 @@ public void VIP_OnVIPClientRemoved(int client, const char[] szReason, int iAdmin } stock void UnloadVIPClient(int client) -{ - RemoveClient(client); - -#if defined _ccc_included - if (g_bLibraryCCC && GetFeatureStatus(FeatureType_Native, "CCC_UnLoadClient") == FeatureStatus_Available) - CCC_UnLoadClient(client); -#endif - - ServerCommand("sm_reloadadmins"); -} - -stock void LoadVIPClient(int client) { if (!client) return; - LoadClient(client); + RemoveClient(client); #if defined _ccc_included - if (g_bLibraryCCC && GetFeatureStatus(FeatureType_Native, "CCC_LoadClient") == FeatureStatus_Available) - CCC_LoadClient(client); + if (g_bLibraryCCC && GetFeatureStatus(FeatureType_Native, "CCC_UnLoadClient") == FeatureStatus_Available) + CCC_UnLoadClient(client); #endif } @@ -210,136 +209,73 @@ stock void RemoveClient(int client) GetClientAuthId(client, AuthId_Steam2, sAuth, sizeof(sAuth)); AdminId curAdm = INVALID_ADMIN_ID; - // find and delete the admin using that identity if ((curAdm = FindAdminByIdentity(sAuthType, sAuth)) != INVALID_ADMIN_ID) { - RemoveAdmin(curAdm); - } + // Remove VIP flags + SetAdminFlag(curAdm, Admin_Custom1, false); + SetAdminFlag(curAdm, Admin_Custom2, false); - g_bClientLoaded[client] = true; + // Check if current immunity is from VIP + int currentImmunity = GetAdminImmunityLevel(curAdm); + int vipImmunity = g_cvVIPGroupImmunity.IntValue; + + // If current immunity matches VIP immunity, reset it to 0 + if (currentImmunity == vipImmunity) + { + SetAdminImmunityLevel(curAdm, 0); + } + } + g_bClientLoaded[client] = false; CheckLoadAdmin(client); } -stock void LoadClient(int client) +stock void LoadVIPClient(int client) { - ArrayList Groups = new ArrayList(ByteCountToCells(32)); - char sVIPGroupName[64]; + if (!client) + return; - if (VIP_IsClientVIP(client)) - { - if (!VIP_GetClientVIPGroup(client, sVIPGroupName, sizeof(sVIPGroupName))) - g_cvVIPGroupName.GetString(sVIPGroupName, sizeof(sVIPGroupName)); + char sAuthType[] = "steam"; + char sAuth[32]; + GetClientAuthId(client, AuthId_Steam2, sAuth, sizeof(sAuth)); - Groups.PushString(sVIPGroupName); + AdminId curAdm = INVALID_ADMIN_ID; + if ((curAdm = FindAdminByIdentity(sAuthType, sAuth)) == INVALID_ADMIN_ID) + { + char sName[254]; + GetClientName(client, sName, sizeof(sName)); + curAdm = CreateAdmin(sName); + if (!curAdm.BindIdentity(sAuthType, sAuth)) + { + RemoveAdmin(curAdm); + return; + } } - if (Groups.Length) + if (VIP_IsClientVIP(client)) { - char sAuthType[] = "steam"; - char sAuth[32]; - GetClientAuthId(client, AuthId_Steam2, sAuth, sizeof(sAuth)); + // Add VIP flags to existing admin + SetAdminFlag(curAdm, Admin_Custom1, true); + SetAdminFlag(curAdm, Admin_Custom2, true); - AdminId curAdm = INVALID_ADMIN_ID; - // find or create the admin using that identity - if ((curAdm = FindAdminByIdentity(sAuthType, sAuth)) == INVALID_ADMIN_ID) - { - char sName[254]; - GetClientName(client, sName, sizeof(sName)); - curAdm = CreateAdmin(sName); - // That should never happen! - if (!curAdm.BindIdentity(sAuthType, sAuth)) - { - RemoveAdmin(curAdm); - delete Groups; - return; - } - } - else - { - // Check if admin has important flags - bool hasImportantFlags = false; - AdminFlag importantFlags[] = { - Admin_Kick, - Admin_Ban, - Admin_Unban, - Admin_Slay, - Admin_Changemap, - Admin_Convars, - Admin_Config, - Admin_RCON, - Admin_Root - }; - - for (int i = 0; i < sizeof(importantFlags); i++) - { - if (GetAdminFlag(curAdm, importantFlags[i])) - { - hasImportantFlags = true; - break; - } - } - - // Only remove admin if they don't have important flags - if (!hasImportantFlags) - { - // Remove the admin completely and recreate it - char sName[254]; - GetClientName(client, sName, sizeof(sName)); - RemoveAdmin(curAdm); - curAdm = CreateAdmin(sName); - if (!curAdm.BindIdentity(sAuthType, sAuth)) - { - RemoveAdmin(curAdm); - delete Groups; - return; - } - } - else - { - // Admin has important flags, don't modify their permissions - delete Groups; - return; - } - } + // Check current immunity level + int currentImmunity = GetAdminImmunityLevel(curAdm); + int vipImmunity = g_cvVIPGroupImmunity.IntValue; - for (int i = 0; i < Groups.Length; i++) + // Only set VIP immunity if it's higher than current immunity + if (vipImmunity > currentImmunity) { - char sGroup[32]; - Groups.GetString(i, sGroup, sizeof(sGroup)); - - GroupId grp; - if((grp = FindAdmGroup(sGroup)) == INVALID_GROUP_ID) - { - grp = CreateAdmGroup(sGroup); - if (grp == INVALID_GROUP_ID) - { - LogError("Failed to create admin group: %s", sGroup); - continue; - } - } - - if (StrEqual(sGroup, sVIPGroupName)) - { - // Force set the flags for VIP group - SetAdmGroupAddFlag(grp, Admin_Custom1, true); - SetAdmGroupAddFlag(grp, Admin_Custom2, true); - SetAdmGroupImmunityLevel(grp, g_cvVIPGroupImmunity.IntValue); - } - - // Force inherit the group - if (!AdminInheritGroup(curAdm, grp)) - { - LogError("Failed to inherit admin group %s for admin %s", sGroup, sAuth); - } + SetAdminImmunityLevel(curAdm, vipImmunity); } } - delete Groups; - g_bClientLoaded[client] = true; - CheckLoadAdmin(client); + +#if defined _ccc_included + if (g_bLibraryCCC && GetFeatureStatus(FeatureType_Native, "CCC_LoadClient") == FeatureStatus_Available) + CCC_LoadClient(client); +#endif } stock void CheckLoadAdmin(int client) From fdac040c69f746bcc0271a53de10780367c49585 Mon Sep 17 00:00:00 2001 From: Rushaway Date: Tue, 2 Sep 2025 15:33:09 +0200 Subject: [PATCH 3/6] Refactor VIP client loading and admin checks --- .../sourcemod/scripting/VIP_SourcemodFlags.sp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/addons/sourcemod/scripting/VIP_SourcemodFlags.sp b/addons/sourcemod/scripting/VIP_SourcemodFlags.sp index 2dfc44c..4e58ba3 100644 --- a/addons/sourcemod/scripting/VIP_SourcemodFlags.sp +++ b/addons/sourcemod/scripting/VIP_SourcemodFlags.sp @@ -142,10 +142,14 @@ public void OnClientDisconnect(int client) public Action OnClientPreAdminCheck(int client) { - // If the client is VIP but not loaded yet, load them - if (!g_bClientLoaded[client] && VIP_IsClientVIP(client)) + // If the client hasn't been processed yet, handle both VIP and non-VIP + if (!g_bClientLoaded[client]) { - LoadVIPClient(client); + if (VIP_IsClientVIP(client)) + LoadVIPClient(client); + else + g_bClientLoaded[client] = true; // Non-VIP clients should be marked as processed so they are not blocked + NotifyPostAdminCheck(client); return Plugin_Handled; } @@ -226,8 +230,8 @@ stock void RemoveClient(int client) } } - g_bClientLoaded[client] = false; - CheckLoadAdmin(client); + // Keep client marked as processed; do not reset the loaded flag here + TryNotifyPostAdminCheck(client); } stock void LoadVIPClient(int client) @@ -270,7 +274,7 @@ stock void LoadVIPClient(int client) } g_bClientLoaded[client] = true; - CheckLoadAdmin(client); + TryNotifyPostAdminCheck(client); #if defined _ccc_included if (g_bLibraryCCC && GetFeatureStatus(FeatureType_Native, "CCC_LoadClient") == FeatureStatus_Available) @@ -278,7 +282,8 @@ stock void LoadVIPClient(int client) #endif } -stock void CheckLoadAdmin(int client) +// Ensure admin cache is applied and notify post-admin check when ready +stock void TryNotifyPostAdminCheck(int client) { if (IsClientInGame(client) && IsClientAuthorized(client)) { From 59befb3ac5bf0ed4fa15a3bed736ccc9977ee84c Mon Sep 17 00:00:00 2001 From: Rushaway Date: Wed, 3 Sep 2025 16:04:09 +0200 Subject: [PATCH 4/6] Update VIP_SourcemodFlags.sp --- .../sourcemod/scripting/VIP_SourcemodFlags.sp | 37 ++++++++++++++----- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/addons/sourcemod/scripting/VIP_SourcemodFlags.sp b/addons/sourcemod/scripting/VIP_SourcemodFlags.sp index 4e58ba3..297bf3b 100644 --- a/addons/sourcemod/scripting/VIP_SourcemodFlags.sp +++ b/addons/sourcemod/scripting/VIP_SourcemodFlags.sp @@ -22,6 +22,10 @@ bool g_bReloadVips = false; bool g_bLibraryCCC = false; bool g_bLateLoaded = false; +// Track original immunity levels and VIP immunity status +int g_iOriginalImmunity[MAXPLAYERS + 1] = { 0, ... }; +bool g_bVIPImmunityApplied[MAXPLAYERS + 1] = { false, ... }; + public Plugin myinfo = { name = "[VIP] Sourcemod Flags", @@ -73,7 +77,11 @@ public void OnMapEnd() g_bSbppClientsLoaded = false; g_bReloadVips = false; for (int i = 0; i <= MaxClients; i++) + { g_bClientLoaded[i] = false; + g_iOriginalImmunity[i] = 0; + g_bVIPImmunityApplied[i] = false; + } } public Action Command_ReloadVips(int client, int args) @@ -138,6 +146,8 @@ public bool OnClientConnect(int client, char[] rejectmsg, int maxlen) public void OnClientDisconnect(int client) { g_bClientLoaded[client] = false; + g_iOriginalImmunity[client] = 0; + g_bVIPImmunityApplied[client] = false; } public Action OnClientPreAdminCheck(int client) @@ -199,6 +209,10 @@ stock void UnloadVIPClient(int client) return; RemoveClient(client); + + // Reset client loaded flag to allow reprocessing if VIP status is regained + g_bClientLoaded[client] = false; + g_bVIPImmunityApplied[client] = false; #if defined _ccc_included if (g_bLibraryCCC && GetFeatureStatus(FeatureType_Native, "CCC_UnLoadClient") == FeatureStatus_Available) @@ -219,18 +233,14 @@ stock void RemoveClient(int client) SetAdminFlag(curAdm, Admin_Custom1, false); SetAdminFlag(curAdm, Admin_Custom2, false); - // Check if current immunity is from VIP - int currentImmunity = GetAdminImmunityLevel(curAdm); - int vipImmunity = g_cvVIPGroupImmunity.IntValue; - - // If current immunity matches VIP immunity, reset it to 0 - if (currentImmunity == vipImmunity) + // Only restore immunity if VIP immunity was actually applied + if (g_bVIPImmunityApplied[client]) { - SetAdminImmunityLevel(curAdm, 0); + // Restore original immunity level + SetAdminImmunityLevel(curAdm, g_iOriginalImmunity[client]); } } - // Keep client marked as processed; do not reset the loaded flag here TryNotifyPostAdminCheck(client); } @@ -266,10 +276,19 @@ stock void LoadVIPClient(int client) int currentImmunity = GetAdminImmunityLevel(curAdm); int vipImmunity = g_cvVIPGroupImmunity.IntValue; + // Store original immunity level before applying VIP immunity + g_iOriginalImmunity[client] = currentImmunity; + // Only set VIP immunity if it's higher than current immunity if (vipImmunity > currentImmunity) { SetAdminImmunityLevel(curAdm, vipImmunity); + g_bVIPImmunityApplied[client] = true; + } + else + { + // VIP immunity not applied because current immunity is higher + g_bVIPImmunityApplied[client] = false; } } @@ -282,7 +301,7 @@ stock void LoadVIPClient(int client) #endif } -// Ensure admin cache is applied and notify post-admin check when ready +// Apply admin cache and conditionally notify post-admin check if client is ready and SBPP is loaded stock void TryNotifyPostAdminCheck(int client) { if (IsClientInGame(client) && IsClientAuthorized(client)) From 9ffa9bc4d9db5662048e9449f4f2fd494adde90d Mon Sep 17 00:00:00 2001 From: Rushaway Date: Wed, 3 Sep 2025 16:57:42 +0200 Subject: [PATCH 5/6] Refactor VIP Sourcemod Flags script --- addons/sourcemod/scripting/VIP_SourcemodFlags.sp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/addons/sourcemod/scripting/VIP_SourcemodFlags.sp b/addons/sourcemod/scripting/VIP_SourcemodFlags.sp index 297bf3b..027788e 100644 --- a/addons/sourcemod/scripting/VIP_SourcemodFlags.sp +++ b/addons/sourcemod/scripting/VIP_SourcemodFlags.sp @@ -160,7 +160,7 @@ public Action OnClientPreAdminCheck(int client) else g_bClientLoaded[client] = true; // Non-VIP clients should be marked as processed so they are not blocked - NotifyPostAdminCheck(client); + TryNotifyPostAdminCheck(client); return Plugin_Handled; } @@ -209,7 +209,7 @@ stock void UnloadVIPClient(int client) return; RemoveClient(client); - + // Reset client loaded flag to allow reprocessing if VIP status is regained g_bClientLoaded[client] = false; g_bVIPImmunityApplied[client] = false; @@ -308,8 +308,12 @@ stock void TryNotifyPostAdminCheck(int client) { RunAdminCacheChecks(client); + #if defined _sourcebanspp_included if (g_bSbppClientsLoaded && g_bClientLoaded[client]) + { NotifyPostAdminCheck(client); + } + #endif } } From 51d6040291cac0c38784fcf0e95587adaf229f33 Mon Sep 17 00:00:00 2001 From: Rushaway Date: Thu, 4 Sep 2025 10:22:59 +0200 Subject: [PATCH 6/6] Refactor VIP Sourcemod Flags plugin structure --- addons/sourcemod/scripting/VIP_SourcemodFlags.sp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/addons/sourcemod/scripting/VIP_SourcemodFlags.sp b/addons/sourcemod/scripting/VIP_SourcemodFlags.sp index 027788e..c3ba30a 100644 --- a/addons/sourcemod/scripting/VIP_SourcemodFlags.sp +++ b/addons/sourcemod/scripting/VIP_SourcemodFlags.sp @@ -161,7 +161,7 @@ public Action OnClientPreAdminCheck(int client) g_bClientLoaded[client] = true; // Non-VIP clients should be marked as processed so they are not blocked TryNotifyPostAdminCheck(client); - return Plugin_Handled; + return Plugin_Continue; } return Plugin_Continue; @@ -276,8 +276,9 @@ stock void LoadVIPClient(int client) int currentImmunity = GetAdminImmunityLevel(curAdm); int vipImmunity = g_cvVIPGroupImmunity.IntValue; - // Store original immunity level before applying VIP immunity - g_iOriginalImmunity[client] = currentImmunity; + // Store original immunity level only if VIP immunity was not previously applied + if (!g_bVIPImmunityApplied[client]) + g_iOriginalImmunity[client] = currentImmunity; // Only set VIP immunity if it's higher than current immunity if (vipImmunity > currentImmunity)