From 66dffdbd61a6921f286197f952a7071e5261d1b3 Mon Sep 17 00:00:00 2001 From: R1KO Date: Sat, 10 Oct 2026 21:12:10 +0300 Subject: [PATCH 1/9] Point the README changelog link and AGENTS.md at GitHub Releases; these edits were left out of the updates.md removal. --- AGENTS.md | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 6cc2945..e9cb598 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -47,4 +47,4 @@ - `GLOBAL_TRIE` / `GLOBAL_INFO` are index `[0]` of per-client arrays — slot 0 = global, not a player. - Use methodmaps (`StringMap`, `Cookie`, `KeyValues`, `delete`), not legacy procedural calls (`CreateTrie`, `SetClientCookie`, `CloseHandle`, `Kv*`). - Debug logging via `DBG_*` / `DebugMessage` functions from `Debug.sp` (empty unless `DEBUG_MODE 1`); calls still need a trailing `;`. -- English only in code, comments, cvar descriptions, log/error strings and docs. Other languages live only in `translations/*.phrases.txt` and the per-language values of `data/vip/cfg/*.ini`. Any new user-facing text → new phrase in `vip_core.phrases.txt` with at least `en` and `ru`. Bump `VIP_VERSION` in `VIP_Core.sp` only when asked; changelog lives in `updates.md`. +- English only in code, comments, cvar descriptions, log/error strings and docs. Other languages live only in `translations/*.phrases.txt` and the per-language values of `data/vip/cfg/*.ini`. Any new user-facing text → new phrase in `vip_core.phrases.txt` with at least `en` and `ru`. Bump `VIP_VERSION` in `VIP_Core.sp` only when asked; changelog lives in GitHub Releases (release notes). diff --git a/README.md b/README.md index 6e9d9e6..78935e0 100644 --- a/README.md +++ b/README.md @@ -18,4 +18,4 @@ The plugin is very flexible and easy to configure, it can work with both SQLite ### Guides - [Module update guide](docs/update_modules.md) - [Issue labels](docs/issue_labels.md) -- [Changelog](updates.md) +- [Changelog](https://github.com/R1KO/VIP-Core/releases) From 0ea7661f8f4081a654b7d8ce220f47a7ee98d4cb Mon Sep 17 00:00:00 2001 From: R1KO Date: Sat, 10 Oct 2026 21:20:25 +0300 Subject: [PATCH 2/9] Default iAdmin to -1 (plugin) in VIP_GiveClientVIP and VIP_RemoveClientVIP2, as in 3.1-dev, so calls with _ are logged as by plugin, not by server. Document every iAdmin value and reason the VIP_OnVIPClientAdded/Removed forwards actually receive. --- .../sourcemod/scripting/include/vip_core.inc | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/addons/sourcemod/scripting/include/vip_core.inc b/addons/sourcemod/scripting/include/vip_core.inc index b143796..afe7e03 100644 --- a/addons/sourcemod/scripting/include/vip_core.inc +++ b/addons/sourcemod/scripting/include/vip_core.inc @@ -218,7 +218,10 @@ forward void VIP_OnClientDisconnect(int iClient, bool bIsVIP); * Called when a player receives VIP status. * * @param iClient Client index. - * @param iAdmin Admin index (0 - server). + * @param iAdmin Who gave it: admin index (> 0), 0 - server, + * -1 - admin who left before the database answered, + * -2 - plugin (VIP_GiveClientVIP). + * Check iAdmin > 0 before using it as a client index. * * @noreturn */ @@ -231,8 +234,12 @@ forward void VIP_OnVIPClientAdded(int iClient, int iAdmin); * @param szReason Reason: * "Expired" - Expired; * "Removed by Admin" - Removed by an admin; - * "Removed by native" - Removed by a native. - * @param iAdmin Admin index (0 - server). + * "VIP-Group Changed" - Group changed by an admin; + * "Removed for VIP-status change" - VIP given again via VIP_GiveClientVIP; + * "Removed by " - Removed via VIP_RemoveClientVIP2. + * @param iAdmin Who removed it: admin index (> 0), 0 - server (expiry), + * -2 - plugin. + * Check iAdmin > 0 before using it as a client index. * * @noreturn */ @@ -428,7 +435,8 @@ native void VIP_SendClientVIPMenu(int iClient, bool bSelection = false); /** * Gives VIP rights to a player. * - * @param iAdmin Admin index (0 - server, -1 or any negative - plugin). + * @param iAdmin Admin index, 0 - server, -1 or any negative - plugin (default). + * Logged as "by server" / "by plugin " / "by admin ". * @param iClient Client index. * @param iTime Time in seconds. * @param szGroup VIP group name. @@ -436,7 +444,7 @@ native void VIP_SendClientVIPMenu(int iClient, bool bSelection = false); * * @noreturn */ -native void VIP_GiveClientVIP(int iAdmin = 0, int iClient, int iTime, const char[] szGroup, bool bAddToDB = true); +native void VIP_GiveClientVIP(int iAdmin = -1, int iClient, int iTime, const char[] szGroup, bool bAddToDB = true); #pragma deprecated Use VIP_GiveClientVIP() instead native bool VIP_SetClientVIP(int iClient, int iTime, any AuthType, const char[] szGroup, bool bAddToDB = true); @@ -444,7 +452,8 @@ native bool VIP_SetClientVIP(int iClient, int iTime, any AuthType, const char[] /** * Removes VIP rights from a player. * - * @param iAdmin Admin index (0 - server, -1 or any negative - plugin). + * @param iAdmin Admin index, 0 - server, -1 or any negative - plugin (default). + * Logged as "by server" / "by plugin " / "by admin ". * @param iClient Client index. * @param bInDB Whether to remove from the database. * @param bNotify Player notification (true - notify / false - do not notify). @@ -452,7 +461,7 @@ native bool VIP_SetClientVIP(int iClient, int iTime, any AuthType, const char[] * @return true - on success. * false - on failure. */ -native bool VIP_RemoveClientVIP2(int iAdmin = 0, int iClient, bool bInDB, bool bNotify); +native bool VIP_RemoveClientVIP2(int iAdmin = -1, int iClient, bool bInDB, bool bNotify); #pragma deprecated Use VIP_RemoveClientVIP2() instead native bool VIP_RemoveClientVIP(int iClient, bool bInDB, bool bNotify); From c85b948afca8e20f258d89226ef68186b26f4a85 Mon Sep 17 00:00:00 2001 From: R1KO Date: Sat, 10 Oct 2026 21:23:11 +0300 Subject: [PATCH 3/9] Build the server filter (g_szSID) in one place, DB_UpdateServerFilter, instead of three copies. The admin VIP list now uses one query for MySQL and SQLite (WHERE 1 plus filters) instead of three branches and the [5] string slicing. --- addons/sourcemod/scripting/vip/Clients.sp | 12 +------- addons/sourcemod/scripting/vip/Cvars.sp | 13 +-------- addons/sourcemod/scripting/vip/Database.sp | 23 +++++++++++---- .../sourcemod/scripting/vip/adminmenu/List.sp | 28 ++----------------- 4 files changed, 22 insertions(+), 54 deletions(-) diff --git a/addons/sourcemod/scripting/vip/Clients.sp b/addons/sourcemod/scripting/vip/Clients.sp index 2eb0547..9726ead 100644 --- a/addons/sourcemod/scripting/vip/Clients.sp +++ b/addons/sourcemod/scripting/vip/Clients.sp @@ -106,20 +106,10 @@ void Clients_LoadClient(int iClient, bool bNotify) return; } - char szWhere[64]; - if(g_szSID[0]) - { - #if USE_MORE_SERVERS - FormatEx(SZF(szWhere), " AND (`sid` = %d OR `sid` = 0)", g_CVAR_iServerID); - #else - strcopy(SZF(szWhere), g_szSID); - #endif - } - FormatEx(SZF(szQuery), "SELECT `expires`, `group`, `name` \ FROM `vip_users` \ WHERE `account_id` = %d%s LIMIT 1;", - iAccountID, szWhere); + iAccountID, g_szSID); DataPack hDataPack = new DataPack(); hDataPack.WriteCell(UID(iClient)); diff --git a/addons/sourcemod/scripting/vip/Cvars.sp b/addons/sourcemod/scripting/vip/Cvars.sp index eb3e3e4..b012255 100644 --- a/addons/sourcemod/scripting/vip/Cvars.sp +++ b/addons/sourcemod/scripting/vip/Cvars.sp @@ -72,18 +72,7 @@ public void OnAdminFlagChange(ConVar hCvar, const char[] szOldValue, const char[ public void OnServerIDChange(ConVar hCvar, const char[] szOldValue, const char[] szNewValue) { g_CVAR_iServerID = hCvar.IntValue; - if (GLOBAL_INFO & IS_MySQL) - { - #if USE_MORE_SERVERS - FormatEx(SZF(g_szSID), " AND (`sid` = %d OR `sid` = 0)", g_CVAR_iServerID); - #else - FormatEx(SZF(g_szSID), " AND `sid` = %d", g_CVAR_iServerID); - #endif - } - else - { - g_szSID[0] = 0; - } + DB_UpdateServerFilter(); } public void OnStorageIDChange(ConVar hCvar, const char[] szOldValue, const char[] szNewValue) diff --git a/addons/sourcemod/scripting/vip/Database.sp b/addons/sourcemod/scripting/vip/Database.sp index 6914e72..958764e 100644 --- a/addons/sourcemod/scripting/vip/Database.sp +++ b/addons/sourcemod/scripting/vip/Database.sp @@ -75,17 +75,29 @@ public void OnDBConnect(Database hDatabase, const char[] szError, any data) CreateTables(); } +void DB_UpdateServerFilter() +{ + if (!(GLOBAL_INFO & IS_MySQL)) + { + g_szSID[0] = 0; + return; + } + + #if USE_MORE_SERVERS + FormatEx(SZF(g_szSID), " AND (`sid` = %d OR `sid` = 0)", g_CVAR_iServerID); + #else + FormatEx(SZF(g_szSID), " AND `sid` = %d", g_CVAR_iServerID); + #endif +} + void CreateTables() { DBG_Database("CreateTables"); + DB_UpdateServerFilter(); + if (GLOBAL_INFO & IS_MySQL) { - #if USE_MORE_SERVERS - FormatEx(SZF(g_szSID), " AND (`sid` = %d OR `sid` = 0)", g_CVAR_iServerID); - #else - FormatEx(SZF(g_szSID), " AND `sid` = %d", g_CVAR_iServerID); - #endif g_hDatabase.Query(SQL_Callback_StorageTableCreate, "CREATE TABLE IF NOT EXISTS `vip_storage` (\ `account_id` INT NOT NULL, \ `sid` INT UNSIGNED NOT NULL, \ @@ -106,7 +118,6 @@ void CreateTables() } else { - g_szSID[0] = 0; g_hDatabase.Query(SQL_Callback_StorageTableCreate, "CREATE TABLE IF NOT EXISTS `vip_storage` (\ `account_id` INTEGER NOT NULL, \ `key` VARCHAR(128) NOT NULL, \ diff --git a/addons/sourcemod/scripting/vip/adminmenu/List.sp b/addons/sourcemod/scripting/vip/adminmenu/List.sp index 0d194b2..d3f0db4 100644 --- a/addons/sourcemod/scripting/vip/adminmenu/List.sp +++ b/addons/sourcemod/scripting/vip/adminmenu/List.sp @@ -218,31 +218,9 @@ void ShowVipPlayersFromDBMenu(int iClient, int iOffset = 0) } } - if (GLOBAL_INFO & IS_MySQL) - { - FormatEx(SZF(szQuery), "SELECT `account_id`, \ - `name` \ - FROM `vip_users` \ - WHERE %s%s \ - LIMIT %d, %d;", - g_szSID[5], szWhere, iOffset, LIST_OFFSET); - } - else - { - if(szWhere[0]) - { - FormatEx(SZF(szQuery), "SELECT `account_id`, `name` \ - FROM `vip_users` \ - WHERE %s LIMIT %d, %d;", - szWhere[5], iOffset, LIST_OFFSET); - } - else - { - FormatEx(SZF(szQuery), "SELECT `account_id`, `name` \ - FROM `vip_users` LIMIT %d, %d;", - iOffset, LIST_OFFSET); - } - } + // WHERE 1 lets every filter start with " AND ", on both MySQL and SQLite + FormatEx(SZF(szQuery), "SELECT `account_id`, `name` FROM `vip_users` WHERE 1%s%s LIMIT %d, %d;", + g_szSID, szWhere, iOffset, LIST_OFFSET); DBG_SQL_Query(szQuery); From f20510cfa3b518dc510b570d96df8a3a47180a3a Mon Sep 17 00:00:00 2001 From: R1KO Date: Sat, 10 Oct 2026 22:16:43 +0300 Subject: [PATCH 4/9] Store registered features as an enum struct Feature in g_hFeatureRegistry instead of an ArrayList with FEATURES_* indexes in g_hFeatures[0]. Menu callbacks are plain Function fields, so the DataPack and its SM 1.10 position workaround are gone; behavior is unchanged. --- addons/sourcemod/scripting/VIP_Core.sp | 10 +- addons/sourcemod/scripting/vip/API.sp | 132 ++++++++------------- addons/sourcemod/scripting/vip/CMD.sp | 16 ++- addons/sourcemod/scripting/vip/Clients.sp | 16 ++- addons/sourcemod/scripting/vip/Features.sp | 58 +++------ addons/sourcemod/scripting/vip/Global.sp | 24 ++-- addons/sourcemod/scripting/vip/VipMenu.sp | 49 +++----- 7 files changed, 109 insertions(+), 196 deletions(-) diff --git a/addons/sourcemod/scripting/VIP_Core.sp b/addons/sourcemod/scripting/VIP_Core.sp index 257c696..2350f37 100644 --- a/addons/sourcemod/scripting/VIP_Core.sp +++ b/addons/sourcemod/scripting/VIP_Core.sp @@ -67,15 +67,7 @@ public void OnPluginStart() g_iMaxPageItems = GetMaxPageItems(GetMenuStyleHandle(MenuStyle_Default)); g_hFeaturesArray = new ArrayList(ByteCountToCells(FEATURE_NAME_LENGTH)); - GLOBAL_TRIE = new StringMap(); - - // Fix DataPack positions in sm 1.10 - DataPack hDataPack = new DataPack(); - hDataPack.WriteCell(0); - ITEM_DISPLAY = hDataPack.Position; - hDataPack.WriteCell(0); - ITEM_DRAW = hDataPack.Position; - delete hDataPack; + g_hFeatureRegistry = new StringMap(); API_SetupForwards(); ReadConfigs(); diff --git a/addons/sourcemod/scripting/vip/API.sp b/addons/sourcemod/scripting/vip/API.sp index 45dfb06..3564e96 100644 --- a/addons/sourcemod/scripting/vip/API.sp +++ b/addons/sourcemod/scripting/vip/API.sp @@ -870,35 +870,22 @@ public int Native_RegisterFeature(Handle hPlugin, int iNumParams) DBG_API("VIP_ToggleState -> %s", g_szToggleState[view_as(eDefStatus)]); DBG_API("Cookie -> %s", bCookie ? "true" : "false"); - ArrayList hArray = new ArrayList(); - GLOBAL_TRIE.SetValue(szFeature, hArray); - - hArray.Push(hPlugin); - hArray.Push(eValType); - hArray.Push(eType); + Feature eFeature; + eFeature.hPlugin = hPlugin; + eFeature.eValType = eValType; + eFeature.eType = eType; + eFeature.eDefStatus = eDefStatus; + eFeature.fnSelect = ItemSelectCallback; + eFeature.fnDisplay = ItemDisplayCallback; + eFeature.fnDraw = ItemDrawCallback; + if (eType == TOGGLABLE || (eType == SELECTABLE && bCookie)) + { + eFeature.hCookie = new Cookie(szFeature, szFeature, CookieAccess_Private); + } + g_hFeatureRegistry.SetArray(szFeature, eFeature, sizeof(eFeature)); if (eType != HIDE) { - Cookie hCookie = null; - bool bRegisterCookie = (eType == SELECTABLE && bCookie); - if (eType == TOGGLABLE || bRegisterCookie) - { - hCookie = new Cookie(szFeature, szFeature, CookieAccess_Private); - } - - hArray.Push(hCookie); - - DataPack hDataPack = new DataPack(); - hDataPack.WriteFunction(ItemSelectCallback); - hDataPack.WriteFunction(ItemDisplayCallback); - hDataPack.WriteFunction(ItemDrawCallback); - hArray.Push(hDataPack); - - if (eType == TOGGLABLE) - { - hArray.Push(eDefStatus); - } - AddFeatureToVIPMenu(szFeature); } @@ -928,10 +915,10 @@ public int Native_UnregisterFeature(Handle hPlugin, int iNumParams) if (IsValidFeature(szFeature)) { - ArrayList hArray; - if (GLOBAL_TRIE.GetValue(szFeature, hArray) /* && view_as(hArray.Get(FEATURES_PLUGIN)) == hPlugin*/) + Feature eFeature; + if (Features_Get(szFeature, eFeature)) { - UnregisterFeature(szFeature, hArray); + UnregisterFeature(szFeature, eFeature); int i = g_hFeaturesArray.FindString(szFeature); if (i != -1) @@ -953,21 +940,21 @@ public int Native_UnregisterMe(Handle hPlugin, int iNumParams) DebugMessage("FeaturesArraySize: %d", g_hFeaturesArray.Length); if (g_hFeaturesArray.Length > 0) { - char szFeature[FEATURE_NAME_LENGTH]; - ArrayList hArray; + char szFeature[FEATURE_NAME_LENGTH]; + Feature eFeature; for (int i = 0, iSize = g_hFeaturesArray.Length; i < iSize; ++i) { g_hFeaturesArray.GetString(i, SZF(szFeature)); - if (GLOBAL_TRIE.GetValue(szFeature, hArray)) + if (Features_Get(szFeature, eFeature)) { - if (view_as(hArray.Get(FEATURES_PLUGIN)) != hPlugin) + if (eFeature.hPlugin != hPlugin) { continue; } - UnregisterFeature(szFeature, hArray); + UnregisterFeature(szFeature, eFeature); g_hFeaturesArray.Erase(i); --i; @@ -979,21 +966,12 @@ public int Native_UnregisterMe(Handle hPlugin, int iNumParams) return 0; } -void UnregisterFeature(const char[] szFeature, ArrayList hArray) +void UnregisterFeature(const char[] szFeature, Feature eFeature) { - VIP_FeatureType eType = view_as(hArray.Get(FEATURES_ITEM_TYPE)); - if (eType != HIDE) - { - // TOGGLABLE and SELECTABLE (bCookie) features own a cookie handle, others store null - delete view_as(hArray.Get(FEATURES_COOKIE)); - delete view_as(hArray.Get(FEATURES_MENU_CALLBACKS)); - } - - delete hArray; - - GLOBAL_TRIE.Remove(szFeature); + delete eFeature.hCookie; + g_hFeatureRegistry.Remove(szFeature); - if (eType != HIDE) + if (eFeature.eType != HIDE) { char szItemInfo[FEATURE_NAME_LENGTH]; for (int j = 0, iSize = g_hVIPMenu.ItemCount; j < iSize; ++j) @@ -1038,10 +1016,10 @@ public int Native_GetFeatureType(Handle hPlugin, int iNumParams) char szFeature[FEATURE_NAME_LENGTH]; GetNativeString(1, SZF(szFeature)); - ArrayList hArray; - if (GLOBAL_TRIE.GetValue(szFeature, hArray)) + Feature eFeature; + if (Features_Get(szFeature, eFeature)) { - return hArray.Get(FEATURES_ITEM_TYPE); + return view_as(eFeature.eType); } return ThrowNativeError(SP_ERROR_NATIVE, "Feature \"%s\" is invalid", szFeature); @@ -1052,10 +1030,10 @@ public int Native_GetFeatureValueType(Handle hPlugin, int iNumParams) char szFeature[FEATURE_NAME_LENGTH]; GetNativeString(1, SZF(szFeature)); - ArrayList hArray; - if (GLOBAL_TRIE.GetValue(szFeature, hArray)) + Feature eFeature; + if (Features_Get(szFeature, eFeature)) { - return hArray.Get(FEATURES_VALUE_TYPE); + return view_as(eFeature.eValType); } return ThrowNativeError(SP_ERROR_NATIVE, "Feature \"%s\" is invalid", szFeature); @@ -1120,20 +1098,14 @@ public int Native_SetClientFeatureStatus(Handle hPlugin, int iNumParams) eOldStatus = Features_GetStatus(iClient, szFeature); eNewStatus = view_as(GetNativeCell(3)); - ArrayList hArray; - if (GLOBAL_TRIE.GetValue(szFeature, hArray)) + Feature eFeature; + if (Features_Get(szFeature, eFeature)) { - if (view_as(hArray.Get(FEATURES_ITEM_TYPE)) == TOGGLABLE) + if (eFeature.eType == TOGGLABLE) { - if (iNumParams > 3 && GetNativeCell(4)) + if (iNumParams > 3 && GetNativeCell(4) && eFeature.fnSelect != INVALID_FUNCTION) { - DataPack hDataPack = view_as(hArray.Get(FEATURES_MENU_CALLBACKS)); - hDataPack.Position = ITEM_SELECT; - Function Function_Select = hDataPack.ReadFunction(); - if (Function_Select != INVALID_FUNCTION) - { - Function_OnItemToggle(view_as(hArray.Get(FEATURES_PLUGIN)), Function_Select, iClient, szFeature, eOldStatus, eNewStatus); - } + Function_OnItemToggle(eFeature.hPlugin, eFeature.fnSelect, iClient, szFeature, eOldStatus, eNewStatus); } if (eOldStatus != eNewStatus) @@ -1141,7 +1113,7 @@ public int Native_SetClientFeatureStatus(Handle hPlugin, int iNumParams) Features_SetStatus(iClient, szFeature, eNewStatus); if (iNumParams > 4 && GetNativeCell(5)) { - Features_SaveStatus(iClient, szFeature, hArray, eNewStatus); + Features_SaveStatus(iClient, szFeature, eFeature.hCookie, eNewStatus); } return true; } @@ -1230,8 +1202,8 @@ public int Native_GiveClientFeature(Handle hPlugin, int iNumParams) { char szFeature[64]; GetNativeString(2, SZF(szFeature)); - ArrayList hArray; - if (!IsValidFeature(szFeature) || !GLOBAL_TRIE.GetValue(szFeature, hArray)) + Feature eFeature; + if (!IsValidFeature(szFeature) || !Features_Get(szFeature, eFeature)) { ThrowNativeError(SP_ERROR_NATIVE, "Feature \"%s\" is invalid", szFeature); return 0; @@ -1247,7 +1219,7 @@ public int Native_GiveClientFeature(Handle hPlugin, int iNumParams) g_iClientInfo[iClient] |= IS_VIP | IS_LOADED; } - switch (view_as(hArray.Get(FEATURES_VALUE_TYPE))) + switch (eFeature.eValType) { case BOOL: { @@ -1269,15 +1241,11 @@ public int Native_GiveClientFeature(Handle hPlugin, int iNumParams) Features_SetStatus(iClient, szFeature, ENABLED); - if (view_as(hArray.Get(FEATURES_ITEM_TYPE)) == TOGGLABLE) + if (eFeature.eType == TOGGLABLE) { - DataPack hDataPack = view_as(hArray.Get(FEATURES_MENU_CALLBACKS)); - hDataPack.Position = ITEM_SELECT; - Function fCallback = hDataPack.ReadFunction(); - - if (fCallback != INVALID_FUNCTION) + if (eFeature.fnSelect != INVALID_FUNCTION) { - Function_OnItemToggle(view_as(hArray.Get(FEATURES_PLUGIN)), fCallback, iClient, szFeature, NO_ACCESS, ENABLED); + Function_OnItemToggle(eFeature.hPlugin, eFeature.fnSelect, iClient, szFeature, NO_ACCESS, ENABLED); } CreateForward_OnFeatureToggle(iClient, szFeature, NO_ACCESS, ENABLED); } @@ -1295,8 +1263,8 @@ public int Native_RemoveClientFeature(Handle hPlugin, int iNumParams) { char szFeature[64]; GetNativeString(2, SZF(szFeature)); - ArrayList hArray; - if (!IsValidFeature(szFeature) || !GLOBAL_TRIE.GetValue(szFeature, hArray)) + Feature eFeature; + if (!IsValidFeature(szFeature) || !Features_Get(szFeature, eFeature)) { ThrowNativeError(SP_ERROR_NATIVE, "Feature \"%s\" is invalid", szFeature); return 0; @@ -1312,15 +1280,11 @@ public int Native_RemoveClientFeature(Handle hPlugin, int iNumParams) ResetClient(iClient); } - if (eToggleState != NO_ACCESS && view_as(hArray.Get(FEATURES_ITEM_TYPE)) == TOGGLABLE) + if (eToggleState != NO_ACCESS && eFeature.eType == TOGGLABLE) { - DataPack hDataPack = view_as(hArray.Get(FEATURES_MENU_CALLBACKS)); - hDataPack.Position = ITEM_SELECT; - Function fCallback = hDataPack.ReadFunction(); - - if (fCallback != INVALID_FUNCTION) + if (eFeature.fnSelect != INVALID_FUNCTION) { - Function_OnItemToggle(view_as(hArray.Get(FEATURES_PLUGIN)), fCallback, iClient, szFeature, eToggleState, NO_ACCESS); + Function_OnItemToggle(eFeature.hPlugin, eFeature.fnSelect, iClient, szFeature, eToggleState, NO_ACCESS); } CreateForward_OnFeatureToggle(iClient, szFeature, eToggleState, NO_ACCESS); } diff --git a/addons/sourcemod/scripting/vip/CMD.sp b/addons/sourcemod/scripting/vip/CMD.sp index 103828f..c3c807e 100644 --- a/addons/sourcemod/scripting/vip/CMD.sp +++ b/addons/sourcemod/scripting/vip/CMD.sp @@ -211,21 +211,19 @@ public Action DumpFeatures_CMD(int iClient, int iArgs) char szFeature[FEATURE_NAME_LENGTH]; char szFeatureType[32]; char szFeatureValType[32]; - ArrayList hArray; - Handle hPlugin; + Feature eFeature; for(int i = 0; i < iFeatures; ++i) { g_hFeaturesArray.GetString(i, SZF(szFeature)); - if(GLOBAL_TRIE.GetValue(szFeature, hArray)) + if (Features_Get(szFeature, eFeature)) { - hPlugin = view_as(hArray.Get(FEATURES_PLUGIN)); - GetPluginInfo(hPlugin, PlInfo_Name, SZF(szPluginName)); - GetPluginInfo(hPlugin, PlInfo_Version, SZF(szPluginVersion)); - GetPluginFilename(hPlugin, SZF(szPluginPath)); + GetPluginInfo(eFeature.hPlugin, PlInfo_Name, SZF(szPluginName)); + GetPluginInfo(eFeature.hPlugin, PlInfo_Version, SZF(szPluginVersion)); + GetPluginFilename(eFeature.hPlugin, SZF(szPluginPath)); - strcopy(SZF(szFeatureType), g_szFeatureType[view_as(hArray.Get(FEATURES_ITEM_TYPE))]); - strcopy(SZF(szFeatureValType), g_szValueType[view_as(hArray.Get(FEATURES_VALUE_TYPE))]); + strcopy(SZF(szFeatureType), g_szFeatureType[view_as(eFeature.eType)]); + strcopy(SZF(szFeatureValType), g_szValueType[view_as(eFeature.eValType)]); hFile.WriteLine("%d. %-32s %-16s %-16s %-64s %-32s %-256s", i, szFeature, szFeatureType, szFeatureValType, szPluginName, szPluginVersion, szPluginPath); } diff --git a/addons/sourcemod/scripting/vip/Clients.sp b/addons/sourcemod/scripting/vip/Clients.sp index 9726ead..bdb22c4 100644 --- a/addons/sourcemod/scripting/vip/Clients.sp +++ b/addons/sourcemod/scripting/vip/Clients.sp @@ -370,30 +370,30 @@ void Clients_LoadVIPFeature(int iClient, const char[] szFeature) void Clients_LoadFeature(int iClient, const char[] szFeature) { - static ArrayList hArray; - if (!GLOBAL_TRIE.GetValue(szFeature, hArray)) + Feature eFeature; + if (!Features_Get(szFeature, eFeature)) { return; } DBG_Clients("LoadClientFeature: %s", szFeature); - if (!GetValue(iClient, view_as(hArray.Get(FEATURES_VALUE_TYPE)), szFeature)) + if (!GetValue(iClient, eFeature.eValType, szFeature)) { return; } static VIP_ToggleState eStatus; DBG_Clients("GetValue: == true"); - if (view_as(hArray.Get(FEATURES_ITEM_TYPE)) == TOGGLABLE) + if (eFeature.eType == TOGGLABLE) { static char szBuffer[4]; - Features_GetSavedStatus(iClient, szFeature, hArray, SZF(szBuffer)); + Features_GetSavedStatus(iClient, szFeature, eFeature.hCookie, SZF(szBuffer)); eStatus = view_as(StringToInt(szBuffer)); DBG_Clients("GetSavedStatus: '%s'", szBuffer); if (szBuffer[0] == '\0' || !Features_IsValidStatus(eStatus)) { - switch(hArray.Get(FEATURES_DEF_STATUS)) + switch(eFeature.eDefStatus) { case NO_ACCESS: eStatus = g_CVAR_bDefaultStatus ? ENABLED : DISABLED; case ENABLED: eStatus = ENABLED; @@ -403,9 +403,8 @@ void Clients_LoadFeature(int iClient, const char[] szFeature) // Persist the default only once the store is loaded, so it can't shadow a value that is still loading if (Features_IsStatusStoreReady(iClient)) { - Features_SaveStatus(iClient, szFeature, hArray, eStatus); + Features_SaveStatus(iClient, szFeature, eFeature.hCookie, eStatus); } - // Features_SaveStatus(iClient, szFeature, hCookie, eStatus); } } else @@ -414,7 +413,6 @@ void Clients_LoadFeature(int iClient, const char[] szFeature) } Features_SetStatus(iClient, szFeature, eStatus); - // Function_OnItemToggle(view_as(hArray.Get(FEATURES_PLUGIN)), Function:hArray.Get(FEATURES_ITEM_SELECT), iClient, szFeature, NO_ACCESS, ENABLED); } bool Features_IsValidStatus(VIP_ToggleState eStatus) diff --git a/addons/sourcemod/scripting/vip/Features.sp b/addons/sourcemod/scripting/vip/Features.sp index 380b527..196b2d2 100644 --- a/addons/sourcemod/scripting/vip/Features.sp +++ b/addons/sourcemod/scripting/vip/Features.sp @@ -1,3 +1,8 @@ +bool Features_Get(const char[] szFeature, Feature eFeature) +{ + return g_hFeatureRegistry.GetArray(szFeature, eFeature, sizeof(eFeature)); +} + void Features_TurnOffAll(int iClient) { DebugMessage("Features_TurnOffAll %N (%i)", iClient, iClient); @@ -13,31 +18,19 @@ void Features_TurnOffAll(int iClient) } char szFeature[FEATURE_NAME_LENGTH]; - VIP_ToggleState eOldStatus; - Function Function_Toggle; - ArrayList hArray; - DataPack hDataPack; + Feature eFeature; for(int i = 0; i < iFeatures; ++i) { g_hFeaturesArray.GetString(i, SZF(szFeature)); - if (!GLOBAL_TRIE.GetValue(szFeature, hArray)) - { - continue; - } - - if (view_as(hArray.Get(FEATURES_ITEM_TYPE)) != TOGGLABLE) + if (!Features_Get(szFeature, eFeature) || eFeature.eType != TOGGLABLE) { continue; } - eOldStatus = Features_GetStatus(iClient, szFeature); - hDataPack = view_as(hArray.Get(FEATURES_MENU_CALLBACKS)); - hDataPack.Position = ITEM_SELECT; - Function_Toggle = hDataPack.ReadFunction(); - if(Function_Toggle != INVALID_FUNCTION) + if (eFeature.fnSelect != INVALID_FUNCTION) { - Function_OnItemToggle(view_as(hArray.Get(FEATURES_PLUGIN)), Function_Toggle, iClient, szFeature, eOldStatus, NO_ACCESS); + Function_OnItemToggle(eFeature.hPlugin, eFeature.fnSelect, iClient, szFeature, Features_GetStatus(iClient, szFeature), NO_ACCESS); } } } @@ -53,34 +46,21 @@ void Features_TurnOnAll(int iClient) } char szFeature[FEATURE_NAME_LENGTH]; + Feature eFeature; VIP_ToggleState eNewStatus; - Function Function_Toggle; - ArrayList hArray; - DataPack hDataPack; for(int i = 0; i < iFeatures; ++i) { g_hFeaturesArray.GetString(i, SZF(szFeature)); - if (!GLOBAL_TRIE.GetValue(szFeature, hArray)) - { - continue; - } - - if (view_as(hArray.Get(FEATURES_ITEM_TYPE)) != TOGGLABLE) + if (!Features_Get(szFeature, eFeature) || eFeature.eType != TOGGLABLE || eFeature.fnSelect == INVALID_FUNCTION) { continue; } - hDataPack = view_as(hArray.Get(FEATURES_MENU_CALLBACKS)); - hDataPack.Position = ITEM_SELECT; - Function_Toggle = hDataPack.ReadFunction(); - if(Function_Toggle != INVALID_FUNCTION) + eNewStatus = Features_GetStatus(iClient, szFeature); + if (eNewStatus != NO_ACCESS) { - eNewStatus = Features_GetStatus(iClient, szFeature); - if(eNewStatus != NO_ACCESS) - { - Function_OnItemToggle(view_as(hArray.Get(FEATURES_PLUGIN)), Function_Toggle, iClient, szFeature, NO_ACCESS, eNewStatus); - } + Function_OnItemToggle(eFeature.hPlugin, eFeature.fnSelect, iClient, szFeature, NO_ACCESS, eNewStatus); } } } @@ -114,10 +94,8 @@ bool Features_IsStatusStoreReady(int iClient) #endif } -void Features_GetSavedStatus(int iClient, const char[] szFeature, ArrayList hArray, char[] szValue, int iMaxLength) +void Features_GetSavedStatus(int iClient, const char[] szFeature, Cookie hCookie, char[] szValue, int iMaxLength) { - Cookie hCookie = view_as(hArray.Get(FEATURES_COOKIE)); - #if USE_CLIENTPREFS #pragma unused szFeature hCookie.Get(iClient, szValue, iMaxLength); @@ -135,16 +113,16 @@ void Features_GetSavedStatus(int iClient, const char[] szFeature, ArrayList hArr #endif } -void Features_SaveStatus(int iClient, const char[] szFeature, ArrayList hArray, VIP_ToggleState eStatus) +void Features_SaveStatus(int iClient, const char[] szFeature, Cookie hCookie, VIP_ToggleState eStatus) { char szValue[4]; IntToString(view_as(eStatus), SZF(szValue)); #if USE_CLIENTPREFS #pragma unused szFeature - view_as(hArray.Get(FEATURES_COOKIE)).Set(iClient, szValue); + hCookie.Set(iClient, szValue); #else - #pragma unused hArray + #pragma unused hCookie char szKey[STORAGE_KEY_LENGTH]; Features_GetStorageKey(szFeature, SZF(szKey)); Storage_SetClientValue(iClient, szKey, szValue); diff --git a/addons/sourcemod/scripting/vip/Global.sp b/addons/sourcemod/scripting/vip/Global.sp index c5348b9..4819eb5 100644 --- a/addons/sourcemod/scripting/vip/Global.sp +++ b/addons/sourcemod/scripting/vip/Global.sp @@ -1,4 +1,3 @@ -#define GLOBAL_TRIE g_hFeatures[0] #define GLOBAL_INFO g_iClientInfo[0] #define UID(%0) GetClientUserId(%0) @@ -40,20 +39,18 @@ stock const char KEY_EXPIRES[] = "Core->Expires"; stock const char KEY_GROUP[] = "Core->Group"; stock const char KEY_MENUITEM[] = "Core->SelectionItem"; -enum +enum struct Feature { - FEATURES_PLUGIN = 0, - FEATURES_VALUE_TYPE, - FEATURES_ITEM_TYPE, - FEATURES_COOKIE, - FEATURES_MENU_CALLBACKS, - FEATURES_DEF_STATUS + Handle hPlugin; + VIP_ValueType eValType; + VIP_FeatureType eType; + VIP_ToggleState eDefStatus; + Cookie hCookie; // TOGGLABLE, or SELECTABLE registered with bCookie; null otherwise + Function fnSelect; + Function fnDisplay; + Function fnDraw; } -DataPackPos ITEM_SELECT = view_as(0); -DataPackPos ITEM_DISPLAY; -DataPackPos ITEM_DRAW; - enum { TIME_MODE_SECONDS = 0, @@ -93,7 +90,8 @@ Database g_hDatabase; Menu g_hVIPMenu; -ArrayList g_hFeaturesArray; +ArrayList g_hFeaturesArray; // Feature names in registration order +StringMap g_hFeatureRegistry; // Feature name -> Feature ArrayList g_hSortArray; StringMap g_hFeatures[MAXPLAYERS+1]; diff --git a/addons/sourcemod/scripting/vip/VipMenu.sp b/addons/sourcemod/scripting/vip/VipMenu.sp index 142c5e1..8ee3b78 100644 --- a/addons/sourcemod/scripting/vip/VipMenu.sp +++ b/addons/sourcemod/scripting/vip/VipMenu.sp @@ -16,12 +16,12 @@ void AddFeatureToVIPMenu(const char[] szFeature) int i, iSize; char szItemInfo[128]; - ArrayList hArray; + Feature eFeature; iSize = g_hFeaturesArray.Length; for (i = 0; i < iSize; ++i) { g_hFeaturesArray.GetString(i, SZF(szItemInfo)); - if (GLOBAL_TRIE.GetValue(szItemInfo, hArray) && view_as(hArray.Get(FEATURES_ITEM_TYPE)) != HIDE) + if (Features_Get(szItemInfo, eFeature) && eFeature.eType != HIDE) { DebugMessage("AddMenuItem: %s", szItemInfo); g_hVIPMenu.AddItem(szItemInfo, szItemInfo); @@ -107,9 +107,7 @@ public int Handler_VIPMenu(Menu hMenu, MenuAction action, int iClient, int iOpti } } static char szItemInfo[FEATURE_NAME_LENGTH]; - ArrayList hBuffer; - Function fCallback; - Handle hPlugin; + Feature eFeature; /* switch (action) { @@ -171,21 +169,17 @@ public int Handler_VIPMenu(Menu hMenu, MenuAction action, int iClient, int iOpti DebugMessage("MenuAction_DrawItem: Client: %i, Feature: %s, iStyle: %i", iClient, szItemInfo, iStyle); - if (GLOBAL_TRIE.GetValue(szItemInfo, hBuffer)) + if (Features_Get(szItemInfo, eFeature)) { - if (view_as(hBuffer.Get(FEATURES_VALUE_TYPE)) != VIP_NULL && Features_GetStatus(iClient, szItemInfo) == NO_ACCESS) + if (eFeature.eValType != VIP_NULL && Features_GetStatus(iClient, szItemInfo) == NO_ACCESS) { iStyle = g_CVAR_bHideNoAccessItems ? ITEMDRAW_RAWLINE:ITEMDRAW_DISABLED; DebugMessage("NO_ACCESS -> iStyle: %i", iStyle); } - DataPack hDataPack = hBuffer.Get(FEATURES_MENU_CALLBACKS); - hDataPack.Position = ITEM_DRAW; - fCallback = hDataPack.ReadFunction(); - if (fCallback != INVALID_FUNCTION) + if (eFeature.fnDraw != INVALID_FUNCTION) { - hPlugin = view_as(hBuffer.Get(FEATURES_PLUGIN)); - Call_StartFunction(hPlugin, fCallback); + Call_StartFunction(eFeature.hPlugin, eFeature.fnDraw); Call_PushCell(iClient); Call_PushString(szItemInfo); Call_PushCell(iStyle); @@ -207,18 +201,13 @@ public int Handler_VIPMenu(Menu hMenu, MenuAction action, int iClient, int iOpti char szDisplay[128]; - if (GLOBAL_TRIE.GetValue(szItemInfo, hBuffer)) + if (Features_Get(szItemInfo, eFeature)) { - DataPack hDataPack = view_as(hBuffer.Get(FEATURES_MENU_CALLBACKS)); - hDataPack.Position = ITEM_DISPLAY; - fCallback = hDataPack.ReadFunction(); - if (fCallback != INVALID_FUNCTION) + if (eFeature.fnDisplay != INVALID_FUNCTION) { - hPlugin = view_as(hBuffer.Get(FEATURES_PLUGIN)); - szDisplay[0] = 0; bool bResult; - Call_StartFunction(hPlugin, fCallback); + Call_StartFunction(eFeature.hPlugin, eFeature.fnDisplay); Call_PushCell(iClient); Call_PushString(szItemInfo); Call_PushStringEx(SZF(szDisplay), SM_PARAM_STRING_UTF8 | SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK); @@ -233,7 +222,7 @@ public int Handler_VIPMenu(Menu hMenu, MenuAction action, int iClient, int iOpti } } - if (view_as(hBuffer.Get(FEATURES_ITEM_TYPE)) == TOGGLABLE) + if (eFeature.eType == TOGGLABLE) { if(CanTestFeatures() && GetFeatureStatus(FeatureType_Native, "TranslationPhraseExists") == FeatureStatus_Available) { @@ -271,24 +260,20 @@ public int Handler_VIPMenu(Menu hMenu, MenuAction action, int iClient, int iOpti { g_hVIPMenu.GetItem(iOption, SZF(szItemInfo)); - if (GLOBAL_TRIE.GetValue(szItemInfo, hBuffer)) + if (Features_Get(szItemInfo, eFeature)) { PlaySound(iClient, ITEM_TOGGLE_SOUND); DebugMessage("MenuAction_Select: Client: %i, Feature: %s", iClient, szItemInfo); - DataPack hDataPack = view_as(hBuffer.Get(FEATURES_MENU_CALLBACKS)); - hDataPack.Position = ITEM_SELECT; - fCallback = hDataPack.ReadFunction(); - hPlugin = view_as(hBuffer.Get(FEATURES_PLUGIN)); - if (view_as(hBuffer.Get(FEATURES_ITEM_TYPE)) == TOGGLABLE) + if (eFeature.eType == TOGGLABLE) { VIP_ToggleState eOldStatus, eNewStatus; eOldStatus = Features_GetStatus(iClient, szItemInfo); eNewStatus = (eOldStatus == ENABLED) ? DISABLED:ENABLED; - if (fCallback != INVALID_FUNCTION) + if (eFeature.fnSelect != INVALID_FUNCTION) { - eNewStatus = Function_OnItemToggle(hPlugin, fCallback, iClient, szItemInfo, eOldStatus, eNewStatus); + eNewStatus = Function_OnItemToggle(eFeature.hPlugin, eFeature.fnSelect, iClient, szItemInfo, eOldStatus, eNewStatus); } if (eNewStatus != eOldStatus) @@ -297,7 +282,7 @@ public int Handler_VIPMenu(Menu hMenu, MenuAction action, int iClient, int iOpti if (eNewStatus != eOldStatus) { Features_SetStatus(iClient, szItemInfo, eNewStatus); - Features_SaveStatus(iClient, szItemInfo, hBuffer, eNewStatus); + Features_SaveStatus(iClient, szItemInfo, eFeature.hCookie, eNewStatus); } } @@ -306,7 +291,7 @@ public int Handler_VIPMenu(Menu hMenu, MenuAction action, int iClient, int iOpti } g_hFeatures[iClient].SetValue(KEY_MENUITEM, hMenu.Selection); - if (Function_OnItemSelect(hPlugin, fCallback, iClient, szItemInfo)) + if (Function_OnItemSelect(eFeature.hPlugin, eFeature.fnSelect, iClient, szItemInfo)) { hMenu.DisplayAt(iClient, hMenu.Selection, MENU_TIME_FOREVER); } From 89225aaed722c4a0b31cd53eaa0ac151a0ef2d48 Mon Sep 17 00:00:00 2001 From: R1KO Date: Sat, 10 Oct 2026 22:16:43 +0300 Subject: [PATCH 5/9] Keep per-player state in an enum struct PlayerData (g_ePlayer[]) instead of g_iClientInfo bit flags and three parallel StringMap arrays. Server state moves from slot 0 to g_bStarted, g_bMySQL and g_bConnecting; behavior is unchanged. --- addons/sourcemod/scripting/vip/API.sp | 112 ++++++++---------- addons/sourcemod/scripting/vip/AdminMenu.sp | 74 ++++++------ addons/sourcemod/scripting/vip/CMD.sp | 4 +- addons/sourcemod/scripting/vip/Clients.sp | 78 ++++++------ addons/sourcemod/scripting/vip/Configs.sp | 4 +- addons/sourcemod/scripting/vip/Database.sp | 32 ++--- addons/sourcemod/scripting/vip/Features.sp | 6 +- addons/sourcemod/scripting/vip/Global.sp | 42 ++++--- addons/sourcemod/scripting/vip/Info.sp | 4 +- addons/sourcemod/scripting/vip/Storage.sp | 7 +- addons/sourcemod/scripting/vip/UTIL.sp | 2 +- addons/sourcemod/scripting/vip/VipMenu.sp | 14 +-- .../sourcemod/scripting/vip/adminmenu/Add.sp | 10 +- .../sourcemod/scripting/vip/adminmenu/Del.sp | 10 +- .../sourcemod/scripting/vip/adminmenu/Edit.sp | 4 +- .../sourcemod/scripting/vip/adminmenu/List.sp | 82 ++++++------- 16 files changed, 240 insertions(+), 245 deletions(-) diff --git a/addons/sourcemod/scripting/vip/API.sp b/addons/sourcemod/scripting/vip/API.sp index 3564e96..334c9ca 100644 --- a/addons/sourcemod/scripting/vip/API.sp +++ b/addons/sourcemod/scripting/vip/API.sp @@ -57,7 +57,7 @@ void CreateForward_OnClientStorageLoaded(int iClient) bool CreateForward_OnClientPreLoad(int iClient) { - DBG_API("g_hGlobalForward_OnClientPreLoad(%N (%d), %b)", iClient, iClient, g_iClientInfo[iClient] & IS_VIP); + DBG_API("g_hGlobalForward_OnClientPreLoad(%N (%d), %b)", iClient, iClient, g_ePlayer[iClient].bVIP); bool bResult = true; Call_StartForward(g_hGlobalForward_OnClientPreLoad); Call_PushCell(iClient); @@ -69,10 +69,10 @@ bool CreateForward_OnClientPreLoad(int iClient) void CreateForward_OnClientLoaded(int iClient) { - DBG_API("CreateForward_OnClientLoaded(%N (%d), %b)", iClient, iClient, g_iClientInfo[iClient] & IS_VIP); + DBG_API("CreateForward_OnClientLoaded(%N (%d), %b)", iClient, iClient, g_ePlayer[iClient].bVIP); Call_StartForward(g_hGlobalForward_OnClientLoaded); Call_PushCell(iClient); - Call_PushCell(g_iClientInfo[iClient] & IS_VIP); + Call_PushCell(g_ePlayer[iClient].bVIP); Call_Finish(); } @@ -86,10 +86,10 @@ void CreateForward_OnVIPClientLoaded(int iClient) void CreateForward_OnClientDisconnect(int iClient) { - DBG_API("CreateForward_OnClientDisconnect(%N (%d), %b)", iClient, iClient, g_iClientInfo[iClient] & IS_VIP); + DBG_API("CreateForward_OnClientDisconnect(%N (%d), %b)", iClient, iClient, g_ePlayer[iClient].bVIP); Call_StartForward(g_hGlobalForward_OnClientDisconnect); Call_PushCell(iClient); - Call_PushCell(g_iClientInfo[iClient] & IS_VIP); + Call_PushCell(g_ePlayer[iClient].bVIP); Call_Finish(); } @@ -114,11 +114,11 @@ void CreateForward_OnVIPClientRemoved(int iClient, const char[] sReason, int iAd void CreateForward_OnPlayerSpawn(int iClient, int iTeam) { - DBG_API("CreateForward_OnPlayerSpawn(%N (%d), %d, %b)", iClient, iClient, iTeam, g_iClientInfo[iClient] & IS_VIP); + DBG_API("CreateForward_OnPlayerSpawn(%N (%d), %d, %b)", iClient, iClient, iTeam, g_ePlayer[iClient].bVIP); Call_StartForward(g_hGlobalForward_OnPlayerSpawn); Call_PushCell(iClient); Call_PushCell(iTeam); - Call_PushCell(g_iClientInfo[iClient] & IS_VIP); + Call_PushCell(g_ePlayer[iClient].bVIP); Call_Finish(); } @@ -312,7 +312,7 @@ public APLRes AskPluginLoad2(Handle myself, bool bLate, char[] szError, int err_ return APLRes_Success; } -#define VIP_CLIENT(%0) (g_hFeatures[%0] && (g_iClientInfo[%0] & IS_VIP)) +#define VIP_CLIENT(%0) (g_ePlayer[%0].hFeatures && g_ePlayer[%0].bVIP) public int Native_CheckClient(Handle hPlugin, int iNumParams) { @@ -334,8 +334,8 @@ public any Native_IsClientVIP(Handle hPlugin, int iNumParams) DBG_API("iClient = %d", iClient); if (CheckValidClient(iClient, false)) { - DBG_API("IS_VIP = %b", (g_iClientInfo[iClient] & IS_VIP)); - return view_as(g_iClientInfo[iClient] & IS_VIP); + DBG_API("IS_VIP = %b", g_ePlayer[iClient].bVIP); + return g_ePlayer[iClient].bVIP; } return false; @@ -400,7 +400,7 @@ public int Native_GetClientID(Handle hPlugin, int iNumParams) { DBG_API("VIP_CLIENT"); int iClientID; - if (g_hFeatures[iClient].GetValue(KEY_CID, iClientID)) + if (g_ePlayer[iClient].hFeatures.GetValue(KEY_CID, iClientID)) { DBG_API("GetValue(%s) = %d", KEY_CID, iClientID); return iClientID; @@ -419,7 +419,7 @@ public int Native_GetClientVIPGroup(Handle hPlugin, int iNumParams) szGroup[0] = 0; - if (g_hFeatures[iClient].GetString(KEY_GROUP, SZF(szGroup))) + if (g_ePlayer[iClient].hFeatures.GetString(KEY_GROUP, SZF(szGroup))) { SetNativeString(2, szGroup, GetNativeCell(3), true); return true; @@ -440,13 +440,13 @@ public int Native_SetClientVIPGroup(Handle hPlugin, int iNumParams) if (UTIL_CheckValidVIPGroup(szGroup)) { char szOldGroup[64]; - g_hFeatures[iClient].GetString(KEY_GROUP, SZF(szOldGroup)); - if (g_hFeatures[iClient].SetString(KEY_GROUP, szGroup)) + g_ePlayer[iClient].hFeatures.GetString(KEY_GROUP, SZF(szOldGroup)); + if (g_ePlayer[iClient].hFeatures.SetString(KEY_GROUP, szGroup)) { if (view_as(GetNativeCell(3))) { int iClientID; - if (g_hFeatures[iClient].GetValue(KEY_CID, iClientID) && iClientID != -1) + if (g_ePlayer[iClient].hFeatures.GetValue(KEY_CID, iClientID) && iClientID != -1) { char szQuery[256]; FormatEx(SZF(szQuery), "UPDATE `vip_users` SET `group` = '%s' WHERE `account_id` = %d%s;", szGroup, iClientID, g_szSID); @@ -481,7 +481,7 @@ public int Native_GetClientAccessTime(Handle hPlugin, int iNumParams) if (CheckValidClient(iClient, false) && VIP_CLIENT(iClient)) { int iExp; - if (g_hFeatures[iClient].GetValue(KEY_EXPIRES, iExp)) + if (g_ePlayer[iClient].hFeatures.GetValue(KEY_EXPIRES, iExp)) { return iExp; } @@ -503,12 +503,12 @@ public int Native_SetClientAccessTime(Handle hPlugin, int iNumParams) return false; } - if (g_hFeatures[iClient].SetValue(KEY_EXPIRES, iTime)) + if (g_ePlayer[iClient].hFeatures.SetValue(KEY_EXPIRES, iTime)) { if (view_as(GetNativeCell(3))) { int iClientID; - if (g_hFeatures[iClient].GetValue(KEY_CID, iClientID) && iClientID != -1) + if (g_ePlayer[iClient].hFeatures.GetValue(KEY_CID, iClientID) && iClientID != -1) { char szQuery[256]; FormatEx(SZF(szQuery), "UPDATE `vip_users` SET `expires` = %d WHERE `account_id` = %d%s;", iTime, iClientID, g_szSID); @@ -545,7 +545,7 @@ public int Native_GetVIPClientTrie(Handle hPlugin, int iNumParams) int iClient = GetNativeCell(1); if (CheckValidClient(iClient, false) && VIP_CLIENT(iClient)) { - return view_as(g_hFeatures[iClient]); + return view_as(g_ePlayer[iClient].hFeatures); } return 0; @@ -570,7 +570,7 @@ public int Native_SendClientVIPMenu(Handle hPlugin, int iNumParams) } int iItem = 0; - g_hFeatures[iClient].GetValue(KEY_MENUITEM, iItem); + g_ePlayer[iClient].hFeatures.GetValue(KEY_MENUITEM, iItem); g_hVIPMenu.DisplayAt(iClient, iItem, MENU_TIME_FOREVER); } @@ -607,10 +607,10 @@ int API_GiveClientVIP(Handle hPlugin, int iAdmin, int iClient, int iTime, const { if (CheckValidClient(iClient, false) && (iAdmin < 1 || CheckValidClient(iAdmin, false))) { - if (g_iClientInfo[iClient] & IS_VIP) + if (g_ePlayer[iClient].bVIP) { int iClientID; - g_hFeatures[iClient].GetValue(KEY_CID, iClientID); + g_ePlayer[iClient].hFeatures.GetValue(KEY_CID, iClientID); if (iClientID == -1 && bAddToDB) { Clients_RemoveVIPStatus(iClient); @@ -651,10 +651,10 @@ int API_GiveClientVIP(Handle hPlugin, int iAdmin, int iClient, int iTime, const Clients_CreateExpiredTimer(iClient, iTime + iCurrentTime, iCurrentTime); } - g_hFeatures[iClient].SetString(KEY_GROUP, szGroup); - g_hFeatures[iClient].SetValue(KEY_CID, -1); - g_iClientInfo[iClient] |= IS_VIP; - g_iClientInfo[iClient] |= IS_LOADED; + g_ePlayer[iClient].hFeatures.SetString(KEY_GROUP, szGroup); + g_ePlayer[iClient].hFeatures.SetValue(KEY_CID, -1); + g_ePlayer[iClient].bVIP = true; + g_ePlayer[iClient].bLoaded = true; Clients_LoadVIPFeatures(iClient); @@ -713,13 +713,13 @@ int API_RemoveClientVIP(Handle hPlugin, if (bInDB) { int iClientID; - if (g_hFeatures[iClient].GetValue(KEY_CID, iClientID) && iClientID != -1) + if (g_ePlayer[iClient].hFeatures.GetValue(KEY_CID, iClientID) && iClientID != -1) { DB_RemoveClientFromID(REASON_PLUGIN, iClient, _, true, _, _, szPluginName); } } - if (g_iClientInfo[iClient] & IS_MENU_OPEN) + if (g_ePlayer[iClient].bMenuOpen) { CancelClientMenu(iClient); } @@ -829,7 +829,7 @@ public int Native_GetClientStorageValue(Handle hPlugin, int iNumParams) public int Native_IsVIPLoaded(Handle hPlugin, int iNumParams) { - return ((GLOBAL_INFO & IS_STARTED) && g_hDatabase); + return (g_bStarted && g_hDatabase); } public int Native_RegisterFeature(Handle hPlugin, int iNumParams) @@ -891,7 +891,7 @@ public int Native_RegisterFeature(Handle hPlugin, int iNumParams) for (int iClient = 1; iClient <= MaxClients; ++iClient) { - if (IsClientInGame(iClient) && (g_iClientInfo[iClient] & IS_VIP)) + if (IsClientInGame(iClient) && g_ePlayer[iClient].bVIP) { Clients_LoadVIPFeaturesPre(iClient, szFeature); } @@ -992,10 +992,10 @@ void UnregisterFeature(const char[] szFeature, Feature eFeature) for (int j = 1; j <= MaxClients; ++j) { - if (IsClientInGame(j) && g_iClientInfo[j] & IS_VIP) + if (IsClientInGame(j) && g_ePlayer[j].bVIP) { - g_hFeatures[j].Remove(szFeature); - g_hFeatureStatus[j].Remove(szFeature); + g_ePlayer[j].hFeatures.Remove(szFeature); + g_ePlayer[j].hFeatureStatus.Remove(szFeature); } } @@ -1133,7 +1133,7 @@ public int Native_GetClientFeatureInt(Handle hPlugin, int iNumParams) int iValue; GetNativeString(2, SZF(szFeature)); - if (g_hFeatures[iClient].GetValue(szFeature, iValue) && iValue != 0) + if (g_ePlayer[iClient].hFeatures.GetValue(szFeature, iValue) && iValue != 0) { return iValue; } @@ -1151,7 +1151,7 @@ public int Native_GetClientFeatureFloat(Handle hPlugin, int iNumParams) float fValue; GetNativeString(2, SZF(szFeature)); - if (g_hFeatures[iClient].GetValue(szFeature, fValue) && fValue != 0.0) + if (g_ePlayer[iClient].hFeatures.GetValue(szFeature, fValue) && fValue != 0.0) { return view_as(fValue); } @@ -1169,7 +1169,7 @@ public int Native_GetClientFeatureBool(Handle hPlugin, int iNumParams) GetNativeString(2, SZF(szFeature)); // VIP_GiveClientFeature can store false, so the key existing is not enough - return g_hFeatures[iClient].GetValue(szFeature, bValue) && bValue; + return g_ePlayer[iClient].hFeatures.GetValue(szFeature, bValue) && bValue; } return false; @@ -1184,7 +1184,7 @@ public int Native_GetClientFeatureString(Handle hPlugin, int iNumParams) char szFeature[64], szBuffer[256]; GetNativeString(2, SZF(szFeature)); - if (g_hFeatures[iClient].GetString(szFeature, SZF(szBuffer))) + if (g_ePlayer[iClient].hFeatures.GetString(szFeature, SZF(szBuffer))) { SetNativeString(3, szBuffer, iLen, true); return true; @@ -1212,30 +1212,31 @@ public int Native_GiveClientFeature(Handle hPlugin, int iNumParams) char szValue[256]; GetNativeString(3, SZF(szValue)); - if (!(g_iClientInfo[iClient] & IS_VIP)) + if (!g_ePlayer[iClient].bVIP) { Clients_CreateClientVIPSettings(iClient, 0); - g_hFeatures[iClient].SetValue(KEY_CID, -1); - g_iClientInfo[iClient] |= IS_VIP | IS_LOADED; + g_ePlayer[iClient].hFeatures.SetValue(KEY_CID, -1); + g_ePlayer[iClient].bVIP = true; + g_ePlayer[iClient].bLoaded = true; } switch (eFeature.eValType) { case BOOL: { - g_hFeatures[iClient].SetValue(szFeature, view_as(StringToInt(szValue))); + g_ePlayer[iClient].hFeatures.SetValue(szFeature, view_as(StringToInt(szValue))); } case INT: { - g_hFeatures[iClient].SetValue(szFeature, StringToInt(szValue)); + g_ePlayer[iClient].hFeatures.SetValue(szFeature, StringToInt(szValue)); } case FLOAT: { - g_hFeatures[iClient].SetValue(szFeature, StringToFloat(szValue)); + g_ePlayer[iClient].hFeatures.SetValue(szFeature, StringToFloat(szValue)); } case STRING: { - g_hFeatures[iClient].SetString(szFeature, szValue); + g_ePlayer[iClient].hFeatures.SetString(szFeature, szValue); } } @@ -1272,10 +1273,10 @@ public int Native_RemoveClientFeature(Handle hPlugin, int iNumParams) VIP_ToggleState eToggleState = Features_GetStatus(iClient, szFeature); - g_hFeatures[iClient].Remove(szFeature); - g_hFeatureStatus[iClient].Remove(szFeature); + g_ePlayer[iClient].hFeatures.Remove(szFeature); + g_ePlayer[iClient].hFeatureStatus.Remove(szFeature); - if (!g_hFeatures[iClient].Size) + if (!g_ePlayer[iClient].hFeatures.Size) { ResetClient(iClient); } @@ -1308,7 +1309,7 @@ public int Native_GetDatabase(Handle hPlugin, int iNumParams) public int Native_GetDatabaseType(Handle hPlugin, int iNumParams) { - return (GLOBAL_INFO & IS_MySQL); + return g_bMySQL; } public int Native_TimeToSeconds(Handle hPlugin, int iNumParams) @@ -1375,20 +1376,7 @@ bool CheckValidClient(const int &iClient, bool bCheckVIP = true) } if (bCheckVIP) { - /* - if (!(g_iClientInfo[iClient] & IS_LOADED)) - { - ThrowNativeError(SP_ERROR_NATIVE, "Client %i is not loaded", iClient); - return false; - } - if (!(g_iClientInfo[iClient] & IS_VIP) || !(g_iClientInfo[iClient] & IS_AUTHORIZED)) - { - ThrowNativeError(SP_ERROR_NATIVE, "Client %i is not VIP", iClient); - return false; - } - */ - - return view_as(g_iClientInfo[iClient] & IS_VIP); + return g_ePlayer[iClient].bVIP; } return true; diff --git a/addons/sourcemod/scripting/vip/AdminMenu.sp b/addons/sourcemod/scripting/vip/AdminMenu.sp index f290630..5a4d4e2 100644 --- a/addons/sourcemod/scripting/vip/AdminMenu.sp +++ b/addons/sourcemod/scripting/vip/AdminMenu.sp @@ -50,7 +50,7 @@ void DisplayAdminMenu(int iClient) void BackToAdminMenu(int iClient) { AdminMenuType eThrowMenuType; - g_hClientData[iClient].GetValue(DATA_KEY_ThrowMenuType, eThrowMenuType); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_ThrowMenuType, eThrowMenuType); switch (eThrowMenuType) { case TOP_ADMIN_MENU: g_hTopMenu.Display(iClient, TopMenuPosition_LastCategory); @@ -60,13 +60,13 @@ void BackToAdminMenu(int iClient) void InitiateDataMap(int iClient) { - if (g_hClientData[iClient] == null) + if (g_ePlayer[iClient].hData == null) { - g_hClientData[iClient] = new StringMap(); + g_ePlayer[iClient].hData = new StringMap(); } else { - g_hClientData[iClient].Clear(); + g_ePlayer[iClient].hData.Clear(); } } @@ -75,7 +75,7 @@ int IsClientOnline(int ID) int iClientID; for (int i = 1; i <= MaxClients; ++i) { - if (IsClientInGame(i) && g_hFeatures[i] != null && g_hFeatures[i].GetValue(KEY_CID, iClientID) && iClientID == ID) + if (IsClientInGame(i) && g_ePlayer[i].hFeatures != null && g_ePlayer[i].hFeatures.GetValue(KEY_CID, iClientID) && iClientID == ID) { return i; } @@ -135,14 +135,14 @@ public int Handler_VIPAdminMenu(Menu hMenu, MenuAction action, int iClient, int case 0: { InitiateDataMap(iClient); - g_hClientData[iClient].SetValue(DATA_KEY_MenuType, MENU_TYPE_ADD); - g_hClientData[iClient].SetValue(DATA_KEY_ThrowMenuType, ADMIN_MENU); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_MenuType, MENU_TYPE_ADD); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_ThrowMenuType, ADMIN_MENU); ShowAddVIPMenu(iClient); } case 1: { InitiateDataMap(iClient); - g_hClientData[iClient].SetValue(DATA_KEY_ThrowMenuType, ADMIN_MENU); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_ThrowMenuType, ADMIN_MENU); ShowVipPlayersListMenu(iClient); } case 2: @@ -230,8 +230,8 @@ public void Handler_MenuAdd(TopMenu hMenu, TopMenuAction action, TopMenuObject o case TopMenuAction_SelectOption: { InitiateDataMap(iClient); - g_hClientData[iClient].SetValue(DATA_KEY_MenuType, MENU_TYPE_ADD); - g_hClientData[iClient].SetValue(DATA_KEY_ThrowMenuType, TOP_ADMIN_MENU); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_MenuType, MENU_TYPE_ADD); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_ThrowMenuType, TOP_ADMIN_MENU); ShowAddVIPMenu(iClient); } } @@ -247,7 +247,7 @@ public void Handler_MenuList(TopMenu hMenu, TopMenuAction action, TopMenuObject case TopMenuAction_SelectOption: { InitiateDataMap(iClient); - g_hClientData[iClient].SetValue(DATA_KEY_ThrowMenuType, TOP_ADMIN_MENU); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_ThrowMenuType, TOP_ADMIN_MENU); ShowVipPlayersListMenu(iClient); } } @@ -287,7 +287,7 @@ void ShowTimeMenu(int iClient) Menu hMenu = new Menu(MenuHandler_TimeMenu); TimeActionItem iMenuType; - g_hClientData[iClient].GetValue(DATA_KEY_TimeType, iMenuType); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_TimeType, iMenuType); switch (iMenuType) { @@ -346,7 +346,7 @@ public int MenuHandler_TimeMenu(Menu hMenu, MenuAction action, int iClient, int if (iItem == MenuCancel_ExitBack) { AdminMenuItem eMenuItem; - g_hClientData[iClient].GetValue(DATA_KEY_MenuType, eMenuItem); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_MenuType, eMenuItem); switch (eMenuItem) { @@ -362,16 +362,16 @@ public int MenuHandler_TimeMenu(Menu hMenu, MenuAction action, int iClient, int int iTime, iTarget; AdminMenuItem eMenuItem; iTime = S2I(szName); - g_hClientData[iClient].GetValue(DATA_KEY_MenuType, eMenuItem); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_MenuType, eMenuItem); if (eMenuItem == MENU_TYPE_ADD) { - g_hClientData[iClient].GetValue(DATA_KEY_TargetUID, iTarget); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_TargetUID, iTarget); if ((iTarget = GetClientOfUserId(iTarget))) { char szBuffer[64]; hMenu.GetItem(iItem, SZF(szBuffer)); - g_hClientData[iClient].SetValue(DATA_KEY_Time, S2I(szBuffer)); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_Time, S2I(szBuffer)); ShowGroupsMenu(iClient); } else @@ -384,10 +384,10 @@ public int MenuHandler_TimeMenu(Menu hMenu, MenuAction action, int iClient, int char szTime[64]; int iExpires; - g_hClientData[iClient].GetString(DATA_KEY_Name, SZF(szName)); + g_ePlayer[iClient].hData.GetString(DATA_KEY_Name, SZF(szName)); TimeActionItem eTimeActionItem; - g_hClientData[iClient].GetValue(DATA_KEY_TimeType, eTimeActionItem); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_TimeType, eTimeActionItem); switch(eTimeActionItem) { case TIME_SET: @@ -411,7 +411,7 @@ public int MenuHandler_TimeMenu(Menu hMenu, MenuAction action, int iClient, int } case TIME_ADD: { - g_hClientData[iClient].GetValue(DATA_KEY_Time, iExpires); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_Time, iExpires); if (iExpires <= 0) { VIP_PrintToChatClient(iClient, "%t", "UNABLE_TO_EXTENDED"); @@ -431,7 +431,7 @@ public int MenuHandler_TimeMenu(Menu hMenu, MenuAction action, int iClient, int } case TIME_TAKE: { - g_hClientData[iClient].GetValue(DATA_KEY_Time, iExpires); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_Time, iExpires); if (iExpires <= 0) { VIP_PrintToChatClient(iClient, "%t", "UNABLE_TO_REDUCE"); @@ -459,8 +459,8 @@ public int MenuHandler_TimeMenu(Menu hMenu, MenuAction action, int iClient, int } } - g_hClientData[iClient].GetValue(DATA_KEY_TargetID, iTarget); - g_hClientData[iClient].SetValue(DATA_KEY_Time, iExpires); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_TargetID, iTarget); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_Time, iExpires); char szQuery[512]; FormatEx(SZF(szQuery), "UPDATE `vip_users` SET `expires` = '%d' WHERE `account_id` = '%d'%s;", iExpires, iTarget, g_szSID); @@ -518,7 +518,7 @@ public int MenuHandler_GroupsList(Menu hMenu, MenuAction action, int iClient, in if (iItem == MenuCancel_ExitBack) { AdminMenuItem eMenuItem; - g_hClientData[iClient].GetValue(DATA_KEY_MenuType, eMenuItem); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_MenuType, eMenuItem); switch(eMenuItem) { case MENU_TYPE_ADD: @@ -537,23 +537,23 @@ public int MenuHandler_GroupsList(Menu hMenu, MenuAction action, int iClient, in char szGroup[64]; hMenu.GetItem(iItem, SZF(szGroup)); AdminMenuItem eMenuItem; - g_hClientData[iClient].GetValue(DATA_KEY_MenuType, eMenuItem); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_MenuType, eMenuItem); switch(eMenuItem) { case MENU_TYPE_ADD: { int iTarget, iBuffer; - g_hClientData[iClient].GetValue(DATA_KEY_TargetUID, iTarget); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_TargetUID, iTarget); iTarget = CID(iTarget); if (iTarget) { - g_hClientData[iClient].GetValue(DATA_KEY_Time, iBuffer); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_Time, iBuffer); // Keep the menu to return to (BackToAdminMenu below) AdminMenuType eThrowMenuType; - g_hClientData[iClient].GetValue(DATA_KEY_ThrowMenuType, eThrowMenuType); - g_hClientData[iClient].Clear(); - g_hClientData[iClient].SetValue(DATA_KEY_ThrowMenuType, eThrowMenuType); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_ThrowMenuType, eThrowMenuType); + g_ePlayer[iClient].hData.Clear(); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_ThrowMenuType, eThrowMenuType); UTIL_ADD_VIP_PLAYER(iClient, iTarget, _, iBuffer, szGroup); } @@ -569,9 +569,9 @@ public int MenuHandler_GroupsList(Menu hMenu, MenuAction action, int iClient, in char szQuery[256], szName[MNL], szOldGroup[64]; hMenu.GetItem(iItem, SZF(szGroup)); int iTargetID; - g_hClientData[iClient].GetValue(DATA_KEY_TargetID, iTargetID); - g_hClientData[iClient].GetString(DATA_KEY_Name, SZF(szName)); - g_hClientData[iClient].GetString(DATA_KEY_Group, SZF(szOldGroup)); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_TargetID, iTargetID); + g_ePlayer[iClient].hData.GetString(DATA_KEY_Name, SZF(szName)); + g_ePlayer[iClient].hData.GetString(DATA_KEY_Group, SZF(szOldGroup)); FormatEx(SZF(szQuery), "UPDATE `vip_users` SET `group` = '%s' WHERE `account_id` = %d%s;", szGroup, iTargetID, g_szSID); @@ -579,7 +579,7 @@ public int MenuHandler_GroupsList(Menu hMenu, MenuAction action, int iClient, in g_hDatabase.Query(SQL_Callback_ErrorCheck, szQuery); int iTarget = 0; - g_hClientData[iClient].GetValue(DATA_KEY_TargetUID, iTarget); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_TargetUID, iTarget); iTarget = CID(iTarget); if (!iTarget) { @@ -628,11 +628,11 @@ public void SQL_Callback_ChangeTime(Database hOwner, DBResultSet hResult, const if (iClient) { int iTarget; - g_hClientData[iClient].GetValue(DATA_KEY_TargetUID, iTarget); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_TargetUID, iTarget); iTarget = CID(iTarget); if(!iTarget) { - g_hClientData[iClient].GetValue(DATA_KEY_TargetID, iTarget); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_TargetID, iTarget); iTarget = IsClientOnline(iTarget); } @@ -656,9 +656,9 @@ public Action OnClientSayCommand(int iClient, const char[] szCommand, const char { if(iClient > 0 && iClient <= MaxClients && szArgs[0]) { - if(g_iClientInfo[iClient] & IS_WAIT_CHAT_SEARCH) + if (g_ePlayer[iClient].bWaitChatSearch) { - if(g_iClientInfo[iClient] & IS_WAIT_CHAT_SEARCH) + if (g_ePlayer[iClient].bWaitChatSearch) { ShowWaitSearchMenu(iClient, szArgs); } diff --git a/addons/sourcemod/scripting/vip/CMD.sp b/addons/sourcemod/scripting/vip/CMD.sp index c3c807e..dd7542d 100644 --- a/addons/sourcemod/scripting/vip/CMD.sp +++ b/addons/sourcemod/scripting/vip/CMD.sp @@ -109,7 +109,7 @@ public Action AddVIP_CMD(int iClient, int iArgs) { if(IsClientInGame(iTargetList[i])) { - if (g_iClientInfo[iTargetList[i]] & IS_VIP) + if (g_ePlayer[iTargetList[i]].bVIP) { ReplyToCommand(iClient, "[VIP] %t", "ALREADY_HAS_VIP"); continue; @@ -243,7 +243,7 @@ public Action VIPMenu_CMD(int iClient, int iArgs) { if (OnVipMenuFlood(iClient) == false) { - if (g_iClientInfo[iClient] & IS_VIP) + if (g_ePlayer[iClient].bVIP) { g_hVIPMenu.Display(iClient, MENU_TIME_FOREVER); } diff --git a/addons/sourcemod/scripting/vip/Clients.sp b/addons/sourcemod/scripting/vip/Clients.sp index bdb22c4..288f6aa 100644 --- a/addons/sourcemod/scripting/vip/Clients.sp +++ b/addons/sourcemod/scripting/vip/Clients.sp @@ -6,11 +6,12 @@ static bool g_bClientWaitsForAuth[MAXPLAYERS+1]; // Drops the VIP status only: session flags (spawned, menu open, chat input) stay void ResetClient(int iClient) { - g_iClientInfo[iClient] = (g_iClientInfo[iClient] & ~IS_VIP) | IS_LOADED; + g_ePlayer[iClient].bVIP = false; + g_ePlayer[iClient].bLoaded = true; ++g_iClientLoadSerial[iClient]; - delete g_hFeatures[iClient]; - delete g_hFeatureStatus[iClient]; + delete g_ePlayer[iClient].hFeatures; + delete g_ePlayer[iClient].hFeatureStatus; } // Takes the VIP status away from a player in game: modules get their features toggled off first @@ -22,8 +23,7 @@ void Clients_RemoveVIPStatus(int iClient) public void OnClientPutInServer(int iClient) { - // g_iClientInfo[iClient] = 0; - DBG_Clients("OnClientPutInServer %N (%d): %b", iClient, iClient, g_iClientInfo[iClient]); + DBG_Clients("OnClientPutInServer %N (%d)", iClient, iClient); if(!IsFakeClient(iClient) && !IsClientSourceTV(iClient)) { @@ -58,8 +58,8 @@ public void OnClientDisconnect(int iClient) Storage_ResetClient(iClient); ResetClient(iClient); - delete g_hClientData[iClient]; - g_iClientInfo[iClient] = 0; + delete g_ePlayer[iClient].hData; + g_ePlayer[iClient].ClearFlags(); g_bClientWaitsForAuth[iClient] = false; } @@ -71,9 +71,9 @@ void Clients_CheckVipAccess(int iClient, bool bNotify = false, bool bForward = f } Clients_RemoveVIPStatus(iClient); - g_iClientInfo[iClient] &= ~IS_LOADED; + g_ePlayer[iClient].bLoaded = false; - if (IsFakeClient(iClient) == false && (GLOBAL_INFO & IS_STARTED) && g_hDatabase) + if (IsFakeClient(iClient) == false && g_bStarted && g_hDatabase) { Clients_LoadClient(iClient, bNotify); // DBG_Clients("Clients_CheckVipAccess %N:\tis %sa VIP", iClient, g_bIsClientVIP[iClient] ? "":"not ") @@ -86,7 +86,7 @@ void Clients_CheckVipAccess(int iClient, bool bNotify = false, bool bForward = f void Clients_SetLoaded(int iClient) { - g_iClientInfo[iClient] |= IS_LOADED; + g_ePlayer[iClient].bLoaded = true; CreateForward_OnClientLoaded(iClient); } @@ -96,7 +96,7 @@ void Clients_LoadClient(int iClient, bool bNotify) int iAccountID = GetSteamAccountID(iClient); - DBG_Clients("Clients_LoadClient %N (%d), %b: - > %x, %u", iClient, iClient, g_iClientInfo[iClient], g_hDatabase, g_hDatabase); + DBG_Clients("Clients_LoadClient %N (%d), VIP: %b - > %x, %u", iClient, iClient, g_ePlayer[iClient].bVIP, g_hDatabase, g_hDatabase); // Not authorized yet: loaded as non-VIP for now, checked again from OnClientAuthorized if (!iAccountID) @@ -190,11 +190,11 @@ public void SQL_Callback_OnClientAuthorized(Database hOwner, DBResultSet hResult { Clients_CreateClientVIPSettings(iClient, iExpires); - g_hFeatures[iClient].SetValue(KEY_CID, iAccountID); + g_ePlayer[iClient].hFeatures.SetValue(KEY_CID, iAccountID); - g_hFeatures[iClient].SetString(KEY_GROUP, szGroup); + g_ePlayer[iClient].hFeatures.SetString(KEY_GROUP, szGroup); - g_iClientInfo[iClient] |= IS_VIP; + g_ePlayer[iClient].bVIP = true; Clients_SetLoaded(iClient); @@ -235,13 +235,13 @@ void Clients_OnVIPClientLoaded(int iClient) void Clients_CreateClientVIPSettings(int iClient, int iExp) { // A reload may overlap with a load still in flight - delete g_hFeatures[iClient]; - delete g_hFeatureStatus[iClient]; + delete g_ePlayer[iClient].hFeatures; + delete g_ePlayer[iClient].hFeatureStatus; - g_hFeatures[iClient] = new StringMap(); - g_hFeatureStatus[iClient] = new StringMap(); + g_ePlayer[iClient].hFeatures = new StringMap(); + g_ePlayer[iClient].hFeatureStatus = new StringMap(); - g_hFeatures[iClient].SetValue(KEY_EXPIRES, iExp); + g_ePlayer[iClient].hFeatures.SetValue(KEY_EXPIRES, iExp); } #if DEBUG_MODE @@ -301,9 +301,9 @@ public Action Timer_CheckCookies(Handle hTimer, Handle hDP) char szFeature[FEATURE_NAME_LENGTH]; hDataPack.ReadString(SZF(szFeature)); - DBG_Clients("Timer_CheckCookies -> iClient: %N (%d), IsClientVIP: %b, attempt: %d", iClient, iClient, view_as(g_iClientInfo[iClient] & IS_VIP), iAttempt); + DBG_Clients("Timer_CheckCookies -> iClient: %N (%d), IsClientVIP: %b, attempt: %d", iClient, iClient, g_ePlayer[iClient].bVIP, iAttempt); // Reloaded in the meantime: the new load waits on its own timer - if (!iClient || !(g_iClientInfo[iClient] & IS_VIP) || iLoadSerial != g_iClientLoadSerial[iClient]) + if (!iClient || !g_ePlayer[iClient].bVIP || iLoadSerial != g_iClientLoadSerial[iClient]) { return Plugin_Stop; } @@ -329,7 +329,7 @@ void Clients_LoadVIPFeatures(int iClient) { char szFeature[FEATURE_NAME_LENGTH]; - g_hFeatures[iClient].GetString(KEY_GROUP, SZF(szFeature)); + g_ePlayer[iClient].hFeatures.GetString(KEY_GROUP, SZF(szFeature)); if (UTIL_CheckValidVIPGroup(szFeature)) { for (int i = 0; i < iFeatures; ++i) @@ -355,7 +355,7 @@ void Clients_LoadVIPFeature(int iClient, const char[] szFeature) { char szGroup[FEATURE_NAME_LENGTH]; - g_hFeatures[iClient].GetString(KEY_GROUP, SZF(szGroup)); + g_ePlayer[iClient].hFeatures.GetString(KEY_GROUP, SZF(szGroup)); if (UTIL_CheckValidVIPGroup(szGroup)) { Clients_LoadFeature(iClient, szFeature); @@ -438,7 +438,7 @@ bool GetValue(int iClient, VIP_ValueType ValueType, const char[] szFeature) if (g_hGroups.GetNum(szFeature)) { DBG_Clients("value: 1"); - return g_hFeatures[iClient].SetValue(szFeature, true); + return g_ePlayer[iClient].hFeatures.SetValue(szFeature, true); } return false; } @@ -449,7 +449,7 @@ bool GetValue(int iClient, VIP_ValueType ValueType, const char[] szFeature) if (iValue != 0) { DBG_Clients("value: %d", iValue); - return g_hFeatures[iClient].SetValue(szFeature, iValue); + return g_ePlayer[iClient].hFeatures.SetValue(szFeature, iValue); } return false; } @@ -460,7 +460,7 @@ bool GetValue(int iClient, VIP_ValueType ValueType, const char[] szFeature) if (fValue != 0.0) { DBG_Clients("value: %f", fValue); - return g_hFeatures[iClient].SetValue(szFeature, fValue); + return g_ePlayer[iClient].hFeatures.SetValue(szFeature, fValue); } return false; @@ -472,7 +472,7 @@ bool GetValue(int iClient, VIP_ValueType ValueType, const char[] szFeature) if (szBuffer[0]) { DBG_Clients("value: %s", szBuffer); - return g_hFeatures[iClient].SetString(szFeature, szBuffer); + return g_ePlayer[iClient].hFeatures.SetString(szFeature, szBuffer); } return false; } @@ -511,7 +511,7 @@ public void Event_PlayerSpawn(Event hEvent, const char[] sEvName, bool bDontBroa int UserID = hEvent.GetInt("userid"); int iClient = CID(UserID); DBG_Clients("Event_PlayerSpawn: %N (%d)", iClient, iClient); - if (!(g_iClientInfo[iClient] & IS_SPAWNED)) + if (!g_ePlayer[iClient].bSpawned) { CreateTimer(g_CVAR_fSpawnDelay, Timer_OnPlayerSpawn, UserID, TIMER_FLAG_NO_MAPCHANGE); } @@ -521,7 +521,7 @@ public void Event_PlayerDeath(Event hEvent, const char[] sEvName, bool bDontBroa { int iClient = CID(hEvent.GetInt("userid")); DBG_Clients("Event_PlayerDeath: %N (%d)", iClient, iClient); - g_iClientInfo[iClient] &= ~IS_SPAWNED; + g_ePlayer[iClient].bSpawned = false; } public Action Timer_OnPlayerSpawn(Handle hTimer, any UserID) @@ -534,16 +534,16 @@ public Action Timer_OnPlayerSpawn(Handle hTimer, any UserID) { DBG_Clients("Timer_OnPlayerSpawn: %N (%d)", iClient, iClient); - if (g_iClientInfo[iClient] & IS_VIP) + if (g_ePlayer[iClient].bVIP) { int iExp; - if (g_hFeatures[iClient].GetValue(KEY_EXPIRES, iExp) && iExp > 0 && iExp < GetTime()) + if (g_ePlayer[iClient].hFeatures.GetValue(KEY_EXPIRES, iExp) && iExp > 0 && iExp < GetTime()) { Clients_ExpiredClient(iClient); } } - g_iClientInfo[iClient] |= IS_SPAWNED; + g_ePlayer[iClient].bSpawned = true; CreateForward_OnPlayerSpawn(iClient, iTeam); } } @@ -559,8 +559,8 @@ public void Event_RoundEnd(Event hEvent, const char[] sEvName, bool bDontBroadca { if (IsClientInGame(i)) { - g_iClientInfo[i] &= ~IS_SPAWNED; - if ((g_iClientInfo[i] & IS_VIP) && g_hFeatures[i].GetValue(KEY_EXPIRES, iExp) && iExp > 0 && iExp < iTime) + g_ePlayer[i].bSpawned = false; + if (g_ePlayer[i].bVIP && g_ePlayer[i].hFeatures.GetValue(KEY_EXPIRES, iExp) && iExp > 0 && iExp < iTime) { Clients_ExpiredClient(i); } @@ -573,10 +573,10 @@ public Action Timer_VIP_Expired(Handle hTimer, any UserID) DBG_Clients("Timer_VIP_Expired %d:", UserID); int iClient = CID(UserID); - if (iClient && g_iClientInfo[iClient] & IS_VIP) + if (iClient && g_ePlayer[iClient].bVIP) { int iExp; - if (g_hFeatures[iClient].GetValue(KEY_EXPIRES, iExp) && iExp > 0 && iExp < GetTime()) + if (g_ePlayer[iClient].hFeatures.GetValue(KEY_EXPIRES, iExp) && iExp > 0 && iExp < GetTime()) { DBG_Clients("Timer_VIP_Expired %N:", iClient); @@ -592,10 +592,10 @@ void Clients_ExpiredClient(int iClient) DBG_Clients("Clients_ExpiredClient %N:", iClient); int iClientID; - g_hFeatures[iClient].GetValue(KEY_EXPIRES, iClientID); + g_ePlayer[iClient].hFeatures.GetValue(KEY_EXPIRES, iClientID); if (g_CVAR_iDeleteExpired == 0 || (g_CVAR_iDeleteExpired > 0 && GetTime() >= ((g_CVAR_iDeleteExpired*86400) + iClientID))) { - if (g_hFeatures[iClient].GetValue(KEY_CID, iClientID) && iClientID != -1) + if (g_ePlayer[iClient].hFeatures.GetValue(KEY_CID, iClientID) && iClientID != -1) { if (g_CVAR_bLogsEnable) { @@ -606,7 +606,7 @@ void Clients_ExpiredClient(int iClient) } } - if(g_iClientInfo[iClient] & IS_MENU_OPEN) + if (g_ePlayer[iClient].bMenuOpen) { CancelClientMenu(iClient); } diff --git a/addons/sourcemod/scripting/vip/Configs.sp b/addons/sourcemod/scripting/vip/Configs.sp index 385693e..5357b68 100644 --- a/addons/sourcemod/scripting/vip/Configs.sp +++ b/addons/sourcemod/scripting/vip/Configs.sp @@ -12,9 +12,9 @@ public void OnMapStart() void OnReadyToStart() { DebugMessage("OnReadyToStart"); - if (!(GLOBAL_INFO & IS_STARTED)) + if (!g_bStarted) { - GLOBAL_INFO |= IS_STARTED; + g_bStarted = true; CreateForward_OnVIPLoaded(); diff --git a/addons/sourcemod/scripting/vip/Database.sp b/addons/sourcemod/scripting/vip/Database.sp index 958764e..89932e0 100644 --- a/addons/sourcemod/scripting/vip/Database.sp +++ b/addons/sourcemod/scripting/vip/Database.sp @@ -14,18 +14,18 @@ void DB_Connect() // DebugMessage("DB_Connect: %b", g_bIsVIPLoaded); DBG_Database("DB_Connect"); - if (GLOBAL_INFO & IS_LOADING) + if (g_bConnecting) { return; } if (g_hDatabase != null) { - UNSET_BIT(GLOBAL_INFO, IS_LOADING); + g_bConnecting = false; return; } - SET_BIT(GLOBAL_INFO, IS_LOADING); + g_bConnecting = true; if (SQL_CheckConfig("vip_core")) // "vip_core" { @@ -44,7 +44,7 @@ public void OnDBConnect(Database hDatabase, const char[] szError, any data) if (hDatabase == null || szError[0]) { SetFailState("OnDBConnect %s", szError); - UNSET_BIT(GLOBAL_INFO, IS_MySQL); + g_bMySQL = false; // CreateTimer(5.0, Timer_DB_Reconnect); return; } @@ -53,7 +53,7 @@ public void OnDBConnect(Database hDatabase, const char[] szError, any data) if (data == 1) { - UNSET_BIT(GLOBAL_INFO, IS_MySQL); + g_bMySQL = false; } else { @@ -62,22 +62,22 @@ public void OnDBConnect(Database hDatabase, const char[] szError, any data) if (strcmp(szDriver, "mysql", false) == 0) { - SET_BIT(GLOBAL_INFO, IS_MySQL); + g_bMySQL = true; } else { - UNSET_BIT(GLOBAL_INFO, IS_MySQL); + g_bMySQL = false; } } - DBG_Database("OnDBConnect %x, %u - > (MySQL: %b)", g_hDatabase, g_hDatabase, GLOBAL_INFO & IS_MySQL); + DBG_Database("OnDBConnect %x, %u - > (MySQL: %b)", g_hDatabase, g_hDatabase, g_bMySQL); CreateTables(); } void DB_UpdateServerFilter() { - if (!(GLOBAL_INFO & IS_MySQL)) + if (!g_bMySQL) { g_szSID[0] = 0; return; @@ -96,7 +96,7 @@ void CreateTables() DB_UpdateServerFilter(); - if (GLOBAL_INFO & IS_MySQL) + if (g_bMySQL) { g_hDatabase.Query(SQL_Callback_StorageTableCreate, "CREATE TABLE IF NOT EXISTS `vip_storage` (\ `account_id` INT NOT NULL, \ @@ -143,7 +143,7 @@ public void SQL_Callback_TableCreate(Database hOwner, DBResultSet hResult, const return; } - if (GLOBAL_INFO & IS_MySQL) + if (g_bMySQL) { g_hDatabase.Query(SQL_Callback_ErrorCheck, "SET NAMES '" ... CHARSET ... "'", _, DBPrio_High); g_hDatabase.Query(SQL_Callback_ErrorCheck, "SET CHARSET '" ... CHARSET ... "'", _, DBPrio_High); @@ -151,7 +151,7 @@ public void SQL_Callback_TableCreate(Database hOwner, DBResultSet hResult, const g_hDatabase.SetCharset(CHARSET); } - UNSET_BIT(GLOBAL_INFO, IS_LOADING); + g_bConnecting = false; OnReadyToStart(); @@ -207,7 +207,7 @@ public void SQL_Callback_ErrorCheck(Database hOwner, DBResultSet hResult, const void DB_UpdateClient(int iClient, const char[] szDbName = NULL_STRING) { int iClientID; - g_hFeatures[iClient].GetValue(KEY_CID, iClientID); + g_ePlayer[iClient].hFeatures.GetValue(KEY_CID, iClientID); char szQuery[256]; @@ -254,13 +254,13 @@ void DB_RemoveClientFromID(int iAdmin = 0, { strcopy(SZF(szGroup), szSourceGroup); } - else if(g_hFeatures[iClient]) + else if (g_ePlayer[iClient].hFeatures) { - g_hFeatures[iClient].GetString(KEY_GROUP, SZF(szGroup)); + g_ePlayer[iClient].hFeatures.GetString(KEY_GROUP, SZF(szGroup)); if(!iClientID) { - g_hFeatures[iClient].GetValue(KEY_CID, iClientID); + g_ePlayer[iClient].hFeatures.GetValue(KEY_CID, iClientID); } } } diff --git a/addons/sourcemod/scripting/vip/Features.sp b/addons/sourcemod/scripting/vip/Features.sp index 196b2d2..6b3598b 100644 --- a/addons/sourcemod/scripting/vip/Features.sp +++ b/addons/sourcemod/scripting/vip/Features.sp @@ -6,7 +6,7 @@ bool Features_Get(const char[] szFeature, Feature eFeature) void Features_TurnOffAll(int iClient) { DebugMessage("Features_TurnOffAll %N (%i)", iClient, iClient); - if (!(g_iClientInfo[iClient] & IS_VIP)) + if (!g_ePlayer[iClient].bVIP) { return; } @@ -68,13 +68,13 @@ void Features_TurnOnAll(int iClient) void Features_SetStatus(int iClient, const char[] szFeature, VIP_ToggleState eStatus) { DebugMessage("Features_SetStatus: %N (%i) -> Feature: %s, eStatus: %i", iClient, iClient, szFeature, eStatus); - g_hFeatureStatus[iClient].SetValue(szFeature, eStatus); + g_ePlayer[iClient].hFeatureStatus.SetValue(szFeature, eStatus); } VIP_ToggleState Features_GetStatus(const int &iClient, const char[] szFeature) { static VIP_ToggleState eStatus; - if(g_hFeatureStatus[iClient].GetValue(szFeature, eStatus)) + if (g_ePlayer[iClient].hFeatureStatus.GetValue(szFeature, eStatus)) { DebugMessage("Features_GetStatus: %N (%i) -> Feature: %s, eStatus: %i", iClient, iClient, szFeature, eStatus); return eStatus; diff --git a/addons/sourcemod/scripting/vip/Global.sp b/addons/sourcemod/scripting/vip/Global.sp index 4819eb5..10c8902 100644 --- a/addons/sourcemod/scripting/vip/Global.sp +++ b/addons/sourcemod/scripting/vip/Global.sp @@ -1,5 +1,3 @@ -#define GLOBAL_INFO g_iClientInfo[0] - #define UID(%0) GetClientUserId(%0) #define CID(%0) GetClientOfUserId(%0) #define SZF(%0) %0, sizeof(%0) @@ -19,17 +17,6 @@ #define SET_BIT(%0,%1) %0 |= %1 #define UNSET_BIT(%0,%1) %0 &= ~%1 -#define IS_VIP (1<<0) // Player is a VIP -#define IS_LOADED (1<<1) // Player is loaded -#define IS_WAIT_CHAT_PASS (1<<2) // Waiting for a password in chat -#define IS_WAIT_CHAT_SEARCH (1<<3) // Waiting for a search value in chat -#define IS_SPAWNED (1<<4) // Player has spawned -#define IS_MENU_OPEN (1<<5) // VIP menu is open - -#define IS_STARTED (1<<0) -#define IS_MySQL (1<<1) -#define IS_LOADING (1<<2) - #define REASON_PLUGIN -2 #define REASON_EXPIRED -3 #define REASON_OUTDATED -4 @@ -94,12 +81,33 @@ ArrayList g_hFeaturesArray; // Feature names in registration order StringMap g_hFeatureRegistry; // Feature name -> Feature ArrayList g_hSortArray; -StringMap g_hFeatures[MAXPLAYERS+1]; -StringMap g_hFeatureStatus[MAXPLAYERS+1]; +enum struct PlayerData +{ + bool bVIP; + bool bLoaded; // VIP check finished (VIP or not) + bool bSpawned; + bool bMenuOpen; + bool bWaitChatSearch; // Admin menu waits for a search value in chat + + StringMap hFeatures; // Feature values, plus KEY_CID / KEY_EXPIRES / KEY_GROUP / KEY_MENUITEM + StringMap hFeatureStatus; // Feature name -> VIP_ToggleState + StringMap hData; // Admin menu state (DATA_KEY_*) + + void ClearFlags() + { + this.bVIP = false; + this.bLoaded = false; + this.bSpawned = false; + this.bMenuOpen = false; + this.bWaitChatSearch = false; + } +} -StringMap g_hClientData[MAXPLAYERS+1]; +PlayerData g_ePlayer[MAXPLAYERS+1]; -int g_iClientInfo[MAXPLAYERS+1]; +bool g_bStarted; // Connected and VIP_OnVIPLoaded fired +bool g_bMySQL; +bool g_bConnecting; // DB_Connect is in progress int g_iMaxPageItems; diff --git a/addons/sourcemod/scripting/vip/Info.sp b/addons/sourcemod/scripting/vip/Info.sp index 3c6ad46..3315558 100644 --- a/addons/sourcemod/scripting/vip/Info.sp +++ b/addons/sourcemod/scripting/vip/Info.sp @@ -175,12 +175,12 @@ void ReplaceValues(int iClient, char[] szBuffer, int iBufLen, bool bExt) char szName[MAX_NAME_LENGTH]; char szGroup[64]; GetClientName(iClient, SZF(szName)); ReplaceString(szBuffer, iBufLen, "{NAME}", szName); - g_hFeatures[iClient].GetString(KEY_GROUP, SZF(szGroup)); + g_ePlayer[iClient].hFeatures.GetString(KEY_GROUP, SZF(szGroup)); ReplaceString(szBuffer, iBufLen, "{GROUP}", szGroup); if (bExt) { int iExpires; - g_hFeatures[iClient].GetValue(KEY_EXPIRES, iExpires); + g_ePlayer[iClient].hFeatures.GetValue(KEY_EXPIRES, iExpires); DebugMessage("GetValue(%s) = %d", KEY_EXPIRES, iExpires); DebugMessage("GetTime() = %d", GetTime()); DebugMessage("TIMELEFT = %d", iExpires - GetTime()); diff --git a/addons/sourcemod/scripting/vip/Storage.sp b/addons/sourcemod/scripting/vip/Storage.sp index a09ad49..51de1c1 100644 --- a/addons/sourcemod/scripting/vip/Storage.sp +++ b/addons/sourcemod/scripting/vip/Storage.sp @@ -30,7 +30,7 @@ bool Storage_GetClientValue(int iClient, const char[] szKey, char[] szValue, int void Storage_LoadClient(int iClient) { - if (!g_hDatabase || !(GLOBAL_INFO & IS_STARTED) || Storage_IsClientLoaded(iClient)) + if (!g_hDatabase || !g_bStarted || Storage_IsClientLoaded(iClient)) { return; } @@ -98,7 +98,6 @@ void Storage_SaveClient(int iClient, bool bSync = false) return; } - bool bMySQL = view_as(GLOBAL_INFO & IS_MySQL); int iUpdated = GetTime(); char szKey[STORAGE_KEY_LENGTH], szValue[STORAGE_VALUE_LENGTH], szQuery[1024]; @@ -119,7 +118,7 @@ void Storage_SaveClient(int iClient, bool bSync = false) g_hStorage[iClient].GetString(szKey, SZF(szValue)); // Database.Format escapes %s - if (bMySQL) + if (g_bMySQL) { g_hDatabase.Format(SZF(szQuery), "INSERT INTO `vip_storage` (`account_id`, `sid`, `key`, `value`, `updated`) \ VALUES (%d, %d, '%s', '%s', %d) \ @@ -183,7 +182,7 @@ void Storage_ResetClient(int iClient) static void Storage_GetServerFilter(char[] szFilter, int iMaxLength) { szFilter[0] = 0; - if (GLOBAL_INFO & IS_MySQL) + if (g_bMySQL) { FormatEx(szFilter, iMaxLength, " AND `sid` = %d", g_CVAR_iStorageID); } diff --git a/addons/sourcemod/scripting/vip/UTIL.sp b/addons/sourcemod/scripting/vip/UTIL.sp index 4551b29..23717bf 100644 --- a/addons/sourcemod/scripting/vip/UTIL.sp +++ b/addons/sourcemod/scripting/vip/UTIL.sp @@ -369,7 +369,7 @@ void UTIL_ADD_VIP_PLAYER(int iAdmin = 0, int iLastVisit = iTarget ? GetTime():0; - if (GLOBAL_INFO & IS_MySQL) + if (g_bMySQL) { FormatEx(SZF(szQuery), "INSERT INTO `vip_users` (`account_id`, `sid`, `expires`, `group`, `name`, `lastvisit`) VALUES (%d, %d, %d, '%s', '%s', %d) \ ON DUPLICATE KEY UPDATE `expires` = %d, `group` = '%s';", iAccountID, g_CVAR_iServerID, iExpires, szGroup, szName, iLastVisit, iExpires, szGroup); diff --git a/addons/sourcemod/scripting/vip/VipMenu.sp b/addons/sourcemod/scripting/vip/VipMenu.sp index 8ee3b78..d5955de 100644 --- a/addons/sourcemod/scripting/vip/VipMenu.sp +++ b/addons/sourcemod/scripting/vip/VipMenu.sp @@ -101,7 +101,7 @@ public int Handler_VIPMenu(Menu hMenu, MenuAction action, int iClient, int iOpti action == MenuAction_DrawItem || action == MenuAction_Select) { - if(!(g_iClientInfo[iClient] & IS_VIP) || !g_hFeatures[iClient]) + if (!g_ePlayer[iClient].bVIP || !g_ePlayer[iClient].hFeatures) { return 0; } @@ -113,7 +113,7 @@ public int Handler_VIPMenu(Menu hMenu, MenuAction action, int iClient, int iOpti { case MenuAction_Display, MenuAction_DrawItem, MenuAction_DisplayItem, MenuAction_Select: { - if (!(g_iClientInfo[iClient] & IS_VIP)) + if (!g_ePlayer[iClient].bVIP) { (g_hVIPMenu).Cancel(); DisplayClientInfo(iClient, "expired_info"); @@ -126,18 +126,18 @@ public int Handler_VIPMenu(Menu hMenu, MenuAction action, int iClient, int iOpti { case MenuAction_Cancel: { - UNSET_BIT(g_iClientInfo[iClient], IS_MENU_OPEN); + g_ePlayer[iClient].bMenuOpen = false; } case MenuAction_Display: { - SET_BIT(g_iClientInfo[iClient], IS_MENU_OPEN); + g_ePlayer[iClient].bMenuOpen = true; - g_hFeatures[iClient].Remove(KEY_MENUITEM); + g_ePlayer[iClient].hFeatures.Remove(KEY_MENUITEM); DebugMessage("MenuAction_Display: Client: %i", iClient); char szTitle[256]; int iExp; - if (g_hFeatures[iClient].GetValue(KEY_EXPIRES, iExp) && iExp > 0) + if (g_ePlayer[iClient].hFeatures.GetValue(KEY_EXPIRES, iExp) && iExp > 0) { int iTime = GetTime(); if (iTime < iExp) @@ -290,7 +290,7 @@ public int Handler_VIPMenu(Menu hMenu, MenuAction action, int iClient, int iOpti return 0; } - g_hFeatures[iClient].SetValue(KEY_MENUITEM, hMenu.Selection); + g_ePlayer[iClient].hFeatures.SetValue(KEY_MENUITEM, hMenu.Selection); if (Function_OnItemSelect(eFeature.hPlugin, eFeature.fnSelect, iClient, szItemInfo)) { hMenu.DisplayAt(iClient, hMenu.Selection, MENU_TIME_FOREVER); diff --git a/addons/sourcemod/scripting/vip/adminmenu/Add.sp b/addons/sourcemod/scripting/vip/adminmenu/Add.sp index 73157ec..8993f7a 100644 --- a/addons/sourcemod/scripting/vip/adminmenu/Add.sp +++ b/addons/sourcemod/scripting/vip/adminmenu/Add.sp @@ -11,9 +11,9 @@ void ShowAddVIPMenu(int iClient) { if (IsClientInGame(i) && IsFakeClient(i) == false && GetClientName(i, SZF(szName))) { - if (g_iClientInfo[i] & IS_VIP) + if (g_ePlayer[i].bVIP) { - g_hFeatures[i].GetValue(KEY_CID, iClientID); + g_ePlayer[i].hFeatures.GetValue(KEY_CID, iClientID); if (iClientID != -1) { continue; @@ -55,9 +55,9 @@ public int MenuHandler_AddVip_PlayerList(Menu hMenu, MenuAction action, int iCli int UserID = StringToInt(szUserID); if (CID(UserID)) { - g_hClientData[iClient].SetValue(DATA_KEY_TargetUID, UserID); - g_hClientData[iClient].SetValue(DATA_KEY_TimeType, TIME_SET); - g_hClientData[iClient].SetValue(DATA_KEY_MenuType, MENU_TYPE_ADD); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_TargetUID, UserID); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_TimeType, TIME_SET); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_MenuType, MENU_TYPE_ADD); ShowTimeMenu(iClient); } else VIP_PrintToChatClient(iClient, "%t", "PLAYER_NO_LONGER_AVAILABLE"); } diff --git a/addons/sourcemod/scripting/vip/adminmenu/Del.sp b/addons/sourcemod/scripting/vip/adminmenu/Del.sp index 40be6e1..4b8ce45 100644 --- a/addons/sourcemod/scripting/vip/adminmenu/Del.sp +++ b/addons/sourcemod/scripting/vip/adminmenu/Del.sp @@ -4,7 +4,7 @@ void ShowDeleteVipPlayerMenu(int iClient) Menu hMenu = new Menu(MenuHandler_DeleteVipPlayerMenu); - g_hClientData[iClient].GetString(DATA_KEY_Name, szBuffer, MAX_NAME_LENGTH); + g_ePlayer[iClient].hData.GetString(DATA_KEY_Name, szBuffer, MAX_NAME_LENGTH); hMenu.SetTitle("%T\n%s ?:\n \n", "MENU_DEL_VIP", iClient, szBuffer); FormatEx(SZF(szBuffer), "%T", "CONFIRM", iClient); @@ -36,10 +36,10 @@ public int MenuHandler_DeleteVipPlayerMenu(Menu hMenu, MenuAction action, int iC case 0: { int iTargetID; - g_hClientData[iClient].GetValue(DATA_KEY_TargetID, iTargetID); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_TargetID, iTargetID); int iTarget = 0; - if(g_hClientData[iClient].GetValue(DATA_KEY_TargetUID, iTarget)) + if (g_ePlayer[iClient].hData.GetValue(DATA_KEY_TargetUID, iTarget)) { iTarget = CID(iTarget); } @@ -62,8 +62,8 @@ public int MenuHandler_DeleteVipPlayerMenu(Menu hMenu, MenuAction action, int iC if(iTargetID != -1) { char szGroup[64], szName[MAX_NAME_LENGTH]; - g_hClientData[iClient].GetString(DATA_KEY_Name, SZF(szName)); - g_hClientData[iClient].GetString(DATA_KEY_Group, SZF(szGroup)); + g_ePlayer[iClient].hData.GetString(DATA_KEY_Name, SZF(szName)); + g_ePlayer[iClient].hData.GetString(DATA_KEY_Group, SZF(szGroup)); DB_RemoveClientFromID(iClient, _, iTargetID, true, szName, szGroup); } diff --git a/addons/sourcemod/scripting/vip/adminmenu/Edit.sp b/addons/sourcemod/scripting/vip/adminmenu/Edit.sp index c9ca842..b34b847 100644 --- a/addons/sourcemod/scripting/vip/adminmenu/Edit.sp +++ b/addons/sourcemod/scripting/vip/adminmenu/Edit.sp @@ -32,8 +32,8 @@ public int MenuHandler_EditTimeMenu(Menu hMenu, MenuAction action, int iClient, } case MenuAction_Select: { - g_hClientData[iClient].SetValue(DATA_KEY_TimeType, iItem); - g_hClientData[iClient].SetValue(DATA_KEY_MenuType, MENU_TYPE_EDIT); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_TimeType, iItem); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_MenuType, MENU_TYPE_EDIT); ShowTimeMenu(iClient); } } diff --git a/addons/sourcemod/scripting/vip/adminmenu/List.sp b/addons/sourcemod/scripting/vip/adminmenu/List.sp index d3f0db4..a92c4e5 100644 --- a/addons/sourcemod/scripting/vip/adminmenu/List.sp +++ b/addons/sourcemod/scripting/vip/adminmenu/List.sp @@ -2,8 +2,8 @@ static const int LIST_OFFSET = 60; void ShowVipPlayersListMenu(int iClient) { - g_hClientData[iClient].SetValue(DATA_KEY_MenuListType, MENU_TYPE_ONLINE_LIST); - g_hClientData[iClient].Remove(DATA_KEY_Search); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_MenuListType, MENU_TYPE_ONLINE_LIST); + g_ePlayer[iClient].hData.Remove(DATA_KEY_Search); char szUserID[16], szName[128]; int i, iClientID; @@ -21,9 +21,9 @@ void ShowVipPlayersListMenu(int iClient) szUserID[0] = 0; for (i = 1; i <= MaxClients; ++i) { - if (IsClientInGame(i) && (g_iClientInfo[i] & IS_VIP) && !IsFakeClient(i) && GetClientName(i, SZF(szName))) + if (IsClientInGame(i) && g_ePlayer[i].bVIP && !IsFakeClient(i) && GetClientName(i, SZF(szName))) { - g_hFeatures[i].GetValue(KEY_CID, iClientID); + g_ePlayer[i].hFeatures.GetValue(KEY_CID, iClientID); FormatEx(SZF(szUserID), "u%d", UID(i)); if (iClientID == -1) { @@ -76,7 +76,7 @@ public int MenuHandler_VipPlayersListMenu(Menu hMenu, MenuAction action, int iCl if (!strcmp(szUserID, "show_all")) // Show all { - g_hClientData[iClient].Remove(DATA_KEY_Search); + g_ePlayer[iClient].hData.Remove(DATA_KEY_Search); ShowVipPlayersFromDBMenu(iClient); return 0; @@ -85,7 +85,7 @@ public int MenuHandler_VipPlayersListMenu(Menu hMenu, MenuAction action, int iCl if (!strcmp(szUserID, "more")) // Show more { int iOffset; - g_hClientData[iClient].GetValue(DATA_KEY_Offset, iOffset); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_Offset, iOffset); ShowVipPlayersFromDBMenu(iClient, iOffset + LIST_OFFSET); return 0; @@ -97,9 +97,9 @@ public int MenuHandler_VipPlayersListMenu(Menu hMenu, MenuAction action, int iCl int iTarget = CID(UserID); if (iTarget) { - g_hClientData[iClient].SetValue(DATA_KEY_TargetUID, UserID); - g_hFeatures[iTarget].GetValue(KEY_CID, UserID); - g_hClientData[iClient].SetValue(DATA_KEY_TargetID, UserID); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_TargetUID, UserID); + g_ePlayer[iTarget].hFeatures.GetValue(KEY_CID, UserID); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_TargetID, UserID); if(UserID == -1) { @@ -119,8 +119,8 @@ public int MenuHandler_VipPlayersListMenu(Menu hMenu, MenuAction action, int iCl } // Picked from the DB list: forget a player picked earlier from the online list - g_hClientData[iClient].Remove(DATA_KEY_TargetUID); - g_hClientData[iClient].SetValue(DATA_KEY_TargetID, S2I(szUserID)); + g_ePlayer[iClient].hData.Remove(DATA_KEY_TargetUID); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_TargetID, S2I(szUserID)); ShowTargetInfo(iClient); } @@ -138,12 +138,12 @@ void ShowWaitSearchMenu(int iClient, const char[] szSearch = NULL_STRING) FormatEx(SZF(szBuffer), "%T", "CONFIRM", iClient); if (szSearch[0]) { - // g_iClientInfo[iClient] &= ~IS_WAIT_CHAT_SEARCH; + // g_ePlayer[iClient].bWaitChatSearch = false; hMenu.AddItem(szSearch, szBuffer); } else { - g_iClientInfo[iClient] |= IS_WAIT_CHAT_SEARCH; + g_ePlayer[iClient].bWaitChatSearch = true; hMenu.AddItem(NULL_STRING, szBuffer, ITEMDRAW_DISABLED); } @@ -164,7 +164,7 @@ public int MenuHandler_SearchPlayersListMenu(Menu hMenu, MenuAction action, int { if (iItem != MenuCancel_Interrupted) { - g_iClientInfo[iClient] &= ~IS_WAIT_CHAT_SEARCH; + g_ePlayer[iClient].bWaitChatSearch = false; } if (iItem == MenuCancel_ExitBack) @@ -174,14 +174,14 @@ public int MenuHandler_SearchPlayersListMenu(Menu hMenu, MenuAction action, int } case MenuAction_Select: { - g_iClientInfo[iClient] &= ~IS_WAIT_CHAT_SEARCH; + g_ePlayer[iClient].bWaitChatSearch = false; switch (iItem) { case 0: { char szSearch[32]; hMenu.GetItem(iItem, SZF(szSearch)); - g_hClientData[iClient].SetString(DATA_KEY_Search, szSearch); + g_ePlayer[iClient].hData.SetString(DATA_KEY_Search, szSearch); ShowVipPlayersFromDBMenu(iClient); } case 1: @@ -198,13 +198,13 @@ public int MenuHandler_SearchPlayersListMenu(Menu hMenu, MenuAction action, int void ShowVipPlayersFromDBMenu(int iClient, int iOffset = 0) { LogMessage("ShowVipPlayersFromDBMenu"); - g_hClientData[iClient].SetValue(DATA_KEY_MenuListType, MENU_TYPE_DB_LIST); - g_hClientData[iClient].SetValue(DATA_KEY_Offset, iOffset); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_MenuListType, MENU_TYPE_DB_LIST); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_Offset, iOffset); char szQuery[1024], szSearch[64], szWhere[128]; szSearch[0] = 0; szWhere[0] = 0; - if(g_hClientData[iClient].GetString(DATA_KEY_Search, SZF(szSearch)) && szSearch[0]) + if (g_ePlayer[iClient].hData.GetString(DATA_KEY_Search, SZF(szSearch)) && szSearch[0]) { int iAccountID = UTIL_GetAccountIDFromSteamID(szSearch); if(iAccountID) @@ -243,7 +243,7 @@ public void SQL_Callback_SelectVipPlayers(Database hOwner, DBResultSet hResult, Menu hMenu = new Menu(MenuHandler_VipPlayersListMenu); hMenu.ExitBackButton = true; szSearch[0] = 0; - g_hClientData[iClient].GetString(DATA_KEY_Search, SZF(szSearch)); + g_ePlayer[iClient].hData.GetString(DATA_KEY_Search, SZF(szSearch)); if(szSearch[0]) { hMenu.SetTitle("%T:\n%T:\n ", "MENU_LIST_VIP", iClient, "MENU_SEARCH", iClient, szSearch, hResult.RowCount); @@ -295,7 +295,7 @@ public void SQL_Callback_SelectVipPlayers(Database hOwner, DBResultSet hResult, void ShowTargetInfo(int iClient) { int iClientID; - g_hClientData[iClient].GetValue(DATA_KEY_TargetID, iClientID); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_TargetID, iClientID); char szQuery[512]; FormatEx(SZF(szQuery), "SELECT `group`, \ @@ -334,19 +334,19 @@ public void SQL_Callback_SelectVipClientInfo(Database hOwner, DBResultSet hResul char szGroup[64], szName[32]; hResult.FetchString(0, SZF(szGroup)); // GROUP - g_hClientData[iClient].SetString(DATA_KEY_Group, szGroup); + g_ePlayer[iClient].hData.SetString(DATA_KEY_Group, szGroup); DBG_SQL_Response("hResult.FetchString(0) = '%s", szGroup); int iExpires = hResult.FetchInt(1); // Expires - g_hClientData[iClient].SetValue(DATA_KEY_Time, iExpires); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_Time, iExpires); DBG_SQL_Response("hResult.FetchInt(1) = %d", iExpires); hResult.FetchString(2, SZF(szName)); // Name - g_hClientData[iClient].SetString(DATA_KEY_Name, szName); + g_ePlayer[iClient].hData.SetString(DATA_KEY_Name, szName); DBG_SQL_Response("hResult.FetchString(2) = '%s", szName); int iAccountID = hResult.FetchInt(3); // Auth - g_hClientData[iClient].SetValue(DATA_KEY_Auth, iAccountID); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_Auth, iAccountID); DBG_SQL_Response("hResult.FetchInt(3) = %d", iAccountID); ShowTargetInfoMenu(iClient); @@ -357,7 +357,7 @@ void ShowTemporaryTargetInfo(int iClient) { char szGroup[64], szName[32]; int iTarget; - g_hClientData[iClient].GetValue(DATA_KEY_TargetUID, iTarget); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_TargetUID, iTarget); iTarget = CID(iTarget); if(!iTarget) { @@ -366,17 +366,17 @@ void ShowTemporaryTargetInfo(int iClient) return; } - g_hFeatures[iTarget].GetString(KEY_GROUP, SZF(szGroup)); - g_hClientData[iClient].SetString(DATA_KEY_Group, szGroup); + g_ePlayer[iTarget].hFeatures.GetString(KEY_GROUP, SZF(szGroup)); + g_ePlayer[iClient].hData.SetString(DATA_KEY_Group, szGroup); int iExpires, iAccountID; - g_hFeatures[iTarget].GetValue(KEY_EXPIRES, iExpires); - g_hClientData[iClient].SetValue(DATA_KEY_Time, iExpires); + g_ePlayer[iTarget].hFeatures.GetValue(KEY_EXPIRES, iExpires); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_Time, iExpires); GetClientName(iTarget, SZF(szName)); iAccountID = GetSteamAccountID(iTarget); - g_hClientData[iClient].SetString(DATA_KEY_Name, szName); - g_hClientData[iClient].SetValue(DATA_KEY_Auth, iAccountID); + g_ePlayer[iClient].hData.SetString(DATA_KEY_Name, szName); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_Auth, iAccountID); ShowTargetInfoMenu(iClient); } @@ -384,13 +384,13 @@ void ShowTemporaryTargetInfo(int iClient) void ShowTargetInfoMenu(int iClient) { char szGroup[64], szName[32], szAuth[32], szBuffer[128]; - g_hClientData[iClient].GetString(DATA_KEY_Group, SZF(szGroup)); - g_hClientData[iClient].GetString(DATA_KEY_Name, SZF(szName)); + g_ePlayer[iClient].hData.GetString(DATA_KEY_Group, SZF(szGroup)); + g_ePlayer[iClient].hData.GetString(DATA_KEY_Name, SZF(szName)); int iExpires, iClientID, iAccountID; - g_hClientData[iClient].GetValue(DATA_KEY_Time, iExpires); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_Time, iExpires); DebugMessage("GetValue(%s) = %d", DATA_KEY_Time, iExpires); - g_hClientData[iClient].GetValue(DATA_KEY_TargetID, iClientID); - g_hClientData[iClient].GetValue(DATA_KEY_Auth, iAccountID); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_TargetID, iClientID); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_Auth, iAccountID); UTIL_GetSteamIDFromAccountID(iAccountID, SZF(szAuth)); if (iExpires > 0) @@ -444,7 +444,7 @@ public int MenuHandler_VipClientInfoMenu(Menu hMenu, MenuAction action, int iCli { DebugMessage("MenuHandler_VipClientInfoMenu->MenuCancel_ExitBack"); AdminMenuItem eItem; - g_hClientData[iClient].GetValue(DATA_KEY_MenuListType, eItem); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_MenuListType, eItem); DebugMessage("GetValue(%s) = %d", DATA_KEY_MenuListType, eItem); switch(eItem) { @@ -455,7 +455,7 @@ public int MenuHandler_VipClientInfoMenu(Menu hMenu, MenuAction action, int iCli case MENU_TYPE_DB_LIST: { int iOffset; - g_hClientData[iClient].GetValue(DATA_KEY_Offset, iOffset); + g_ePlayer[iClient].hData.GetValue(DATA_KEY_Offset, iOffset); ShowVipPlayersFromDBMenu(iClient, iOffset); } } @@ -469,9 +469,9 @@ public int MenuHandler_VipClientInfoMenu(Menu hMenu, MenuAction action, int iCli case 1: ShowEditTimeMenu(iClient); case 2: { - g_hClientData[iClient].SetValue(DATA_KEY_MenuType, MENU_TYPE_EDIT); + g_ePlayer[iClient].hData.SetValue(DATA_KEY_MenuType, MENU_TYPE_EDIT); char szGroup[64]; - g_hClientData[iClient].GetString(DATA_KEY_Group, SZF(szGroup)); + g_ePlayer[iClient].hData.GetString(DATA_KEY_Group, SZF(szGroup)); ShowGroupsMenu(iClient, szGroup); } } From 8a3d89b1870525d583cec599b06ae5f01ac9d6b6 Mon Sep 17 00:00:00 2001 From: R1KO Date: Sun, 11 Oct 2026 01:08:40 +0300 Subject: [PATCH 6/9] Remove dead code: unused SET_BIT/UNSET_BIT, SZFA and MPL macros and a stray LogMessage in the admin VIP list. AGENTS.md now describes the Feature/PlayerData globals instead of the removed flag bits and slot 0. --- AGENTS.md | 3 +-- addons/sourcemod/scripting/vip/Global.sp | 5 ----- addons/sourcemod/scripting/vip/adminmenu/List.sp | 1 - 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index e9cb598..6ec33d7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,7 +13,7 @@ ## Layout - `scripting/VIP_Core.sp` — entry point; `#include`s every `vip/*.sp` into ONE compilation unit (order matters: Global → Debug → ... → API → CMD → Clients). New file = add `#include` there. - Compile-time switches in `VIP_Core.sp`: `DEBUG_MODE`, `USE_ADMINMENU` (gates `AdminMenu.sp` + `vip/adminmenu/*`), `USE_MORE_SERVERS`, `USE_CLIENTPREFS` (toggle statuses in cookies vs `vip_storage`; status I/O only via `Features_GetSavedStatus`/`Features_SaveStatus`). -- `vip/Global.sp` — all globals, macros (`SZF`, `UID/CID`, `SET_BIT/UNSET_BIT`), client flag bits (`IS_VIP`, `IS_LOADED`, ...), core state bits (`IS_STARTED`, `IS_MySQL`, `IS_LOADING`). +- `vip/Global.sp` — all globals, macros (`SZF`, `UID/CID`), feature registry (`Feature` in `g_hFeatureRegistry`), per-player state (`PlayerData g_ePlayer[]`), server state (`g_bStarted`, `g_bMySQL`, `g_bConnecting`). - `vip/API.sp` — forwards (`API_SetupForwards`, `CreateForward_*`) and natives (`AskPluginLoad2`, `RegNative(X)` → `VIP_X` bound to `Native_X`). - `vip/Database.sp` — connection, schema, queries. `UTIL.sp` — shared helpers; check here before writing new ones. `Clients.sp` — client load/unload lifecycle, spawn. `Features.sp` — feature registry. - `include/vip_core.inc` — PUBLIC API for third-party modules. `data/vip/cfg/*.ini` — runtime configs (groups, info, sort_menu, times). `translations/vip_core.phrases.txt` — all user-facing strings. @@ -44,7 +44,6 @@ ## Conventions - Pass client across async boundaries as userid (`UID`/`CID`), never raw index. -- `GLOBAL_TRIE` / `GLOBAL_INFO` are index `[0]` of per-client arrays — slot 0 = global, not a player. - Use methodmaps (`StringMap`, `Cookie`, `KeyValues`, `delete`), not legacy procedural calls (`CreateTrie`, `SetClientCookie`, `CloseHandle`, `Kv*`). - Debug logging via `DBG_*` / `DebugMessage` functions from `Debug.sp` (empty unless `DEBUG_MODE 1`); calls still need a trailing `;`. - English only in code, comments, cvar descriptions, log/error strings and docs. Other languages live only in `translations/*.phrases.txt` and the per-language values of `data/vip/cfg/*.ini`. Any new user-facing text → new phrase in `vip_core.phrases.txt` with at least `en` and `ru`. Bump `VIP_VERSION` in `VIP_Core.sp` only when asked; changelog lives in GitHub Releases (release notes). diff --git a/addons/sourcemod/scripting/vip/Global.sp b/addons/sourcemod/scripting/vip/Global.sp index 10c8902..102f404 100644 --- a/addons/sourcemod/scripting/vip/Global.sp +++ b/addons/sourcemod/scripting/vip/Global.sp @@ -1,7 +1,6 @@ #define UID(%0) GetClientUserId(%0) #define CID(%0) GetClientOfUserId(%0) #define SZF(%0) %0, sizeof(%0) -#define SZFA(%0,%1) %0[%1], sizeof(%0[]) #define I2S(%0,%1) IntToString(%0, SZF(%1)) @@ -11,12 +10,8 @@ #define PMP PLATFORM_MAX_PATH #define MNL MAX_NAME_LENGTH -#define MPL MAXPLAYERS #define MCL MaxClients -#define SET_BIT(%0,%1) %0 |= %1 -#define UNSET_BIT(%0,%1) %0 &= ~%1 - #define REASON_PLUGIN -2 #define REASON_EXPIRED -3 #define REASON_OUTDATED -4 diff --git a/addons/sourcemod/scripting/vip/adminmenu/List.sp b/addons/sourcemod/scripting/vip/adminmenu/List.sp index a92c4e5..99d2db7 100644 --- a/addons/sourcemod/scripting/vip/adminmenu/List.sp +++ b/addons/sourcemod/scripting/vip/adminmenu/List.sp @@ -197,7 +197,6 @@ public int MenuHandler_SearchPlayersListMenu(Menu hMenu, MenuAction action, int void ShowVipPlayersFromDBMenu(int iClient, int iOffset = 0) { - LogMessage("ShowVipPlayersFromDBMenu"); g_ePlayer[iClient].hData.SetValue(DATA_KEY_MenuListType, MENU_TYPE_DB_LIST); g_ePlayer[iClient].hData.SetValue(DATA_KEY_Offset, iOffset); From 1bcf89fe28043a1ea3cff46335a60903daf8af26 Mon Sep 17 00:00:00 2001 From: R1KO Date: Sun, 11 Oct 2026 01:15:33 +0300 Subject: [PATCH 7/9] Print VIP chat messages on engines without a dedicated color branch in Colors_Print; the default case replaced {TEAM} but never sent the message. Taken from #105. --- addons/sourcemod/scripting/vip/Colors.sp | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/sourcemod/scripting/vip/Colors.sp b/addons/sourcemod/scripting/vip/Colors.sp index 5e3ebc3..71374b2 100644 --- a/addons/sourcemod/scripting/vip/Colors.sp +++ b/addons/sourcemod/scripting/vip/Colors.sp @@ -82,6 +82,7 @@ void Colors_Print(int iClient, const char[] szFormat) default: { ReplaceString(SZF(szMessage), "{TEAM}", "\x03"); + PrintToChat(iClient, "%s", szMessage); } } } From 98fc365be40f3bca6546649cb99dc1bd6d1fa7d5 Mon Sep 17 00:00:00 2001 From: R1KO Date: Sun, 11 Oct 2026 01:20:28 +0300 Subject: [PATCH 8/9] Send each line of a VIP chat message as its own SayText2, so long multi-line messages (e.g. info.ini) are no longer cut at one usermessage and CS:GO keeps colors on every line. The native and Colors_Print buffers grow to 1024; based on #105. --- .../sourcemod/scripting/include/vip_core.inc | 4 ++ addons/sourcemod/scripting/vip/API.sp | 4 +- addons/sourcemod/scripting/vip/Colors.sp | 37 ++++++++++++++++++- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/addons/sourcemod/scripting/include/vip_core.inc b/addons/sourcemod/scripting/include/vip_core.inc index afe7e03..301e276 100644 --- a/addons/sourcemod/scripting/include/vip_core.inc +++ b/addons/sourcemod/scripting/include/vip_core.inc @@ -391,6 +391,8 @@ native void VIP_GetClientStorageValue(int iClient, const char[] szKey, char[] sz /** * Prints a chat message to a player with a prefix (translation phrase "VIP_CHAT_PREFIX"). + * A line break ("\n" or the two characters \n, e.g. from a translation) starts a new chat message; + * each line holds up to about 250 bytes, the whole message up to 1024. * * @param iClient Client index. * @param szMessage Formatting rules. @@ -402,6 +404,8 @@ native void VIP_PrintToChatClient(int iClient, const char[] szMessage, any ...); /** * Prints a chat message to all players with a prefix (translation phrase "VIP_CHAT_PREFIX"). + * A line break ("\n" or the two characters \n, e.g. from a translation) starts a new chat message; + * each line holds up to about 250 bytes, the whole message up to 1024. * * @param szMessage Formatting rules. * @param ... Formatting parameters. diff --git a/addons/sourcemod/scripting/vip/API.sp b/addons/sourcemod/scripting/vip/API.sp index 334c9ca..97e1e64 100644 --- a/addons/sourcemod/scripting/vip/API.sp +++ b/addons/sourcemod/scripting/vip/API.sp @@ -348,7 +348,7 @@ public int Native_PrintToChatClient(Handle hPlugin, int iNumParams) DBG_API("iClient = %d", iClient); if (CheckValidClient(iClient, false)) { - char szMessage[256]; + char szMessage[1024]; SetGlobalTransTarget(iClient); FormatNativeString(0, 2, 3, sizeof(szMessage), _, szMessage); @@ -361,7 +361,7 @@ public int Native_PrintToChatClient(Handle hPlugin, int iNumParams) public int Native_PrintToChatAll(Handle hPlugin, int iNumParams) { DBG_API("Native_PrintToChatAll(%d)", iNumParams); - char szMessage[256]; + char szMessage[1024]; for (int i = 1; i <= MCL; ++i) { diff --git a/addons/sourcemod/scripting/vip/Colors.sp b/addons/sourcemod/scripting/vip/Colors.sp index 5e3ebc3..9325d86 100644 --- a/addons/sourcemod/scripting/vip/Colors.sp +++ b/addons/sourcemod/scripting/vip/Colors.sp @@ -1,6 +1,6 @@ void Colors_Print(int iClient, const char[] szFormat) { - char szMessage[512]; + char szMessage[1024]; FormatEx(SZF(szMessage), g_EngineVersion == Engine_CSGO ? " \x01%t %s":"\x01%t %s", "VIP_CHAT_PREFIX", szFormat); ReplaceString(SZF(szMessage), "\\n", "\n"); @@ -122,7 +122,42 @@ int Colors_FindPlayerByTeam(int iTeam) return 0; } +// One SayText2 holds at most 255 bytes and CS:GO drops colors after '\n', so every line goes as its own message void Colors_SayText2(int iClient, int iAuthor = 0, const char[] szMessage) +{ + // 255 bytes minus the author and chat flag bytes + char szLine[253]; + int iStart = 0; + for (int i = 0; ; ++i) + { + if (szMessage[i] != '\n' && szMessage[i]) + { + continue; + } + + if (i > iStart) + { + // CS:GO ignores a color code at the very start of a message + int iOffset = (iStart > 0 && g_EngineVersion == Engine_CSGO) ? 1 : 0; + szLine[0] = ' '; + int iLength = i - iStart + 1; + if (iLength > sizeof(szLine) - iOffset) + { + iLength = sizeof(szLine) - iOffset; + } + strcopy(szLine[iOffset], iLength, szMessage[iStart]); + Colors_SendSayText2(iClient, iAuthor, szLine); + } + + if (!szMessage[i]) + { + break; + } + iStart = i + 1; + } +} + +static void Colors_SendSayText2(int iClient, int iAuthor, const char[] szMessage) { int iClients[1]; iClients[0] = iClient; From 3a73813fa062732ff70b0c6ba0f8ff5ab566b397 Mon Sep 17 00:00:00 2001 From: R1KO Date: Sun, 11 Oct 2026 01:35:46 +0300 Subject: [PATCH 9/9] Bump version to 3.1.1 R. --- addons/sourcemod/scripting/VIP_Core.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sourcemod/scripting/VIP_Core.sp b/addons/sourcemod/scripting/VIP_Core.sp index 2350f37..a1d5769 100644 --- a/addons/sourcemod/scripting/VIP_Core.sp +++ b/addons/sourcemod/scripting/VIP_Core.sp @@ -7,7 +7,7 @@ #include #if !defined VIP_VERSION -#define VIP_VERSION "3.1.0 R" +#define VIP_VERSION "3.1.1 R" #endif