From 29dd9c3bc87e94ed2edcf10197470213f2e4b5fb Mon Sep 17 00:00:00 2001 From: DosMike Date: Sat, 5 Aug 2023 16:53:35 +0200 Subject: [PATCH 1/4] Fix potential issue with menu and profile names --- scripting/mcp-chattags.sp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripting/mcp-chattags.sp b/scripting/mcp-chattags.sp index f5cd601..32daf59 100644 --- a/scripting/mcp-chattags.sp +++ b/scripting/mcp-chattags.sp @@ -426,9 +426,9 @@ public int ChatTagProfileMenuHandler(Menu menu, MenuAction action, int param1, i } } else if (action == MenuAction_Select) { char buffer[32], name[32]; - menu.GetItem(param2, buffer, sizeof(buffer)); + menu.GetItem(param2, buffer, 0, _, name, sizeof(name)); //info buffer is too small + if (!StrEqual(name, STR_NO_PROFILE)) buffer = name; mcpct_profile.Set(param1, buffer); - name = (buffer[0]==0) ? STR_NO_PROFILE : buffer; if (UpdateProfile(param1)) { PrintToChat(param1, "[ChatTag] You activate profile \"%s\"", name); } else { From d2d59bb142deeac19f03c6edb74de904487a4b9c Mon Sep 17 00:00:00 2001 From: DosMike Date: Sun, 6 Aug 2023 16:57:38 +0200 Subject: [PATCH 2/4] Update mcp-chattags to automatically switch profiles when permissions change --- Modules.md | 16 ++++++++++--- scripting/mcp-chattags.sp | 47 ++++++++++++++++++++++++++++++--------- 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/Modules.md b/Modules.md index cc70f00..d4df56d 100644 --- a/Modules.md +++ b/Modules.md @@ -9,9 +9,19 @@ Replacement for Custom Chat-Colors and Custom Chat-Colors Toggle. Config is compatible, but you should also be able to key on flag groups and overrides. -A difference to CCC Toggle is, that players can select which of the profiles they want active. -If you want it to behave like CCC without CCC Toggle, just activating the first profile, you can -set the convar `chattag_menu_enabled` to 0. +A difference to CCC Toggle is, that players can select which of the profiles they +want active. If you want it to behave like CCC without CCC Toggle, you can set the +convar `chattag_menu_enabled` to 0. + +Setting the convar `chattag_load_behaviour` to 1, as well will also reload the +first matching profile every time a player connects, while zero will not change +the profile on connect. + +If you set `chattag_load_behaviour` to 2, it will try to detect changes in access to +profiles, and switch profile, if the list of accessible profiles changes for a user. +This is intended to help with ranks that get unlocked externally, so users don't have +to know /settings is a thing. It is not possible to detect what profile excatly was +granted or revoked permission to, so it will always pick first in the config. Reloading the config can be done with the ADMFLAG_CONFIG command `sm_reloadchattags`. diff --git a/scripting/mcp-chattags.sp b/scripting/mcp-chattags.sp index 32daf59..4eeedbc 100644 --- a/scripting/mcp-chattags.sp +++ b/scripting/mcp-chattags.sp @@ -34,10 +34,12 @@ ArrayList profiles; Cookie mcpct_style; //what to color Cookie mcpct_profile; //profile name +Cookie mcpct_crc; //if the crc changes, we have a new profile GlobalForward mcpct_fwd_change; ConVar cvar_settingsMenuEnabled; +ConVar cvar_loadBehaviour; public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) { @@ -54,12 +56,14 @@ public void OnPluginStart() { mcpct_style = new Cookie("mcpchattag_style", "Style of MCP Chat Tag", CookieAccess_Private); mcpct_profile = new Cookie("mcpchattag_profile", "Style of MCP Chat Tag", CookieAccess_Private); + mcpct_crc = new Cookie("mcpchattag_checksum", "CRC of available profiles to detect changes", CookieAccess_Private); mcpct_fwd_change = CreateGlobalForward("MCP_CT_OnProfileChanged", ET_Event, Param_Cell, Param_String, Param_String, Param_String, Param_CellByRef); SetCookieMenuItem(ChatTagCookieMenu, 0, "Chat Tag Settings"); cvar_settingsMenuEnabled = CreateConVar("chattag_menu_enabled", "1", "0=Disable the /settings menu, 1=Enable", _, true, 0.0, true, 1.0); + cvar_settingsMenuEnabled = CreateConVar("chattag_load_behaviour", "2", "What to do when a client connects. 0=Use last active profil, 1=Use forst matching profile, 2=Like 1 if available profiles changed", _, true, 0.0, true, 2.0); RegAdminCmd("sm_reloadchattags", Cmd_Reload, ADMFLAG_CONFIG, "Reload chat tags"); @@ -91,16 +95,39 @@ public Action Cmd_Reload(int admin, int args) public void OnClientAuthorized(int client, const char[] auth) { char tmp[32]; - cvar_settingsMenuEnabled.GetString(tmp, sizeof(tmp)); - if (StringToInt(tmp)==0) { - ArrayList list = FindApplicableProfiles(client); - if (list.Length>0) { - list.GetString(0, tmp, sizeof(tmp)); - mcpct_profile.Set(client, tmp); - mcpct_style.Set(client, "15"); + bool refresh; + ArrayList list = FindApplicableProfiles(client); + + //check profile hash + // // make crc16 + int crc; + for (int i; i<=list.Length; i++) { + list.GetString(i, tmp, sizeof(tmp)); + for (int c; tmp[c] != 0; c+=2) { + crc += (tmp[c]<<8)|(tmp[c+1]); + if ((crc & 0x10000)!=0) crc = (crc&0xffff)+1; + if (tmp[c+1]==0) break; //next loop would be oob } - delete list; } + // // get old hash + mcpct_crc.Get(client, tmp, sizeof(tmp)); + int oldCrc = StringToInt(tmp,16); + // // store new hash + FormatEx(tmp, sizeof(tmp), "%04X", crc); + mcpct_crc.Set(client, tmp); + // // get load behaviour + cvar_loadBehaviour.GetString(tmp, sizeof(tmp)); + int load = StringToInt(tmp); + // // should we refresh? + refresh |= ((crc != oldCrc && load==2) || load==1); + + //if profile should refresh, pick the first match and save + if (refresh && list.Length>0) { + list.GetString(0, tmp, sizeof(tmp)); + mcpct_profile.Set(client, tmp); + mcpct_style.Set(client, "15"); + } + delete list; UpdateProfile(client); } @@ -395,8 +422,8 @@ void ShowChatTagProfileMenu(int client, int page=1) { } } - choices.Sort(Sort_Descending, Sort_String); - for (int i=choices.Length-1; i>=0; i--) { + int max=choices.Length; + for (int i=0; i Date: Sun, 6 Aug 2023 18:14:08 +0200 Subject: [PATCH 3/4] Fixed various bugs with loading/applying styles --- scripting/mcp-chattags.sp | 54 ++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/scripting/mcp-chattags.sp b/scripting/mcp-chattags.sp index 4eeedbc..46f714d 100644 --- a/scripting/mcp-chattags.sp +++ b/scripting/mcp-chattags.sp @@ -6,7 +6,7 @@ #pragma semicolon 1 #pragma newdecls required -#define PLUGIN_VERSION "23w31a" +#define PLUGIN_VERSION "23w31b" #define STR_NO_PROFILE "None" #define STR_PERSONAL "Personal" @@ -63,14 +63,12 @@ public void OnPluginStart() { SetCookieMenuItem(ChatTagCookieMenu, 0, "Chat Tag Settings"); cvar_settingsMenuEnabled = CreateConVar("chattag_menu_enabled", "1", "0=Disable the /settings menu, 1=Enable", _, true, 0.0, true, 1.0); - cvar_settingsMenuEnabled = CreateConVar("chattag_load_behaviour", "2", "What to do when a client connects. 0=Use last active profil, 1=Use forst matching profile, 2=Like 1 if available profiles changed", _, true, 0.0, true, 2.0); + cvar_loadBehaviour = CreateConVar("chattag_load_behaviour", "2", "What to do when a client connects. 0=Use last active profil, 1=Use forst matching profile, 2=Like 1 if available profiles changed", _, true, 0.0, true, 2.0); RegAdminCmd("sm_reloadchattags", Cmd_Reload, ADMFLAG_CONFIG, "Reload chat tags"); for (int client=1;client<=MaxClients;client++) { - if (IsClientInGame(client) && !IsFakeClient(client) && !IsClientReplay(client) && !IsClientSourceTV(client) && IsClientAuthorized(client)) { - OnClientAuthorized(client, ""); - } + OnClientPostAdminCheck(client); } } @@ -80,28 +78,26 @@ public void ChatTagCookieMenu(int client, CookieMenuAction action, any info, cha } } -public Action Cmd_Reload(int admin, int args) -{ +public Action Cmd_Reload(int admin, int args) { LoadConfig(); for (int client=1;client<=MaxClients;client++) { - if (IsClientInGame(client) && !IsFakeClient(client) && !IsClientReplay(client) && !IsClientSourceTV(client) && IsClientAuthorized(client)) { - OnClientAuthorized(client, ""); - } + OnClientPostAdminCheck(client); } ReplyToCommand(admin, "[ChatTag] Reloaded %d profiles", profiles.Length); return Plugin_Handled; } - -public void OnClientAuthorized(int client, const char[] auth) { +public void OnClientPostAdminCheck(int client) { + if (!IsClientInGame(client) || IsFakeClient(client) || IsClientReplay(client) || IsClientSourceTV(client) || !IsClientAuthorized(client)) + return; + char tmp[32]; - bool refresh; ArrayList list = FindApplicableProfiles(client); //check profile hash // // make crc16 int crc; - for (int i; i<=list.Length; i++) { + for (int i; i %04X)", client, refresh ? "Refresh" : "Keep", oldCrc, crc); //if profile should refresh, pick the first match and save if (refresh && list.Length>0) { list.GetString(0, tmp, sizeof(tmp)); + PrintToServer("[ChatTag] %N active profile now %s", client, tmp); mcpct_profile.Set(client, tmp); mcpct_style.Set(client, "15"); } @@ -147,11 +146,14 @@ void LoadConfig() { ChatStyle style; if (kv.GotoFirstSubKey()) { do { + bool isPersonal; kv.GetSectionName(buffer, sizeof(buffer)); if (strncmp(buffer,"STEAM_",6)==0 || buffer[0]=='[') { + isPersonal = true; strcopy(style.filter, sizeof(ChatStyle::filter), buffer); style.name = STR_PERSONAL; } else { + isPersonal = false; kv.GetString("flag", style.filter, sizeof(ChatStyle::filter), ""); strcopy(style.name, sizeof(ChatStyle::name), buffer); } @@ -169,7 +171,14 @@ void LoadConfig() { kv.GetString("textcolor", buffer, sizeof(buffer), "\x01"); TranslateColor(buffer, sizeof(buffer)); strcopy(style.chat, sizeof(ChatStyle::chat), buffer); - profiles.PushArray(style); + if (isPersonal) { + //insert front + profiles.ShiftUp(0); + profiles.SetArray(0, style); + } else { + //push back + profiles.PushArray(style); + } } while (kv.GotoNextKey()); } @@ -196,10 +205,11 @@ bool UpdateProfile(int client) { ChatStyle prof; for (int i=profiles.Length-1; i>=0; i--) { profiles.GetArray(i,prof); - if (StrEqual(prof.name, name, false)) { + if ( StrEqual(prof.name, name, false) || + (StrEqual(STR_PERSONAL, name) && (prof.filter[0]=='[' || strncmp(prof.filter, "STEAM_", 6)==0)) ) { // can we still use this group? - if (!HasPermission(client, prof.filter)) break; + if (!HasPermission(client, prof.filter)) continue; prof.apply(client, style); return true; @@ -210,8 +220,9 @@ bool UpdateProfile(int client) { } void ProcessTagStyle(char[] tag, int taglen, ChatStyleOptions style) { + PrintToServer("[ChatTag] Style: %X", style); char tagcopy[MCP_MAXLENGTH_NAME]; - if (style != CS_NONE) { + if ((style & CS_PREFIX) != CS_NONE) { strcopy(tagcopy, sizeof(tagcopy), tag); if ((style & CS_TAGTEXT)==CS_NONE) style&=~CS_TAGCOLOR; //no point w/o text switch (style & CS_PREFIX) { @@ -274,7 +285,8 @@ ArrayList FindApplicableProfiles(int client) { return applicable; } ChatStyle prof; - for (int i=profiles.Length-1; i>=0; i--) { + int max = profiles.Length; + for (int i; i= 0) { choices.Erase(at); - if (StrEqual(STR_NO_PROFILE, active)) { + if (StrEqual(STR_PERSONAL, active)) { FormatEx(buffer, sizeof(buffer), "[%s]", STR_PERSONAL); menu.AddItem(STR_PERSONAL, buffer, ITEMDRAW_DISABLED); } else { From b6c1ffd11a03697193cffe524e175e2688559192 Mon Sep 17 00:00:00 2001 From: DosMike Date: Sun, 6 Aug 2023 18:14:58 +0200 Subject: [PATCH 4/4] Remove debug prints --- scripting/mcp-chattags.sp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/scripting/mcp-chattags.sp b/scripting/mcp-chattags.sp index 46f714d..ecbbe90 100644 --- a/scripting/mcp-chattags.sp +++ b/scripting/mcp-chattags.sp @@ -117,12 +117,9 @@ public void OnClientPostAdminCheck(int client) { // // should we refresh? bool refresh = ((crc != oldCrc && load==2) || load==1); - PrintToServer("[ChatTag] %N %s (%04X -> %04X)", client, refresh ? "Refresh" : "Keep", oldCrc, crc); - //if profile should refresh, pick the first match and save if (refresh && list.Length>0) { list.GetString(0, tmp, sizeof(tmp)); - PrintToServer("[ChatTag] %N active profile now %s", client, tmp); mcpct_profile.Set(client, tmp); mcpct_style.Set(client, "15"); } @@ -220,7 +217,6 @@ bool UpdateProfile(int client) { } void ProcessTagStyle(char[] tag, int taglen, ChatStyleOptions style) { - PrintToServer("[ChatTag] Style: %X", style); char tagcopy[MCP_MAXLENGTH_NAME]; if ((style & CS_PREFIX) != CS_NONE) { strcopy(tagcopy, sizeof(tagcopy), tag);